mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 04:38:00 +00:00
Add reveal button to mobile-gui
- currently it gets all cards that was revealed by via reveal(...) - update menutab to show scroll indicator as default
This commit is contained in:
@@ -18,6 +18,7 @@ import forge.game.player.PlayerView;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.StackItemView;
|
||||
import forge.game.zone.MagicStack;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.trackable.TrackableObject;
|
||||
import forge.trackable.TrackableProperty;
|
||||
import forge.util.collect.FCollectionView;
|
||||
@@ -64,15 +65,19 @@ public class GameView extends TrackableObject {
|
||||
public String getTitle() {
|
||||
return get(TrackableProperty.Title);
|
||||
}
|
||||
|
||||
public boolean isCommander() {
|
||||
return get(TrackableProperty.IsCommander);
|
||||
}
|
||||
|
||||
public GameType getGameType() {
|
||||
return get(TrackableProperty.GameType);
|
||||
}
|
||||
|
||||
public int getPoisonCountersToLose() {
|
||||
return get(TrackableProperty.PoisonCountersToLose);
|
||||
}
|
||||
|
||||
public int getNumGamesInMatch() {
|
||||
return get(TrackableProperty.NumGamesInMatch);
|
||||
}
|
||||
@@ -80,31 +85,39 @@ public class GameView extends TrackableObject {
|
||||
public int getTurn() {
|
||||
return get(TrackableProperty.Turn);
|
||||
}
|
||||
|
||||
void updateTurn(PhaseHandler phaseHandler) {
|
||||
set(TrackableProperty.Turn, phaseHandler.getTurn());
|
||||
}
|
||||
|
||||
public PhaseType getPhase() {
|
||||
return get(TrackableProperty.Phase);
|
||||
}
|
||||
|
||||
void updatePhase(PhaseHandler phaseHandler) {
|
||||
set(TrackableProperty.Phase, phaseHandler.getPhase());
|
||||
}
|
||||
|
||||
public PlayerView getPlayerTurn() {
|
||||
return get(TrackableProperty.PlayerTurn);
|
||||
}
|
||||
|
||||
void updatePlayerTurn(PhaseHandler phaseHandler) {
|
||||
set(TrackableProperty.PlayerTurn, PlayerView.get(phaseHandler.getPlayerTurn()));
|
||||
}
|
||||
|
||||
public void updateNeedsPhaseRedrawn(PlayerView p, PhaseType ph) {
|
||||
set(TrackableProperty.PlayerTurn, p);
|
||||
set(TrackableProperty.Phase, ph);
|
||||
set(TrackableProperty.NeedsPhaseRedrawn, true);
|
||||
}
|
||||
|
||||
public boolean getNeedsPhaseRedrawn() {
|
||||
if (get(TrackableProperty.NeedsPhaseRedrawn) == null)
|
||||
return false;
|
||||
return get(TrackableProperty.NeedsPhaseRedrawn);
|
||||
}
|
||||
|
||||
public void clearNeedsPhaseRedrawn() {
|
||||
set(TrackableProperty.NeedsPhaseRedrawn, false);
|
||||
}
|
||||
@@ -112,18 +125,23 @@ public class GameView extends TrackableObject {
|
||||
public void updatePlanarPlayer(PlayerView p) {
|
||||
set(TrackableProperty.PlanarPlayer, p);
|
||||
}
|
||||
|
||||
public PlayerView getPlanarPlayer() {
|
||||
return get(TrackableProperty.PlanarPlayer);
|
||||
}
|
||||
|
||||
public FCollectionView<StackItemView> getStack() {
|
||||
return get(TrackableProperty.Stack);
|
||||
}
|
||||
|
||||
public StackItemView peekStack() {
|
||||
return Iterables.getFirst(getStack(), null);
|
||||
}
|
||||
|
||||
public int getStormCount() {
|
||||
return get(TrackableProperty.StormCount);
|
||||
}
|
||||
|
||||
void updateStack(final MagicStack stack) {
|
||||
set(TrackableProperty.Stack, StackItemView.getCollection(stack));
|
||||
set(TrackableProperty.StormCount, stack.getSpellsCastThisTurn().size());
|
||||
@@ -132,6 +150,7 @@ public class GameView extends TrackableObject {
|
||||
public boolean isFirstGameInMatch() {
|
||||
return getNumPlayedGamesInMatch() == 0;
|
||||
}
|
||||
|
||||
public int getNumPlayedGamesInMatch() {
|
||||
return get(TrackableProperty.NumPlayedGamesInMatch);
|
||||
}
|
||||
@@ -139,23 +158,29 @@ public class GameView extends TrackableObject {
|
||||
public boolean isGameOver() {
|
||||
return get(TrackableProperty.GameOver);
|
||||
}
|
||||
|
||||
public boolean isMatchOver() {
|
||||
return get(TrackableProperty.MatchOver);
|
||||
}
|
||||
|
||||
public boolean isMulligan() {
|
||||
if (get(TrackableProperty.Mulligan) == null)
|
||||
return false;
|
||||
return get(TrackableProperty.Mulligan);
|
||||
}
|
||||
|
||||
public void updateIsMulligan(boolean value) {
|
||||
set(TrackableProperty.Mulligan, value);
|
||||
}
|
||||
|
||||
public String getWinningPlayerName() {
|
||||
return get(TrackableProperty.WinningPlayerName);
|
||||
}
|
||||
|
||||
public int getWinningTeam() {
|
||||
return get(TrackableProperty.WinningTeam);
|
||||
}
|
||||
|
||||
void updateGameOver(final Game game) {
|
||||
set(TrackableProperty.GameOver, game.isGameOver());
|
||||
set(TrackableProperty.MatchOver, game.getMatch().isMatchOver());
|
||||
@@ -168,16 +193,27 @@ public class GameView extends TrackableObject {
|
||||
public GameLog getGameLog() {
|
||||
return get(TrackableProperty.GameLog);
|
||||
}
|
||||
|
||||
void updateGameLog(GameLog gameLog) {
|
||||
flagAsChanged(TrackableProperty.GameLog); //don't need to set the property since it won't change
|
||||
}
|
||||
|
||||
public TrackableCollection<CardView> getRevealedCollection() {
|
||||
return get(TrackableProperty.RevealedCardsCollection);
|
||||
}
|
||||
|
||||
public void updateRevealedCards(TrackableCollection<CardView> collection) {
|
||||
set(TrackableProperty.RevealedCardsCollection, collection);
|
||||
}
|
||||
|
||||
public CombatView getCombat() {
|
||||
return get(TrackableProperty.CombatView);
|
||||
}
|
||||
|
||||
public void updateCombatView(CombatView combatView) {
|
||||
set(TrackableProperty.CombatView, combatView);
|
||||
}
|
||||
|
||||
void updateCombat(Combat combat) {
|
||||
if (combat == null) {
|
||||
set(TrackableProperty.CombatView, null);
|
||||
|
||||
@@ -43,6 +43,7 @@ public enum TrackableProperty {
|
||||
SplitCard(TrackableTypes.BooleanType),
|
||||
MergedCards(TrackableTypes.StringType),
|
||||
MergedCardsCollection(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||
RevealedCardsCollection(TrackableTypes.CardViewCollectionType, FreezeMode.IgnoresFreeze),
|
||||
PaperCardBackup(TrackableTypes.IPaperCardType),
|
||||
|
||||
Attacking(TrackableTypes.BooleanType),
|
||||
@@ -278,6 +279,7 @@ public enum TrackableProperty {
|
||||
TrackableProperty(TrackableType<?> type0) {
|
||||
this(type0, FreezeMode.RespectsFreeze);
|
||||
}
|
||||
|
||||
TrackableProperty(TrackableType<?> type0, FreezeMode freezeMode0) {
|
||||
type = type0;
|
||||
freezeMode = freezeMode0;
|
||||
@@ -293,7 +295,7 @@ public enum TrackableProperty {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void updateObjLookup(Tracker tracker, T newObj) {
|
||||
((TrackableType<T>)type).updateObjLookup(tracker, newObj);
|
||||
((TrackableType<T>) type).updateObjLookup(tracker, newObj);
|
||||
}
|
||||
|
||||
public void copyChangedProps(TrackableObject from, TrackableObject to) {
|
||||
@@ -302,15 +304,17 @@ public enum TrackableProperty {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getDefaultValue() {
|
||||
return ((TrackableType<T>)type).getDefaultValue();
|
||||
return ((TrackableType<T>) type).getDefaultValue();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T deserialize(TrackableDeserializer td, T oldValue) {
|
||||
return ((TrackableType<T>)type).deserialize(td, oldValue);
|
||||
return ((TrackableType<T>) type).deserialize(td, oldValue);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> void serialize(TrackableSerializer ts, T value) {
|
||||
((TrackableType<T>)type).serialize(ts, value);
|
||||
((TrackableType<T>) type).serialize(ts, value);
|
||||
}
|
||||
|
||||
//cache array of all properties to allow quick lookup by ordinal,
|
||||
@@ -318,9 +322,11 @@ public enum TrackableProperty {
|
||||
//we don't need to worry about the values changing since we will ensure
|
||||
//both players are on the same version of Forge before allowing them to connect
|
||||
private static TrackableProperty[] props = values();
|
||||
|
||||
public static int serialize(TrackableProperty prop) {
|
||||
return prop.ordinal();
|
||||
}
|
||||
|
||||
public static TrackableProperty deserialize(int ordinal) {
|
||||
return props[ordinal];
|
||||
}
|
||||
|
||||
@@ -1132,7 +1132,8 @@ public class Forge implements ApplicationListener {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static float mouseMovedX = 0;
|
||||
public static float mouseMovedY = 0;
|
||||
private static class MainInputProcessor extends FGestureAdapter {
|
||||
private static final List<FDisplayObject> potentialListeners = new ArrayList<>();
|
||||
private static char lastKeyTyped;
|
||||
@@ -1216,7 +1217,7 @@ public class Forge implements ApplicationListener {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updatePotentialListeners(int x, int y) {
|
||||
private void updatePotentialListeners(float x, float y) {
|
||||
potentialListeners.clear();
|
||||
|
||||
//base potential listeners on object containing touch down point
|
||||
@@ -1391,8 +1392,6 @@ public class Forge implements ApplicationListener {
|
||||
}
|
||||
|
||||
//mouseMoved and scrolled events for desktop version
|
||||
private int mouseMovedX, mouseMovedY;
|
||||
|
||||
@Override
|
||||
public boolean mouseMoved(int screenX, int screenY) {
|
||||
magnify = true;
|
||||
|
||||
@@ -338,6 +338,9 @@ public enum FSkinImage implements FImage {
|
||||
|
||||
FAVICON (FSkinProp.ICO_FAVICON, SourceFile.ICONS),
|
||||
LOCK (FSkinProp.ICO_LOCK, SourceFile.ICONS),
|
||||
//reveal icons
|
||||
SEE (FSkinProp.ICO_SEE, SourceFile.ICONS),
|
||||
UNSEE (FSkinProp.ICO_UNSEE, SourceFile.ICONS),
|
||||
|
||||
//Layout images
|
||||
HANDLE (FSkinProp.IMG_HANDLE, SourceFile.ICONS),
|
||||
|
||||
@@ -774,9 +774,7 @@ public class CardRenderer {
|
||||
}
|
||||
//Darken unselectable cards
|
||||
if (unselectable) {
|
||||
g.setAlphaComposite(0.6f);
|
||||
g.fillRect(Color.BLACK, cx, cy, cw, ch);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
g.fillRect(FSkinColor.getStandardColor(Color.BLACK).alphaColor(0.6f), cx, cy, cw, ch);
|
||||
}
|
||||
//Magenta outline when card is chosen
|
||||
if (MatchController.instance.isUsedToPay(card)) {
|
||||
|
||||
@@ -7,8 +7,13 @@ import forge.Graphics;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinColor.Colors;
|
||||
import forge.assets.FSkinTexture;
|
||||
import forge.gui.GuiBase;
|
||||
import forge.screens.FScreen;
|
||||
import forge.screens.match.views.VDevMenu;
|
||||
import forge.screens.match.views.VGameMenu;
|
||||
import forge.screens.match.views.VLog;
|
||||
import forge.screens.match.views.VPlayers;
|
||||
import forge.screens.match.views.VReveal;
|
||||
import forge.screens.match.views.VStack;
|
||||
import forge.toolbox.FContainer;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FOverlay;
|
||||
@@ -34,6 +39,7 @@ public abstract class FDropDown extends FScrollPane {
|
||||
public FMenuTab getMenuTab() {
|
||||
return menuTab;
|
||||
}
|
||||
|
||||
public void setMenuTab(FMenuTab menuTab0) {
|
||||
menuTab = menuTab0;
|
||||
}
|
||||
@@ -41,6 +47,7 @@ public abstract class FDropDown extends FScrollPane {
|
||||
public FContainer getDropDownContainer() {
|
||||
return dropDownContainer;
|
||||
}
|
||||
|
||||
public void setDropDownContainer(FContainer dropDownContainer0) {
|
||||
dropDownContainer = dropDownContainer0;
|
||||
}
|
||||
@@ -69,9 +76,11 @@ public abstract class FDropDown extends FScrollPane {
|
||||
public void hide() {
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
public void setNextSelected() {
|
||||
scrollToHoveredChild(true);
|
||||
}
|
||||
|
||||
public void setPreviousSelected() {
|
||||
scrollToHoveredChild(false);
|
||||
}
|
||||
@@ -101,7 +110,9 @@ public abstract class FDropDown extends FScrollPane {
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible0) {
|
||||
if (isVisible() == visible0) { return; }
|
||||
if (isVisible() == visible0) {
|
||||
return;
|
||||
}
|
||||
|
||||
//add/remove drop down from its container, current screen, or top overlay when its visibility changes
|
||||
FContainer container = getContainer();
|
||||
@@ -114,8 +125,7 @@ public abstract class FDropDown extends FScrollPane {
|
||||
container.add(backdrop);
|
||||
}
|
||||
container.add(this);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
container.remove(this);
|
||||
if (backdrop != null) {
|
||||
backdrop.setVisible(false);
|
||||
@@ -131,10 +141,13 @@ public abstract class FDropDown extends FScrollPane {
|
||||
}
|
||||
|
||||
protected abstract boolean autoHide();
|
||||
|
||||
protected abstract ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight);
|
||||
|
||||
protected void updateSizeAndPosition() {
|
||||
if (menuTab == null) { return; }
|
||||
if (menuTab == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Rectangle boundary = Forge.getCurrentScreen().getDropDownBoundary();
|
||||
|
||||
@@ -145,8 +158,7 @@ public abstract class FDropDown extends FScrollPane {
|
||||
if (y < boundary.y + boundary.height / 2) {
|
||||
showAbove = false;
|
||||
maxVisibleHeight = boundary.y + boundary.height - y; //prevent covering prompt
|
||||
}
|
||||
else { //handle drop downs at near bottom of screen
|
||||
} else { //handle drop downs at near bottom of screen
|
||||
showAbove = true;
|
||||
y = menuTab.screenPos.y;
|
||||
maxVisibleHeight = y - boundary.y;
|
||||
@@ -191,6 +203,31 @@ public abstract class FDropDown extends FScrollPane {
|
||||
float w = getWidth();
|
||||
float h = getHeight();
|
||||
g.drawRect(2, getBorderColor(), 0, 0, w, h); //ensure border shows up on all sides
|
||||
if (getDropDownOwner() instanceof FMenuTab) {
|
||||
try {
|
||||
if (getScrollLeft() > 0) {
|
||||
float x = getIndicatorMargin();
|
||||
float y = getHeight() / 2;
|
||||
g.fillTriangle(getIndicatorColor(), x, y, x + getIndicatorSize(), y - getIndicatorSize(), x + getIndicatorSize(), y + getIndicatorSize());
|
||||
}
|
||||
if (getScrollLeft() < getMaxScrollLeft()) {
|
||||
float x = getWidth() - getIndicatorMargin();
|
||||
float y = getHeight() / 2;
|
||||
g.fillTriangle(getIndicatorColor(), x, y, x - getIndicatorSize(), y - getIndicatorSize(), x - getIndicatorSize(), y + getIndicatorSize());
|
||||
}
|
||||
if (getScrollTop() > 0) {
|
||||
float x = getWidth() / 2;
|
||||
float y = getIndicatorMargin();
|
||||
g.fillTriangle(getIndicatorColor(), x, y, x - getIndicatorSize(), y + getIndicatorSize(), x + getIndicatorSize(), y + getIndicatorSize());
|
||||
}
|
||||
if (getScrollTop() < getMaxScrollTop()) {
|
||||
float x = getWidth() / 2;
|
||||
float y = getHeight() - getIndicatorSize();
|
||||
g.fillTriangle(getIndicatorColor(), x, y, x - getIndicatorSize(), y - getIndicatorSize(), x + getIndicatorSize(), y - getIndicatorSize());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected FDisplayObject getDropDownOwner() {
|
||||
@@ -201,6 +238,7 @@ public abstract class FDropDown extends FScrollPane {
|
||||
FDisplayObject owner = getDropDownOwner();
|
||||
return owner == null || !owner.screenPos.contains(x, y); //auto-hide when backdrop pressed unless over owner
|
||||
}
|
||||
|
||||
public void tapChild() {
|
||||
if (selectedChild != null) {
|
||||
selectedChild.tap(0, 0, 1);
|
||||
@@ -210,18 +248,20 @@ public abstract class FDropDown extends FScrollPane {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
if (getMenuTab() != null)
|
||||
getMenuTab().clearSelected();
|
||||
hide();
|
||||
}
|
||||
|
||||
public void scrollToHoveredChild(boolean down) {
|
||||
selectedChild = null;
|
||||
for (FDisplayObject fDisplayObject : getChildren()) {
|
||||
if (fDisplayObject.isHovered()) {
|
||||
//System.out.println(fDisplayObject.screenPos.x+"|"+fDisplayObject.screenPos.y);
|
||||
float mod = down ? 0 : -fDisplayObject.screenPos.height;
|
||||
float y = fDisplayObject.screenPos.y+mod;
|
||||
float y = fDisplayObject.screenPos.y + mod;
|
||||
scrollIntoView(fDisplayObject.screenPos.x, y, fDisplayObject.screenPos.width, fDisplayObject.screenPos.height, 0);
|
||||
selectedChild = fDisplayObject;
|
||||
break;
|
||||
@@ -252,7 +292,9 @@ public abstract class FDropDown extends FScrollPane {
|
||||
|
||||
@Override
|
||||
public boolean tap(float x, float y, int count) {
|
||||
if (!isVisible()) { return false; }
|
||||
if (!isVisible()) {
|
||||
return false;
|
||||
}
|
||||
hide(); //always hide if tapped
|
||||
|
||||
return preventOwnerHandlingBackupTap(x, y, count);
|
||||
@@ -260,21 +302,21 @@ public abstract class FDropDown extends FScrollPane {
|
||||
|
||||
@Override
|
||||
public boolean pan(float x, float y, float deltaX, float deltaY, boolean moreVertical) {
|
||||
if (!GuiBase.isAndroid())
|
||||
if (!isMatchHeader())
|
||||
hide(); //always hide if backdrop panned
|
||||
return false; //allow pan to pass through to object behind backdrop
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean fling(float velocityX, float velocityY) {
|
||||
if (!GuiBase.isAndroid())
|
||||
if (!isMatchHeader())
|
||||
hide(); //always hide if backdrop flung
|
||||
return false; //allow fling to pass through to object behind backdrop
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean zoom(float x, float y, float amount) {
|
||||
if (!GuiBase.isAndroid())
|
||||
if (!isMatchHeader())
|
||||
hide(); //always hide if backdrop zoomed
|
||||
return false; //allow zoom to pass through to object behind backdrop
|
||||
}
|
||||
@@ -284,4 +326,20 @@ public abstract class FDropDown extends FScrollPane {
|
||||
//draw nothing for backdrop
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMatchHeader() {
|
||||
if (this instanceof VGameMenu)
|
||||
return true;
|
||||
if (this instanceof VPlayers)
|
||||
return true;
|
||||
if (this instanceof VReveal)
|
||||
return true;
|
||||
if (this instanceof VLog)
|
||||
return true;
|
||||
if (this instanceof VDevMenu)
|
||||
return true;
|
||||
if (this instanceof VStack)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,21 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.badlogic.gdx.Input;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.screens.FScreen.Header;
|
||||
import forge.screens.match.MatchController;
|
||||
|
||||
public class FMenuBar extends Header {
|
||||
private final List<FMenuTab> tabs = new ArrayList<>();
|
||||
private int selected = -1;
|
||||
|
||||
public void addTab(String text0, FDropDown dropDown0) {
|
||||
FMenuTab tab = new FMenuTab(text0, this, dropDown0, tabs.size());
|
||||
addTab(text0, dropDown0, false);
|
||||
}
|
||||
|
||||
public void addTab(String text0, FDropDown dropDown0, boolean iconOnly) {
|
||||
FMenuTab tab = new FMenuTab(text0, this, dropDown0, tabs.size(), iconOnly);
|
||||
dropDown0.setMenuTab(tab);
|
||||
tabs.add(add(tab));
|
||||
}
|
||||
@@ -29,10 +35,22 @@ public class FMenuBar extends Header {
|
||||
protected void doLayout(float width, float height) {
|
||||
int visibleTabCount = 0;
|
||||
float minWidth = 0;
|
||||
int iconOnlyTabCount = 0;
|
||||
float iconMinWidth = 0;
|
||||
for (FMenuTab tab : tabs) {
|
||||
if (tab.isVisible()) {
|
||||
minWidth += tab.getMinWidth();
|
||||
visibleTabCount++;
|
||||
if (Forge.isLandscapeMode()) {
|
||||
if (!tab.iconOnly) {
|
||||
minWidth += tab.getMinWidth();
|
||||
visibleTabCount++;
|
||||
} else {
|
||||
iconMinWidth += tab.getMinWidth();
|
||||
iconOnlyTabCount++;
|
||||
}
|
||||
} else {
|
||||
minWidth += tab.getMinWidth();
|
||||
visibleTabCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
int tabWidth;
|
||||
@@ -40,12 +58,15 @@ public class FMenuBar extends Header {
|
||||
float dx = (width - minWidth) / visibleTabCount;
|
||||
for (FMenuTab tab : tabs) {
|
||||
if (tab.isVisible()) {
|
||||
if (tab.iconOnly) {
|
||||
tab.setActiveIcon(MatchController.instance.getGameView().getRevealedCollection() != null);
|
||||
}
|
||||
tabWidth = Math.round(tab.getMinWidth() + dx);
|
||||
if (x + tabWidth > width) {
|
||||
tabWidth = Math.round(width - x); //prevent final tab extending off screen
|
||||
}
|
||||
tab.setBounds(x, 0, tabWidth, height);
|
||||
x += tabWidth;
|
||||
tab.setBounds(tab.iconOnly ? 0 : x, 0, tab.iconOnly ? tab.getMinWidth() + FMenuTab.PADDING * 2 : tabWidth, height);
|
||||
x += tab.iconOnly ? tab.getMinWidth() + FMenuTab.PADDING * 2 : tabWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,6 +82,7 @@ public class FMenuBar extends Header {
|
||||
public float doLandscapeLayout(float screenWidth, float screenHeight) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setNextSelected() {
|
||||
selected++;
|
||||
closeAll();
|
||||
@@ -68,13 +90,15 @@ public class FMenuBar extends Header {
|
||||
selected = 0;
|
||||
try {
|
||||
tabs.get(selected).showDropDown();
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (selected > tabs.size()) {
|
||||
closeAll();
|
||||
selected = tabs.size();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPreviousSelected() {
|
||||
selected--;
|
||||
closeAll();
|
||||
@@ -82,21 +106,25 @@ public class FMenuBar extends Header {
|
||||
selected = tabs.size();
|
||||
try {
|
||||
tabs.get(selected).showDropDown();
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if (selected < 0) {
|
||||
closeAll();
|
||||
selected = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void closeAll() {
|
||||
for (FMenuTab fMenuTab : tabs) {
|
||||
fMenuTab.hideDropDown();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowingMenu(boolean anyDropdown) {
|
||||
return tabs.stream().anyMatch(tab -> tab.isShowingDropdownMenu(anyDropdown));
|
||||
}
|
||||
|
||||
public void clearSelected() {
|
||||
selected--;
|
||||
if (selected < -1)
|
||||
|
||||
@@ -5,14 +5,18 @@ import com.badlogic.gdx.utils.Align;
|
||||
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinColor.Colors;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.FSkinImage;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.util.Utils;
|
||||
|
||||
public class FMenuTab extends FDisplayObject {
|
||||
public static final FSkinFont FONT = FSkinFont.get(12);
|
||||
boolean iconOnly = false;
|
||||
boolean active = false;
|
||||
private static FSkinColor getSelBackColor() {
|
||||
if (Forge.isMobileAdventureMode)
|
||||
return FSkinColor.get(Colors.ADV_CLR_ACTIVE);
|
||||
@@ -42,10 +46,11 @@ public class FMenuTab extends FDisplayObject {
|
||||
private float minWidth;
|
||||
private int index;
|
||||
|
||||
public FMenuTab(String text0, FMenuBar menuBar0, FDropDown dropDown0, int index0) {
|
||||
public FMenuTab(String text0, FMenuBar menuBar0, FDropDown dropDown0, int index0, boolean iconOnly0) {
|
||||
menuBar = menuBar0;
|
||||
dropDown = dropDown0;
|
||||
index = index0;
|
||||
iconOnly = iconOnly0;
|
||||
setText(text0);
|
||||
}
|
||||
|
||||
@@ -89,6 +94,10 @@ public class FMenuTab extends FDisplayObject {
|
||||
menuBar.revalidate();
|
||||
}
|
||||
|
||||
public void setActiveIcon(boolean value) {
|
||||
active = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(boolean visible0) {
|
||||
if (isVisible() == visible0) { return; }
|
||||
@@ -102,6 +111,10 @@ public class FMenuTab extends FDisplayObject {
|
||||
}
|
||||
|
||||
public float getMinWidth() {
|
||||
if (iconOnly) {
|
||||
float multiplier = Forge.isLandscapeMode() ? 2.5f : 1.8f;
|
||||
return FONT.getLineHeight() * multiplier;
|
||||
}
|
||||
return minWidth;
|
||||
}
|
||||
|
||||
@@ -140,7 +153,14 @@ public class FMenuTab extends FDisplayObject {
|
||||
h = getHeight() - 2 * PADDING;
|
||||
if (isHovered())
|
||||
g.fillRect(getSelBackColor().brighter(), x, y, w, h);
|
||||
g.drawText(text, FONT, foreColor, x, y, w, h, false, Align.center, true);
|
||||
if (iconOnly) {
|
||||
float mod = w * 0.75f;
|
||||
FImage icon = active ? FSkinImage.SEE : FSkinImage.UNSEE;
|
||||
float scaleW = icon.getWidth() * 0.8f;
|
||||
float scaleH = icon.getHeight() * 0.8f;
|
||||
g.drawImage(icon, x + w/2 - scaleW/2, y + h/2 - scaleH/2, scaleW, scaleH);
|
||||
} else
|
||||
g.drawText(text, FONT, foreColor, x, y, w, h, false, Align.center, true);
|
||||
}
|
||||
public boolean isShowingDropdownMenu(boolean any) {
|
||||
if (dropDown == null)
|
||||
|
||||
@@ -123,9 +123,7 @@ public class LoadingOverlay extends FOverlay {
|
||||
float y = (getHeight() - panelHeight) / 2;
|
||||
float oldAlpha = g.getfloatAlphaComposite();
|
||||
//dark translucent back..
|
||||
g.setAlphaComposite(0.6f);
|
||||
g.fillRect(Color.BLACK, 0, 0, getWidth(), getHeight());
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
g.fillRect(FSkinColor.getStandardColor(Color.BLACK).alphaColor(0.6f), 0, 0, getWidth(), getHeight());
|
||||
//overlay
|
||||
g.fillRect(getOverlayColor(), x, y, panelWidth, panelHeight);
|
||||
g.drawRect(Utils.scale(2), getForeColor(), x, y, panelWidth, panelHeight);
|
||||
|
||||
@@ -13,6 +13,7 @@ import forge.card.CardZoom;
|
||||
import forge.game.spellability.StackItemView;
|
||||
import forge.gui.interfaces.IGuiGame;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.screens.match.views.VReveal;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.util.Utils;
|
||||
import forge.util.collect.FCollectionView;
|
||||
@@ -77,6 +78,7 @@ public class MatchScreen extends FScreen {
|
||||
private List<VPlayerPanel> playerPanelsList;
|
||||
private final VGameMenu gameMenu;
|
||||
private final VPlayers players;
|
||||
private final VReveal revealed;
|
||||
private final VLog log;
|
||||
private final VStack stack;
|
||||
private final VDevMenu devMenu;
|
||||
@@ -101,7 +103,7 @@ public class MatchScreen extends FScreen {
|
||||
for (VPlayerPanel playerPanel : playerPanels0) {
|
||||
playerPanels.put(playerPanel.getPlayer(), scroller.add(playerPanel));
|
||||
playerPanel.setFlipped(true);
|
||||
if(!playerPanel.getPlayer().isAI())
|
||||
if (!playerPanel.getPlayer().isAI())
|
||||
humanCount++;
|
||||
}
|
||||
bottomPlayerPanel = playerPanels0.get(0);
|
||||
@@ -111,7 +113,7 @@ public class MatchScreen extends FScreen {
|
||||
//reorder list so bottom player is at the end of the list ensuring top to bottom turn order
|
||||
playerPanelsList.remove(bottomPlayerPanel);
|
||||
playerPanelsList.add(bottomPlayerPanel);
|
||||
selectedPlayer = playerPanelsList.size()-1;
|
||||
selectedPlayer = playerPanelsList.size() - 1;
|
||||
|
||||
bottomPlayerPrompt = add(new VPrompt("", "",
|
||||
e -> getGameController().selectButtonOk(),
|
||||
@@ -133,6 +135,8 @@ public class MatchScreen extends FScreen {
|
||||
gameMenu.setDropDownContainer(this);
|
||||
players = new VPlayers();
|
||||
players.setDropDownContainer(this);
|
||||
revealed = new VReveal();
|
||||
revealed.setDropDownContainer(this);
|
||||
log = new VLog();
|
||||
log.setDropDownContainer(this);
|
||||
devMenu = new VDevMenu();
|
||||
@@ -140,15 +144,15 @@ public class MatchScreen extends FScreen {
|
||||
stack = new VStack();
|
||||
stack.setDropDownContainer(this);
|
||||
|
||||
FMenuBar menuBar = (FMenuBar)getHeader();
|
||||
FMenuBar menuBar = (FMenuBar) getHeader();
|
||||
if (topPlayerPrompt == null) {
|
||||
menuBar.addTab("", revealed, true);
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblGame"), gameMenu);
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblPlayers") + " (" + playerPanels.size() + ")", players);
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblLog"), log);
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblDev"), devMenu);
|
||||
menuBar.addTab( Forge.getLocalizer().getMessage("lblStack") + " (0)", stack);
|
||||
}
|
||||
else {
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblStack") + " (0)", stack);
|
||||
} else {
|
||||
menuBar.addTab("\u2022 \u2022 \u2022", new PlayerSpecificMenu(true));
|
||||
stack.setRotate90(true);
|
||||
menuBar.addTab(Forge.getLocalizer().getMessage("lblStack") + " (0)", stack);
|
||||
@@ -162,11 +166,11 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean is4Player(){
|
||||
private boolean is4Player() {
|
||||
return playerPanels.keySet().size() == 4;
|
||||
}
|
||||
|
||||
private boolean is3Player(){
|
||||
private boolean is3Player() {
|
||||
return playerPanels.keySet().size() == 3;
|
||||
}
|
||||
|
||||
@@ -176,9 +180,10 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
private class HiddenMenuTab extends FMenuTab {
|
||||
private HiddenMenuTab(FDropDown dropDown0) {
|
||||
super(null, null, dropDown0, -1);
|
||||
super(null, null, dropDown0, -1, false);
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String text0) {
|
||||
//avoid trying to set text for this tab
|
||||
@@ -214,8 +219,7 @@ public class MatchScreen extends FScreen {
|
||||
Rectangle menuScreenPos = PlayerSpecificMenu.this.screenPos;
|
||||
if (dropDown.getRotate180()) {
|
||||
dropDown.getMenuTab().screenPos.setPosition(menuScreenPos.x + menuScreenPos.width, menuScreenPos.y);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
dropDown.getMenuTab().screenPos.setPosition(menuScreenPos.x + menuScreenPos.width, menuScreenPos.y + menuScreenPos.height);
|
||||
}
|
||||
dropDown.show();
|
||||
@@ -233,8 +237,7 @@ public class MatchScreen extends FScreen {
|
||||
if (ForgePreferences.DEV_MODE) {
|
||||
addItem(new MenuItem(Forge.getLocalizer().getMessage("lblDev"), devMenu));
|
||||
}
|
||||
}
|
||||
else { //TODO: Support using menu when player doesn't have priority
|
||||
} else { //TODO: Support using menu when player doesn't have priority
|
||||
FMenuItem item = new FMenuItem(Forge.getLocalizer().getMessage("lblMustWaitPriority"), null);
|
||||
item.setEnabled(false);
|
||||
addItem(item);
|
||||
@@ -280,7 +283,7 @@ public class MatchScreen extends FScreen {
|
||||
return topPlayerPanel;
|
||||
}
|
||||
|
||||
public void setViewWinLose( ViewWinLose viewWinLose ){
|
||||
public void setViewWinLose(ViewWinLose viewWinLose) {
|
||||
this.viewWinLose = viewWinLose;
|
||||
}
|
||||
|
||||
@@ -338,29 +341,31 @@ public class MatchScreen extends FScreen {
|
||||
@Override
|
||||
protected void drawOverlay(Graphics g) {
|
||||
final GameView game = MatchController.instance.getGameView();
|
||||
if (game == null) { return; }
|
||||
|
||||
if (gameMenu!=null) {
|
||||
if (gameMenu.getChildCount()>1){
|
||||
if (viewWinLose == null) {
|
||||
gameMenu.getChildAt(0).setEnabled(!game.isMulligan());
|
||||
gameMenu.getChildAt(1).setEnabled(!game.isMulligan());
|
||||
if (!Forge.isMobileAdventureMode) {
|
||||
gameMenu.getChildAt(2).setEnabled(!game.isMulligan());
|
||||
gameMenu.getChildAt(3).setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
gameMenu.getChildAt(0).setEnabled(false);
|
||||
gameMenu.getChildAt(1).setEnabled(false);
|
||||
if (!Forge.isMobileAdventureMode) {
|
||||
gameMenu.getChildAt(2).setEnabled(false);
|
||||
gameMenu.getChildAt(3).setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (game == null) {
|
||||
return;
|
||||
}
|
||||
if (devMenu!=null) {
|
||||
if (devMenu.isVisible()){
|
||||
|
||||
if (gameMenu != null) {
|
||||
if (gameMenu.getChildCount() > 1) {
|
||||
if (viewWinLose == null) {
|
||||
gameMenu.getChildAt(0).setEnabled(!game.isMulligan());
|
||||
gameMenu.getChildAt(1).setEnabled(!game.isMulligan());
|
||||
if (!Forge.isMobileAdventureMode) {
|
||||
gameMenu.getChildAt(2).setEnabled(!game.isMulligan());
|
||||
gameMenu.getChildAt(3).setEnabled(false);
|
||||
}
|
||||
} else {
|
||||
gameMenu.getChildAt(0).setEnabled(false);
|
||||
gameMenu.getChildAt(1).setEnabled(false);
|
||||
if (!Forge.isMobileAdventureMode) {
|
||||
gameMenu.getChildAt(2).setEnabled(false);
|
||||
gameMenu.getChildAt(3).setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (devMenu != null) {
|
||||
if (devMenu.isVisible()) {
|
||||
try {
|
||||
//rollbackphase enable -- todo limit by gametype?
|
||||
devMenu.getChildAt(2).setEnabled(game.getPlayers().size() == 2 && game.getStack().size() == 0 && !GuiBase.isNetworkplay() && game.getPhase().isMain() && !game.getPlayerTurn().isAI());
|
||||
@@ -384,7 +389,7 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
drawArcs(g);
|
||||
if (FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_MAGNIFIER) && Forge.magnify && Forge.magnifyToggle) {
|
||||
if (Forge.isLandscapeMode() && (!GuiBase.isAndroid()||Forge.hasGamepad()) && !CardZoom.isOpen() && potentialListener != null) {
|
||||
if (Forge.isLandscapeMode() && (!GuiBase.isAndroid() || Forge.hasGamepad()) && !CardZoom.isOpen() && potentialListener != null) {
|
||||
for (FDisplayObject object : potentialListener) {
|
||||
if (object != null) {
|
||||
if (object instanceof FCardPanel) {
|
||||
@@ -398,24 +403,23 @@ public class MatchScreen extends FScreen {
|
||||
float cardW = getHeight() * 0.45f;
|
||||
float cardH = FCardPanel.ASPECT_RATIO * cardW;
|
||||
float cardX = !ZoneType.Battlefield.equals(cardPanel.getCard().getZone())
|
||||
? cardPanel.screenPos.x-cardW : cardPanel.screenPos.x+(cardPanel.isTapped()
|
||||
? cardPanel.getWidth() : cardPanel.getWidth()/1.4f);
|
||||
? cardPanel.screenPos.x - cardW : cardPanel.screenPos.x + (cardPanel.isTapped()
|
||||
? cardPanel.getWidth() : cardPanel.getWidth() / 1.4f);
|
||||
if (vPlayerPanel.getSelectedTab() != null && vPlayerPanel.getSelectedTab().isVisible()
|
||||
&& cardX > vPlayerPanel.getSelectedTab().getDisplayArea().getLeft()) {
|
||||
cardX = cardPanel.screenPos.x-cardW;
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
}
|
||||
if ((cardX+cardW) > scroller.getWidth()+scroller.getLeft())
|
||||
cardX = cardPanel.screenPos.x-cardW;
|
||||
if ((cardX + cardW) > scroller.getWidth() + scroller.getLeft())
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
if (vPlayerPanel.getCommandZone() != null
|
||||
&& vPlayerPanel.getCommandZone().isVisible() && cardX > vPlayerPanel.getCommandZone().screenPos.x)
|
||||
cardX = cardPanel.screenPos.x-cardW;
|
||||
float cardY = (cardPanel.screenPos.y-cardH)+cardPanel.getHeight();
|
||||
cardX = cardPanel.screenPos.x - cardW;
|
||||
float cardY = (cardPanel.screenPos.y - cardH) + cardPanel.getHeight();
|
||||
if (vPlayerPanel.getPlayer() == bottomPlayerPanel.getPlayer()) {
|
||||
cardY = bottomPlayerPrompt.screenPos.y - cardH;
|
||||
}
|
||||
else if (cardY < vPlayerPanel.getField().screenPos.y && vPlayerPanel.getPlayer() != bottomPlayerPanel.getPlayer()) {
|
||||
} else if (cardY < vPlayerPanel.getField().screenPos.y && vPlayerPanel.getPlayer() != bottomPlayerPanel.getPlayer()) {
|
||||
cardY = vPlayerPanel.getField().screenPos.y;
|
||||
if ((cardY+cardH) > bottomPlayerPrompt.screenPos.y)
|
||||
if ((cardY + cardH) > bottomPlayerPrompt.screenPos.y)
|
||||
cardY = bottomPlayerPrompt.screenPos.y - cardH;
|
||||
}
|
||||
if (Forge.magnifyShowDetails)
|
||||
@@ -433,11 +437,11 @@ public class MatchScreen extends FScreen {
|
||||
if (object.isHovered() && cardView != null && getStack().isVisible()) {
|
||||
float cardW = getHeight() * 0.45f;
|
||||
float cardH = FCardPanel.ASPECT_RATIO * cardW;
|
||||
float cardX = object.screenPos.x-cardW-Utils.scale(4);
|
||||
float cardY = object.screenPos.y-Utils.scale(2);
|
||||
float cardX = object.screenPos.x - cardW - Utils.scale(4);
|
||||
float cardY = object.screenPos.y - Utils.scale(2);
|
||||
if (cardY < topPlayerPanel.getField().screenPos.y)
|
||||
cardY = topPlayerPanel.getField().screenPos.y;
|
||||
if ((cardY+cardH) > bottomPlayerPrompt.screenPos.y)
|
||||
if ((cardY + cardH) > bottomPlayerPrompt.screenPos.y)
|
||||
cardY = bottomPlayerPrompt.screenPos.y - cardH;
|
||||
if (Forge.magnifyShowDetails)
|
||||
CardImageRenderer.drawDetails(g, cardView, MatchController.instance.getGameView(), false, cardX, cardY, cardW, cardH);
|
||||
@@ -453,6 +457,7 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void drawArcs(Graphics g) {
|
||||
//get all card targeting arrow origins on the battlefield
|
||||
final Map<Integer, Vector2> endpoints = new HashMap<>();
|
||||
@@ -483,11 +488,11 @@ public class MatchScreen extends FScreen {
|
||||
@Override
|
||||
public boolean keyDown(int keyCode) {
|
||||
// TODO: make the keyboard shortcuts configurable on Mobile
|
||||
if (Forge.hasGamepad() && ((FMenuBar)getHeader()).isShowingMenu(false) && (keyCode == Keys.ESCAPE || keyCode == Keys.ENTER))
|
||||
if (Forge.hasGamepad() && ((FMenuBar) getHeader()).isShowingMenu(false) && (keyCode == Keys.ESCAPE || keyCode == Keys.ENTER))
|
||||
return false;
|
||||
switch (keyCode) {
|
||||
case Keys.DPAD_DOWN:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -506,11 +511,12 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
revalidate(true);
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.DPAD_RIGHT:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -519,11 +525,12 @@ public class MatchScreen extends FScreen {
|
||||
selectedPlayerPanel().getSelectedRow().setNextSelected(1);
|
||||
}
|
||||
revalidate(true);
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.DPAD_UP:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -542,11 +549,12 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
revalidate(true);
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.DPAD_LEFT:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -555,11 +563,12 @@ public class MatchScreen extends FScreen {
|
||||
selectedPlayerPanel().getSelectedRow().setPreviousSelected(1);
|
||||
}
|
||||
revalidate(true);
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.BUTTON_Y:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -567,11 +576,12 @@ public class MatchScreen extends FScreen {
|
||||
} else {
|
||||
selectedPlayerPanel().getSelectedRow().showZoom();
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.BUTTON_A:
|
||||
if (!((FMenuBar)getHeader()).isShowingMenu(true)) {
|
||||
if (!((FMenuBar) getHeader()).isShowingMenu(true)) {
|
||||
try {
|
||||
InfoTab selected = selectedPlayerPanel().getSelectedTab();
|
||||
if (selected != null && selected.getDisplayArea().isVisible()) {
|
||||
@@ -581,7 +591,8 @@ public class MatchScreen extends FScreen {
|
||||
//nullPotentialListener();
|
||||
selectedPlayerPanel().getSelectedRow().tapChild();
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Keys.BUTTON_L1: //switch selected panels
|
||||
@@ -590,7 +601,7 @@ public class MatchScreen extends FScreen {
|
||||
selectedPlayerPanel().hideSelectedTab();
|
||||
selectedPlayer--;
|
||||
if (selectedPlayer < 0)
|
||||
selectedPlayer=playerPanelsList.size()-1;
|
||||
selectedPlayer = playerPanelsList.size() - 1;
|
||||
selectedPlayerPanel().closeSelectedTab();
|
||||
selectedPlayerPanel().getSelectedRow().unselectCurrent();
|
||||
//selectedPlayerPanel().setNextSelectedTab(true);
|
||||
@@ -652,8 +663,7 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
if (gui.shouldAlwaysAcceptTrigger(triggerID)) {
|
||||
gui.setShouldAlwaysAskTrigger(triggerID);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gui.setShouldAlwaysAcceptTrigger(triggerID);
|
||||
if (stackInstance.equals(gameView.peekStack())) {
|
||||
//auto-yes if ability is on top of stack
|
||||
@@ -686,8 +696,7 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
if (gui.shouldAlwaysDeclineTrigger(triggerID)) {
|
||||
gui.setShouldAlwaysAskTrigger(triggerID);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gui.setShouldAlwaysDeclineTrigger(triggerID);
|
||||
if (stackInstance.equals(gameView.peekStack())) {
|
||||
//auto-no if ability is on top of stack
|
||||
@@ -749,7 +758,7 @@ public class MatchScreen extends FScreen {
|
||||
public void resetFields() {
|
||||
CardAreaPanel.resetForNewGame();
|
||||
for (VPlayerPanel playerPanel : getPlayerPanels().values()) {
|
||||
for (CardAreaPanel p : playerPanel.getField().getCardPanels()){
|
||||
for (CardAreaPanel p : playerPanel.getField().getCardPanels()) {
|
||||
p.reset();
|
||||
}
|
||||
playerPanel.getZoneTab(ZoneType.Hand).getDisplayArea().clear();
|
||||
@@ -778,22 +787,23 @@ 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
|
||||
// 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
|
||||
// pfps needs to actually do something
|
||||
}
|
||||
|
||||
public void updateSingleCard(final CardView card) {
|
||||
final CardAreaPanel pnl = CardAreaPanel.get(card);
|
||||
if (pnl == null) { return; }
|
||||
if (pnl == null) {
|
||||
return;
|
||||
}
|
||||
final ZoneType zone = card.getZone();
|
||||
if (zone != null && zone == ZoneType.Battlefield) {
|
||||
pnl.updateCard(card);
|
||||
}
|
||||
else { //ensure card not on battlefield is reset such that it no longer thinks it's on the battlefield
|
||||
} else { //ensure card not on battlefield is reset such that it no longer thinks it's on the battlefield
|
||||
pnl.setTapped(false);
|
||||
pnl.getAttachedPanels().clear();
|
||||
pnl.setAttachedToPanel(null);
|
||||
@@ -801,12 +811,14 @@ public class MatchScreen extends FScreen {
|
||||
pnl.setNextPanelInStack(null);
|
||||
}
|
||||
}
|
||||
|
||||
private String daytime = null;
|
||||
private Float time = null;
|
||||
FSkinTexture currentBG = getBG();
|
||||
|
||||
FSkinTexture getBG() {
|
||||
if (Forge.isMobileAdventureMode) {
|
||||
switch(GameScene.instance().getAdventurePlayerLocation(false)) {
|
||||
switch (GameScene.instance().getAdventurePlayerLocation(false)) {
|
||||
case "green":
|
||||
return FSkinTexture.ADV_BG_FOREST;
|
||||
case "black":
|
||||
@@ -831,6 +843,7 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
return FSkinTexture.BG_MATCH;
|
||||
}
|
||||
|
||||
private class BGAnimation extends ForgeAnimation {
|
||||
private static final float DURATION = 1.4f;
|
||||
private float progress = 0;
|
||||
@@ -845,7 +858,7 @@ public class MatchScreen extends FScreen {
|
||||
percentage = 1;
|
||||
}
|
||||
if (MatchController.instance.getGameView().isMatchOver())
|
||||
percentage=1;
|
||||
percentage = 1;
|
||||
if (Forge.isMobileAdventureMode) {
|
||||
if (percentage < 1)
|
||||
g.drawNightDay(image, x, y, w, h, time, false, 0);
|
||||
@@ -870,14 +883,14 @@ public class MatchScreen extends FScreen {
|
||||
if (hasActivePlane()) {
|
||||
String dt = MatchController.instance.getDayTime() == null ? "" : MatchController.instance.getDayTime();
|
||||
if (percentage < 1)
|
||||
g.drawRipple(image, x, y, w, h, 1-percentage);
|
||||
g.drawRipple(image, x, y, w, h, 1 - percentage);
|
||||
if ("Day".equalsIgnoreCase(dt)) {
|
||||
g.setAlphaComposite(percentage);
|
||||
g.drawNightDay(image, x, y, w, h, 100f, true, 1-percentage);
|
||||
g.drawNightDay(image, x, y, w, h, 100f, true, 1 - percentage);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
} else if ("Night".equalsIgnoreCase(dt)) {
|
||||
g.setAlphaComposite(percentage);
|
||||
g.drawNightDay(image, x, y, w, h, -100f, true, 1-percentage);
|
||||
g.drawNightDay(image, x, y, w, h, -100f, true, 1 - percentage);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
}
|
||||
} else {
|
||||
@@ -925,6 +938,7 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class FieldScroller extends FScrollPane {
|
||||
private float extraHeight = 0;
|
||||
private String plane = "";
|
||||
@@ -935,12 +949,12 @@ public class MatchScreen extends FScreen {
|
||||
super.drawBackground(g);
|
||||
if (!FModel.getPreferences().getPrefBoolean(FPref.UI_MATCH_IMAGE_VISIBLE)) {
|
||||
if (!Forge.isMobileAdventureMode)
|
||||
if(!hasActivePlane())
|
||||
if (!hasActivePlane())
|
||||
return;
|
||||
}
|
||||
boolean isGameFast = MatchController.instance.isGameFast();
|
||||
float midField = topPlayerPanel.getBottom();
|
||||
float promptHeight = !Forge.isLandscapeMode() || bottomPlayerPrompt == null ? 0f : bottomPlayerPrompt.getHeight()/1.3f;
|
||||
float promptHeight = !Forge.isLandscapeMode() || bottomPlayerPrompt == null ? 0f : bottomPlayerPrompt.getHeight() / 1.3f;
|
||||
float x = topPlayerPanel.getField().getLeft();
|
||||
float y = midField - topPlayerPanel.getField().getHeight() - promptHeight;
|
||||
float w = getWidth() - x;
|
||||
@@ -998,8 +1012,10 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//auto adjust zoom for local multiplayer landscape mode
|
||||
List<VPlayerPanel> losers = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public void drawOverlay(Graphics g) {
|
||||
if (Forge.isLandscapeMode()) {
|
||||
@@ -1017,20 +1033,20 @@ public class MatchScreen extends FScreen {
|
||||
height = p.getAvatar().getHeight();
|
||||
p.setVisible(false);
|
||||
playerPanelsList.remove(p);
|
||||
System.out.println("Removed panel: "+p.getPlayer().toString());
|
||||
System.out.println("Removed panel: " + p.getPlayer().toString());
|
||||
}
|
||||
}
|
||||
losers.clear();
|
||||
if (playerPanelsList.size() == 2) {
|
||||
//reset avatar size
|
||||
for (VPlayerPanel playerPanel : playerPanelsList) {
|
||||
float size = playerPanel.getAvatar().getWidth()*2;
|
||||
float size = playerPanel.getAvatar().getWidth() * 2;
|
||||
playerPanel.getAvatar().setSize(size, size);
|
||||
playerPanel.revalidate(true);
|
||||
System.out.println("Panel Resized: "+playerPanel.getPlayer().toString());
|
||||
System.out.println("Panel Resized: " + playerPanel.getPlayer().toString());
|
||||
}
|
||||
}
|
||||
zoom(0,0, height);
|
||||
zoom(0, 0, height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,7 +1057,7 @@ public class MatchScreen extends FScreen {
|
||||
|
||||
//field separator lines
|
||||
if (!Forge.isLandscapeMode()) {
|
||||
for (VPlayerPanel playerPanel: playerPanelsList){
|
||||
for (VPlayerPanel playerPanel : playerPanelsList) {
|
||||
midField = playerPanel.getTop();
|
||||
y = midField - playerPanel.getField().getHeight();
|
||||
if (playerPanel.getSelectedTab() == null) {
|
||||
@@ -1051,7 +1067,7 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
}
|
||||
|
||||
for (VPlayerPanel playerPanel: playerPanelsList){
|
||||
for (VPlayerPanel playerPanel : playerPanelsList) {
|
||||
midField = playerPanel.getTop();
|
||||
y = midField - 0.5f;
|
||||
g.drawLine(1, getBorderColor(), x, y, w, y);
|
||||
@@ -1066,7 +1082,7 @@ public class MatchScreen extends FScreen {
|
||||
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
|
||||
float totalHeight = visibleHeight + extraHeight;
|
||||
float avatarHeight = VAvatar.HEIGHT;
|
||||
if (is4Player() || is3Player()){
|
||||
if (is4Player() || is3Player()) {
|
||||
avatarHeight *= 0.5f;
|
||||
}
|
||||
float playerCount = getPlayerPanels().keySet().size();
|
||||
@@ -1154,14 +1170,19 @@ public class MatchScreen extends FScreen {
|
||||
}
|
||||
backupHorzScrollPane(playerPanel.getCommandZone(), x, horzScrollPanes);
|
||||
}
|
||||
|
||||
private void backupHorzScrollPane(FScrollPane scrollPane, float x, Map<FScrollPane, Pair<Float, Float>> horzScrollPanes) {
|
||||
horzScrollPanes.put(scrollPane, Pair.of(scrollPane.getScrollLeft(), scrollPane.getScrollWidth()));
|
||||
}
|
||||
}
|
||||
private String getPlaneName(){ return MatchController.instance.getGameView().getPlanarPlayer().getCurrentPlaneName(); }
|
||||
private boolean hasActivePlane(){
|
||||
if(MatchController.instance.getGameView() != null)
|
||||
if(MatchController.instance.getGameView().getPlanarPlayer() != null) {
|
||||
|
||||
private String getPlaneName() {
|
||||
return MatchController.instance.getGameView().getPlanarPlayer().getCurrentPlaneName();
|
||||
}
|
||||
|
||||
private boolean hasActivePlane() {
|
||||
if (MatchController.instance.getGameView() != null)
|
||||
if (MatchController.instance.getGameView().getPlanarPlayer() != null) {
|
||||
return !MatchController.instance.getGameView().getPlanarPlayer().getCurrentPlaneName().equals("");
|
||||
}
|
||||
return false;
|
||||
@@ -1172,22 +1193,25 @@ public class MatchScreen extends FScreen {
|
||||
setPotentialListener(listeners);
|
||||
super.buildTouchListeners(screenX, screenY, listeners);
|
||||
}
|
||||
|
||||
public VPlayerPanel selectedPlayerPanel() {
|
||||
if (selectedPlayer >= playerPanelsList.size())
|
||||
selectedPlayer = playerPanelsList.size()-1;
|
||||
selectedPlayer = playerPanelsList.size() - 1;
|
||||
if (playerPanelsList.isEmpty())
|
||||
return null;
|
||||
return playerPanelsList.get(selectedPlayer);
|
||||
}
|
||||
|
||||
public static void setPotentialListener(List<FDisplayObject> listener) {
|
||||
if (potentialListener != null)
|
||||
for (FDisplayObject f: potentialListener)
|
||||
for (FDisplayObject f : potentialListener)
|
||||
f.setHovered(false);
|
||||
potentialListener = listener;
|
||||
}
|
||||
|
||||
public static void nullPotentialListener() {
|
||||
if (potentialListener != null)
|
||||
for (FDisplayObject f: potentialListener)
|
||||
for (FDisplayObject f : potentialListener)
|
||||
f.setHovered(false);
|
||||
potentialListener = null;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.Graphics;
|
||||
import forge.animation.ForgeAnimation;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkin;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.player.PlayerView;
|
||||
@@ -153,15 +154,11 @@ public class VAvatar extends FDisplayObject {
|
||||
float alpha = displayPriority ? 1f : 0.8f;
|
||||
if (alphaModifier < 1)
|
||||
alpha = alphaModifier;
|
||||
g.setAlphaComposite(alpha);
|
||||
g.drawRect(w / 16f, Color.CYAN, 0, 0, w, h);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
g.drawRect(w / 16f, FSkinColor.getStandardColor(Color.CYAN).alphaColor(alpha), 0, 0, w, h);
|
||||
}
|
||||
//priority indicator
|
||||
if (displayPriority && player.getHasPriority() && alphaModifier == 1) {
|
||||
g.setAlphaComposite(0.6f);
|
||||
g.drawRect(w / 16f, Color.LIME, 0, 0, w, h);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
g.drawRect(w / 16f, FSkinColor.getStandardColor(Color.LIME).alphaColor(0.6f), 0, 0, w, h);
|
||||
}
|
||||
//highlighted
|
||||
if (MatchController.instance.isHighlighted(player)) {
|
||||
|
||||
159
forge-gui-mobile/src/forge/screens/match/views/VReveal.java
Normal file
159
forge-gui-mobile/src/forge/screens/match/views/VReveal.java
Normal file
@@ -0,0 +1,159 @@
|
||||
package forge.screens.match.views;
|
||||
|
||||
import com.badlogic.gdx.utils.Align;
|
||||
import forge.Forge;
|
||||
import forge.Graphics;
|
||||
import forge.assets.FImage;
|
||||
import forge.assets.FSkinColor;
|
||||
import forge.assets.FSkinFont;
|
||||
import forge.assets.TextRenderer;
|
||||
import forge.card.CardRenderer;
|
||||
import forge.card.CardZoom;
|
||||
import forge.game.card.CardView;
|
||||
import forge.gui.card.CardDetailUtil;
|
||||
import forge.menu.FDropDown;
|
||||
import forge.screens.match.MatchController;
|
||||
import forge.toolbox.FDisplayObject;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class VReveal extends FDropDown {
|
||||
public static final float MARGINS = Utils.scale(4);
|
||||
private static final FSkinFont FONT = FSkinFont.get(11);
|
||||
public static final float PADDING = Utils.scale(3);
|
||||
private TrackableCollection<CardView> revealed;
|
||||
|
||||
private static FSkinColor getAltRowColor() {
|
||||
if (Forge.isMobileAdventureMode)
|
||||
return FSkinColor.get(FSkinColor.Colors.ADV_CLR_ZEBRA);
|
||||
return FSkinColor.get(FSkinColor.Colors.CLR_ZEBRA);
|
||||
}
|
||||
|
||||
private static FSkinColor getRowColor() {
|
||||
return getAltRowColor().darker();
|
||||
}
|
||||
|
||||
private static FSkinColor getForeColor() {
|
||||
if (Forge.isMobileAdventureMode)
|
||||
return FSkinColor.get(FSkinColor.Colors.ADV_CLR_TEXT);
|
||||
return FSkinColor.get(FSkinColor.Colors.CLR_TEXT);
|
||||
}
|
||||
|
||||
private final TextRenderer renderer = new TextRenderer(false);
|
||||
|
||||
@Override
|
||||
protected boolean autoHide() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawBackground(Graphics g) {
|
||||
float w = getWidth();
|
||||
float h = getHeight();
|
||||
g.fillRect(getRowColor(), 0, 0, w, h); //can fill background with main row color since drop down will never be taller than number of rows
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ScrollBounds updateAndGetPaneSize(float maxWidth, float maxVisibleHeight) {
|
||||
float x = MARGINS;
|
||||
float y = MARGINS;
|
||||
float totalWidth = Forge.getScreenWidth();
|
||||
float width = totalWidth - 2 * MARGINS;
|
||||
float entryHeight;
|
||||
float entryWidth = totalWidth;
|
||||
float minWidth = 4 * Utils.AVG_FINGER_WIDTH;
|
||||
if (entryWidth < minWidth) {
|
||||
entryWidth = minWidth;
|
||||
}
|
||||
revealed = MatchController.instance.getGameView().getRevealedCollection();
|
||||
if (revealed == null || revealed.isEmpty()) {
|
||||
FLabel label = add(new FLabel.Builder().text("[" + Forge.getLocalizer().getMessage("lblEmpty") + "]").font(FSkinFont.get(11)).align(Align.center).build());
|
||||
|
||||
float height = Math.round(label.getAutoSizeBounds().height) + 2 * PADDING;
|
||||
label.setBounds(x, y, width, height);
|
||||
|
||||
return new ScrollBounds(totalWidth, y + height + MARGINS);
|
||||
} else {
|
||||
clear();
|
||||
boolean isAltRow = false;
|
||||
RevealEntryDisplay revealEntryDisplay;
|
||||
x = getMenuTab().screenPos.x;
|
||||
y = 1;
|
||||
for (CardView c : revealed) {
|
||||
revealEntryDisplay = add(new RevealEntryDisplay(c, isAltRow));
|
||||
isAltRow = !isAltRow;
|
||||
entryHeight = revealEntryDisplay.getMinHeight(entryWidth) + MARGINS;
|
||||
revealEntryDisplay.setBounds(0, y, entryWidth, entryHeight);
|
||||
y += entryHeight;
|
||||
}
|
||||
}
|
||||
return new ScrollBounds(totalWidth, y + MARGINS);
|
||||
}
|
||||
|
||||
private class RevealEntryDisplay extends FDisplayObject {
|
||||
CardView card;
|
||||
boolean altRow;
|
||||
String text;
|
||||
FImage cardArt;
|
||||
|
||||
private RevealEntryDisplay(CardView cardView, boolean isAltRow) {
|
||||
card = cardView;
|
||||
altRow = isAltRow;
|
||||
text = CardTranslation.getTranslatedName(card.getCurrentState().getName()) + "\n" + formatType();
|
||||
cardArt = CardRenderer.getCardArt(cardView);
|
||||
}
|
||||
|
||||
private float getMinHeight(float width) {
|
||||
width -= 2 * PADDING; //account for left and right insets
|
||||
float height = renderer.getWrappedBounds("\n", FONT, width).height;
|
||||
height += 2 * PADDING;
|
||||
return Math.round(height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tap(float x, float y, int count) {
|
||||
try {
|
||||
List<CardView> cardViewList = new ArrayList<>(revealed);
|
||||
int index = cardViewList.indexOf(card);
|
||||
CardZoom.show(cardViewList, index, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Graphics g) {
|
||||
float w = getWidth();
|
||||
float h = getHeight();
|
||||
float cardArtWidth = h * 1.302f;
|
||||
|
||||
if (altRow) {
|
||||
g.fillRect(getAltRowColor(), 0, 0, w, h);
|
||||
}
|
||||
if (isHovered()) {
|
||||
g.fillRect(getForeColor().brighter().alphaColor(0.3f), 0, 0, w, h);
|
||||
}
|
||||
g.drawImage(cardArt, 0, 0, cardArtWidth, h);
|
||||
//use full height without padding so text not scaled down
|
||||
renderer.drawText(g, text, FONT, getForeColor(), cardArtWidth + PADDING, PADDING, w - (2 * PADDING + cardArtWidth), h, 0, h, false, Align.left, false);
|
||||
}
|
||||
|
||||
private String formatType() {
|
||||
String type = CardDetailUtil.formatCardType(card.getCurrentState(), true);
|
||||
if (card.getCurrentState().isCreature()) { //include P/T or Loyalty at end of type
|
||||
type += " (" + card.getCurrentState().getPower() + " / " + card.getCurrentState().getToughness() + ")";
|
||||
} else if (card.getCurrentState().isPlaneswalker()) {
|
||||
type += " (" + card.getCurrentState().getLoyalty() + ")";
|
||||
} else if (card.getCurrentState().getType().hasSubtype("Vehicle")) {
|
||||
type += String.format(" [%s / %s]", card.getCurrentState().getPower(), card.getCurrentState().getToughness());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -427,9 +427,7 @@ public class FLabel extends FDisplayObject implements IButton {
|
||||
else if (!text.isEmpty()) {
|
||||
float oldAlpha = g.getfloatAlphaComposite();
|
||||
if (isHovered() && selectable) {
|
||||
g.setAlphaComposite(0.4f);
|
||||
g.fillRect(Color.GRAY, x, y, w, h);
|
||||
g.setAlphaComposite(oldAlpha);
|
||||
g.fillRect(FSkinColor.getStandardColor(Color.GRAY).alphaColor(0.4f), x, y, w, h);
|
||||
}
|
||||
drawText(g, x, y, w, h, alignment);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import forge.util.Utils;
|
||||
|
||||
public abstract class FScrollPane extends FContainer {
|
||||
private static final float FLING_DECEL = 750f;
|
||||
private static FSkinColor getIndicatorColor() {
|
||||
public static FSkinColor getIndicatorColor() {
|
||||
if (Forge.isMobileAdventureMode)
|
||||
return FSkinColor.get(FSkinColor.Colors.ADV_CLR_TEXT).alphaColor(0.7f);
|
||||
return FSkinColor.get(FSkinColor.Colors.CLR_TEXT).alphaColor(0.7f);
|
||||
@@ -30,6 +30,14 @@ public abstract class FScrollPane extends FContainer {
|
||||
scrollBounds = new ScrollBounds();
|
||||
}
|
||||
|
||||
public float getIndicatorMargin() {
|
||||
return INDICATOR_MARGIN;
|
||||
}
|
||||
|
||||
public float getIndicatorSize() {
|
||||
return INDICATOR_SIZE;
|
||||
}
|
||||
|
||||
public float getScrollLeft() {
|
||||
return scrollLeft;
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.1 MiB |
@@ -9,6 +9,7 @@ import java.util.Set;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import forge.trackable.TrackableCollection;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
@@ -50,12 +51,15 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public final boolean hasLocalPlayers() {
|
||||
return !gameControllers.isEmpty();
|
||||
}
|
||||
|
||||
public final Set<PlayerView> getLocalPlayers() {
|
||||
return gameControllers.keySet();
|
||||
}
|
||||
|
||||
public final int getLocalPlayerCount() {
|
||||
return gameControllers.size();
|
||||
}
|
||||
|
||||
public final boolean isLocalPlayer(final PlayerView player) {
|
||||
return gameControllers.containsKey(player);
|
||||
}
|
||||
@@ -94,12 +98,15 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
currentPlayer = player;
|
||||
updateCurrentPlayer(player);
|
||||
}
|
||||
|
||||
protected abstract void updateCurrentPlayer(PlayerView player);
|
||||
|
||||
private GameView gameView = null;
|
||||
|
||||
public final GameView getGameView() {
|
||||
return gameView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameView(final GameView gameView0) {
|
||||
if (gameView == null || gameView0 == null) {
|
||||
@@ -118,6 +125,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public final IGameController getGameController() {
|
||||
return getGameController(getCurrentPlayer());
|
||||
}
|
||||
|
||||
public final IGameController getGameController(final PlayerView player) {
|
||||
if (player == null) {
|
||||
return spectator;
|
||||
@@ -180,6 +188,16 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
updateCards(Collections.singleton(card));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRevealedCards(TrackableCollection<CardView> collection) {
|
||||
if (gameView != null) {
|
||||
TrackableCollection<CardView> existing = gameView.getRevealedCollection();
|
||||
if (existing != null)
|
||||
collection.addAll(existing);
|
||||
gameView.updateRevealedCards(collection);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshCardDetails(final Iterable<CardView> cards) {
|
||||
//not needed for base game implementation
|
||||
@@ -199,7 +217,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
if (gameView != null && gameView.isGameOver()) {
|
||||
return true;
|
||||
}
|
||||
if (spectator!=null) { //workaround fix!! this is needed on above code or it will
|
||||
if (spectator != null) { //workaround fix!! this is needed on above code or it will
|
||||
for (Map.Entry<PlayerView, IGameController> e : gameControllers.entrySet()) {
|
||||
if (e.getValue().equals(spectator)) {
|
||||
gameControllers.remove(e.getKey());
|
||||
@@ -212,7 +230,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
if (getGameController().mayLookAtAllCards()) { // when it bugged here, the game thinks the spectator (null)
|
||||
return true; // is the humancontroller here (maybe because there is an existing game thread???)
|
||||
}
|
||||
} catch (NullPointerException e){
|
||||
} catch (NullPointerException e) {
|
||||
return true; // return true so it will work as normal
|
||||
}
|
||||
} else {
|
||||
@@ -225,10 +243,14 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
@Override
|
||||
public boolean mayFlip(final CardView cv) {
|
||||
if (cv == null) { return false; }
|
||||
if (cv == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CardStateView altState = cv.getAlternateState();
|
||||
if (altState == null) { return false; }
|
||||
if (altState == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (altState.getState()) {
|
||||
case Original:
|
||||
@@ -252,6 +274,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
|
||||
private final Set<PlayerView> highlightedPlayers = Sets.newHashSet();
|
||||
|
||||
@Override
|
||||
public void setHighlighted(final PlayerView pv, final boolean b) {
|
||||
final boolean hasChanged = b ? highlightedPlayers.add(pv) : highlightedPlayers.remove(pv);
|
||||
@@ -265,6 +288,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
|
||||
private final Set<CardView> highlightedCards = Sets.newHashSet();
|
||||
|
||||
// used to highlight cards in UI
|
||||
@Override
|
||||
public void setUsedToPay(final CardView card, final boolean value) {
|
||||
@@ -279,34 +303,56 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
|
||||
private final Set<CardView> selectableCards = Sets.newHashSet();
|
||||
|
||||
public void setSelectables(final Iterable<CardView> cards) {
|
||||
for (CardView cv : cards) { selectableCards.add(cv); }
|
||||
for (CardView cv : cards) {
|
||||
selectableCards.add(cv);
|
||||
}
|
||||
}
|
||||
|
||||
public void clearSelectables() {
|
||||
selectableCards.clear();
|
||||
}
|
||||
|
||||
public boolean isSelectable(final CardView card) {
|
||||
return selectableCards.contains(card);
|
||||
}
|
||||
|
||||
public boolean isSelecting() {
|
||||
return !selectableCards.isEmpty();
|
||||
}
|
||||
public boolean isGamePaused() { return gamePause; }
|
||||
public boolean isGameFast() { return gameSpeed; }
|
||||
public void setgamePause(boolean pause) { gamePause = pause; }
|
||||
public void setGameSpeed(boolean isFast) { gameSpeed = isFast; }
|
||||
|
||||
public boolean isGamePaused() {
|
||||
return gamePause;
|
||||
}
|
||||
|
||||
public boolean isGameFast() {
|
||||
return gameSpeed;
|
||||
}
|
||||
|
||||
public void setgamePause(boolean pause) {
|
||||
gamePause = pause;
|
||||
}
|
||||
|
||||
public void setGameSpeed(boolean isFast) {
|
||||
gameSpeed = isFast;
|
||||
}
|
||||
|
||||
public void pauseMatch() {
|
||||
IGameController controller = spectator;
|
||||
if (controller != null && !isGamePaused())
|
||||
controller.selectButtonOk();
|
||||
}
|
||||
|
||||
public void resumeMatch() {
|
||||
IGameController controller = spectator;
|
||||
if (controller != null && isGamePaused())
|
||||
controller.selectButtonOk();
|
||||
}
|
||||
|
||||
/** Concede game, bring up WinLose UI. */
|
||||
/**
|
||||
* Concede game, bring up WinLose UI.
|
||||
*/
|
||||
public boolean concede() {
|
||||
if (gameView.isGameOver()) {
|
||||
return true;
|
||||
@@ -346,11 +392,9 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
ignoreConcedeChain = false;
|
||||
return false;
|
||||
}
|
||||
else if (spectator == null) {
|
||||
} else if (spectator == null) {
|
||||
return true; //if no local players or spectator, just quit
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (showConfirmDialog(Localizer.getInstance().getMessage("lblCloseGameSpectator"), Localizer.getInstance().getMessage("lblCloseGame"), Localizer.getInstance().getMessage("lblClose"), Localizer.getInstance().getMessage("lblCancel"))) {
|
||||
IGameController controller = spectator;
|
||||
spectator = null; //ensure we don't prompt again, including when calling nextGameDecision below
|
||||
@@ -421,14 +465,11 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
awaitNextInputTask = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
FThreads.invokeInEdtLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (awaitNextInputTimer) {
|
||||
if (awaitNextInputTask != null) {
|
||||
updatePromptForAwait(getCurrentPlayer());
|
||||
awaitNextInputTask = null;
|
||||
}
|
||||
FThreads.invokeInEdtLater(() -> {
|
||||
synchronized (awaitNextInputTimer) {
|
||||
if (awaitNextInputTask != null) {
|
||||
updatePromptForAwait(getCurrentPlayer());
|
||||
awaitNextInputTask = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -451,7 +492,8 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
if (awaitNextInputTask != null) {
|
||||
try {
|
||||
awaitNextInputTask.cancel(); //cancel timer once next input shown if needed
|
||||
} catch (final Exception ex) {} //suppress any exception thrown by cancel()
|
||||
} catch (final Exception ex) {
|
||||
} //suppress any exception thrown by cancel()
|
||||
awaitNextInputTask = null;
|
||||
}
|
||||
}
|
||||
@@ -470,9 +512,11 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
// Abilities to auto-yield to
|
||||
private final Set<String> autoYields = Sets.newHashSet();
|
||||
|
||||
public final Iterable<String> getAutoYields() {
|
||||
return autoYields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean shouldAutoYield(final String key) {
|
||||
String abilityKey = key.indexOf("): ") != -1 ? key.substring(key.indexOf("): ") + 3) : key;
|
||||
@@ -480,6 +524,7 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
return !getDisableAutoYields() && autoYields.contains(yieldPerAbility ? abilityKey : key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShouldAutoYield(final String key, final boolean autoYield) {
|
||||
String abilityKey = key.indexOf("): ") != -1 ? key.substring(key.indexOf("): ") + 3) : key;
|
||||
@@ -487,16 +532,17 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
if (autoYield) {
|
||||
autoYields.add(yieldPerAbility ? abilityKey : key);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
autoYields.remove(yieldPerAbility ? abilityKey : key);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean disableAutoYields;
|
||||
|
||||
public final boolean getDisableAutoYields() {
|
||||
return disableAutoYields;
|
||||
}
|
||||
|
||||
public final void setDisableAutoYields(final boolean b0) {
|
||||
disableAutoYields = b0;
|
||||
}
|
||||
@@ -511,16 +557,29 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
private final Map<Integer, Boolean> triggersAlwaysAccept = Maps.newTreeMap();
|
||||
|
||||
@Override
|
||||
public final boolean shouldAlwaysAcceptTrigger(final int trigger) { return Boolean.TRUE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); }
|
||||
@Override
|
||||
public final boolean shouldAlwaysDeclineTrigger(final int trigger) { return Boolean.FALSE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger))); }
|
||||
public final boolean shouldAlwaysAcceptTrigger(final int trigger) {
|
||||
return Boolean.TRUE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShouldAlwaysAcceptTrigger(final int trigger) { triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.TRUE); }
|
||||
public final boolean shouldAlwaysDeclineTrigger(final int trigger) {
|
||||
return Boolean.FALSE.equals(triggersAlwaysAccept.get(Integer.valueOf(trigger)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShouldAlwaysDeclineTrigger(final int trigger) { triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.FALSE); }
|
||||
public final void setShouldAlwaysAcceptTrigger(final int trigger) {
|
||||
triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShouldAlwaysAskTrigger(final int trigger) { triggersAlwaysAccept.remove(Integer.valueOf(trigger)); }
|
||||
public final void setShouldAlwaysDeclineTrigger(final int trigger) {
|
||||
triggersAlwaysAccept.put(Integer.valueOf(trigger), Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setShouldAlwaysAskTrigger(final int trigger) {
|
||||
triggersAlwaysAccept.remove(Integer.valueOf(trigger));
|
||||
}
|
||||
|
||||
// End of Triggers preliminary choice
|
||||
|
||||
@@ -529,15 +588,12 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @param <T> is automatically inferred.
|
||||
* @param message a {@link java.lang.String} object.
|
||||
* @param choices a T object.
|
||||
* @return null if choices is missing, empty, or if the users' choices are
|
||||
* empty; otherwise, returns the first item in the List returned by
|
||||
* getChoices.
|
||||
* empty; otherwise, returns the first item in the List returned by
|
||||
* getChoices.
|
||||
* @see #getChoices(String, int, int, List)
|
||||
*/
|
||||
@Override
|
||||
@@ -550,17 +606,15 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
}
|
||||
|
||||
// returned Object will never be null
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* getChoice.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* a T object.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @param <T> a T object.
|
||||
* @param message a {@link java.lang.String} object.
|
||||
* @param choices a T object.
|
||||
* @return a T object.
|
||||
*/
|
||||
@Override
|
||||
@@ -588,13 +642,17 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
public Integer getInteger(final String message, final int min) {
|
||||
return getInteger(message, min, Integer.MAX_VALUE, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInteger(final String message, final int min, final int max) {
|
||||
return getInteger(message, min, max, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getInteger(final String message, final int min, final int max, final boolean sortDesc) {
|
||||
if (max <= min) { return min; } //just return min if max <= min
|
||||
if (max <= min) {
|
||||
return min;
|
||||
} //just return min if max <= min
|
||||
|
||||
//force cutting off after 100 numbers at most
|
||||
if (max == Integer.MAX_VALUE) {
|
||||
@@ -654,7 +712,9 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
while (true) {
|
||||
final String str = showInputDialog(prompt, message);
|
||||
if (str == null) { return null; } // that is 'cancel'
|
||||
if (str == null) {
|
||||
return null;
|
||||
} // that is 'cancel'
|
||||
|
||||
if (StringUtils.isNumeric(str)) {
|
||||
final Integer val = Integer.valueOf(str);
|
||||
@@ -696,8 +756,8 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
* current implementation requires the user to cancel in order to get the
|
||||
* new item to be the first item in the resulting list.
|
||||
*
|
||||
* @param title the dialog title.
|
||||
* @param newItem the object to insert.
|
||||
* @param title the dialog title.
|
||||
* @param newItem the object to insert.
|
||||
* @param oldItems the list of objects.
|
||||
* @return A shallow copy of the list of objects, with newItem inserted.
|
||||
*/
|
||||
@@ -753,13 +813,13 @@ public abstract class AbstractGuiGame implements IGuiGame, IMayViewCards {
|
||||
|
||||
@Override
|
||||
public boolean showConfirmDialog(final String message, final String title,
|
||||
final boolean defaultYes) {
|
||||
final boolean defaultYes) {
|
||||
return showConfirmDialog(message, title, Localizer.getInstance().getMessage("lblYes"), Localizer.getInstance().getMessage("lblNo"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showConfirmDialog(final String message, final String title,
|
||||
final String yesButtonText, final String noButtonText) {
|
||||
final String yesButtonText, final String noButtonText) {
|
||||
return showConfirmDialog(message, title, yesButtonText, noButtonText, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,90 +31,142 @@ import forge.util.ITriggerEvent;
|
||||
|
||||
public interface IGuiGame {
|
||||
void setGameView(GameView gameView);
|
||||
|
||||
GameView getGameView();
|
||||
|
||||
void setOriginalGameController(PlayerView view, IGameController gameController);
|
||||
|
||||
void setGameController(PlayerView player, IGameController gameController);
|
||||
|
||||
void setSpectator(IGameController spectator);
|
||||
|
||||
void openView(TrackableCollection<PlayerView> myPlayers);
|
||||
|
||||
void afterGameEnd();
|
||||
|
||||
void showCombat();
|
||||
|
||||
void showPromptMessage(PlayerView playerView, String message);
|
||||
|
||||
void showCardPromptMessage(PlayerView playerView, String message, CardView card);
|
||||
|
||||
void updateButtons(PlayerView owner, boolean okEnabled, boolean cancelEnabled, boolean focusOk);
|
||||
|
||||
void updateButtons(PlayerView owner, String label1, String label2, boolean enable1, boolean enable2, boolean focus1);
|
||||
|
||||
void flashIncorrectAction();
|
||||
|
||||
void alertUser();
|
||||
|
||||
void updatePhase(boolean saveState);
|
||||
|
||||
void updateTurn(PlayerView player);
|
||||
|
||||
void updatePlayerControl();
|
||||
|
||||
void enableOverlay();
|
||||
|
||||
void disableOverlay();
|
||||
|
||||
void finishGame();
|
||||
|
||||
void showManaPool(PlayerView player);
|
||||
|
||||
void hideManaPool(PlayerView player);
|
||||
|
||||
void updateStack();
|
||||
|
||||
void notifyStackAddition(final GameEventSpellAbilityCast event);
|
||||
|
||||
void notifyStackRemoval(final GameEventSpellRemovedFromStack event);
|
||||
|
||||
void handleLandPlayed(Card land);
|
||||
|
||||
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);
|
||||
|
||||
void updateRevealedCards(TrackableCollection<CardView> collection);
|
||||
|
||||
void refreshCardDetails(Iterable<CardView> cards);
|
||||
|
||||
void refreshField();
|
||||
|
||||
GameState getGamestate();
|
||||
|
||||
void updateManaPool(Iterable<PlayerView> manaPoolUpdate);
|
||||
|
||||
void updateLives(Iterable<PlayerView> livesUpdate);
|
||||
|
||||
void setPanelSelection(CardView hostCard);
|
||||
|
||||
SpellAbilityView getAbilityToPlay(CardView hostCard, List<SpellAbilityView> abilities, ITriggerEvent triggerEvent);
|
||||
|
||||
Map<CardView, Integer> assignCombatDamage(CardView attacker, List<CardView> blockers, int damage, GameEntityView defender, boolean overrideOrder, boolean maySkip);
|
||||
|
||||
// The Object passed should be GameEntityView for most case. Can be Byte for "generate mana of any combination" effect
|
||||
Map<Object, Integer> assignGenericAmount(CardView effectSource, Map<Object, Integer> target, int amount, final boolean atLeastOne, final String amountLabel);
|
||||
|
||||
void message(String message);
|
||||
|
||||
void message(String message, String title);
|
||||
|
||||
void showErrorDialog(String message);
|
||||
|
||||
void showErrorDialog(String message, String title);
|
||||
|
||||
boolean showConfirmDialog(String message, String title);
|
||||
|
||||
boolean showConfirmDialog(String message, String title, boolean defaultYes);
|
||||
|
||||
boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText);
|
||||
|
||||
boolean showConfirmDialog(String message, String title, String yesButtonText, String noButtonText, boolean defaultYes);
|
||||
|
||||
int showOptionDialog(String message, String title, FSkinProp icon, List<String> options, int defaultOption);
|
||||
|
||||
String showInputDialog(String message, String title);
|
||||
|
||||
String showInputDialog(String message, String title, FSkinProp icon);
|
||||
|
||||
String showInputDialog(String message, String title, FSkinProp icon, String initialInput);
|
||||
|
||||
String showInputDialog(String message, String title, FSkinProp icon, String initialInput, List<String> inputOptions);
|
||||
|
||||
boolean confirm(CardView c, String question);
|
||||
|
||||
boolean confirm(CardView c, String question, List<String> options);
|
||||
|
||||
boolean confirm(CardView c, String question, boolean defaultIsYes, List<String> options);
|
||||
|
||||
<T> List<T> getChoices(String message, int min, int max, List<T> choices);
|
||||
|
||||
<T> List<T> getChoices(String message, int min, int max, List<T> choices, T selected, Function<T, String> display);
|
||||
|
||||
// Get Integer in range
|
||||
Integer getInteger(String message, int min);
|
||||
|
||||
Integer getInteger(String message, int min, int max);
|
||||
|
||||
Integer getInteger(String message, int min, int max, boolean sortDesc);
|
||||
|
||||
Integer getInteger(String message, int min, int max, int cutoff);
|
||||
|
||||
/**
|
||||
* Convenience for getChoices(message, 0, 1, choices).
|
||||
*
|
||||
* @param <T>
|
||||
* is automatically inferred.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @param <T> is automatically inferred.
|
||||
* @param message a {@link java.lang.String} object.
|
||||
* @param choices a T object.
|
||||
* @return null if choices is missing, empty, or if the users' choices are
|
||||
* empty; otherwise, returns the first item in the List returned by
|
||||
* getChoices.
|
||||
* empty; otherwise, returns the first item in the List returned by
|
||||
* getChoices.
|
||||
*/
|
||||
<T> T oneOrNone(String message, List<T> choices);
|
||||
|
||||
@@ -123,12 +175,9 @@ public interface IGuiGame {
|
||||
* getChoice.
|
||||
* </p>
|
||||
*
|
||||
* @param <T>
|
||||
* a T object.
|
||||
* @param message
|
||||
* a {@link java.lang.String} object.
|
||||
* @param choices
|
||||
* a T object.
|
||||
* @param <T> a T object.
|
||||
* @param message a {@link java.lang.String} object.
|
||||
* @param choices a T object.
|
||||
* @return One of {@code choices}. Can only be {@code null} if {@code choices} is empty.
|
||||
*/
|
||||
<T> T one(String message, List<T> choices);
|
||||
@@ -136,9 +185,11 @@ public interface IGuiGame {
|
||||
<T> void reveal(String message, List<T> items);
|
||||
|
||||
<T> List<T> many(String title, String topCaption, int cnt, List<T> sourceChoices, CardView c);
|
||||
|
||||
<T> List<T> many(String title, String topCaption, int min, int max, List<T> sourceChoices, CardView c);
|
||||
|
||||
<T> List<T> order(String title, String top, List<T> sourceChoices, CardView c);
|
||||
|
||||
<T> List<T> order(String title, String top, int remainingObjectsMin, int remainingObjectsMax, List<T> sourceChoices, List<T> destChoices, CardView referenceCard, boolean sideboardingMode);
|
||||
|
||||
/**
|
||||
@@ -146,53 +197,78 @@ public interface IGuiGame {
|
||||
* current implementation requires the user to cancel in order to get the
|
||||
* new item to be the first item in the resulting list.
|
||||
*
|
||||
* @param title
|
||||
* the dialog title.
|
||||
* @param newItem
|
||||
* the object to insert.
|
||||
* @param oldItems
|
||||
* the list of objects.
|
||||
* @param title the dialog title.
|
||||
* @param newItem the object to insert.
|
||||
* @param oldItems the list of objects.
|
||||
* @return A shallow copy of the list of objects, with newItem inserted.
|
||||
*/
|
||||
<T> List<T> insertInList(String title, T newItem, List<T> oldItems);
|
||||
|
||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main, String message);
|
||||
|
||||
GameEntityView chooseSingleEntityForEffect(String title, List<? extends GameEntityView> optionList, DelayedReveal delayedReveal, boolean isOptional);
|
||||
|
||||
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<CardView> manipulateCardList(String title, final Iterable<CardView> cards, final Iterable<CardView> manipulable, boolean toTop, boolean toBottom, boolean toAnywhere);
|
||||
|
||||
void setCard(CardView card);
|
||||
|
||||
void setPlayerAvatar(LobbyPlayer player, IHasIcon ihi);
|
||||
|
||||
PlayerZoneUpdates openZones(PlayerView controller, Collection<ZoneType> zones, Map<PlayerView, Object> players, boolean backupLastZones);
|
||||
|
||||
void restoreOldZones(PlayerView playerView, PlayerZoneUpdates playerZoneUpdates);
|
||||
|
||||
void setHighlighted(PlayerView pv, boolean b);
|
||||
|
||||
void setUsedToPay(CardView card, boolean value);
|
||||
|
||||
void setSelectables(final Iterable<CardView> cards);
|
||||
|
||||
void clearSelectables();
|
||||
|
||||
boolean isSelecting();
|
||||
|
||||
boolean isGamePaused();
|
||||
|
||||
void setgamePause(boolean pause);
|
||||
|
||||
void setGameSpeed(boolean gameSpeed);
|
||||
|
||||
String getDayTime();
|
||||
|
||||
void updateDayTime(String daytime);
|
||||
|
||||
void awaitNextInput();
|
||||
|
||||
void cancelAwaitNextInput();
|
||||
|
||||
boolean isUiSetToSkipPhase(PlayerView playerTurn, PhaseType phase);
|
||||
|
||||
void autoPassUntilEndOfTurn(PlayerView player);
|
||||
|
||||
boolean mayAutoPass(PlayerView player);
|
||||
|
||||
void autoPassCancel(PlayerView player);
|
||||
|
||||
void updateAutoPassPrompt();
|
||||
|
||||
boolean shouldAutoYield(String key);
|
||||
|
||||
void setShouldAutoYield(String key, boolean autoYield);
|
||||
|
||||
boolean shouldAlwaysAcceptTrigger(int trigger);
|
||||
|
||||
boolean shouldAlwaysDeclineTrigger(int trigger);
|
||||
|
||||
void setShouldAlwaysAcceptTrigger(int trigger);
|
||||
|
||||
void setShouldAlwaysDeclineTrigger(int trigger);
|
||||
|
||||
void setShouldAlwaysAskTrigger(int trigger);
|
||||
|
||||
void clearAutoYields();
|
||||
|
||||
void setCurrentPlayer(PlayerView player);
|
||||
|
||||
@@ -328,6 +328,9 @@ public enum FSkinProp {
|
||||
|
||||
ICO_FAVICON (new int[] {0, 640, 80, 80}, PropType.ICON),
|
||||
ICO_LOCK (new int[] {620, 800, 48, 48}, PropType.ICON),
|
||||
//reveal icons
|
||||
ICO_SEE (new int[] {568, 1520, 60, 40}, PropType.ICON),
|
||||
ICO_UNSEE (new int[] {568, 1560, 60, 40}, PropType.ICON),
|
||||
|
||||
//layout images
|
||||
IMG_HANDLE (new int[] {320, 450, 80, 20}, PropType.IMAGE),
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import forge.trackable.TrackableCollection;
|
||||
import forge.util.ImageUtil;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.Range;
|
||||
@@ -148,7 +149,7 @@ import io.sentry.Sentry;
|
||||
|
||||
/**
|
||||
* A prototype for player controller class
|
||||
*
|
||||
* <p>
|
||||
* Handles phase skips for now.
|
||||
*/
|
||||
public class PlayerControllerHuman extends PlayerController implements IGameController {
|
||||
@@ -258,8 +259,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
* Set this to {@code true} to enable this player to see all cards any other
|
||||
* player can see.
|
||||
*
|
||||
* @param mayLookAtAllCards
|
||||
* the mayLookAtAllCards to set
|
||||
* @param mayLookAtAllCards the mayLookAtAllCards to set
|
||||
*/
|
||||
public void setMayLookAtAllCards(final boolean mayLookAtAllCards) {
|
||||
this.mayLookAtAllCards = mayLookAtAllCards;
|
||||
@@ -271,7 +271,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public SpellAbility getAbilityToPlay(final Card hostCard, final List<SpellAbility> abilities,
|
||||
final ITriggerEvent triggerEvent) {
|
||||
final ITriggerEvent triggerEvent) {
|
||||
// make sure another human player can't choose opponents cards just because he might see them
|
||||
if (triggerEvent != null && !hostCard.isInPlay() && !hostCard.getOwner().equals(player) &&
|
||||
!hostCard.getController().equals(player) &&
|
||||
@@ -355,15 +355,15 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public Map<Card, Integer> assignCombatDamage(final Card attacker, final CardCollectionView blockers, final CardCollectionView remaining,
|
||||
final int damageDealt, final GameEntity defender, final boolean overrideOrder) {
|
||||
final int damageDealt, final GameEntity defender, final boolean overrideOrder) {
|
||||
// Attacker is a poor name here, since the creature assigning damage
|
||||
// could just as easily be the blocker.
|
||||
final Map<Card, Integer> map = Maps.newHashMap();
|
||||
|
||||
if ((attacker.hasKeyword(Keyword.TRAMPLE) && defender != null) || (blockers.size() > 1)
|
||||
|| ((attacker.hasKeyword("You may assign CARDNAME's combat damage divided as you choose among " +
|
||||
"defending player and/or any number of creatures they control.")) && overrideOrder &&
|
||||
blockers.size() > 0) || (attacker.hasKeyword("Trample:Planeswalker") && defender instanceof Card)) {
|
||||
"defending player and/or any number of creatures they control.")) && overrideOrder &&
|
||||
blockers.size() > 0) || (attacker.hasKeyword("Trample:Planeswalker") && defender instanceof Card)) {
|
||||
GameEntityViewMap<Card, CardView> gameCacheBlockers = GameEntityView.getMap(blockers);
|
||||
final CardView vAttacker = CardView.get(attacker);
|
||||
final GameEntityView vDefender = GameEntityView.get(defender);
|
||||
@@ -398,7 +398,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
vAffected.put(GameEntityView.get(e.getKey()), e.getValue());
|
||||
}
|
||||
final Map<Object, Integer> vResult = getGui().assignGenericAmount(vSource, vAffected, shieldAmount, false,
|
||||
localizer.getMessage("lblShield"));
|
||||
localizer.getMessage("lblShield"));
|
||||
Map<GameEntity, Integer> result = new HashMap<>();
|
||||
if (vResult != null) { //fix for netplay
|
||||
for (Map.Entry<GameEntity, Integer> e : affected.entrySet()) {
|
||||
@@ -420,7 +420,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
vAffected.put(it.next(), maxAmount);
|
||||
}
|
||||
final Map<Object, Integer> vResult = getGui().assignGenericAmount(vSource, vAffected, manaAmount, false,
|
||||
localizer.getMessage("lblMana").toLowerCase());
|
||||
localizer.getMessage("lblMana").toLowerCase());
|
||||
Map<Byte, Integer> result = new HashMap<>();
|
||||
if (vResult != null) { //fix for netplay
|
||||
it = colorSet.iterator();
|
||||
@@ -471,7 +471,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
ability.getParamOrDefault("AnnounceTitle", announce);
|
||||
if (cost.isMandatory()) {
|
||||
return chooseNumber(ability, localizer.getMessage("lblChooseAnnounceForCard", announceTitle,
|
||||
CardTranslation.getTranslatedName(ability.getHostCard().getName())) , min, max);
|
||||
CardTranslation.getTranslatedName(ability.getHostCard().getName())), min, max);
|
||||
}
|
||||
if ("NumTimes".equals(announce)) {
|
||||
return getGui().getInteger(localizer.getMessage("lblHowManyTimesToPay", ability.getPayCosts().getTotalMana(),
|
||||
@@ -483,18 +483,18 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public CardCollectionView choosePermanentsToSacrifice(final SpellAbility sa, final int min, final int max,
|
||||
final CardCollectionView valid, final String message) {
|
||||
final CardCollectionView valid, final String message) {
|
||||
return choosePermanentsTo(min, max, valid, message, localizer.getMessage("lblSacrifice").toLowerCase(), sa);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CardCollectionView choosePermanentsToDestroy(final SpellAbility sa, final int min, final int max,
|
||||
final CardCollectionView valid, final String message) {
|
||||
final CardCollectionView valid, final String message) {
|
||||
return choosePermanentsTo(min, max, valid, message, localizer.getMessage("lblDestroy"), sa);
|
||||
}
|
||||
|
||||
private CardCollectionView choosePermanentsTo(final int min, int max, final CardCollectionView valid,
|
||||
final String message, final String action, final SpellAbility sa) {
|
||||
final String message, final String action, final SpellAbility sa) {
|
||||
max = Math.min(max, valid.size());
|
||||
if (max <= 0) {
|
||||
return CardCollection.EMPTY;
|
||||
@@ -516,7 +516,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
private boolean useSelectCardsInput(final FCollectionView<? extends GameEntity> sourceList) {
|
||||
// can't use InputSelect from GUI thread (e.g., DevMode Tutor)
|
||||
if (FThreads.isGuiThread()) { return false; }
|
||||
if (FThreads.isGuiThread()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -535,11 +537,11 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
|
||||
final boolean useUiPointAtCard =
|
||||
(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.Sideboard)) :
|
||||
(cz.is(ZoneType.Hand, player) || cz.is(ZoneType.Battlefield));
|
||||
(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.Sideboard)) :
|
||||
(cz.is(ZoneType.Hand, player) || cz.is(ZoneType.Battlefield));
|
||||
if (!useUiPointAtCard) {
|
||||
return false;
|
||||
}
|
||||
@@ -549,7 +551,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public CardCollectionView chooseCardsForEffect(final CardCollectionView sourceList, final SpellAbility sa,
|
||||
final String title, final int min, final int max, final boolean isOptional, Map<String, Object> params) {
|
||||
final String title, final int min, final int max, final boolean isOptional, Map<String, Object> params) {
|
||||
// If only one card to choose, use a dialog box.
|
||||
// Otherwise, use the order dialog to be able to grab multiple cards in one shot
|
||||
|
||||
@@ -586,8 +588,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public <T extends GameEntity> T chooseSingleEntityForEffect(final FCollectionView<T> optionList,
|
||||
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final boolean isOptional,
|
||||
final Player targetedPlayer, Map<String, Object> params) {
|
||||
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final boolean isOptional,
|
||||
final Player targetedPlayer, Map<String, Object> params) {
|
||||
// Human is supposed to read the message and understand from it what to choose
|
||||
if (optionList.isEmpty()) {
|
||||
if (delayedReveal != null) {
|
||||
@@ -632,7 +634,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
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, Map<String, Object> params) {
|
||||
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer, Map<String, Object> params) {
|
||||
// useful details for debugging problems with the mass select logic
|
||||
Sentry.setExtra("Card", sa.getCardView().toString());
|
||||
Sentry.setExtra("SpellAbility", sa.toString());
|
||||
@@ -688,13 +690,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public int chooseNumber(final SpellAbility sa, final String title, final List<Integer> choices,
|
||||
final Player relatedPlayer) {
|
||||
final Player relatedPlayer) {
|
||||
return getGui().one(title, choices).intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellAbility chooseSingleSpellForEffect(final List<SpellAbility> spells, final SpellAbility sa,
|
||||
final String title, Map<String, Object> params) {
|
||||
final String title, Map<String, Object> params) {
|
||||
if (spells.size() < 2) {
|
||||
return Iterables.getFirst(spells, null);
|
||||
}
|
||||
@@ -719,7 +721,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
//override generic
|
||||
List<SpellAbilityView> chosen = getGui().getChoices(title, num, num, Lists.newArrayList(spellViewCache.keySet()));
|
||||
|
||||
for(SpellAbilityView view : chosen) {
|
||||
for (SpellAbilityView view : chosen) {
|
||||
if (spellViewCache.containsKey(view)) {
|
||||
result.add(spellViewCache.get(view));
|
||||
}
|
||||
@@ -744,13 +746,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
case "FirstRemembered":
|
||||
o = sa.getHostCard().getFirstRemembered();
|
||||
if (o instanceof Card) {
|
||||
show = (Card)o;
|
||||
show = (Card) o;
|
||||
}
|
||||
break;
|
||||
case "LastRemembered":
|
||||
o = sa.getHostCard().getFirstRemembered();
|
||||
if (o instanceof Card) {
|
||||
show = (Card)o;
|
||||
show = (Card) o;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -766,13 +768,13 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean confirmBidAction(final SpellAbility sa, final PlayerActionConfirmMode bidlife, final String string,
|
||||
final int bid, final Player winner) {
|
||||
final int bid, final Player winner) {
|
||||
return InputConfirm.confirm(this, sa, string + " " + localizer.getMessage("lblHighestBidder") + " " + winner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmStaticApplication(final Card hostCard, final GameEntity affected, final String logic,
|
||||
final String message) {
|
||||
final String message) {
|
||||
return InputConfirm.confirm(this, CardView.get(hostCard), message);
|
||||
}
|
||||
|
||||
@@ -919,7 +921,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
final String fm = MessageUtil.formatMessage(message, getLocalPlayerView(), owner);
|
||||
if (!cards.isEmpty()) {
|
||||
tempShowCards(cards);
|
||||
getGui().reveal(fm, CardView.getCollection(cards));
|
||||
TrackableCollection<CardView> collection = CardView.getCollection(cards);
|
||||
getGui().reveal(fm, collection);
|
||||
getGui().updateRevealedCards(collection);
|
||||
endTempShowCards();
|
||||
} else {
|
||||
getGui().message(MessageUtil.formatMessage(localizer.getMessage("lblThereNoCardInPlayerZone", "{player's}", zone.getTranslatedName().toLowerCase()),
|
||||
@@ -935,14 +939,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
|
||||
public ImmutablePair<CardCollection, CardCollection> arrangeForMove(final String title, final FCollectionView<Card> cards, final List<Card> manipulable, final boolean topOK, final boolean bottomOK) {
|
||||
List<Card> result = manipulateCardList(title, cards, manipulable, topOK, bottomOK, false);
|
||||
List<Card> result = manipulateCardList(title, cards, manipulable, topOK, bottomOK, false);
|
||||
CardCollection toBottom = new CardCollection();
|
||||
CardCollection toTop = new CardCollection();
|
||||
for (int i = 0; i<cards.size() && manipulable.contains(result.get(i)) ; i++ ) {
|
||||
for (int i = 0; i < cards.size() && manipulable.contains(result.get(i)); i++) {
|
||||
toTop.add(result.get(i));
|
||||
}
|
||||
if (toTop.size() < cards.size()) { // the top isn't everything
|
||||
for (int i = result.size()-1; i>=0 && manipulable.contains(result.get(i)); i-- ) {
|
||||
for (int i = result.size() - 1; i >= 0 && manipulable.contains(result.get(i)); i--) {
|
||||
toBottom.add(result.get(i));
|
||||
}
|
||||
}
|
||||
@@ -956,10 +960,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
tempShowCards(topN);
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_SELECT_FROM_CARD_DISPLAYS) &&
|
||||
(!GuiBase.getInterface().isLibgdxPort()) && (!GuiBase.isNetworkplay())) { //prevent crash for desktop vs mobile port it will crash the netplay since mobile doesnt have manipulatecardlist, send the alternate below
|
||||
(!GuiBase.getInterface().isLibgdxPort()) && (!GuiBase.isNetworkplay())) { //prevent crash for desktop vs mobile port it will crash the netplay since mobile doesnt have manipulatecardlist, send the alternate below
|
||||
CardCollectionView cardList = player.getCardsIn(ZoneType.Library);
|
||||
ImmutablePair<CardCollection, CardCollection> result =
|
||||
arrangeForMove(localizer.getMessage("lblMoveCardstoToporBbottomofLibrary"), cardList, topN, true, true);
|
||||
arrangeForMove(localizer.getMessage("lblMoveCardstoToporBbottomofLibrary"), cardList, topN, true, true);
|
||||
toTop = result.getLeft();
|
||||
toBottom = result.getRight();
|
||||
} else {
|
||||
@@ -974,7 +978,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
toBottom = new CardCollection();
|
||||
List<CardView> views = getGui().many(localizer.getMessage("lblSelectCardsToBeOutOnTheBottomOfYourLibrary"),
|
||||
localizer.getMessage("lblCardsToPutOnTheBottom"), -1, cardCacheScry.getTrackableKeys(), null);
|
||||
localizer.getMessage("lblCardsToPutOnTheBottom"), -1, cardCacheScry.getTrackableKeys(), null);
|
||||
cardCacheScry.addToList(views, toBottom);
|
||||
|
||||
topN.removeAll(toBottom);
|
||||
@@ -986,7 +990,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
GameEntityViewMap<Card, CardView> cardCacheOrder = GameEntityView.getMap(topN);
|
||||
toTop = new CardCollection();
|
||||
views = getGui().order(localizer.getMessage("lblArrangeCardsToBePutOnTopOfYourLibrary"),
|
||||
localizer.getMessage("lblTopOfLibrary"), cardCacheOrder.getTrackableKeys(), null);
|
||||
localizer.getMessage("lblTopOfLibrary"), cardCacheOrder.getTrackableKeys(), null);
|
||||
cardCacheOrder.addToList(views, toTop);
|
||||
}
|
||||
}
|
||||
@@ -1088,34 +1092,34 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
List<CardView> choices = gameCacheMove.getTrackableKeys();
|
||||
|
||||
switch (destinationZone) {
|
||||
case Library:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoLibrary"), localizer.getMessage(bottomOfLibrary ? "lblClosestToBottom" : "lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case Battlefield:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutOntoBattlefield"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case Graveyard:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoGraveyard"), localizer.getMessage("lblClosestToBottom"), choices, null);
|
||||
break;
|
||||
case Exile:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoExile"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case PlanarDeck:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoPlanarDeck"), localizer.getMessage("lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case SchemeDeck:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoSchemeDeck"), localizer.getMessage("lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case Stack:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCopiesCast"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case None: //for when we want to order but don't really want to move the cards
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCards"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
default:
|
||||
System.out.println("ZoneType " + destinationZone + " - Not Ordered");
|
||||
endTempShowCards();
|
||||
return cards;
|
||||
case Library:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoLibrary"), localizer.getMessage(bottomOfLibrary ? "lblClosestToBottom" : "lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case Battlefield:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutOntoBattlefield"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case Graveyard:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoGraveyard"), localizer.getMessage("lblClosestToBottom"), choices, null);
|
||||
break;
|
||||
case Exile:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoExile"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case PlanarDeck:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoPlanarDeck"), localizer.getMessage("lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case SchemeDeck:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCardsPutIntoSchemeDeck"), localizer.getMessage("lblClosestToTop"), choices, null);
|
||||
break;
|
||||
case Stack:
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCopiesCast"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
case None: //for when we want to order but don't really want to move the cards
|
||||
choices = getGui().order(localizer.getMessage("lblChooseOrderCards"), localizer.getMessage("lblPutFirst"), choices, null);
|
||||
break;
|
||||
default:
|
||||
System.out.println("ZoneType " + destinationZone + " - Not Ordered");
|
||||
endTempShowCards();
|
||||
return cards;
|
||||
}
|
||||
endTempShowCards();
|
||||
CardCollection result = new CardCollection();
|
||||
@@ -1125,7 +1129,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public CardCollectionView chooseCardsToDiscardFrom(final Player p, final SpellAbility sa,
|
||||
final CardCollection valid, final int min, final int max) {
|
||||
final CardCollection valid, final int min, final int max) {
|
||||
boolean optional = min == 0;
|
||||
|
||||
if (p != player) {
|
||||
@@ -1184,8 +1188,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public CardCollectionView chooseCardsToDiscardUnlessType(final int num, final CardCollectionView hand,
|
||||
final String uType, final SpellAbility sa) {
|
||||
String [] splitUTypes = uType.split(",");
|
||||
final String uType, final SpellAbility sa) {
|
||||
String[] splitUTypes = uType.split(",");
|
||||
final InputSelectEntitiesFromList<Card> target = new InputSelectEntitiesFromList<Card>(this, num, num, hand,
|
||||
sa) {
|
||||
private static final long serialVersionUID = -5774108410928795591L;
|
||||
@@ -1206,10 +1210,10 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return super.hasAllTargets();
|
||||
}
|
||||
};
|
||||
int n=1;
|
||||
int n = 1;
|
||||
StringBuilder promptType = new StringBuilder();
|
||||
for (String part : splitUTypes) {
|
||||
if (n==1) {
|
||||
if (n == 1) {
|
||||
promptType.append(part.toLowerCase());
|
||||
} else {
|
||||
promptType.append(" or ").append(part.toLowerCase());
|
||||
@@ -1247,7 +1251,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public String chooseSomeType(final String kindOfType, final SpellAbility sa, final Collection<String> validTypes,
|
||||
final List<String> invalidTypes, final boolean isOptional) {
|
||||
final List<String> invalidTypes, final boolean isOptional) {
|
||||
final List<String> types = Lists.newArrayList(validTypes);
|
||||
if (invalidTypes != null && !invalidTypes.isEmpty()) {
|
||||
Iterables.removeAll(types, invalidTypes);
|
||||
@@ -1378,7 +1382,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public Object vote(final SpellAbility sa, final String prompt, final List<Object> options,
|
||||
final ListMultimap<Object, Player> votes, Player forPlayer) {
|
||||
final ListMultimap<Object, Player> votes, Player forPlayer) {
|
||||
return getGui().one(prompt, options);
|
||||
}
|
||||
|
||||
@@ -1392,7 +1396,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public boolean confirmReplacementEffect(final ReplacementEffect replacementEffect, final SpellAbility effectSA,
|
||||
GameEntity affected, final String question) {
|
||||
GameEntity affected, final String question) {
|
||||
if (GuiBase.getInterface().isLibgdxPort()) {
|
||||
return this.getGui().confirm(effectSA.getView().getHostCard(), question.replaceAll("\n", " "));
|
||||
} else {
|
||||
@@ -1430,7 +1434,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
if (mayAutoPass()) {
|
||||
if (CombatUtil.validateAttackers(combat)) {
|
||||
return; // don't prompt to declare attackers if user chose to
|
||||
// end the turn and not attacking is legal
|
||||
// end the turn and not attacking is legal
|
||||
}
|
||||
// otherwise: cancel auto pass because of this unexpected attack
|
||||
autoPassCancel();
|
||||
@@ -1482,7 +1486,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
if (getGui().isUiSetToSkipPhase(getGame().getPhaseHandler().getPlayerTurn().getView(),
|
||||
getGame().getPhaseHandler().getPhase())) {
|
||||
return null; // avoid prompt for input if stack is empty and
|
||||
// player is set to skip the current phase
|
||||
// player is set to skip the current phase
|
||||
}
|
||||
} else {
|
||||
final SpellAbility ability = stack.peekAbility();
|
||||
@@ -1522,13 +1526,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
return choices;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
final InputSelectCardsFromList inp = new InputSelectCardsFromList(this, nDiscard, nDiscard,
|
||||
@SuppressWarnings("serial") final InputSelectCardsFromList inp = new InputSelectCardsFromList(this, nDiscard, nDiscard,
|
||||
player.getZone(ZoneType.Hand).getCards()) {
|
||||
@Override
|
||||
protected final boolean allowAwaitNextInput() {
|
||||
return true; // prevent Cleanup message getting stuck during
|
||||
// opponent's next turn
|
||||
// opponent's next turn
|
||||
}
|
||||
};
|
||||
final String message = localizer.getMessage("lblCleanupPhase") + "\n"
|
||||
@@ -1551,7 +1554,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean payManaOptional(final Card c, final Cost cost, final SpellAbility sa, final String prompt,
|
||||
final ManaPaymentPurpose purpose) {
|
||||
final ManaPaymentPurpose purpose) {
|
||||
if (sa == null && cost.isOnlyManaCost() && cost.getTotalMana().isZero()
|
||||
&& !FModel.getPreferences().getPrefBoolean(FPref.MATCHPREF_PROMPT_FREE_BLOCKS)) {
|
||||
return true;
|
||||
@@ -1590,36 +1593,36 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean chooseBinary(final SpellAbility sa, final String question, final BinaryChoiceType kindOfChoice,
|
||||
final Boolean defaultVal) {
|
||||
final Boolean defaultVal) {
|
||||
final List<String> labels;
|
||||
switch (kindOfChoice) {
|
||||
case HeadsOrTails:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblHeads"), localizer.getMessage("lblTails"));
|
||||
break;
|
||||
case TapOrUntap:
|
||||
labels = ImmutableList.of(StringUtils.capitalize(localizer.getMessage("lblTap")),
|
||||
localizer.getMessage("lblUntap"));
|
||||
break;
|
||||
case OddsOrEvens:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblOdds"), localizer.getMessage("lblEvens"));
|
||||
break;
|
||||
case UntapOrLeaveTapped:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblUntap"), localizer.getMessage("lblLeaveTapped"));
|
||||
break;
|
||||
case UntapTimeVault:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblUntapAndSkipThisTurn"), localizer.getMessage("lblLeaveTapped"));
|
||||
break;
|
||||
case PlayOrDraw:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblPlay"), localizer.getMessage("lblDraw"));
|
||||
break;
|
||||
case LeftOrRight:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblLeft"), localizer.getMessage("lblRight"));
|
||||
break;
|
||||
case AddOrRemove:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblAddCounter"), localizer.getMessage("lblRemoveCounter"));
|
||||
break;
|
||||
default:
|
||||
labels = ImmutableList.copyOf(kindOfChoice.toString().split("Or"));
|
||||
case HeadsOrTails:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblHeads"), localizer.getMessage("lblTails"));
|
||||
break;
|
||||
case TapOrUntap:
|
||||
labels = ImmutableList.of(StringUtils.capitalize(localizer.getMessage("lblTap")),
|
||||
localizer.getMessage("lblUntap"));
|
||||
break;
|
||||
case OddsOrEvens:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblOdds"), localizer.getMessage("lblEvens"));
|
||||
break;
|
||||
case UntapOrLeaveTapped:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblUntap"), localizer.getMessage("lblLeaveTapped"));
|
||||
break;
|
||||
case UntapTimeVault:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblUntapAndSkipThisTurn"), localizer.getMessage("lblLeaveTapped"));
|
||||
break;
|
||||
case PlayOrDraw:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblPlay"), localizer.getMessage("lblDraw"));
|
||||
break;
|
||||
case LeftOrRight:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblLeft"), localizer.getMessage("lblRight"));
|
||||
break;
|
||||
case AddOrRemove:
|
||||
labels = ImmutableList.of(localizer.getMessage("lblAddCounter"), localizer.getMessage("lblRemoveCounter"));
|
||||
break;
|
||||
default:
|
||||
labels = ImmutableList.copyOf(kindOfChoice.toString().split("Or"));
|
||||
}
|
||||
|
||||
return InputConfirm.confirm(this, sa, question, defaultVal == null || defaultVal.booleanValue(), labels);
|
||||
@@ -1627,9 +1630,9 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean chooseFlipResult(final SpellAbility sa, final Player flipper, final boolean[] results,
|
||||
final boolean call) {
|
||||
final String[] labelsSrc = call ? new String[] { localizer.getMessage("lblHeads"), localizer.getMessage("lblTails") }
|
||||
: new String[] { localizer.getMessage("lblWinTheFlip"), localizer.getMessage("lblLoseTheFlip") };
|
||||
final boolean call) {
|
||||
final String[] labelsSrc = call ? new String[]{localizer.getMessage("lblHeads"), localizer.getMessage("lblTails")}
|
||||
: new String[]{localizer.getMessage("lblWinTheFlip"), localizer.getMessage("lblLoseTheFlip")};
|
||||
final List<String> sortedResults = new ArrayList<String>();
|
||||
for (boolean result : results) {
|
||||
sortedResults.add(labelsSrc[result ? 0 : 1]);
|
||||
@@ -1644,14 +1647,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public Card chooseProtectionShield(final GameEntity entityBeingDamaged, final List<String> options,
|
||||
final Map<String, Card> choiceMap) {
|
||||
final Map<String, Card> choiceMap) {
|
||||
final String title = entityBeingDamaged + " - " + localizer.getMessage("lblSelectPreventionShieldToUse");
|
||||
return choiceMap.get(getGui().one(title, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<SpellAbilityStackInstance, GameObject> chooseTarget(final SpellAbility saSpellskite,
|
||||
final List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
||||
final List<Pair<SpellAbilityStackInstance, GameObject>> allTargets) {
|
||||
if (allTargets.size() < 2) {
|
||||
return Iterables.getFirst(allTargets, null);
|
||||
}
|
||||
@@ -1692,7 +1695,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public List<AbilitySub> chooseModeForAbility(final SpellAbility sa, List<AbilitySub> possible, final int min, final int num,
|
||||
boolean allowRepeat) {
|
||||
boolean allowRepeat) {
|
||||
boolean trackerFrozen = getGame().getTracker().isFrozen();
|
||||
if (trackerFrozen) {
|
||||
// The view tracker needs to be unfrozen to update the SpellAbilityViews at this point, or it may crash
|
||||
@@ -1726,7 +1729,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public List<String> chooseColors(final String message, final SpellAbility sa, final int min, final int max,
|
||||
List<String> options) {
|
||||
List<String> options) {
|
||||
options = options.stream().map(DeckRecognizer::getLocalisedMagicColorName).collect(Collectors.toList());
|
||||
List<String> choices = getGui().getChoices(message, min, max, options);
|
||||
return choices.stream().map(DeckRecognizer::getColorNameByLocalisedName).collect(Collectors.toList());
|
||||
@@ -1736,12 +1739,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
public byte chooseColor(final String message, final SpellAbility sa, final ColorSet colors) {
|
||||
final int cntColors = colors.countColors();
|
||||
switch (cntColors) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return colors.getColor();
|
||||
default:
|
||||
return chooseColorCommon(message, sa == null ? null : sa.getHostCard(), colors, false);
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return colors.getColor();
|
||||
default:
|
||||
return chooseColorCommon(message, sa == null ? null : sa.getHostCard(), colors, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1749,15 +1752,15 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
public byte chooseColorAllowColorless(final String message, final Card c, final ColorSet colors) {
|
||||
final int cntColors = 1 + colors.countColors();
|
||||
switch (cntColors) {
|
||||
case 1:
|
||||
return 0;
|
||||
default:
|
||||
return chooseColorCommon(message, c, colors, true);
|
||||
case 1:
|
||||
return 0;
|
||||
default:
|
||||
return chooseColorCommon(message, c, colors, true);
|
||||
}
|
||||
}
|
||||
|
||||
private byte chooseColorCommon(final String message, final Card c, final ColorSet colors,
|
||||
final boolean withColorless) {
|
||||
final boolean withColorless) {
|
||||
final ImmutableList.Builder<String> colorNamesBuilder = ImmutableList.builder();
|
||||
if (withColorless) {
|
||||
colorNamesBuilder.add(MagicColor.toLongString(MagicColor.COLORLESS));
|
||||
@@ -1778,7 +1781,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public ICardFace chooseSingleCardFace(final SpellAbility sa, final String message, final Predicate<ICardFace> cpp,
|
||||
final String name) {
|
||||
final String name) {
|
||||
final Iterable<ICardFace> cardsFromDb = FModel.getMagicDb().getCommonCards().getAllFaces();
|
||||
final List<ICardFace> cards = Lists.newArrayList(Iterables.filter(cardsFromDb, cpp));
|
||||
CardFaceView cardFaceView;
|
||||
@@ -1794,7 +1797,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public CounterType chooseCounterType(final List<CounterType> options, final SpellAbility sa, final String prompt,
|
||||
Map<String, Object> params) {
|
||||
Map<String, Object> params) {
|
||||
if (options.size() <= 1) {
|
||||
return Iterables.getFirst(options, null);
|
||||
}
|
||||
@@ -1830,7 +1833,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public ReplacementEffect chooseSingleReplacementEffect(final String prompt,
|
||||
final List<ReplacementEffect> possibleReplacers) {
|
||||
final List<ReplacementEffect> possibleReplacers) {
|
||||
final ReplacementEffect first = possibleReplacers.get(0);
|
||||
if (possibleReplacers.size() == 1) {
|
||||
return first;
|
||||
@@ -1853,7 +1856,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean payCostToPreventEffect(final Cost cost, final SpellAbility sa, final boolean alreadyPaid,
|
||||
final FCollectionView<Player> allPayers) {
|
||||
final FCollectionView<Player> allPayers) {
|
||||
// if it's paid by the AI already the human can pay, but it won't change anything
|
||||
return HumanPlay.payCostDuringAbilityResolve(this, player, sa.getHostCard(), cost, sa, null);
|
||||
}
|
||||
@@ -1883,7 +1886,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
if (!needPrompt && !saStr.equals(firstStr) && !currentSa.hasParam("OrderDuplicates")) {
|
||||
needPrompt = true; // prompt by default unless all abilities
|
||||
// are the same
|
||||
// are the same
|
||||
}
|
||||
|
||||
saLookupKey.append(delim).append(saStr);
|
||||
@@ -2065,7 +2068,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean chooseCardsPile(final SpellAbility sa, final CardCollectionView pile1,
|
||||
final CardCollectionView pile2, final String faceUp) {
|
||||
final CardCollectionView pile2, final String faceUp) {
|
||||
final String p1Str = TextUtil.concatNoSpace("-- Pile 1 (", String.valueOf(pile1.size()), " cards) --");
|
||||
final String p2Str = TextUtil.concatNoSpace("-- Pile 2 (", String.valueOf(pile2.size()), " cards) --");
|
||||
|
||||
@@ -2125,23 +2128,23 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
for (Player p : unplayable.keySet()) {
|
||||
final Map<DeckSection, List<? extends PaperCard>> removedUnplayableCards = unplayable.get(p);
|
||||
final List<PaperCard> labels = new ArrayList<>();
|
||||
for (final DeckSection s: new TreeSet<>(removedUnplayableCards.keySet())) {
|
||||
for (final DeckSection s : new TreeSet<>(removedUnplayableCards.keySet())) {
|
||||
if (DeckSection.Sideboard.equals(s))
|
||||
continue;
|
||||
for (PaperCard c: removedUnplayableCards.get(s)) {
|
||||
for (PaperCard c : removedUnplayableCards.get(s)) {
|
||||
labels.add(c);
|
||||
}
|
||||
}
|
||||
if (!labels.isEmpty())
|
||||
getGui().reveal(localizer.getMessage("lblActionFromPlayerDeck", message, Lang.getInstance().getPossessedObject(MessageUtil.mayBeYou(player, p), "")),
|
||||
ImmutableList.copyOf(labels));
|
||||
ImmutableList.copyOf(labels));
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (Player p : unplayable.keySet()) {
|
||||
final Map<DeckSection, List<? extends PaperCard>> removedUnplayableCards = unplayable.get(p);
|
||||
final List<Object> labels = new ArrayList<>();
|
||||
for (final DeckSection s: new TreeSet<>(removedUnplayableCards.keySet())) {
|
||||
for (final DeckSection s : new TreeSet<>(removedUnplayableCards.keySet())) {
|
||||
labels.add("=== " + DeckAIUtils.getLocalizedDeckSection(localizer, s) + " ===");
|
||||
labels.addAll(removedUnplayableCards.get(s));
|
||||
}
|
||||
@@ -2163,7 +2166,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public Map<Card, ManaCostShard> chooseCardsForConvokeOrImprovise(final SpellAbility sa, final ManaCost manaCost,
|
||||
final CardCollectionView untappedCards, boolean improvise) {
|
||||
final CardCollectionView untappedCards, boolean improvise) {
|
||||
final InputSelectCardsForConvokeOrImprovise inp = new InputSelectCardsForConvokeOrImprovise(this, player,
|
||||
manaCost, untappedCards, improvise, sa);
|
||||
inp.showAndWait();
|
||||
@@ -2172,7 +2175,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public String chooseCardName(final SpellAbility sa, final Predicate<ICardFace> cpp, final String valid,
|
||||
final String message) {
|
||||
final String message) {
|
||||
while (true) {
|
||||
final ICardFace cardFace = chooseSingleCardFace(sa, message, cpp, sa.getHostCard().getName());
|
||||
final PaperCard cp = FModel.getMagicDb().getCommonCards().getCard(cardFace.getName());
|
||||
@@ -2188,14 +2191,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public Card chooseSingleCardForZoneChange(final ZoneType destination, final List<ZoneType> origin,
|
||||
final SpellAbility sa, final CardCollection fetchList, final DelayedReveal delayedReveal,
|
||||
final String selectPrompt, final boolean isOptional, final Player decider) {
|
||||
final SpellAbility sa, final CardCollection fetchList, final DelayedReveal delayedReveal,
|
||||
final String selectPrompt, final boolean isOptional, final Player decider) {
|
||||
return chooseSingleEntityForEffect(fetchList, delayedReveal, sa, selectPrompt, isOptional, decider, null);
|
||||
}
|
||||
|
||||
public List<Card> chooseCardsForZoneChange(final ZoneType destination, final List<ZoneType> origin,
|
||||
final SpellAbility sa, final CardCollection fetchList, final int min, final int max, final DelayedReveal delayedReveal,
|
||||
final String selectPrompt, final Player decider) {
|
||||
final SpellAbility sa, final CardCollection fetchList, final int min, final int max, final DelayedReveal delayedReveal,
|
||||
final String selectPrompt, final Player decider) {
|
||||
return chooseEntitiesForEffect(fetchList, min, max, delayedReveal, sa, selectPrompt, decider, null);
|
||||
}
|
||||
|
||||
@@ -2292,7 +2295,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
@Override
|
||||
public boolean selectCard(final CardView cardView, final List<CardView> otherCardViewsToSelect,
|
||||
final ITriggerEvent triggerEvent) {
|
||||
final ITriggerEvent triggerEvent) {
|
||||
return inputProxy.selectCard(cardView, otherCardViewsToSelect, triggerEvent);
|
||||
}
|
||||
|
||||
@@ -2539,7 +2542,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
final Card card = gameCacheCounters.get(cv);
|
||||
|
||||
final ImmutableList<CounterType> counters = subtract ? ImmutableList.copyOf(card.getCounters().keySet())
|
||||
: ImmutableList.copyOf(Collections2.transform(CounterEnumType.values, input -> CounterType.get(input)));
|
||||
: ImmutableList.copyOf(Collections2.transform(CounterEnumType.values, input -> CounterType.get(input)));
|
||||
|
||||
final CounterType counter = getGui().oneOrNone(localizer.getMessage("lblWhichTypeofCounter"), counters);
|
||||
if (counter == null) {
|
||||
@@ -2706,8 +2709,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see forge.player.IDevModeCheats#addCardToExile()
|
||||
*/
|
||||
* @see forge.player.IDevModeCheats#addCardToExile()
|
||||
*/
|
||||
@Override
|
||||
public void castASpell() {
|
||||
addCardToZone(ZoneType.Battlefield, false, false);
|
||||
@@ -2847,7 +2850,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
} else if (targetZone == ZoneType.Library) {
|
||||
if (!repeatLast) {
|
||||
lastTopOfTheLibrary = getGui().confirm(forgeCard.getView(), localizer.getMessage("lblCardShouldBeAddedToLibraryTopOrBottom", CardTranslation.getTranslatedName(forgeCard.getName())),
|
||||
true, Arrays.asList(localizer.getMessage("lblTop"), localizer.getMessage("lblBottom")));
|
||||
true, Arrays.asList(localizer.getMessage("lblTop"), localizer.getMessage("lblBottom")));
|
||||
}
|
||||
if (lastTopOfTheLibrary) {
|
||||
getGame().getAction().moveToLibrary(forgeCard, null);
|
||||
@@ -3148,8 +3151,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
}
|
||||
|
||||
// Fetch cards and players specified by the user input
|
||||
final ZoneType[] zones = { ZoneType.Battlefield, ZoneType.Hand, ZoneType.Graveyard, ZoneType.Exile,
|
||||
ZoneType.Command };
|
||||
final ZoneType[] zones = {ZoneType.Battlefield, ZoneType.Hand, ZoneType.Graveyard, ZoneType.Exile,
|
||||
ZoneType.Command};
|
||||
final CardCollectionView cards = getGame().getCardsIn(Arrays.asList(zones));
|
||||
for (final Pair<Integer, Boolean> entity : entityInfo) {
|
||||
boolean found = false;
|
||||
@@ -3306,14 +3309,14 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
*/
|
||||
@Override
|
||||
public List<OptionalCostValue> chooseOptionalCosts(SpellAbility choosen,
|
||||
List<OptionalCostValue> optionalCost) {
|
||||
List<OptionalCostValue> optionalCost) {
|
||||
return getGui().many(localizer.getMessage("lblChooseOptionalCosts"), localizer.getMessage("lblOptionalCosts"), 0, optionalCost.size(),
|
||||
optionalCost, choosen.getHostCard().getView());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean confirmMulliganScry(Player p) {
|
||||
return InputConfirm.confirm(this, (SpellAbility)null, localizer.getMessage("lblDoYouWanttoScry"));
|
||||
return InputConfirm.confirm(this, (SpellAbility) null, localizer.getMessage("lblDoYouWanttoScry"));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3344,7 +3347,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
|
||||
|
||||
public CardCollection getCardList(Iterable<CardView> cardViews) {
|
||||
CardCollection result = new CardCollection();
|
||||
for(CardView cardView : cardViews){
|
||||
for (CardView cardView : cardViews) {
|
||||
final Card c = this.getCard(cardView);
|
||||
if (c != null) {
|
||||
result.add(c);
|
||||
|
||||
Reference in New Issue
Block a user