mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-16 10:48:00 +00:00
Branch GUI refactoring.
Most of the code has been converted, but some problems remain (mostly with Inputs). Nothing has been tested yet.
This commit is contained in:
4
.project
4
.project
@@ -1,9 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>ForgeLocal</name>
|
||||
<name>forge</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
|
||||
@@ -31,17 +31,11 @@ import forge.control.FControl;
|
||||
import forge.deck.CardPool;
|
||||
import forge.error.BugReportDialog;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.IHasIcon;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -81,6 +75,10 @@ import forge.toolbox.MouseTriggerEvent;
|
||||
import forge.toolbox.special.PhaseLabel;
|
||||
import forge.util.BuildInfo;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@@ -132,7 +130,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayShowCard(Card card) {
|
||||
public boolean mayShowCard(CardView card) {
|
||||
return Singletons.getControl().mayShowCard(card);
|
||||
}
|
||||
|
||||
@@ -153,7 +151,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int showCardOptionDialog(final Card card, String message, String title, FSkinProp skinIcon, String[] options, int defaultOption) {
|
||||
public int showCardOptionDialog(final CardView card, String message, String title, FSkinProp skinIcon, String[] options, int defaultOption) {
|
||||
if (card != null) {
|
||||
FThreads.invokeInEdtAndWait(new Runnable() {
|
||||
@Override
|
||||
@@ -177,7 +175,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode) {
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
|
||||
return GuiChoose.order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
|
||||
}
|
||||
|
||||
@@ -231,10 +229,11 @@ public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public void updatePhase() {
|
||||
PhaseHandler pH = Singletons.getControl().getObservedGame().getPhaseHandler();
|
||||
Player p = pH.getPlayerTurn();
|
||||
PhaseType ph = pH.getPhase();
|
||||
//PhaseHandler pH = Singletons.getControl().getObservedGame().getPhaseHandler();
|
||||
//PhaseType ph = pH.getPhase();
|
||||
|
||||
final PlayerView p = Singletons.getControl().getGameView().getPlayerTurn();
|
||||
final PhaseType ph = Singletons.getControl().getGameView().getPhase();
|
||||
final CMatchUI matchUi = CMatchUI.SINGLETON_INSTANCE;
|
||||
PhaseLabel lbl = matchUi.getFieldViewFor(p).getPhaseIndicator().getLabelFor(ph);
|
||||
|
||||
@@ -245,10 +244,10 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTurn(final GameEventTurnBegan event, final Game game) {
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(event.turnOwner);
|
||||
public void updateTurn(final PlayerView player) {
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(player);
|
||||
SDisplayUtil.showTab(nextField);
|
||||
CPrompt.SINGLETON_INSTANCE.updateText(game);
|
||||
CPrompt.SINGLETON_INSTANCE.updateText();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -273,7 +272,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
|
||||
@Override
|
||||
public void finishGame() {
|
||||
new ViewWinLose(Singletons.getControl().getObservedGame());
|
||||
new ViewWinLose(Singletons.getControl().getGameView());
|
||||
if (showOverlay) {
|
||||
SOverlayUtils.showOverlay();
|
||||
}
|
||||
@@ -290,7 +289,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPanelSelection(Card c) {
|
||||
public void setPanelSelection(final CardView c) {
|
||||
GuiUtils.setPanelSelection(c);
|
||||
}
|
||||
|
||||
@@ -374,7 +373,7 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCard(Card card) {
|
||||
public void setCard(final CardView card) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(card);
|
||||
}
|
||||
|
||||
@@ -384,22 +383,22 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUsedToPay(Card card, boolean b) {
|
||||
public void setUsedToPay(final CardView card, final boolean b) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setUsedToPay(card, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHighlighted(Player player, boolean b) {
|
||||
public void setHighlighted(final PlayerView player, final boolean b) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setHighlighted(player, b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPromptMessage(String message) {
|
||||
public void showPromptMessage(final String message) {
|
||||
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stopAtPhase(Player playerTurn, PhaseType phase) {
|
||||
public boolean stopAtPhase(final PlayerView playerTurn, PhaseType phase) {
|
||||
return CMatchUI.SINGLETON_INSTANCE.stopAtPhase(playerTurn, phase);
|
||||
}
|
||||
|
||||
@@ -409,21 +408,22 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game getGame() {
|
||||
return FControl.instance.getObservedGame();
|
||||
@Deprecated
|
||||
public IGameView getGame() {
|
||||
return FControl.instance.getGameView();
|
||||
}
|
||||
|
||||
public Object showManaPool(Player player) {
|
||||
public Object showManaPool(final PlayerView player) {
|
||||
return null; //not needed since mana pool icons are always visible
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideManaPool(Player player, Object zoneToRestore) {
|
||||
public void hideManaPool(final PlayerView player, final Object zoneToRestore) {
|
||||
//not needed since mana pool icons are always visible
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean openZones(List<ZoneType> zones, Map<Player, Object> players) {
|
||||
public boolean openZones(final List<ZoneType> zones, final Map<PlayerView, Object> players) {
|
||||
if (zones.size() == 1) {
|
||||
switch (zones.get(0)) {
|
||||
case Battlefield:
|
||||
@@ -437,31 +437,31 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restoreOldZones(Map<Player, Object> playersToRestoreZonesFor) {
|
||||
public void restoreOldZones(final Map<PlayerView, Object> playersToRestoreZonesFor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate) {
|
||||
public void updateZones(final List<Pair<PlayerView, ZoneType>> zonesToUpdate) {
|
||||
CMatchUI.SINGLETON_INSTANCE.updateZones(zonesToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCards(Set<Card> cardsToUpdate) {
|
||||
public void updateCards(final Set<CardView> cardsToUpdate) {
|
||||
CMatchUI.SINGLETON_INSTANCE.updateCards(cardsToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshCardDetails(Collection<Card> cards) {
|
||||
public void refreshCardDetails(final Collection<CardView> cards) {
|
||||
CMatchUI.SINGLETON_INSTANCE.refreshCardDetails(cards);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateManaPool(List<Player> manaPoolUpdate) {
|
||||
public void updateManaPool(final List<PlayerView> manaPoolUpdate) {
|
||||
CMatchUI.SINGLETON_INSTANCE.updateManaPool(manaPoolUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLives(List<Player> livesUpdate) {
|
||||
public void updateLives(final List<PlayerView> livesUpdate) {
|
||||
CMatchUI.SINGLETON_INSTANCE.updateLives(livesUpdate);
|
||||
}
|
||||
|
||||
@@ -471,10 +471,11 @@ public class GuiDesktop implements IGuiBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Card, Integer> getDamageToAssign(Card attacker, List<Card> blockers,
|
||||
int damageDealt, GameEntity defender, boolean overrideOrder) {
|
||||
return CMatchUI.SINGLETON_INSTANCE.getDamageToAssign(attacker, blockers,
|
||||
damageDealt, defender, overrideOrder);
|
||||
public Map<CardView, Integer> getDamageToAssign(final CardView attacker,
|
||||
final List<CardView> blockers, final int damageDealt,
|
||||
final GameEntityView defender, final boolean overrideOrder) {
|
||||
return CMatchUI.SINGLETON_INSTANCE.getDamageToAssign(attacker,
|
||||
blockers, damageDealt, defender, overrideOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.item.InventoryItem;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinIcon;
|
||||
import forge.view.CardView;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@@ -80,6 +81,7 @@ public class ImageCache {
|
||||
* retrieve an image from the cache. returns null if the image is not found in the cache
|
||||
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
|
||||
*/
|
||||
@Deprecated
|
||||
public static BufferedImage getImage(Card card, int width, int height) {
|
||||
final String key;
|
||||
if (!Singletons.getControl().mayShowCard(card) || card.isFaceDown()) {
|
||||
@@ -89,7 +91,21 @@ public class ImageCache {
|
||||
}
|
||||
return scaleImage(key, width, height, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* retrieve an image from the cache. returns null if the image is not found in the cache
|
||||
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
|
||||
*/
|
||||
public static BufferedImage getImage(final CardView card, final int width, final int height) {
|
||||
final String key;
|
||||
if (!Singletons.getControl().mayShowCard(card)) {
|
||||
key = ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE;
|
||||
} else {
|
||||
key = card.getOriginal().getImageKey();
|
||||
}
|
||||
return scaleImage(key, width, height, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve an image from the cache. returns null if the image is not found in the cache
|
||||
* and cannot be loaded from disk. pass -1 for width and/or height to avoid resizing in that dimension.
|
||||
|
||||
@@ -17,6 +17,26 @@
|
||||
*/
|
||||
package forge.control;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.KeyEventDispatcher;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.ImageCache;
|
||||
@@ -35,15 +55,21 @@ import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.gui.GuiDialog;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.framework.*;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.player.LobbyPlayerHuman;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.InvalidLayoutFileException;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.gui.framework.SLayoutIO;
|
||||
import forge.gui.framework.SOverflowUtil;
|
||||
import forge.gui.framework.SResizingUtil;
|
||||
import forge.match.input.InputQueue;
|
||||
import forge.menus.ForgeMenu;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.player.LobbyPlayerHuman;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.quest.QuestController;
|
||||
import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.quest.io.QuestDataIO;
|
||||
@@ -66,19 +92,11 @@ import forge.toolbox.special.PhaseIndicator;
|
||||
import forge.util.GuiDisplayUtil;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.NameGenerator;
|
||||
import forge.view.CardView;
|
||||
import forge.view.FFrame;
|
||||
import forge.view.FView;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -97,7 +115,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
private FScreen currentScreen;
|
||||
private boolean altKeyLastDown;
|
||||
private CloseAction closeAction;
|
||||
private Player localPlayer;
|
||||
private PlayerView localPlayer;
|
||||
|
||||
public static enum CloseAction {
|
||||
NONE,
|
||||
@@ -352,6 +370,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
if (children.length != 0) { children[0].setSize(display.getSize()); }
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Player getCurrentPlayer() {
|
||||
// try current priority
|
||||
Player currentPriority = game.getPhaseHandler().getPriorityPlayer();
|
||||
@@ -369,9 +388,13 @@ public enum FControl implements KeyEventDispatcher {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean mayShowCard(Card c) {
|
||||
return game == null || !gameHasHumanPlayer || c.canBeShownTo(getCurrentPlayer());
|
||||
}
|
||||
public boolean mayShowCard(final CardView c) {
|
||||
return gameView == null || !gameHasHumanPlayer || gameView.mayShowCard(c, getCurrentPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
@@ -382,13 +405,19 @@ public enum FControl implements KeyEventDispatcher {
|
||||
}
|
||||
|
||||
private Game game;
|
||||
private IGameView gameView;
|
||||
private boolean gameHasHumanPlayer;
|
||||
|
||||
@Deprecated
|
||||
public Game getObservedGame() {
|
||||
return game;
|
||||
}
|
||||
|
||||
public Player getLocalPlayer() {
|
||||
public IGameView getGameView() {
|
||||
return this.gameView;
|
||||
}
|
||||
|
||||
public PlayerView getLocalPlayer() {
|
||||
return localPlayer;
|
||||
}
|
||||
|
||||
@@ -428,6 +457,14 @@ public enum FControl implements KeyEventDispatcher {
|
||||
return inputQueue;
|
||||
}
|
||||
|
||||
public final void startGameInSameMatch() {
|
||||
this.startGameWithUi(game.getMatch());
|
||||
}
|
||||
public final void startGameAndClearMatch() {
|
||||
game.getMatch().clearGamesPlayed();
|
||||
startGameInSameMatch();
|
||||
}
|
||||
|
||||
public final void startGameWithUi(final Match match) {
|
||||
if (this.game != null) {
|
||||
this.setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
@@ -436,15 +473,23 @@ public enum FControl implements KeyEventDispatcher {
|
||||
return; //TODO: See if it's possible to run multiple games at once without crashing
|
||||
}
|
||||
setPlayerName(match.getPlayers());
|
||||
final Game newGame = match.createGame();
|
||||
attachToGame(newGame);
|
||||
|
||||
this.game = match.createGame();
|
||||
final LobbyPlayer me = getGuiPlayer();
|
||||
for (final Player p : this.game.getPlayers()) {
|
||||
if (p.getLobbyPlayer().equals(me)) {
|
||||
this.gameView = (IGameView) p.getController();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
attachToGame(this.gameView);
|
||||
|
||||
// It's important to run match in a different thread to allow GUI inputs to be invoked from inside game.
|
||||
// Game is set on pause while gui player takes decisions
|
||||
game.getAction().invoke(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
match.startGame(newGame);
|
||||
match.startGame(game);
|
||||
}
|
||||
});
|
||||
SOverlayUtils.hideOverlay();
|
||||
@@ -459,11 +504,11 @@ public enum FControl implements KeyEventDispatcher {
|
||||
|
||||
private final FControlGameEventHandler fcVisitor = new FControlGameEventHandler();
|
||||
private final FControlGamePlayback playbackControl = new FControlGamePlayback();
|
||||
private void attachToGame(Game game0) {
|
||||
if (game0.getRules().getGameType() == GameType.Quest) {
|
||||
private void attachToGame(final IGameView game0) {
|
||||
if (game0.getGameType().equals(GameType.Quest)) {
|
||||
QuestController qc = FModel.getQuest();
|
||||
// Reset new list when the Match round starts, not when each game starts
|
||||
if (game0.getMatch().getPlayedGames().isEmpty()) {
|
||||
if (game0.isFirstGameInMatch()) {
|
||||
qc.getCards().resetNewList();
|
||||
}
|
||||
game0.subscribeToEvents(qc); // this one listens to player's mulligans ATM
|
||||
@@ -471,49 +516,45 @@ public enum FControl implements KeyEventDispatcher {
|
||||
|
||||
inputQueue = new InputQueue();
|
||||
|
||||
this.game = game0;
|
||||
game.subscribeToEvents(Singletons.getControl().getSoundSystem());
|
||||
game0.subscribeToEvents(Singletons.getControl().getSoundSystem());
|
||||
|
||||
//switch back to match screen music
|
||||
Singletons.getControl().getSoundSystem().setBackgroundMusic(MusicPlaylist.MATCH);
|
||||
|
||||
LobbyPlayer humanLobbyPlayer = getGuiPlayer();
|
||||
final LobbyPlayer humanLobbyPlayer = getGuiPlayer();
|
||||
// The UI controls should use these game data as models
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(game.getRegisteredPlayers(), humanLobbyPlayer);
|
||||
final List<PlayerView> players = game0.getPlayers();
|
||||
CMatchUI.SINGLETON_INSTANCE.initMatch(players, humanLobbyPlayer);
|
||||
|
||||
localPlayer = null;
|
||||
for (Player p : game.getPlayers()) {
|
||||
gameHasHumanPlayer = false;
|
||||
for (final PlayerView p : players) {
|
||||
if (p.getLobbyPlayer() == humanLobbyPlayer) {
|
||||
localPlayer = p;
|
||||
gameHasHumanPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer);
|
||||
CStack.SINGLETON_INSTANCE.setModel(game.getStack(), localPlayer);
|
||||
CPlayers.SINGLETON_INSTANCE.setModel(game);
|
||||
CLog.SINGLETON_INSTANCE.setModel(game.getGameLog());
|
||||
CDock.SINGLETON_INSTANCE.setModel(game0, humanLobbyPlayer);
|
||||
CStack.SINGLETON_INSTANCE.setModel(game0, localPlayer);
|
||||
CPlayers.SINGLETON_INSTANCE.setModel(game0);
|
||||
CLog.SINGLETON_INSTANCE.setModel(game0.getGameLog());
|
||||
|
||||
actuateMatchPreferences();
|
||||
VAntes.SINGLETON_INSTANCE.setModel(game.getRegisteredPlayers());
|
||||
VAntes.SINGLETON_INSTANCE.setModel(players);
|
||||
|
||||
setCurrentScreen(FScreen.MATCH_SCREEN);
|
||||
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
|
||||
|
||||
CPrompt.SINGLETON_INSTANCE.getInputControl().setGame(game);
|
||||
CPrompt.SINGLETON_INSTANCE.getInputControl().setGame(game0);
|
||||
|
||||
// Listen to DuelOutcome event to show ViewWinLose
|
||||
game.subscribeToEvents(fcVisitor);
|
||||
game0.subscribeToEvents(fcVisitor);
|
||||
|
||||
// Add playback controls to match if needed
|
||||
gameHasHumanPlayer = false;
|
||||
for (Player p : game.getPlayers()) {
|
||||
if (p.getController().getLobbyPlayer() == getGuiPlayer())
|
||||
gameHasHumanPlayer = true;
|
||||
}
|
||||
|
||||
if (!gameHasHumanPlayer) {
|
||||
game.subscribeToEvents(playbackControl);
|
||||
if (localPlayer != null) {
|
||||
game0.subscribeToEvents(playbackControl);
|
||||
}
|
||||
|
||||
for (final VField field : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
|
||||
@@ -522,7 +563,7 @@ public enum FControl implements KeyEventDispatcher {
|
||||
|
||||
// per player observers were set in CMatchUI.SINGLETON_INSTANCE.initMatch
|
||||
//Set Field shown to current player.
|
||||
VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(game.getPlayers().get(0));
|
||||
final VField nextField = CMatchUI.SINGLETON_INSTANCE.getFieldViewFor(localPlayer);
|
||||
SDisplayUtil.showTab(nextField);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class FDeckViewer extends FDialog {
|
||||
private final CardManager cardManager;
|
||||
private DeckSection currentSection;
|
||||
|
||||
private final CardDetailPanel cardDetail = new CardDetailPanel(null);
|
||||
private final CardDetailPanel cardDetail = new CardDetailPanel();
|
||||
private final CardPicturePanel cardPicture = new CardPicturePanel();
|
||||
private final FButton btnCopyToClipboard = new FButton("Copy to Clipboard");
|
||||
private final FButton btnChangeSection = new FButton("Change Section");
|
||||
|
||||
@@ -99,7 +99,7 @@ public class BoxedProductCardListViewer extends FDialog {
|
||||
public BoxedProductCardListViewer(final String title, final String message, final List<PaperCard> list, final Icon dialogIcon) {
|
||||
this.list = Collections.unmodifiableList(list);
|
||||
this.jList = new JList<PaperCard>(new ChooserListModel());
|
||||
this.detail = new CardDetailPanel(null);
|
||||
this.detail = new CardDetailPanel();
|
||||
this.picture = new CardPicturePanel();
|
||||
this.picture.setOpaque(false);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
package forge.gui;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* The class CardContainer. A card container is an object that references a
|
||||
@@ -36,7 +36,7 @@ public interface CardContainer {
|
||||
* @param card
|
||||
* a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
void setCard(Card card);
|
||||
void setCard(CardView card);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -45,6 +45,6 @@ public interface CardContainer {
|
||||
*
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
Card getCard();
|
||||
CardView getCard();
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ import forge.item.InventoryItemFromSet;
|
||||
import forge.model.FModel;
|
||||
import forge.toolbox.*;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
import forge.view.FDialog;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -62,7 +64,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
private final FHtmlViewer cdArea;
|
||||
private final FScrollPane scrArea;
|
||||
|
||||
public CardDetailPanel(final Card card) {
|
||||
public CardDetailPanel() {
|
||||
super();
|
||||
this.setLayout(null);
|
||||
this.setOpaque(false);
|
||||
@@ -74,7 +76,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
this.setInfoLabel = new JLabel();
|
||||
this.setInfoLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
|
||||
Font font = new Font("Dialog", 0, 14);
|
||||
final Font font = new Font("Dialog", 0, 14);
|
||||
this.nameCostLabel.setFont(font);
|
||||
this.typeLabel.setFont(font);
|
||||
this.idLabel.setFont(font);
|
||||
@@ -91,8 +93,6 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
this.add(this.powerToughnessLabel);
|
||||
this.add(this.setInfoLabel);
|
||||
this.add(this.scrArea);
|
||||
|
||||
this.setCard(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -121,7 +121,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
this.scrArea.setBounds(0, y, getWidth(), getHeight() - y);
|
||||
}
|
||||
|
||||
public final void setItem(InventoryItemFromSet item) {
|
||||
public final void setItem(final InventoryItemFromSet item) {
|
||||
nameCostLabel.setText(item.getName());
|
||||
typeLabel.setVisible(false);
|
||||
powerToughnessLabel.setVisible(false);
|
||||
@@ -155,7 +155,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
});
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Deprecated
|
||||
public final void setCard(Card card) {
|
||||
this.nameCostLabel.setText("");
|
||||
this.typeLabel.setVisible(true);
|
||||
@@ -169,7 +169,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
this.setInfoLabel.setBorder(null);
|
||||
this.cdArea.setText("");
|
||||
if (card == null) {
|
||||
this.updateBorder(null, false);
|
||||
this.updateBorder((Card)null, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -258,6 +258,102 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
});
|
||||
}
|
||||
|
||||
public final void setCard(final CardView card, final boolean isInAltState) {
|
||||
this.nameCostLabel.setText("");
|
||||
this.typeLabel.setVisible(true);
|
||||
this.typeLabel.setText("");
|
||||
this.powerToughnessLabel.setVisible(true);
|
||||
this.powerToughnessLabel.setText("");
|
||||
this.idLabel.setText("");
|
||||
this.setInfoLabel.setText("");
|
||||
this.setInfoLabel.setToolTipText("");
|
||||
this.setInfoLabel.setOpaque(false);
|
||||
this.setInfoLabel.setBorder(null);
|
||||
this.cdArea.setText("");
|
||||
if (card == null) {
|
||||
this.updateBorder((CardStateView)null, false);
|
||||
return;
|
||||
}
|
||||
|
||||
final CardStateView state = card.getState(isInAltState);
|
||||
//this.setCard(card.card);
|
||||
|
||||
boolean canShowThis = false;
|
||||
|
||||
if (Singletons.getControl().mayShowCard(card) || FDialog.isModalOpen()) { //allow showing cards while modal open to account for revealing, picking, and ordering cards
|
||||
canShowThis = true;
|
||||
|
||||
if (state.getManaCost().isNoCost()) {
|
||||
this.nameCostLabel.setText(state.getName());
|
||||
} else {
|
||||
String manaCost = state.getManaCost().toString();
|
||||
//if (state.isSplitCard() && card.getCurState() == CardCharacteristicName.Original) {
|
||||
// manaCost = card.getRules().getMainPart().getManaCost().toString() + " // " + card.getRules().getOtherPart().getManaCost().toString();
|
||||
//}
|
||||
this.nameCostLabel.setText(FSkin.encodeSymbols(state.getName() + " - " + manaCost, true));
|
||||
}
|
||||
this.typeLabel.setText(CardDetailUtil.formatCardType(state));
|
||||
|
||||
String set = card.getSetCode();
|
||||
this.setInfoLabel.setText(set);
|
||||
if (null != set && !set.isEmpty()) {
|
||||
CardEdition edition = FModel.getMagicDb().getEditions().get(set);
|
||||
if (null == edition) {
|
||||
setInfoLabel.setToolTipText(card.getRarity().name());
|
||||
}
|
||||
else {
|
||||
setInfoLabel.setToolTipText(String.format("%s (%s)", edition.getName(), card.getRarity().name()));
|
||||
}
|
||||
|
||||
this.setInfoLabel.setOpaque(true);
|
||||
|
||||
Color backColor;
|
||||
switch(card.getRarity()) {
|
||||
case Uncommon:
|
||||
backColor = fromDetailColor(DetailColors.UNCOMMON);
|
||||
break;
|
||||
|
||||
case Rare:
|
||||
backColor = fromDetailColor(DetailColors.RARE);
|
||||
break;
|
||||
|
||||
case MythicRare:
|
||||
backColor = fromDetailColor(DetailColors.MYTHIC);
|
||||
break;
|
||||
|
||||
case Special: //"Timeshifted" or other Special Rarity Cards
|
||||
backColor = fromDetailColor(DetailColors.SPECIAL);
|
||||
break;
|
||||
|
||||
default: //case BasicLand: + case Common:
|
||||
backColor = fromDetailColor(DetailColors.COMMON);
|
||||
break;
|
||||
}
|
||||
|
||||
Color foreColor = FSkin.getHighContrastColor(backColor);
|
||||
this.setInfoLabel.setBackground(backColor);
|
||||
this.setInfoLabel.setForeground(foreColor);
|
||||
this.setInfoLabel.setBorder(BorderFactory.createLineBorder(foreColor));
|
||||
}
|
||||
}
|
||||
|
||||
this.updateBorder(state, canShowThis);
|
||||
|
||||
this.powerToughnessLabel.setText(CardDetailUtil.formatPowerToughness(state));
|
||||
|
||||
this.idLabel.setText(CardDetailUtil.formatCardId(state));
|
||||
|
||||
// fill the card text
|
||||
this.cdArea.setText(FSkin.encodeSymbols(CardDetailUtil.composeCardText(state, canShowThis), true));
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrArea.getVerticalScrollBar().setValue(scrArea.getVerticalScrollBar().getMinimum());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** @return FLabel */
|
||||
public FLabel getNameCostLabel() {
|
||||
return this.nameCostLabel;
|
||||
@@ -283,6 +379,7 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
return this.cdArea;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private void updateBorder(final Card card, final boolean canShow) {
|
||||
// color info
|
||||
if (card == null) {
|
||||
@@ -296,6 +393,19 @@ public class CardDetailPanel extends SkinnedPanel {
|
||||
scrArea.setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, color));
|
||||
}
|
||||
|
||||
private void updateBorder(final CardStateView card, final boolean canShow) {
|
||||
// color info
|
||||
if (card == null) {
|
||||
this.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
|
||||
scrArea.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
Color color = fromDetailColor(CardDetailUtil.getBorderColor(card, canShow));
|
||||
this.setBorder(BorderFactory.createLineBorder(color, 2));
|
||||
scrArea.setBorder(BorderFactory.createMatteBorder(2, 0, 0, 0, color));
|
||||
}
|
||||
|
||||
//ensure mouse listener hooked up to all certain opaque child components so it can get raised properly
|
||||
@Override
|
||||
public void addMouseListener(MouseListener l) {
|
||||
|
||||
@@ -97,7 +97,7 @@ public class CardListViewer extends FDialog {
|
||||
public CardListViewer(final String title, final String message, final List<PaperCard> list, final Icon dialogIcon) {
|
||||
this.list = Collections.unmodifiableList(list);
|
||||
this.jList = new JList<PaperCard>(new ChooserListModel());
|
||||
this.detail = new CardDetailPanel(null);
|
||||
this.detail = new CardDetailPanel();
|
||||
this.picture = new CardPicturePanel();
|
||||
this.picture.setOpaque(false);
|
||||
|
||||
|
||||
@@ -18,21 +18,21 @@
|
||||
|
||||
package forge.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.ImageKeys;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.card.Card;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.toolbox.imaging.FImagePanel;
|
||||
import forge.toolbox.imaging.FImageUtil;
|
||||
import forge.toolbox.imaging.FImagePanel.AutoSizeImageMode;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import forge.toolbox.imaging.FImageUtil;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
/**
|
||||
* Displays image associated with a card or inventory item.
|
||||
@@ -48,7 +48,7 @@ public final class CardPicturePanel extends JPanel {
|
||||
|
||||
private final FImagePanel panel;
|
||||
private BufferedImage currentImage;
|
||||
private boolean mayShowCard;
|
||||
private boolean mayShowObject;
|
||||
|
||||
public CardPicturePanel() {
|
||||
super(new BorderLayout());
|
||||
@@ -59,23 +59,21 @@ public final class CardPicturePanel extends JPanel {
|
||||
|
||||
public void setCard(final InventoryItem cp) {
|
||||
this.displayed = cp;
|
||||
this.mayShowCard = true;
|
||||
this.mayShowObject = true;
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
//@Override
|
||||
@Deprecated
|
||||
public void setCard(final Card c, boolean mayShowCard) {
|
||||
this.displayed = c;
|
||||
this.mayShowCard = mayShowCard;
|
||||
this.mayShowObject = mayShowCard;
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
public void setCardImage(CardCharacteristicName flipState) {
|
||||
BufferedImage image = FImageUtil.getImage((Card)displayed, flipState);
|
||||
if (image != null && image != this.currentImage) {
|
||||
this.currentImage = image;
|
||||
this.panel.setImage(image, getAutoSizeImageMode());
|
||||
}
|
||||
public void setCard(final CardStateView c, final boolean mayShowCard) {
|
||||
this.displayed = c;
|
||||
this.mayShowObject = mayShowCard;
|
||||
this.setImage();
|
||||
}
|
||||
|
||||
public void setImage() {
|
||||
@@ -88,14 +86,19 @@ public final class CardPicturePanel extends JPanel {
|
||||
|
||||
public BufferedImage getImage() {
|
||||
if (displayed instanceof InventoryItem) {
|
||||
InventoryItem item = (InventoryItem) displayed;
|
||||
final InventoryItem item = (InventoryItem) displayed;
|
||||
return ImageCache.getOriginalImage(ImageKeys.getImageKey(item, false), true);
|
||||
}
|
||||
else if (displayed instanceof Card) {
|
||||
if (mayShowCard) {
|
||||
if (mayShowObject) {
|
||||
return FImageUtil.getImage((Card)displayed);
|
||||
}
|
||||
return ImageCache.getOriginalImage(ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE, true);
|
||||
} else if (displayed instanceof CardStateView) {
|
||||
if (mayShowObject) {
|
||||
return FImageUtil.getImage((CardStateView)displayed);
|
||||
}
|
||||
return ImageCache.getOriginalImage(ImageKeys.TOKEN_PREFIX + ImageKeys.MORPH_IMAGE, true);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
package forge.gui;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.*;
|
||||
import forge.view.FDialog;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListModel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ListDataEvent;
|
||||
import javax.swing.event.ListDataListener;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.PaperCard;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FButton;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FList;
|
||||
import forge.toolbox.FPanel;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.view.CardView;
|
||||
import forge.view.FDialog;
|
||||
import forge.view.SpellAbilityView;
|
||||
|
||||
// An input box for handling the order of choices.
|
||||
// Left box has the original choices
|
||||
@@ -310,13 +324,13 @@ public class DualListBox<T> extends FDialog {
|
||||
if (!showCard || null == obj) {
|
||||
return;
|
||||
}
|
||||
Card card = null;
|
||||
if (obj instanceof Card) {
|
||||
card = (Card) obj;
|
||||
} else if (obj instanceof SpellAbility) {
|
||||
card = ((SpellAbility) obj).getHostCard();
|
||||
CardView card = null;
|
||||
if (obj instanceof CardView) {
|
||||
card = (CardView) obj;
|
||||
} else if (obj instanceof SpellAbilityView) {
|
||||
card = ((SpellAbilityView) obj).getHostCard();
|
||||
} else if (obj instanceof PaperCard) {
|
||||
card = Card.getCardForUi((IPaperCard) obj);
|
||||
card = CardView.getCardForUi((IPaperCard) obj);
|
||||
}
|
||||
|
||||
GuiUtils.clearPanelSelections();
|
||||
|
||||
@@ -1,24 +1,30 @@
|
||||
package forge.gui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.swing.JList;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.game.card.Card;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FOptionPane;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
@@ -200,8 +206,8 @@ public class GuiChoose {
|
||||
list.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(final ListSelectionEvent ev) {
|
||||
if (list.getSelectedValue() instanceof Card) {
|
||||
Card card = (Card) list.getSelectedValue();
|
||||
if (list.getSelectedValue() instanceof CardView) {
|
||||
final CardView card = (CardView) list.getSelectedValue();
|
||||
if (card.isFaceDown() && Singletons.getControl().mayShowCard(card)) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(card, true);
|
||||
}
|
||||
@@ -240,17 +246,17 @@ public class GuiChoose {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(title, top, 0, 0, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
@@ -261,7 +267,7 @@ public class GuiChoose {
|
||||
}
|
||||
|
||||
public static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode) {
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
|
||||
// An input box for handling the order of choices.
|
||||
|
||||
Callable<List<T>> callable = new Callable<List<T>>() {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
package forge.gui;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.card.Card;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FOptionPane;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.view.CardView;
|
||||
|
||||
/**
|
||||
* Holds player interactions using standard windows
|
||||
*
|
||||
@@ -19,17 +19,17 @@ import java.util.concurrent.FutureTask;
|
||||
public class GuiDialog {
|
||||
private static final String[] defaultConfirmOptions = { "Yes", "No" };
|
||||
|
||||
public static boolean confirm(final Card c, final String question) {
|
||||
public static boolean confirm(final CardView c, final String question) {
|
||||
return GuiDialog.confirm(c, question, true, null);
|
||||
}
|
||||
public static boolean confirm(final Card c, final String question, final boolean defaultChoice) {
|
||||
public static boolean confirm(final CardView c, final String question, final boolean defaultChoice) {
|
||||
return GuiDialog.confirm(c, question, defaultChoice, null);
|
||||
}
|
||||
public static boolean confirm(final Card c, final String question, String[] options) {
|
||||
public static boolean confirm(final CardView c, final String question, String[] options) {
|
||||
return GuiDialog.confirm(c, question, true, options);
|
||||
}
|
||||
|
||||
public static boolean confirm(final Card c, final String question, final boolean defaultIsYes, final String[] options) {
|
||||
public static boolean confirm(final CardView c, final String question, final boolean defaultIsYes, final String[] options) {
|
||||
Callable<Boolean> confirmTask = new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
@@ -37,7 +37,7 @@ public class GuiDialog {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(c);
|
||||
}
|
||||
|
||||
final String title = c == null ? "Question" : c.getCardForUi().getName() + " - Ability";
|
||||
final String title = c == null ? "Question" : c + " - Ability";
|
||||
String questionToUse = StringUtils.isBlank(question) ? "Activate card's ability?" : question;
|
||||
String[] opts = options == null ? defaultConfirmOptions : options;
|
||||
int answer = FOptionPane.showOptionDialog(questionToUse, title, FOptionPane.QUESTION_ICON, opts, defaultIsYes ? 0 : 1);
|
||||
|
||||
@@ -17,20 +17,26 @@
|
||||
*/
|
||||
package forge.gui;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.screens.match.VMatchUI;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.view.arcane.CardPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontFormatException;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JSeparator;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import forge.screens.match.VMatchUI;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.view.CardView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GuiUtils class.
|
||||
@@ -81,15 +87,15 @@ public final class GuiUtils {
|
||||
/**
|
||||
* Highlight a card on the playfield.
|
||||
*
|
||||
* @param c
|
||||
* @param card
|
||||
* a card to be highlighted
|
||||
*/
|
||||
public static void setPanelSelection(final Card c) {
|
||||
public static void setPanelSelection(final CardView card) {
|
||||
mainLoop:
|
||||
for (VField v : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
|
||||
List<CardPanel> panels = v.getTabletop().getCardPanels();
|
||||
for (CardPanel p : panels) {
|
||||
if (p.getCard().equals(c)) {
|
||||
for (final VField v : VMatchUI.SINGLETON_INSTANCE.getFieldViews()) {
|
||||
final List<CardPanel> panels = v.getTabletop().getCardPanels();
|
||||
for (final CardPanel p : panels) {
|
||||
if (p.getCard().equals(card)) {
|
||||
p.setSelected(true);
|
||||
break mainLoop;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package forge.itemmanager.views;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.game.card.Card;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.DeckProxy;
|
||||
import forge.gui.framework.ILocalRepaint;
|
||||
@@ -20,6 +19,7 @@ import forge.toolbox.FSkin.SkinColor;
|
||||
import forge.toolbox.FSkin.SkinFont;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.special.CardZoomer;
|
||||
import forge.view.CardView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -232,7 +232,7 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
||||
ItemInfo item = getItemAtPoint(e.getPoint());
|
||||
if (item != null && item.item instanceof IPaperCard) {
|
||||
setLockHoveredItem(true); //lock hoveredItem while zoomer open
|
||||
Card card = Card.getCardForUi((IPaperCard) item.item);
|
||||
final CardView card = CardView.getCardForUi((IPaperCard) item.item);
|
||||
CardZoomer.SINGLETON_INSTANCE.doMouseButtonZoom(card);
|
||||
}
|
||||
}
|
||||
@@ -1099,8 +1099,8 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
||||
if (item instanceof IPaperCard) {
|
||||
IPaperCard paperCard = (IPaperCard)item;
|
||||
if (paperCard.isFoil()) {
|
||||
Card card = Card.getCardForUi(paperCard);
|
||||
if (card.getFoil() == 0) { //if foil finish not yet established, assign a random one
|
||||
final CardView card = CardView.getCardForUi(paperCard);
|
||||
if (card.getFoilIndex() == 0) { //if foil finish not yet established, assign a random one
|
||||
card.setRandomFoil();
|
||||
}
|
||||
CardPanel.drawFoilEffect(g, card, bounds.x, bounds.y, bounds.width, bounds.height, borderSize);
|
||||
|
||||
@@ -321,7 +321,7 @@ public enum VSubmenuConstructed implements IVSubmenu<CSubmenuConstructed> {
|
||||
FScrollPane scrAvatars = new FScrollPane(vgdAvatarList, true,
|
||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
CardDetailPanel vgdDetail = new CardDetailPanel(null);
|
||||
CardDetailPanel vgdDetail = new CardDetailPanel();
|
||||
vgdAvatarDetails.add(vgdDetail);
|
||||
|
||||
vgdDeckPanel.setLayout(new MigLayout(sectionConstraints));
|
||||
|
||||
@@ -17,49 +17,65 @@
|
||||
*/
|
||||
package forge.screens.match;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.JMenu;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.testng.collections.Maps;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.UiCommand;
|
||||
import forge.FThreads;
|
||||
import forge.ImageCache;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.events.IUiEventVisitor;
|
||||
import forge.events.UiEvent;
|
||||
import forge.events.UiEventAttackerDeclared;
|
||||
import forge.events.UiEventBlockerAssigned;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.*;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.menus.IMenuProvider;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.QuestDraftUtils;
|
||||
import forge.screens.match.controllers.*;
|
||||
import forge.screens.match.controllers.CAntes;
|
||||
import forge.screens.match.controllers.CCombat;
|
||||
import forge.screens.match.controllers.CDetail;
|
||||
import forge.screens.match.controllers.CPicture;
|
||||
import forge.screens.match.controllers.CPrompt;
|
||||
import forge.screens.match.menus.CMatchUIMenus;
|
||||
import forge.screens.match.views.*;
|
||||
import forge.screens.match.views.VCommand;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.screens.match.views.VHand;
|
||||
import forge.screens.match.views.VPlayers;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.FOverlay;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.toolbox.special.PhaseLabel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import forge.view.arcane.PlayArea;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Constructs instance of match UI controller, used as a single point of
|
||||
* top-level control for child UIs. Tasks targeting the view of individual
|
||||
@@ -71,7 +87,7 @@ import java.util.*;
|
||||
public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private List<Player> sortedPlayers;
|
||||
private List<PlayerView> sortedPlayers;
|
||||
private VMatchUI view;
|
||||
|
||||
private EventBus uiEvents;
|
||||
@@ -85,14 +101,12 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
uiEvents.register(visitor);
|
||||
}
|
||||
|
||||
private SkinImage getPlayerAvatar(final Player p, final int defaultIndex) {
|
||||
LobbyPlayer lp = p.getLobbyPlayer();
|
||||
|
||||
if (avatarImages.containsKey(lp)) {
|
||||
return ImageCache.getIcon(avatarImages.get(lp));
|
||||
private SkinImage getPlayerAvatar(final LobbyPlayer p, final int defaultIndex) {
|
||||
if (avatarImages.containsKey(p)) {
|
||||
return ImageCache.getIcon(avatarImages.get(p));
|
||||
}
|
||||
|
||||
int avatarIdx = lp.getAvatarIndex();
|
||||
int avatarIdx = p.getAvatarIndex();
|
||||
return FSkin.getAvatars().get(avatarIdx >= 0 ? avatarIdx : defaultIndex);
|
||||
}
|
||||
|
||||
@@ -108,7 +122,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
* @param numFieldPanels int
|
||||
* @param numHandPanels int
|
||||
*/
|
||||
public void initMatch(final List<Player> players, LobbyPlayer localPlayer) {
|
||||
public void initMatch(final List<PlayerView> players, LobbyPlayer localPlayer) {
|
||||
view = VMatchUI.SINGLETON_INSTANCE;
|
||||
// TODO fix for use with multiplayer
|
||||
|
||||
@@ -121,7 +135,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
final List<VCommand> commands = new ArrayList<VCommand>();
|
||||
|
||||
int i = 0;
|
||||
for (Player p : sortedPlayers) {
|
||||
for (final PlayerView p : sortedPlayers) {
|
||||
// A field must be initialized after it's instantiated, to update player info.
|
||||
// No player, no init.
|
||||
VField f = new VField(EDocID.Fields[i], p, localPlayer);
|
||||
@@ -130,7 +144,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
commands.add(c);
|
||||
|
||||
//setAvatar(f, new ImageIcon(FSkin.getAvatars().get()));
|
||||
setAvatar(f, getPlayerAvatar(p, Integer.parseInt(indices[i > 2 ? 1 : 0])));
|
||||
setAvatar(f, getPlayerAvatar(p.getLobbyPlayer(), Integer.parseInt(indices[i > 2 ? 1 : 0])));
|
||||
f.getLayoutControl().initialize();
|
||||
c.getLayoutControl().initialize();
|
||||
i++;
|
||||
@@ -149,7 +163,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
final List<VHand> hands = new ArrayList<VHand>();
|
||||
|
||||
int i = 0;
|
||||
for (Player p : sortedPlayers) {
|
||||
for (final PlayerView p : sortedPlayers) {
|
||||
if (p.getLobbyPlayer() == localPlayer) {
|
||||
VHand newHand = new VHand(EDocID.Hands[i], p);
|
||||
newHand.getLayoutControl().initialize();
|
||||
@@ -166,9 +180,9 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
view.setHandViews(hands);
|
||||
}
|
||||
|
||||
private List<Player> shiftPlayersPlaceLocalFirst(final List<Player> players, LobbyPlayer localPlayer) {
|
||||
private List<PlayerView> shiftPlayersPlaceLocalFirst(final List<PlayerView> players, final LobbyPlayer localPlayer) {
|
||||
// get an arranged list so that the first local player is at index 0
|
||||
List<Player> sortedPlayers = Lists.newArrayList(players);
|
||||
final List<PlayerView> sortedPlayers = Lists.newArrayList(players);
|
||||
int ixFirstHuman = -1;
|
||||
for (int i = 0; i < players.size(); i++) {
|
||||
if (sortedPlayers.get(i).getLobbyPlayer() == localPlayer) {
|
||||
@@ -199,17 +213,17 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
CPrompt.SINGLETON_INSTANCE.setMessage(s0);
|
||||
}
|
||||
|
||||
public VField getFieldViewFor(Player p) {
|
||||
public VField getFieldViewFor(PlayerView p) {
|
||||
int idx = getPlayerIndex(p);
|
||||
return idx < 0 ? null :view.getFieldViews().get(idx);
|
||||
}
|
||||
|
||||
public VCommand getCommandFor(Player p) {
|
||||
public VCommand getCommandFor(PlayerView p) {
|
||||
int idx = getPlayerIndex(p);
|
||||
return idx < 0 ? null :view.getCommandViews().get(idx);
|
||||
}
|
||||
|
||||
public VHand getHandFor(Player p) {
|
||||
public VHand getHandFor(PlayerView p) {
|
||||
int idx = getPlayerIndex(p);
|
||||
List<VHand> allHands = view.getHands();
|
||||
return idx < 0 || idx >= allHands.size() ? null : allHands.get(idx);
|
||||
@@ -226,15 +240,15 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
* @param overrideOrder overriding combatant order
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<Card, Integer> getDamageToAssign(final Card attacker, final List<Card> blockers, final int damage, final GameEntity defender, final boolean overrideOrder) {
|
||||
public Map<CardView, Integer> getDamageToAssign(final CardView attacker, final List<CardView> blockers, final int damage, final GameEntityView defender, final boolean overrideOrder) {
|
||||
if (damage <= 0) {
|
||||
return new HashMap<Card, Integer>();
|
||||
return Maps.newHashMap();
|
||||
}
|
||||
|
||||
// If the first blocker can absorb all of the damage, don't show the Assign Damage Frame
|
||||
Card firstBlocker = blockers.get(0);
|
||||
if (!overrideOrder && !attacker.hasKeyword("Deathtouch") && firstBlocker.getLethalDamage() >= damage) {
|
||||
Map<Card, Integer> res = new HashMap<Card, Integer>();
|
||||
final CardView firstBlocker = blockers.get(0);
|
||||
if (!overrideOrder && !attacker.getState().hasDeathtouch() && firstBlocker.getLethalDamage() >= damage) {
|
||||
final Map<CardView, Integer> res = Maps.newHashMap();
|
||||
res.put(firstBlocker, damage);
|
||||
return res;
|
||||
}
|
||||
@@ -246,7 +260,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
VAssignDamage v = new VAssignDamage(attacker, blockers, damage, defender, overrideOrder);
|
||||
result[0] = v.getDamageMap();
|
||||
}});
|
||||
return (Map<Card, Integer>)result[0];
|
||||
return (Map<CardView, Integer>)result[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,20 +271,20 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
* @param phase   {@link java.lang.String}
|
||||
* @return boolean
|
||||
*/
|
||||
public final boolean stopAtPhase(final Player turn, final PhaseType phase) {
|
||||
public final boolean stopAtPhase(final PlayerView turn, final PhaseType phase) {
|
||||
VField vf = getFieldViewFor(turn);
|
||||
PhaseLabel label = vf.getPhaseIndicator().getLabelFor(phase);
|
||||
return label == null || label.getEnabled();
|
||||
}
|
||||
|
||||
public void setCard(final Card c) {
|
||||
FThreads.assertExecutedByEdt(true);
|
||||
setCard(c, false);
|
||||
public void setCard(final CardView c) {
|
||||
this.setCard(c, c.isInAltState());
|
||||
}
|
||||
|
||||
public void setCard(final Card c, final boolean showFlipped) {
|
||||
CDetail.SINGLETON_INSTANCE.showCard(c);
|
||||
CPicture.SINGLETON_INSTANCE.showCard(c, showFlipped);
|
||||
public void setCard(final CardView c, final boolean isInAltState) {
|
||||
FThreads.assertExecutedByEdt(true);
|
||||
CDetail.SINGLETON_INSTANCE.showCard(c, isInAltState);
|
||||
CPicture.SINGLETON_INSTANCE.showCard(c, isInAltState);
|
||||
}
|
||||
|
||||
public void setCard(final InventoryItem c) {
|
||||
@@ -278,7 +292,7 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
CPicture.SINGLETON_INSTANCE.showImage(c);
|
||||
}
|
||||
|
||||
private int getPlayerIndex(Player player) {
|
||||
private int getPlayerIndex(PlayerView player) {
|
||||
return sortedPlayers.indexOf(player);
|
||||
}
|
||||
|
||||
@@ -305,19 +319,19 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
CCombat.SINGLETON_INSTANCE.update();
|
||||
} // showBlockers()
|
||||
|
||||
Set<Player> highlightedPlayers = new HashSet<Player>();
|
||||
public void setHighlighted(Player ge, boolean b) {
|
||||
final Set<PlayerView> highlightedPlayers = Sets.newHashSet();
|
||||
public void setHighlighted(PlayerView ge, boolean b) {
|
||||
if (b) highlightedPlayers.add(ge);
|
||||
else highlightedPlayers.remove(ge);
|
||||
}
|
||||
|
||||
public boolean isHighlighted(Player player) {
|
||||
public boolean isHighlighted(final PlayerView player) {
|
||||
return highlightedPlayers.contains(player);
|
||||
}
|
||||
|
||||
Set<Card> highlightedCards = new HashSet<Card>();
|
||||
Set<CardView> highlightedCards = Sets.newHashSet();
|
||||
// used to highlight cards in UI
|
||||
public void setUsedToPay(Card card, boolean value) {
|
||||
public void setUsedToPay(CardView card, boolean value) {
|
||||
FThreads.assertExecutedByEdt(true);
|
||||
|
||||
boolean hasChanged = value ? highlightedCards.add(card) : highlightedCards.remove(card);
|
||||
@@ -326,14 +340,14 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUsedToPay(Card card) {
|
||||
public boolean isUsedToPay(CardView card) {
|
||||
return highlightedCards.contains(card);
|
||||
}
|
||||
|
||||
public void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate) {
|
||||
public void updateZones(List<Pair<PlayerView, ZoneType>> zonesToUpdate) {
|
||||
//System.out.println("updateZones " + zonesToUpdate);
|
||||
for (Pair<Player, ZoneType> kv : zonesToUpdate) {
|
||||
Player owner = kv.getKey();
|
||||
for (Pair<PlayerView, ZoneType> kv : zonesToUpdate) {
|
||||
PlayerView owner = kv.getKey();
|
||||
ZoneType zt = kv.getValue();
|
||||
|
||||
if (zt == ZoneType.Command) {
|
||||
@@ -355,41 +369,39 @@ public enum CMatchUI implements ICDoc, IMenuProvider {
|
||||
}
|
||||
|
||||
// Player's mana pool changes
|
||||
public void updateManaPool(List<Player> manaPoolUpdate) {
|
||||
for (Player p : manaPoolUpdate) {
|
||||
public void updateManaPool(final List<PlayerView> manaPoolUpdate) {
|
||||
for (final PlayerView p : manaPoolUpdate) {
|
||||
getFieldViewFor(p).getDetailsPanel().updateManaPool();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Player's lives and poison counters
|
||||
public void updateLives(List<Player> livesUpdate) {
|
||||
for (Player p : livesUpdate) {
|
||||
public void updateLives(final List<PlayerView> livesUpdate) {
|
||||
for (final PlayerView p : livesUpdate) {
|
||||
getFieldViewFor(p).updateDetails();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void updateCards(Set<Card> cardsToUpdate) {
|
||||
for (Card c : cardsToUpdate) {
|
||||
public void updateCards(final Set<CardView> cardsToUpdate) {
|
||||
for (final CardView c : cardsToUpdate) {
|
||||
updateSingleCard(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateSingleCard(Card c) {
|
||||
Zone zone = c.getZone();
|
||||
if (zone != null && zone.getZoneType() == ZoneType.Battlefield) {
|
||||
PlayArea pa = getFieldViewFor(zone.getPlayer()).getTabletop();
|
||||
public void updateSingleCard(final CardView c) {
|
||||
if (ZoneType.Battlefield.equals(c.getZone())) {
|
||||
final PlayArea pa = getFieldViewFor(c.getController()).getTabletop();
|
||||
pa.updateCard(c, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshCardDetails(Collection<Card> cards) {
|
||||
for (Card c : cards) {
|
||||
Zone zone = c.getZone();
|
||||
if (zone != null && zone.getZoneType() == ZoneType.Battlefield) {
|
||||
PlayArea pa = getFieldViewFor(zone.getPlayer()).getTabletop();
|
||||
CardPanel pnl = pa.getCardPanel(c.getUniqueNumber());
|
||||
public void refreshCardDetails(final Iterable<CardView> cards) {
|
||||
for (final CardView c : cards) {
|
||||
if (ZoneType.Battlefield.equals(c.getZone())) {
|
||||
PlayArea pa = getFieldViewFor(c.getController()).getTabletop();
|
||||
CardPanel pnl = pa.getCardPanel(c.getId());
|
||||
if (pnl != null) {
|
||||
pnl.updatePTOverlay();
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
package forge.screens.match;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.game.Game;
|
||||
import forge.game.Match;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.framework.FScreen;
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* Default controller for a ViewWinLose object. This class can
|
||||
* be extended for various game modes to populate the custom
|
||||
@@ -18,13 +18,13 @@ import java.awt.event.ActionListener;
|
||||
*/
|
||||
public class ControlWinLose {
|
||||
private final ViewWinLose view;
|
||||
protected final Game lastGame;
|
||||
protected final IGameView lastGame;
|
||||
|
||||
/** @param v   ViewWinLose
|
||||
* @param match */
|
||||
public ControlWinLose(final ViewWinLose v, Game game) {
|
||||
public ControlWinLose(final ViewWinLose v, final IGameView game0) {
|
||||
this.view = v;
|
||||
this.lastGame = game;
|
||||
this.lastGame = game0;
|
||||
addListeners();
|
||||
}
|
||||
|
||||
@@ -59,17 +59,15 @@ public class ControlWinLose {
|
||||
saveOptions();
|
||||
|
||||
Singletons.getControl().endCurrentGame();
|
||||
Singletons.getControl().startGameWithUi(lastGame.getMatch());
|
||||
Singletons.getControl().startGameInSameMatch();
|
||||
}
|
||||
|
||||
/** Action performed when "restart" button is pressed in default win/lose UI. */
|
||||
public void actionOnRestart() {
|
||||
SOverlayUtils.hideOverlay();
|
||||
saveOptions();
|
||||
final Match match = lastGame.getMatch();
|
||||
match.clearGamesPlayed();
|
||||
Singletons.getControl().endCurrentGame();
|
||||
Singletons.getControl().startGameWithUi(match);
|
||||
Singletons.getControl().startGameAndClearMatch();
|
||||
}
|
||||
|
||||
/** Action performed when "quit" button is pressed in default win/lose UI. */
|
||||
|
||||
@@ -17,18 +17,20 @@ package forge.screens.match;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.Game;
|
||||
import forge.gauntlet.GauntletWinLoseController;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* The Win/Lose handler for 'gauntlet' type tournament
|
||||
@@ -43,9 +45,9 @@ public class GauntletWinLose extends ControlWinLose {
|
||||
* @param view0 ViewWinLose object
|
||||
* @param match
|
||||
*/
|
||||
public GauntletWinLose(final ViewWinLose view0, Game lastGame) {
|
||||
super(view0, lastGame);
|
||||
controller = new GauntletWinLoseController(view0, lastGame) {
|
||||
public GauntletWinLose(final ViewWinLose view0, final IGameView game0) {
|
||||
super(view0, game0);
|
||||
controller = new GauntletWinLoseController(view0, game0) {
|
||||
@Override
|
||||
protected void showOutcome(String message1, String message2, FSkinProp icon, List<String> lstEventNames, List<String> lstEventRecords, int len, int num) {
|
||||
final JLabel lblTitle = new FLabel.Builder().text("Gauntlet Progress")
|
||||
|
||||
@@ -21,12 +21,12 @@ import java.awt.Dimension;
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.limited.LimitedWinLoseController;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.Colors;
|
||||
import forge.toolbox.FSkin.SkinColor;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* The Win/Lose handler for 'gauntlet' type tournament
|
||||
@@ -46,9 +46,9 @@ public class LimitedWinLose extends ControlWinLose {
|
||||
* @param view0 {@link forge.screens.match.ViewWinLose}
|
||||
* @param match {@link forge.game.Match}
|
||||
*/
|
||||
public LimitedWinLose(final ViewWinLose view0, Game lastGame) {
|
||||
super(view0, lastGame);
|
||||
controller = new LimitedWinLoseController(view0, lastGame) {
|
||||
public LimitedWinLose(final ViewWinLose view0, final IGameView game0) {
|
||||
super(view0, game0);
|
||||
controller = new LimitedWinLoseController(view0, game0) {
|
||||
@Override
|
||||
protected void showOutcome(Runnable runnable) {
|
||||
runnable.run(); //just run on GUI thread
|
||||
|
||||
@@ -24,8 +24,6 @@ import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.Singletons;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.gui.framework.FScreen;
|
||||
import forge.model.FModel;
|
||||
@@ -37,6 +35,8 @@ import forge.screens.home.quest.CSubmenuQuestDraft;
|
||||
import forge.screens.home.quest.VSubmenuQuestDraft;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -58,8 +58,8 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
* @param view0 ViewWinLose object
|
||||
* @param match2
|
||||
*/
|
||||
public QuestDraftWinLose(final ViewWinLose view0, Game lastGame) {
|
||||
super(view0, lastGame);
|
||||
public QuestDraftWinLose(final ViewWinLose view0, final IGameView game0) {
|
||||
super(view0, game0);
|
||||
this.view = view0;
|
||||
qData = FModel.getQuest();
|
||||
}
|
||||
@@ -79,18 +79,18 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
QuestController quest = FModel.getQuest();
|
||||
|
||||
final LobbyPlayer questLobbyPlayer = GuiBase.getInterface().getQuestPlayer();
|
||||
List<Player> players = lastGame.getRegisteredPlayers();
|
||||
final List<PlayerView> players = lastGame.getPlayers();
|
||||
boolean gameHadHumanPlayer = false;
|
||||
for (Player p : players) {
|
||||
for (final PlayerView p : players) {
|
||||
if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
|
||||
gameHadHumanPlayer = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
|
||||
String winner = lastGame.getOutcome().getWinningPlayer().getName();
|
||||
String winner = lastGame.getWinningPlayer().getName();
|
||||
|
||||
quest.getAchievements().getCurrentDraft().setWinner(winner);
|
||||
quest.save();
|
||||
@@ -99,7 +99,7 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
|
||||
if (!gameHadHumanPlayer) {
|
||||
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
this.actionOnQuitMatch();
|
||||
QuestDraftUtils.matchInProgress = false;
|
||||
QuestDraftUtils.update();
|
||||
@@ -114,7 +114,7 @@ public class QuestDraftWinLose extends ControlWinLose {
|
||||
view.getBtnRestart().setEnabled(false);
|
||||
view.getBtnRestart().setVisible(false);
|
||||
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
view.getBtnQuit().setEnabled(true);
|
||||
view.getBtnContinue().setEnabled(false);
|
||||
view.getBtnQuit().setText("Continue Tournament");
|
||||
|
||||
@@ -16,12 +16,16 @@
|
||||
*/
|
||||
package forge.screens.match;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.Game;
|
||||
import forge.item.*;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.quest.*;
|
||||
import forge.quest.QuestWinLoseController;
|
||||
import forge.screens.home.quest.CSubmenuChallenges;
|
||||
import forge.screens.home.quest.CSubmenuDuels;
|
||||
import forge.toolbox.FSkin;
|
||||
@@ -29,11 +33,7 @@ import forge.toolbox.FSkin.Colors;
|
||||
import forge.toolbox.FSkin.SkinColor;
|
||||
import forge.toolbox.FSkin.SkinIcon;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingConstants;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -61,10 +61,10 @@ public class QuestWinLose extends ControlWinLose {
|
||||
* @param view0 ViewWinLose object
|
||||
* @param match2
|
||||
*/
|
||||
public QuestWinLose(final ViewWinLose view0, Game lastGame) {
|
||||
super(view0, lastGame);
|
||||
public QuestWinLose(final ViewWinLose view0, final IGameView game0) {
|
||||
super(view0, game0);
|
||||
view = view0;
|
||||
controller = new QuestWinLoseController(lastGame) {
|
||||
controller = new QuestWinLoseController(game0) {
|
||||
@Override
|
||||
protected void showRewards(Runnable runnable) {
|
||||
runnable.run(); //just run on GUI thread
|
||||
|
||||
@@ -63,7 +63,7 @@ public class QuestWinLoseCardViewer extends FPanel {
|
||||
public QuestWinLoseCardViewer(final List<PaperCard> list) {
|
||||
this.list = Collections.unmodifiableList(list);
|
||||
this.jList = new FList<PaperCard>(new ChooserListModel());
|
||||
this.detail = new CardDetailPanel(null);
|
||||
this.detail = new CardDetailPanel();
|
||||
this.picture = new CardPicturePanel();
|
||||
this.scroller = new FScrollPane(this.jList, false);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package forge.screens.match;
|
||||
|
||||
import forge.control.FControl;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CounterType;
|
||||
@@ -27,13 +28,20 @@ import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.view.CardView;
|
||||
import forge.view.FDialog;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import org.testng.collections.Lists;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.awt.Dialog.ModalityType;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -68,7 +76,7 @@ public class VAssignDamage {
|
||||
private boolean attackerHasInfect = false;
|
||||
private boolean overrideCombatantOrder = false;
|
||||
|
||||
private final GameEntity defender;
|
||||
private final GameEntityView defender;
|
||||
|
||||
private final JLabel lblTotalDamage = new FLabel.Builder().text("Available damage points: Unknown").build();
|
||||
private final JLabel lblAssignRemaining = new FLabel.Builder().text("Distribute the remaining damage points among lethally wounded entities").build();
|
||||
@@ -79,24 +87,24 @@ public class VAssignDamage {
|
||||
|
||||
|
||||
private static class DamageTarget {
|
||||
public final Card card;
|
||||
public final CardView card;
|
||||
public final JLabel label;
|
||||
public int damage;
|
||||
|
||||
public DamageTarget(Card entity0, JLabel lbl) {
|
||||
card = entity0;
|
||||
public DamageTarget(final CardView c, final JLabel lbl) {
|
||||
card = c;
|
||||
label = lbl;
|
||||
}
|
||||
}
|
||||
|
||||
// Indexes of defenders correspond to their indexes in the damage list and labels.
|
||||
private final List<DamageTarget> defenders = new ArrayList<DamageTarget>(); // NULL in this map means defender
|
||||
private final Map<Card, DamageTarget> damage = new HashMap<Card, DamageTarget>(); // NULL in this map means defender
|
||||
private final List<DamageTarget> defenders = Lists.newArrayList(); // NULL in this map means defender
|
||||
private final Map<CardView, DamageTarget> damage = Maps.newHashMap(); // NULL in this map means defender
|
||||
|
||||
private boolean canAssignTo(Card card) {
|
||||
for(DamageTarget dt : defenders) {
|
||||
if ( dt.card == card ) return true;
|
||||
if ( getDamageToKill(dt.card) > dt.damage )
|
||||
private boolean canAssignTo(final CardView card) {
|
||||
for (DamageTarget dt : defenders) {
|
||||
if (dt.card == card ) return true;
|
||||
if (getDamageToKill(dt.card) > dt.damage )
|
||||
return false;
|
||||
}
|
||||
throw new RuntimeException("Asking to assign damage to object which is not present in defenders list");
|
||||
@@ -106,10 +114,10 @@ public class VAssignDamage {
|
||||
private final MouseAdapter mad = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(final MouseEvent evt) {
|
||||
Card source = ((CardPanel) evt.getSource()).getCard();
|
||||
CardView source = ((CardPanel) evt.getSource()).getCard();
|
||||
if (!damage.containsKey(source)) source = null; // to get player instead of fake card
|
||||
|
||||
FSkin.Colors brdrColor = VAssignDamage.this.canAssignTo(source) ? FSkin.Colors.CLR_ACTIVE : FSkin.Colors.CLR_INACTIVE;
|
||||
|
||||
final FSkin.Colors brdrColor = VAssignDamage.this.canAssignTo(source) ? FSkin.Colors.CLR_ACTIVE : FSkin.Colors.CLR_INACTIVE;
|
||||
((CardPanel) evt.getSource()).setBorder(new FSkin.LineSkinBorder(FSkin.getColor(brdrColor), 2));
|
||||
}
|
||||
|
||||
@@ -120,7 +128,7 @@ public class VAssignDamage {
|
||||
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent evt) {
|
||||
Card source = ((CardPanel) evt.getSource()).getCard(); // will be NULL for player
|
||||
CardView source = ((CardPanel) evt.getSource()).getCard(); // will be NULL for player
|
||||
|
||||
boolean meta = evt.isControlDown();
|
||||
boolean isLMB = SwingUtilities.isLeftMouseButton(evt);
|
||||
@@ -133,22 +141,22 @@ public class VAssignDamage {
|
||||
|
||||
/** Constructor.
|
||||
*
|
||||
* @param attacker0 {@link forge.game.card.Card}
|
||||
* @param defenderCards List<{@link forge.game.card.Card}>
|
||||
* @param attacker {@link forge.game.card.Card}
|
||||
* @param blockers List<{@link forge.game.card.Card}>
|
||||
* @param damage0 int
|
||||
* @param defender GameEntity that's bein attacked
|
||||
* @param overrideOrder override combatant order
|
||||
|
||||
*/
|
||||
public VAssignDamage(final Card attacker0, final List<Card> defenderCards, final int damage0, final GameEntity defender, boolean overrideOrder) {
|
||||
dlg.setTitle("Assign damage dealt by " + attacker0.getName());
|
||||
public VAssignDamage(final CardView attacker, final List<CardView> blockers, final int damage0, final GameEntityView defender, boolean overrideOrder) {
|
||||
dlg.setTitle("Assign damage dealt by " + attacker);
|
||||
|
||||
// Set damage storage vars
|
||||
this.totalDamageToAssign = damage0;
|
||||
this.defender = defender;
|
||||
this.attackerHasDeathtouch = attacker0.hasKeyword("Deathtouch");
|
||||
this.attackerHasInfect = attacker0.hasKeyword("Infect");
|
||||
this.attackerHasTrample = defender != null && attacker0.hasKeyword("Trample");
|
||||
this.attackerHasDeathtouch = attacker.getState().hasDeathtouch();
|
||||
this.attackerHasInfect = attacker.getState().hasInfect();
|
||||
this.attackerHasTrample = defender != null && attacker.getState().hasTrample();
|
||||
this.overrideCombatantOrder = overrideOrder;
|
||||
|
||||
// Top-level UI stuff
|
||||
@@ -157,7 +165,7 @@ public class VAssignDamage {
|
||||
pnlMain.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
|
||||
|
||||
// Attacker area
|
||||
final CardPanel pnlAttacker = new CardPanel(attacker0);
|
||||
final CardPanel pnlAttacker = new CardPanel(attacker);
|
||||
pnlAttacker.setOpaque(false);
|
||||
pnlAttacker.setCardBounds(0, 0, 105, 150);
|
||||
|
||||
@@ -170,14 +178,14 @@ public class VAssignDamage {
|
||||
// Defenders area
|
||||
final JPanel pnlDefenders = new JPanel();
|
||||
pnlDefenders.setOpaque(false);
|
||||
int cols = attackerHasTrample ? defenderCards.size() + 1 : defenderCards.size();
|
||||
int cols = attackerHasTrample ? blockers.size() + 1 : blockers.size();
|
||||
final String wrap = "wrap " + Integer.toString(cols);
|
||||
pnlDefenders.setLayout(new MigLayout("insets 0, gap 0, ax center, " + wrap));
|
||||
|
||||
final FScrollPane scrDefenders = new FScrollPane(pnlDefenders, false);
|
||||
|
||||
// Top row of cards...
|
||||
for (final Card c : defenderCards) {
|
||||
for (final CardView c : blockers) {
|
||||
DamageTarget dt = new DamageTarget(c, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build());
|
||||
this.damage.put(c, dt);
|
||||
this.defenders.add(dt);
|
||||
@@ -188,18 +196,18 @@ public class VAssignDamage {
|
||||
DamageTarget dt = new DamageTarget(null, new FLabel.Builder().text("0").fontSize(18).fontAlign(SwingConstants.CENTER).build());
|
||||
this.damage.put(null, dt);
|
||||
this.defenders.add(dt);
|
||||
Card fakeCard;
|
||||
if (defender instanceof Card)
|
||||
fakeCard = (Card)defender;
|
||||
else if (defender instanceof Player) {
|
||||
fakeCard = new Card(-1);
|
||||
fakeCard.setName(this.defender.getName());
|
||||
fakeCard.setOwner((Player)defender);
|
||||
Player p = (Player)defender;
|
||||
fakeCard.setImageKey(CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getOriginalLobbyPlayer()));
|
||||
final CardView fakeCard;
|
||||
if (defender instanceof CardView)
|
||||
fakeCard = (CardView)defender;
|
||||
else if (defender instanceof PlayerView) {
|
||||
fakeCard = new CardView(null, -1);
|
||||
fakeCard.getState().setName(this.defender.toString());
|
||||
final PlayerView p = (PlayerView)defender;
|
||||
fakeCard.getState().setOwner(p);
|
||||
fakeCard.getState().setImageKey(CMatchUI.SINGLETON_INSTANCE.avatarImages.get(p.getLobbyPlayer()));
|
||||
} else {
|
||||
fakeCard = new Card(-2);
|
||||
fakeCard.setName(this.defender.getName());
|
||||
fakeCard = new CardView(null, -2);
|
||||
fakeCard.getState().setName(this.defender.toString());
|
||||
}
|
||||
addPanelForDefender(pnlDefenders, fakeCard);
|
||||
}
|
||||
@@ -259,7 +267,7 @@ public class VAssignDamage {
|
||||
* @param pnlDefenders
|
||||
* @param defender
|
||||
*/
|
||||
private void addPanelForDefender(final JPanel pnlDefenders, final Card defender) {
|
||||
private void addPanelForDefender(final JPanel pnlDefenders, final CardView defender) {
|
||||
final CardPanel cp = new CardPanel(defender);
|
||||
cp.setCardBounds(0, 0, 105, 150);
|
||||
cp.setOpaque(true);
|
||||
@@ -273,7 +281,7 @@ public class VAssignDamage {
|
||||
* @param meta
|
||||
* @param isLMB
|
||||
*/
|
||||
private void assignDamageTo(Card source, boolean meta, boolean isAdding) {
|
||||
private void assignDamageTo(CardView source, final boolean meta, final boolean isAdding) {
|
||||
if ( !damage.containsKey(source) )
|
||||
source = null;
|
||||
|
||||
@@ -366,14 +374,14 @@ public class VAssignDamage {
|
||||
dt.damage = 0;
|
||||
}
|
||||
|
||||
private void addDamage(final Card card, int addedDamage) {
|
||||
private void addDamage(final CardView card, int addedDamage) {
|
||||
// If we don't have enough left or we're trying to unassign too much return
|
||||
int canAssign = getRemainingDamage();
|
||||
final int canAssign = getRemainingDamage();
|
||||
if (canAssign < addedDamage) {
|
||||
addedDamage = canAssign;
|
||||
}
|
||||
|
||||
DamageTarget dt = damage.get(card);
|
||||
final DamageTarget dt = damage.get(card);
|
||||
dt.damage = Math.max(0, addedDamage + dt.damage);
|
||||
}
|
||||
|
||||
@@ -433,28 +441,28 @@ public class VAssignDamage {
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
* @param source
|
||||
* @param card
|
||||
* @return
|
||||
*/
|
||||
private int getDamageToKill(Card source) {
|
||||
private int getDamageToKill(final CardView card) {
|
||||
int lethalDamage = 0;
|
||||
if ( source == null ) {
|
||||
if ( defender instanceof Player ) {
|
||||
Player p = (Player)defender;
|
||||
lethalDamage = attackerHasInfect ? p.getGame().getRules().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife();
|
||||
} else if ( defender instanceof Card ) { // planeswalker
|
||||
Card pw = (Card)defender;
|
||||
lethalDamage = pw.getCounters(CounterType.LOYALTY);
|
||||
if (card == null) {
|
||||
if (defender instanceof PlayerView) {
|
||||
final PlayerView p = (PlayerView)defender;
|
||||
lethalDamage = attackerHasInfect ? FControl.instance.getGameView().getPoisonCountersToLose() - p.getPoisonCounters() : p.getLife();
|
||||
} else if (defender instanceof CardView) { // planeswalker
|
||||
final CardView pw = (CardView)defender;
|
||||
lethalDamage = pw.getState().getLoyalty();
|
||||
}
|
||||
} else {
|
||||
lethalDamage = VAssignDamage.this.attackerHasDeathtouch ? 1 : Math.max(0, source.getLethalDamage());
|
||||
lethalDamage = VAssignDamage.this.attackerHasDeathtouch ? 1 : Math.max(0, card.getLethalDamage());
|
||||
}
|
||||
return lethalDamage;
|
||||
}
|
||||
|
||||
public Map<Card, Integer> getDamageMap() {
|
||||
Map<Card, Integer> result = new HashMap<Card, Integer>();
|
||||
for(DamageTarget dt : defenders)
|
||||
public Map<CardView, Integer> getDamageMap() {
|
||||
Map<CardView, Integer> result = Maps.newHashMapWithExpectedSize(defenders.size());
|
||||
for (DamageTarget dt : defenders)
|
||||
result.put(dt.card, dt.damage);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ import javax.swing.event.ChangeListener;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.Player;
|
||||
import forge.toolbox.FButton;
|
||||
import forge.toolbox.FCheckBox;
|
||||
import forge.toolbox.FList;
|
||||
import forge.toolbox.FOptionPane;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.view.FDialog;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class VAutoYields extends FDialog {
|
||||
@@ -32,12 +32,12 @@ public class VAutoYields extends FDialog {
|
||||
private final FCheckBox chkDisableAll;
|
||||
private final List<String> autoYields;
|
||||
|
||||
public VAutoYields(final Game game, final Player player) {
|
||||
public VAutoYields(final IGameView game, final PlayerView playerView) {
|
||||
super(true);
|
||||
setTitle("Auto-Yields");
|
||||
|
||||
autoYields = new ArrayList<String>();
|
||||
for (String autoYield : player.getController().getAutoYields()) {
|
||||
for (final String autoYield : playerView.getController().getAutoYields()) {
|
||||
autoYields.add(autoYield);
|
||||
}
|
||||
lstAutoYields = new FList<String>(new AutoYieldsListModel());
|
||||
@@ -72,7 +72,7 @@ public class VAutoYields extends FDialog {
|
||||
if (selected != null) {
|
||||
autoYields.remove(selected);
|
||||
btnRemove.setEnabled(autoYields.size() > 0);
|
||||
player.getController().setShouldAutoYield(selected, false);
|
||||
playerView.getController().setShouldAutoYield(selected, false);
|
||||
VAutoYields.this.revalidate();
|
||||
lstAutoYields.repaint();
|
||||
}
|
||||
|
||||
@@ -11,13 +11,11 @@ import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.UiCommand;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameLog;
|
||||
import forge.game.GameLogEntry;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.model.FModel;
|
||||
@@ -29,7 +27,7 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.toolbox.FTextArea;
|
||||
|
||||
import forge.view.IGameView;
|
||||
|
||||
public class ViewWinLose implements IWinLoseView<FButton> {
|
||||
private final FButton btnContinue, btnRestart, btnQuit;
|
||||
@@ -39,12 +37,12 @@ public class ViewWinLose implements IWinLoseView<FButton> {
|
||||
private final SkinnedLabel lblStats = new SkinnedLabel("WinLoseFrame > lblStats needs updating.");
|
||||
private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, align center"));
|
||||
|
||||
private final Game game;
|
||||
private final IGameView game;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public ViewWinLose(final Game game0) {
|
||||
public ViewWinLose(final IGameView game0) {
|
||||
|
||||
game = game0;
|
||||
this.game = game0;
|
||||
|
||||
final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel();
|
||||
|
||||
@@ -60,7 +58,7 @@ public class ViewWinLose implements IWinLoseView<FButton> {
|
||||
// Control of the win/lose is handled differently for various game
|
||||
// modes.
|
||||
ControlWinLose control = null;
|
||||
switch (game0.getRules().getGameType()) {
|
||||
switch (game0.getGameType()) {
|
||||
case Quest:
|
||||
control = new QuestWinLose(this, game0);
|
||||
break;
|
||||
@@ -103,7 +101,7 @@ public class ViewWinLose implements IWinLoseView<FButton> {
|
||||
btnRestart.setFont(FSkin.getFont(22));
|
||||
btnQuit.setText("Quit Match");
|
||||
btnQuit.setFont(FSkin.getFont(22));
|
||||
btnContinue.setEnabled(!game0.getMatch().isMatchOver());
|
||||
btnContinue.setEnabled(!game0.isMatchOver());
|
||||
|
||||
// Assemble game log scroller.
|
||||
final FTextArea txtLog = new FTextArea();
|
||||
@@ -180,20 +178,20 @@ public class ViewWinLose implements IWinLoseView<FButton> {
|
||||
}
|
||||
});
|
||||
|
||||
lblTitle.setText(composeTitle(game0.getOutcome()));
|
||||
lblTitle.setText(composeTitle(game0));
|
||||
|
||||
showGameOutcomeSummary();
|
||||
showPlayerScores();
|
||||
|
||||
}
|
||||
|
||||
private String composeTitle(GameOutcome outcome) {
|
||||
Player winner = outcome.getWinningPlayer();
|
||||
int winningTeam = outcome.getWinningTeam();
|
||||
private String composeTitle(final IGameView game) {
|
||||
final LobbyPlayer winner = game.getWinningPlayer();
|
||||
final int winningTeam = game.getWinningTeam();
|
||||
if (winner == null) {
|
||||
return "It's a draw!";
|
||||
} else if (winningTeam != -1) {
|
||||
return "Team " + winner.getTeam() + " Won!";
|
||||
return "Team " + winningTeam + " Won!";
|
||||
} else {
|
||||
return winner.getName() + " Won!";
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
package forge.screens.match;
|
||||
|
||||
import forge.Singletons;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactory;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.List;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import forge.gui.ForgeAction;
|
||||
import forge.gui.GuiChoose;
|
||||
import forge.match.MatchConstants;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
/**
|
||||
* Receives click and programmatic requests for viewing data stacks in the
|
||||
@@ -20,7 +19,7 @@ import java.util.List;
|
||||
*/
|
||||
public class ZoneAction extends ForgeAction {
|
||||
private static final long serialVersionUID = -5822976087772388839L;
|
||||
private final PlayerZone zone;
|
||||
private final Iterable<CardView> cards;
|
||||
private final String title;
|
||||
|
||||
/**
|
||||
@@ -33,10 +32,10 @@ public class ZoneAction extends ForgeAction {
|
||||
* @param property
|
||||
*   String obj
|
||||
*/
|
||||
public ZoneAction(final PlayerZone zone, MatchConstants property) {
|
||||
public ZoneAction(final Iterable<CardView> cards, final MatchConstants property) {
|
||||
super(property);
|
||||
this.title = property.title;
|
||||
this.zone = zone;
|
||||
this.cards = Iterables.unmodifiableIterable(cards);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,37 +44,33 @@ public class ZoneAction extends ForgeAction {
|
||||
*/
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final List<Card> choices = this.getCardsAsIterable();
|
||||
if (choices.isEmpty()) {
|
||||
final Iterable<CardView> choices = this.getCardsAsIterable();
|
||||
if (!choices.iterator().hasNext()) {
|
||||
GuiChoose.reveal(this.title, "no cards");
|
||||
return;
|
||||
}
|
||||
|
||||
final ArrayList<Card> choices2 = new ArrayList<Card>();
|
||||
for (Card crd : choices) {
|
||||
Card toAdd = crd;
|
||||
if (crd.isFaceDown()) {
|
||||
if (Singletons.getControl().mayShowCard(crd)) {
|
||||
toAdd = CardFactory.copyCard(crd, false);
|
||||
toAdd.setState(CardCharacteristicName.Original);
|
||||
} else {
|
||||
toAdd = new Card(0);
|
||||
toAdd.setName("Face Down");
|
||||
}
|
||||
}
|
||||
final List<CardStateView> choices2 = Lists.newLinkedList();
|
||||
for (final CardView crd : choices) {
|
||||
final CardStateView toAdd;
|
||||
if (crd.isFaceDown() && crd.hasAltState()) {
|
||||
toAdd = crd.getAlternate();
|
||||
} else {
|
||||
toAdd = crd.getState();
|
||||
}
|
||||
choices2.add(toAdd);
|
||||
}
|
||||
|
||||
final Card choice = GuiChoose.oneOrNone(this.title, choices2);
|
||||
final CardStateView choice = GuiChoose.oneOrNone(this.title, choices2);
|
||||
if (choice != null) {
|
||||
this.doAction(choice);
|
||||
this.doAction(choice.getCard());
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Card> getCardsAsIterable() {
|
||||
return this.zone.getCards();
|
||||
protected Iterable<CardView> getCardsAsIterable() {
|
||||
return cards;
|
||||
}
|
||||
|
||||
protected void doAction(final Card c) {
|
||||
protected void doAction(final CardView c) {
|
||||
}
|
||||
} // End ZoneAction
|
||||
@@ -18,24 +18,25 @@
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.UiCommand;
|
||||
import forge.game.player.Player;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.views.VCommand;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Controls Swing components of a player's command instance.
|
||||
*/
|
||||
public class CCommand implements ICDoc {
|
||||
private final Player player;
|
||||
private final PlayerView player;
|
||||
private final VCommand view;
|
||||
|
||||
/**
|
||||
* Controls Swing components of a player's command instance.
|
||||
*
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
* @param player2   {@link forge.game.player.Player}
|
||||
* @param v0   {@link forge.screens.match.views.VCommand}
|
||||
*/
|
||||
public CCommand(final Player p0, final VCommand v0) {
|
||||
this.player = p0;
|
||||
public CCommand(final PlayerView player2, final VCommand v0) {
|
||||
this.player = player2;
|
||||
this.view = v0;
|
||||
}
|
||||
|
||||
@@ -48,7 +49,7 @@ public class CCommand implements ICDoc {
|
||||
}
|
||||
|
||||
/** @return {@link forge.game.player.Player} */
|
||||
public Player getPlayer() {
|
||||
public PlayerView getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import forge.item.InventoryItem;
|
||||
import forge.item.InventoryItemFromSet;
|
||||
import forge.screens.match.views.VDetail;
|
||||
import forge.toolbox.FMouseAdapter;
|
||||
import forge.view.CardView;
|
||||
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
@@ -45,6 +46,7 @@ public enum CDetail implements ICDoc {
|
||||
*
|
||||
* @param c   Card object
|
||||
*/
|
||||
@Deprecated
|
||||
public void showCard(Card c) {
|
||||
if (c != null) {
|
||||
c = c.getCardForUi();
|
||||
@@ -56,7 +58,15 @@ public enum CDetail implements ICDoc {
|
||||
}
|
||||
}
|
||||
|
||||
public void showCard(InventoryItem item) {
|
||||
public void showCard(final CardView c, final boolean isInAltState) {
|
||||
view.getLblFlipcard().setVisible(c != null && c.hasAltState() && Singletons.getControl().mayShowCard(c));
|
||||
view.getPnlDetail().setCard(c, isInAltState);
|
||||
if (view.getParentCell() != null) {
|
||||
view.getParentCell().repaintSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public void showCard(final InventoryItem item) {
|
||||
if (item instanceof IPaperCard) {
|
||||
showCard(Card.getCardForUi((IPaperCard)item));
|
||||
}
|
||||
|
||||
@@ -17,19 +17,18 @@
|
||||
*/
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.UiCommand;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deckchooser.FDeckViewer;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.combat.CombatUtil;
|
||||
import forge.game.phase.PhaseHandler;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
@@ -38,7 +37,6 @@ import forge.gui.SOverlayUtils;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.framework.SLayoutIO;
|
||||
import forge.model.FModel;
|
||||
import forge.player.GamePlayerUtil;
|
||||
import forge.properties.FileLocation;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.CMatchUI;
|
||||
@@ -47,6 +45,7 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.SaveOpenDialog;
|
||||
import forge.toolbox.SaveOpenDialog.Filetypes;
|
||||
import forge.view.FView;
|
||||
import forge.view.IGameView;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
@@ -61,9 +60,9 @@ public enum CDock implements ICDoc {
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private int arcState;
|
||||
private Game game;
|
||||
private IGameView game;
|
||||
|
||||
public void setModel(Game game0, LobbyPlayer player0) {
|
||||
public void setModel(IGameView game0, LobbyPlayer player0) {
|
||||
game = game0;
|
||||
}
|
||||
|
||||
@@ -136,7 +135,8 @@ public enum CDock implements ICDoc {
|
||||
* View deck list.
|
||||
*/
|
||||
public void viewDeckList() {
|
||||
RegisteredPlayer player = GamePlayerUtil.getGuiRegisteredPlayer(game);
|
||||
final LobbyPlayer guiPlayer = GuiBase.getInterface().getGuiPlayer();
|
||||
final RegisteredPlayer player = game.getGuiRegisteredPlayer(guiPlayer);
|
||||
if (player != null) {
|
||||
FDeckViewer.show(player.getDeck());
|
||||
}
|
||||
@@ -178,12 +178,9 @@ public enum CDock implements ICDoc {
|
||||
|
||||
/** Attack with everyone. */
|
||||
public void alphaStrike() {
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
|
||||
final Player p = findAffectedPlayer();
|
||||
final Game game = p.getGame();
|
||||
Combat combat = game.getCombat();
|
||||
if (ph.is(PhaseType.COMBAT_DECLARE_ATTACKERS, p) && combat!= null) { // ph.is(...) includes null check
|
||||
final Player p = this.findAffectedPlayer();
|
||||
final Combat combat = game.getCombat();
|
||||
if (this.game.isCombatDeclareAttackers()) {
|
||||
List<Player> defenders = p.getOpponents();
|
||||
|
||||
for (Card c : CardLists.filter(p.getCardsIn(ZoneType.Battlefield), Presets.CREATURES)) {
|
||||
|
||||
@@ -17,14 +17,17 @@
|
||||
*/
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.UiCommand;
|
||||
import forge.Singletons;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.UiCommand;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.match.MatchConstants;
|
||||
import forge.match.input.Input;
|
||||
@@ -33,19 +36,15 @@ import forge.properties.ForgePreferences;
|
||||
import forge.screens.match.ZoneAction;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.toolbox.MouseTriggerEvent;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.util.List;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Controls Swing components of a player's field instance.
|
||||
*/
|
||||
public class CField implements ICDoc {
|
||||
// The one who owns cards on this side of table
|
||||
private final Player player;
|
||||
private final PlayerView player;
|
||||
// Tho one who looks at screen and 'performs actions'
|
||||
private final LobbyPlayer viewer;
|
||||
private final VField view;
|
||||
@@ -61,42 +60,44 @@ public class CField implements ICDoc {
|
||||
/**
|
||||
* Controls Swing components of a player's field instance.
|
||||
*
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
* @param player2   {@link forge.game.player.Player}
|
||||
* @param v0   {@link forge.screens.match.views.VField}
|
||||
* @param playerViewer
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public CField(final Player p0, final VField v0, LobbyPlayer playerViewer) {
|
||||
this.player = p0;
|
||||
public CField(final PlayerView player2, final VField v0, LobbyPlayer playerViewer) {
|
||||
this.player = player2;
|
||||
this.viewer = playerViewer;
|
||||
this.view = v0;
|
||||
|
||||
ZoneAction handAction = new ZoneAction(player.getZone(ZoneType.Hand), MatchConstants.HUMANHAND) {
|
||||
final ZoneAction handAction = new ZoneAction(player.getHandCards(), MatchConstants.HUMANHAND) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if ( player.getLobbyPlayer() == viewer || ForgePreferences.DEV_MODE || player.hasKeyword("Play with your hand revealed."))
|
||||
if (player.getLobbyPlayer() == viewer || ForgePreferences.DEV_MODE) {// || player.hasKeyword("Play with your hand revealed."))
|
||||
super.actionPerformed(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ZoneAction libraryAction = new ZoneAction(player.getZone(ZoneType.Library), MatchConstants.HUMANLIBRARY) {
|
||||
|
||||
final ZoneAction libraryAction = new ZoneAction(player.getLibraryCards(), MatchConstants.HUMANLIBRARY) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (ForgePreferences.DEV_MODE)
|
||||
if (ForgePreferences.DEV_MODE) {
|
||||
super.actionPerformed(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ZoneAction exileAction = new ZoneAction(player.getZone(ZoneType.Exile), MatchConstants.HUMANEXILED);
|
||||
ZoneAction graveAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANGRAVEYARD);
|
||||
ZoneAction flashBackAction = new ZoneAction(player.getZone(ZoneType.Graveyard), MatchConstants.HUMANFLASHBACK) {
|
||||
|
||||
final ZoneAction exileAction = new ZoneAction(player.getExileCards(), MatchConstants.HUMANEXILED);
|
||||
final ZoneAction graveAction = new ZoneAction(player.getGraveCards(), MatchConstants.HUMANGRAVEYARD);
|
||||
final ZoneAction flashBackAction = new ZoneAction(player.getFlashbackCards(), MatchConstants.HUMANFLASHBACK) {
|
||||
@Override
|
||||
protected List<Card> getCardsAsIterable() {
|
||||
return player.getCardsActivableInExternalZones(true);
|
||||
protected List<CardView> getCardsAsIterable() {
|
||||
return player.getFlashbackCards();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doAction(final Card c) {
|
||||
protected void doAction(final CardView c) {
|
||||
// activate cards only via your own flashback button
|
||||
if (player.getLobbyPlayer() != CField.this.viewer) {
|
||||
return;
|
||||
@@ -157,16 +158,6 @@ public class CField implements ICDoc {
|
||||
public void update() {
|
||||
}
|
||||
|
||||
/** @return {@link forge.game.player.Player} */
|
||||
public Player getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
/** @return {@link forge.screens.match.views.VField} */
|
||||
public VField getView() {
|
||||
return this.view;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
*/
|
||||
|
||||
@@ -17,35 +17,36 @@
|
||||
*/
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.UiCommand;
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.screens.match.views.VHand;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import forge.view.arcane.HandArea;
|
||||
import forge.view.arcane.util.Animation;
|
||||
import forge.view.arcane.util.CardPanelMouseAdapter;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.screens.match.views.VField;
|
||||
import forge.screens.match.views.VHand;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import forge.view.arcane.HandArea;
|
||||
import forge.view.arcane.util.Animation;
|
||||
import forge.view.arcane.util.CardPanelMouseAdapter;
|
||||
|
||||
/**
|
||||
* Controls Swing components of a player's hand instance.
|
||||
*
|
||||
*/
|
||||
public class CHand implements ICDoc {
|
||||
private final Player player;
|
||||
private final PlayerView player;
|
||||
private final VHand view;
|
||||
private boolean initializedAlready = false;
|
||||
|
||||
@@ -55,15 +56,15 @@ public class CHand implements ICDoc {
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
* @param v0   {@link forge.screens.match.views.VHand}
|
||||
*/
|
||||
public CHand(final Player p0, final VHand v0) {
|
||||
public CHand(final PlayerView p0, final VHand v0) {
|
||||
this.player = p0;
|
||||
this.view = v0;
|
||||
v0.getHandArea().addCardPanelMouseListener(new CardPanelMouseAdapter() {
|
||||
@Override
|
||||
public void mouseDragEnd(CardPanel dragPanel, MouseEvent evt) {
|
||||
//update index of dragged card in hand zone to match new index within hand area
|
||||
int index = CHand.this.view.getHandArea().getCardPanels().indexOf(dragPanel);
|
||||
CHand.this.player.getZone(ZoneType.Hand).reposition(dragPanel.getCard(), index);
|
||||
//int index = CHand.this.view.getHandArea().getCardPanels().indexOf(dragPanel);
|
||||
//CHand.this.player.getZone(ZoneType.Hand).reposition(dragPanel.getCard(), index);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -103,12 +104,12 @@ public class CHand implements ICDoc {
|
||||
}
|
||||
|
||||
//update card panels in hand area
|
||||
final List<Card> cards = player.getZone(ZoneType.Hand).getCards();
|
||||
final List<CardView> cards = player.getHandCards();
|
||||
final List<CardPanel> placeholders = new ArrayList<CardPanel>();
|
||||
final List<CardPanel> cardPanels = new ArrayList<CardPanel>();
|
||||
|
||||
for (Card card : cards) {
|
||||
CardPanel cardPanel = p.getCardPanel(card.getUniqueNumber());
|
||||
|
||||
for (final CardView card : cards) {
|
||||
CardPanel cardPanel = p.getCardPanel(card.getId());
|
||||
if (cardPanel == null) { //create placeholders for new cards
|
||||
cardPanel = new CardPanel(card);
|
||||
cardPanel.setDisplayEnabled(false);
|
||||
|
||||
@@ -29,6 +29,7 @@ import forge.item.InventoryItem;
|
||||
import forge.screens.match.views.VPicture;
|
||||
import forge.toolbox.FMouseAdapter;
|
||||
import forge.toolbox.special.CardZoomer;
|
||||
import forge.view.CardView;
|
||||
import forge.view.FDialog;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -57,9 +58,14 @@ public enum CPicture implements ICDoc {
|
||||
private final JLabel flipIndicator = this.view.getLblFlipcard();
|
||||
private final CardZoomer zoomer = CardZoomer.SINGLETON_INSTANCE;
|
||||
|
||||
@Deprecated
|
||||
private Card currentCard = null;
|
||||
@Deprecated
|
||||
private CardCharacteristicName displayedState = CardCharacteristicName.Original;
|
||||
|
||||
private CardView currentView = null;
|
||||
private boolean isDisplayAlt = false;
|
||||
|
||||
private boolean mayShowCurrentCard() {
|
||||
if (currentCard == null) { return false; }
|
||||
if (FDialog.isModalOpen()) { return true; } //allow showing cards while modal open to account for revealing, picking, and ordering cards
|
||||
@@ -70,8 +76,9 @@ public enum CPicture implements ICDoc {
|
||||
* Shows card details and/or picture in sidebar cardview tabber.
|
||||
*
|
||||
*/
|
||||
@Deprecated
|
||||
public void showCard(Card c, boolean showFlipped) {
|
||||
if (c == null) {
|
||||
if (null == c) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -86,6 +93,24 @@ public enum CPicture implements ICDoc {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows card details and/or picture in sidebar cardview tabber.
|
||||
*
|
||||
*/
|
||||
public void showCard(final CardView c, boolean showAlt) {
|
||||
if (null == c) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentView = c;
|
||||
isDisplayAlt = false;
|
||||
flipIndicator.setVisible(c.hasAltState());
|
||||
picturePanel.setCard(c.getState(showAlt), mayShowCurrentCard());
|
||||
if (showAlt && c.hasAltState()) {
|
||||
flipCard();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays image associated with either a {@code Card}
|
||||
* or {@code InventoryItem} instance.
|
||||
@@ -137,7 +162,7 @@ public enum CPicture implements ICDoc {
|
||||
@Override
|
||||
public void onMiddleMouseDown(MouseEvent e) {
|
||||
if (isCardDisplayed()) {
|
||||
CardZoomer.SINGLETON_INSTANCE.doMouseButtonZoom(currentCard, displayedState);
|
||||
CardZoomer.SINGLETON_INSTANCE.doMouseButtonZoom(currentView);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,7 +187,7 @@ public enum CPicture implements ICDoc {
|
||||
public void mouseWheelMoved(MouseWheelEvent arg0) {
|
||||
if (isCardDisplayed()) {
|
||||
if (arg0.getWheelRotation() < 0) {
|
||||
zoomer.doMouseWheelZoom(currentCard, displayedState);
|
||||
zoomer.doMouseWheelZoom(currentView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,10 +203,9 @@ public enum CPicture implements ICDoc {
|
||||
}
|
||||
|
||||
public void flipCard() {
|
||||
if (isCurrentCardFlippable()) {
|
||||
displayedState = CardDetailUtil.getAlternateState(currentCard, displayedState);
|
||||
picturePanel.setCardImage(displayedState);
|
||||
setCardDetailPanel();
|
||||
if (currentView.hasAltState()) {
|
||||
isDisplayAlt = !isDisplayAlt;
|
||||
picturePanel.setCard(currentView.getState(isDisplayAlt), mayShowCurrentCard());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,6 +229,7 @@ public enum CPicture implements ICDoc {
|
||||
currentCard.setState(temp);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
private boolean isCurrentCardFlippable() {
|
||||
if (!mayShowCurrentCard()) { return false; }
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.UiCommand;
|
||||
import forge.game.Game;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.screens.match.views.VPlayers;
|
||||
import forge.view.IGameView;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
@@ -14,7 +14,7 @@ import forge.screens.match.views.VPlayers;
|
||||
public enum CPlayers implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
private Game game;
|
||||
private IGameView game;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
@@ -39,7 +39,7 @@ public enum CPlayers implements ICDoc {
|
||||
VPlayers.SINGLETON_INSTANCE.update(game);
|
||||
}
|
||||
|
||||
public void setModel(Game game) {
|
||||
public void setModel(IGameView game) {
|
||||
this.game = game;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,18 @@
|
||||
*/
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.UiCommand;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
|
||||
import javax.swing.JButton;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.Singletons;
|
||||
import forge.UiCommand;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameRules;
|
||||
import forge.game.Match;
|
||||
@@ -28,11 +38,6 @@ import forge.match.input.InputProxy;
|
||||
import forge.screens.match.views.VPrompt;
|
||||
import forge.toolbox.FSkin;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
/**
|
||||
* Controls the prompt panel in the match UI.
|
||||
*
|
||||
@@ -114,8 +119,9 @@ public enum CPrompt implements ICDoc {
|
||||
* @see java.util.Observer#update(java.util.Observable, java.lang.Object)
|
||||
*/
|
||||
|
||||
public void updateText(Game game) {
|
||||
public void updateText() {
|
||||
FThreads.assertExecutedByEdt(true);
|
||||
final Game game = Singletons.getControl().getObservedGame();
|
||||
final Match match = game.getMatch();
|
||||
final GameRules rules = game.getRules();
|
||||
final String text = String.format("T:%d G:%d/%d [%s]", game.getPhaseHandler().getTurn(), match.getPlayedGames().size() + 1, rules.getGamesPerMatch(), rules.getGameType());
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package forge.screens.match.controllers;
|
||||
|
||||
import forge.UiCommand;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.MagicStack;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.ICDoc;
|
||||
import forge.gui.framework.SDisplayUtil;
|
||||
import forge.screens.match.views.VStack;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Controls the combat panel in the match UI.
|
||||
@@ -18,8 +18,8 @@ public enum CStack implements ICDoc {
|
||||
/** */
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
private MagicStack model;
|
||||
private Player localPlayer;
|
||||
private IGameView model;
|
||||
private PlayerView localPlayer;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.gui.framework.ICDoc#getCommandOnSelect()
|
||||
@@ -42,8 +42,9 @@ public enum CStack implements ICDoc {
|
||||
VStack.SINGLETON_INSTANCE.updateStack(model, localPlayer);
|
||||
}
|
||||
|
||||
public void setModel(MagicStack model0, Player localPlayer0) {
|
||||
model = model0;
|
||||
localPlayer = localPlayer0;
|
||||
public void setModel(final IGameView game0, final PlayerView localPlayer) {
|
||||
model = game0;
|
||||
this.localPlayer = localPlayer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -198,8 +198,8 @@ public final class GameMenu {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
FControl control = Singletons.getControl();
|
||||
VAutoYields autoYields = new VAutoYields(control.getObservedGame(), control.getLocalPlayer());
|
||||
final FControl control = Singletons.getControl();
|
||||
final VAutoYields autoYields = new VAutoYields(control.getGameView(), control.getLocalPlayer());
|
||||
autoYields.showAutoYields();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.gui.CardPicturePanel;
|
||||
import forge.gui.WrapLayout;
|
||||
import forge.gui.framework.DragCell;
|
||||
@@ -29,13 +35,8 @@ import forge.gui.framework.IVDoc;
|
||||
import forge.screens.match.controllers.CAntes;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import forge.view.CardView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of card ante area.
|
||||
@@ -54,7 +55,7 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
private final FScrollPane scroller = new FScrollPane(pnl, false);
|
||||
private final SortedSet<AntePanel> allAntes = new TreeSet<AntePanel>();
|
||||
|
||||
private Iterable<Player> players;
|
||||
private Iterable<PlayerView> players;
|
||||
//========== Constructor
|
||||
private VAntes() {
|
||||
pnl.setLayout(new WrapLayout());
|
||||
@@ -72,8 +73,8 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
parentCell.getBody().add(scroller, "w 100%!, h 100%!");
|
||||
}
|
||||
|
||||
public final void setModel(Iterable<Player> playerz) {
|
||||
players = playerz;
|
||||
public final void setModel(final List<PlayerView> players) {
|
||||
this.players = players;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -121,8 +122,8 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
allAntes.clear();
|
||||
pnl.removeAll();
|
||||
|
||||
for(Player p : players) {
|
||||
for(Card c : p.getZone(ZoneType.Ante)) {
|
||||
for (final PlayerView p : players) {
|
||||
for (final CardView c : p.getAnteCards()) {
|
||||
final AntePanel pnlTemp = new AntePanel(c);
|
||||
allAntes.add(pnlTemp);
|
||||
}
|
||||
@@ -136,15 +137,15 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
//========= Private class handling
|
||||
@SuppressWarnings("serial")
|
||||
private class AntePanel extends JPanel implements Comparable<AntePanel> {
|
||||
private final Card card;
|
||||
private final CardView card;
|
||||
/**
|
||||
*
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
* @param c0   {@link forge.game.card.Card}
|
||||
* @param c   {@link forge.game.card.Card}
|
||||
*/
|
||||
public AntePanel(final Card c0) {
|
||||
public AntePanel(final CardView c) {
|
||||
super();
|
||||
card = c0;
|
||||
card = c;
|
||||
|
||||
final Dimension d = new Dimension(160, 250);
|
||||
setPreferredSize(d);
|
||||
@@ -157,12 +158,12 @@ public enum VAntes implements IVDoc<CAntes> {
|
||||
.fontAlign(SwingConstants.CENTER).build(), "w 160px, h 20px");
|
||||
CardPicturePanel picPanel = new CardPicturePanel();
|
||||
add(picPanel, "w 160px, h 230px");
|
||||
picPanel.setCard(c0, true);
|
||||
picPanel.setCard(c.getState(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(AntePanel o) {
|
||||
return o.card.getUniqueNumber() - card.getUniqueNumber();
|
||||
public int compareTo(final AntePanel o) {
|
||||
return o.card.getId() - card.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -26,10 +27,8 @@ import forge.gui.framework.IVDoc;
|
||||
import forge.screens.match.controllers.CCommand;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.PlayArea;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of a player command instance.
|
||||
@@ -44,7 +43,7 @@ public class VCommand implements IVDoc<CCommand> {
|
||||
private final DragTab tab = new DragTab("Command");
|
||||
|
||||
// Other fields
|
||||
private Player player = null;
|
||||
private PlayerView player = null;
|
||||
|
||||
// Top-level containers
|
||||
private final FScrollPane scroller = new FScrollPane(false);
|
||||
@@ -54,20 +53,20 @@ public class VCommand implements IVDoc<CCommand> {
|
||||
/**
|
||||
* Assembles Swing components of a player command instance.
|
||||
*
|
||||
* @param player0   {@link forge.game.player.Player}
|
||||
* @param p   {@link forge.game.player.Player}
|
||||
* @param id0   {@link forge.gui.framework.EDocID}
|
||||
*/
|
||||
public VCommand(final EDocID id0, final Player player0) {
|
||||
public VCommand(final EDocID id0, final PlayerView p) {
|
||||
this.docID = id0;
|
||||
id0.setDoc(this);
|
||||
|
||||
this.player = player0;
|
||||
if (player0 != null) { tab.setText(player0.getName() + " Command"); }
|
||||
this.player = p;
|
||||
if (p != null) { tab.setText(p.getName() + " Command"); }
|
||||
else { tab.setText("NO PLAYER FOR " + docID.toString()); }
|
||||
|
||||
// TODO player is hard-coded into tabletop...should be dynamic
|
||||
// (haven't looked into it too deeply). Doublestrike 12-04-12
|
||||
tabletop = new PlayArea(scroller, id0 == EDocID.COMMAND_0, player.getZone(ZoneType.Command).getCards(false));
|
||||
tabletop = new PlayArea(scroller, id0 == EDocID.COMMAND_0, player.getCommandCards());
|
||||
|
||||
control = new CCommand(player, this);
|
||||
|
||||
@@ -135,7 +134,7 @@ public class VCommand implements IVDoc<CCommand> {
|
||||
* Gets the player currently associated with this command.
|
||||
* @return {@link forge.game.player.Player}
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
public PlayerView getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public enum VDetail implements IVDoc<CDetail> {
|
||||
private final DragTab tab = new DragTab("Card Detail");
|
||||
|
||||
// Top-level containers
|
||||
private final CardDetailPanel pnlDetail = new CardDetailPanel(null);
|
||||
private final CardDetailPanel pnlDetail = new CardDetailPanel();
|
||||
private final SkinnedLabel lblFlipcard = new SkinnedLabel();
|
||||
|
||||
//========= Constructor
|
||||
|
||||
@@ -17,9 +17,18 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -32,16 +41,8 @@ import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.toolbox.special.PhaseIndicator;
|
||||
import forge.toolbox.special.PlayerDetailsPanel;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.PlayArea;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of a player field instance.
|
||||
@@ -56,7 +57,7 @@ public class VField implements IVDoc<CField> {
|
||||
private final DragTab tab = new DragTab("Field");
|
||||
|
||||
// Other fields
|
||||
private Player player = null;
|
||||
private PlayerView player = null;
|
||||
|
||||
// Top-level containers
|
||||
private final FScrollPane scroller = new FScrollPane(false);
|
||||
@@ -79,22 +80,22 @@ public class VField implements IVDoc<CField> {
|
||||
/**
|
||||
* Assembles Swing components of a player field instance.
|
||||
*
|
||||
* @param playerOnwer   {@link forge.game.player.Player}
|
||||
* @param p   {@link forge.game.player.Player}
|
||||
* @param id0   {@link forge.gui.framework.EDocID}
|
||||
*/
|
||||
public VField(final EDocID id0, final Player playerOnwer, LobbyPlayer playerViewer) {
|
||||
public VField(final EDocID id0, final PlayerView p, final LobbyPlayer playerViewer) {
|
||||
this.docID = id0;
|
||||
id0.setDoc(this);
|
||||
|
||||
this.player = playerOnwer;
|
||||
if (playerOnwer != null) { tab.setText(playerOnwer.getName() + " Field"); }
|
||||
this.player = p;
|
||||
if (p != null) { tab.setText(p.getName() + " Field"); }
|
||||
else { tab.setText("NO PLAYER FOR " + docID.toString()); }
|
||||
|
||||
detailsPanel = new PlayerDetailsPanel(player);
|
||||
|
||||
// TODO player is hard-coded into tabletop...should be dynamic
|
||||
// (haven't looked into it too deeply). Doublestrike 12-04-12
|
||||
tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1, player.getZone(ZoneType.Battlefield).getCards(false));
|
||||
tabletop = new PlayArea(scroller, id0 == EDocID.FIELD_1, player.getBfCards());
|
||||
|
||||
control = new CField(player, this, playerViewer);
|
||||
|
||||
@@ -195,7 +196,7 @@ public class VField implements IVDoc<CField> {
|
||||
* Gets the player currently associated with this field.
|
||||
* @return {@link forge.game.player.Player}
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
public PlayerView getPlayer() {
|
||||
return this.player;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,17 +17,17 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import forge.game.player.Player;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
import forge.gui.framework.IVDoc;
|
||||
import forge.screens.match.controllers.CHand;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.arcane.HandArea;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of hand area.
|
||||
@@ -41,7 +41,6 @@ public class VHand implements IVDoc<CHand> {
|
||||
private final EDocID docID;
|
||||
private final DragTab tab = new DragTab("Your Hand");
|
||||
|
||||
|
||||
// Top-level containers
|
||||
private final FScrollPane scroller = new FScrollPane(false);
|
||||
private final HandArea hand = new HandArea(scroller);
|
||||
@@ -51,23 +50,23 @@ public class VHand implements IVDoc<CHand> {
|
||||
* Assembles Swing components of a player hand instance.
|
||||
*
|
||||
* @param id0   {@link forge.gui.framework.EDocID}
|
||||
* @param owner   {@link forge.game.player.Player}
|
||||
* @param p   {@link forge.game.player.Player}
|
||||
*/
|
||||
public VHand(final EDocID id0, final Player owner) {
|
||||
public VHand(final EDocID id0, final PlayerView p) {
|
||||
docID = id0;
|
||||
id0.setDoc(this);
|
||||
|
||||
if (owner == null) {
|
||||
if (p == null) {
|
||||
tab.setText("NO PLAYER Hand");
|
||||
} else {
|
||||
tab.setText(owner.getName() + " Hand");
|
||||
tab.setText(p.getName() + " Hand");
|
||||
}
|
||||
|
||||
scroller.setViewportView(VHand.this.hand);
|
||||
|
||||
hand.setOpaque(false);
|
||||
|
||||
control = new CHand(owner, this);
|
||||
control = new CHand(p, this);
|
||||
}
|
||||
|
||||
//========= Overridden methods
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.game.GameType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.testng.collections.Maps;
|
||||
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -33,14 +38,9 @@ import forge.screens.match.controllers.CPlayers;
|
||||
import forge.toolbox.FScrollPanel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import forge.view.CardView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of players report.
|
||||
@@ -59,7 +59,7 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
// Other fields
|
||||
private Map<Player, JLabel[]> infoLBLs;
|
||||
private Map<PlayerView, JLabel[]> infoLBLs;
|
||||
|
||||
//========= Overridden methods
|
||||
|
||||
@@ -70,7 +70,7 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
public void populate() {
|
||||
scroller.removeAll();
|
||||
final String constraints = "w 97%!, gapleft 2%, gapbottom 1%";
|
||||
for (final Entry<Player, JLabel[]> p : infoLBLs.entrySet()) {
|
||||
for (final Entry<PlayerView, JLabel[]> p : infoLBLs.entrySet()) {
|
||||
for (JLabel label : p.getValue()) {
|
||||
scroller.add(label, constraints);
|
||||
}
|
||||
@@ -79,9 +79,9 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
parentCell.getBody().add(scroller, "w 100%, h 100%!");
|
||||
}
|
||||
|
||||
public void init(final Iterable<Player> players) {
|
||||
this.infoLBLs = new HashMap<Player, JLabel[]>();
|
||||
for (final Player p : players) {
|
||||
public void init(final List<PlayerView> players) {
|
||||
this.infoLBLs = Maps.newHashMap();
|
||||
for (final PlayerView p : players) {
|
||||
// Create and store labels detailing various non-critical player info.
|
||||
final InfoLabel name = new InfoLabel();
|
||||
final InfoLabel life = new InfoLabel();
|
||||
@@ -142,27 +142,27 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
//========== Observer update methods
|
||||
|
||||
/** @param p0 {@link forge.game.player.Player} */
|
||||
public void update(Game game) {
|
||||
public void update(final IGameView game) {
|
||||
// No need to update if this panel isn't showing
|
||||
if (parentCell == null || !this.equals(parentCell.getSelected())) { return; }
|
||||
boolean isCommander = game.getRules().hasAppliedVariant(GameType.Commander);
|
||||
boolean isCommander = game.isCommander();
|
||||
|
||||
for(Entry<Player, JLabel[]> rr : infoLBLs.entrySet()) {
|
||||
Player p0 = rr.getKey();
|
||||
for(final Entry<PlayerView, JLabel[]> rr : infoLBLs.entrySet()) {
|
||||
PlayerView p0 = rr.getKey();
|
||||
final JLabel[] temp = rr.getValue();
|
||||
temp[1].setText("Life: " + String.valueOf(p0.getLife()) + " | Poison counters: "
|
||||
+ String.valueOf(p0.getPoisonCounters()));
|
||||
temp[2].setText("Maximum hand size: " + String.valueOf(p0.getMaxHandSize()));
|
||||
temp[3].setText("Cards drawn this turn: " + String.valueOf(p0.getNumDrawnThisTurn()));
|
||||
temp[4].setText("Damage Prevention: " + String.valueOf(p0.getPreventNextDamageTotalShields()));
|
||||
temp[4].setText("Damage Prevention: " + String.valueOf(p0.getPreventNextDamage()));
|
||||
if (!p0.getKeywords().isEmpty()) {
|
||||
temp[5].setText(p0.getKeywords().toString());
|
||||
} else {
|
||||
temp[5].setText("");
|
||||
}
|
||||
if (FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE)) {
|
||||
List<Card> list = p0.getCardsIn(ZoneType.Ante);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
final List<CardView> list = p0.getAnteCards();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("Ante'd: ");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
sb.append(list.get(i));
|
||||
@@ -173,7 +173,7 @@ public enum VPlayers implements IVDoc<CPlayers> {
|
||||
temp[6].setText(sb.toString());
|
||||
}
|
||||
if (isCommander) {
|
||||
temp[7].setText(CardFactoryUtil.getCommanderInfo(p0).trim().replace("\r\n", "; "));
|
||||
temp[7].setText(p0.getCommanderInfo());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,16 +17,28 @@
|
||||
*/
|
||||
package forge.screens.match.views;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.JCheckBoxMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.ImageCache;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardDetailUtil;
|
||||
import forge.card.CardDetailUtil.DetailColors;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.zone.MagicStack;
|
||||
import forge.gui.framework.DragCell;
|
||||
import forge.gui.framework.DragTab;
|
||||
import forge.gui.framework.EDocID;
|
||||
@@ -39,18 +51,11 @@ import forge.toolbox.FMouseAdapter;
|
||||
import forge.toolbox.FScrollPanel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedTextArea;
|
||||
import forge.view.CardView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.StackItemView;
|
||||
import forge.view.arcane.CardPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
/**
|
||||
* Assembles Swing components of stack report.
|
||||
@@ -129,10 +134,11 @@ public enum VStack implements IVDoc<CStack> {
|
||||
//========== Observer update methods
|
||||
|
||||
/**
|
||||
* @param stack
|
||||
* @param model
|
||||
* @param viewer */
|
||||
public void updateStack(final MagicStack stack, final Player localPlayer) {
|
||||
tab.setText("Stack : " + stack.size());
|
||||
public void updateStack(final IGameView model, final PlayerView localPlayer) {
|
||||
final java.util.List<StackItemView> items = model.getStack();
|
||||
tab.setText("Stack : " + items.size());
|
||||
|
||||
// No need to update the rest unless it's showing
|
||||
if (!parentCell.getSelected().equals(this)) { return; }
|
||||
@@ -140,15 +146,15 @@ public enum VStack implements IVDoc<CStack> {
|
||||
scroller.removeAll();
|
||||
|
||||
boolean isFirst = true;
|
||||
for (final SpellAbilityStackInstance spell : stack) {
|
||||
StackInstanceTextArea tar = new StackInstanceTextArea(stack, spell, localPlayer);
|
||||
for (final StackItemView item : items) {
|
||||
final StackInstanceTextArea tar = new StackInstanceTextArea(model, item, localPlayer);
|
||||
|
||||
scroller.add(tar, "pushx, growx" + (isFirst ? "" : ", gaptop 2px"));
|
||||
|
||||
//update the Card Picture/Detail when the spell is added to the stack
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(spell.getSourceCard());
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(item.getSource());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,16 +175,14 @@ public enum VStack implements IVDoc<CStack> {
|
||||
private static final int CARD_WIDTH = 50;
|
||||
private static final int CARD_HEIGHT = Math.round((float)CARD_WIDTH * CardPanel.ASPECT_RATIO);
|
||||
|
||||
private final Card sourceCard;
|
||||
private final CardView sourceCard;
|
||||
|
||||
public StackInstanceTextArea(final MagicStack stack, final SpellAbilityStackInstance spell, final Player localPlayer) {
|
||||
sourceCard = spell.getSourceCard().getCardForUi();
|
||||
public StackInstanceTextArea(final IGameView game, final StackItemView item, final PlayerView localPlayer) {
|
||||
sourceCard = item.getSource();
|
||||
|
||||
final String txt = (item.isOptionalTrigger() && item.getActivatingPlayer().equals(localPlayer)
|
||||
? "(OPTIONAL) " : "") + item.getText();
|
||||
|
||||
String txt = spell.getStackDescription();
|
||||
if (spell.getSpellAbility().isOptionalTrigger()
|
||||
&& spell.getSourceCard().getController().equals(localPlayer)) {
|
||||
txt = "(OPTIONAL) " + txt;
|
||||
}
|
||||
setText(txt);
|
||||
setToolTipText(txt);
|
||||
setOpaque(true);
|
||||
@@ -193,13 +197,13 @@ public enum VStack implements IVDoc<CStack> {
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(final MouseEvent e) {
|
||||
if (!spell.getStackDescription().startsWith("Morph ")) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(spell.getSpellAbility().getHostCard());
|
||||
if (!txt.startsWith("Morph ")) {
|
||||
CMatchUI.SINGLETON_INSTANCE.setCard(item.getSource());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (spell.getSpellAbility().isAbility() && localPlayer != null) {
|
||||
if (item.isAbility() && localPlayer != null) {
|
||||
addMouseListener(new FMouseAdapter() {
|
||||
@Override
|
||||
public void onLeftClick(MouseEvent e) {
|
||||
@@ -210,13 +214,13 @@ public enum VStack implements IVDoc<CStack> {
|
||||
onClick(e);
|
||||
}
|
||||
private void onClick(MouseEvent e) {
|
||||
abilityMenu.setStackInstance(stack, spell.getSpellAbility(), localPlayer);
|
||||
abilityMenu.setStackInstance(game, item, localPlayer);
|
||||
abilityMenu.show(e.getComponent(), e.getX(), e.getY());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DetailColors color = CardDetailUtil.getBorderColor(sourceCard, !spell.getStackDescription().startsWith("Morph "));
|
||||
DetailColors color = CardDetailUtil.getBorderColor(item.getSource().getOriginal(), !txt.startsWith("Morph "));
|
||||
setBackground(new Color(color.r, color.g, color.b));
|
||||
setForeground(FSkin.getHighContrastColor(getBackground()));
|
||||
}
|
||||
@@ -228,7 +232,7 @@ public enum VStack implements IVDoc<CStack> {
|
||||
final Graphics2D g2d = (Graphics2D) g;
|
||||
|
||||
//draw image for source card
|
||||
BufferedImage img = ImageCache.getImage(sourceCard, CARD_WIDTH, CARD_HEIGHT);
|
||||
final BufferedImage img = ImageCache.getImage(sourceCard, CARD_WIDTH, CARD_HEIGHT);
|
||||
if (img != null) {
|
||||
g2d.drawImage(img, null, PADDING, PADDING);
|
||||
}
|
||||
@@ -242,8 +246,8 @@ public enum VStack implements IVDoc<CStack> {
|
||||
private final JCheckBoxMenuItem jmiAutoYield;
|
||||
private final JCheckBoxMenuItem jmiAlwaysYes;
|
||||
private final JCheckBoxMenuItem jmiAlwaysNo;
|
||||
private MagicStack stack;
|
||||
private SpellAbility ability;
|
||||
private IGameView game;
|
||||
private StackItemView item;
|
||||
private PlayerController controller;
|
||||
|
||||
private Integer triggerID = 0;
|
||||
@@ -253,10 +257,10 @@ public enum VStack implements IVDoc<CStack> {
|
||||
jmiAutoYield.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
final String key = ability.toUnsuppressedString();
|
||||
final String key = item.getKey();
|
||||
final boolean autoYield = controller.shouldAutoYield(key);
|
||||
controller.setShouldAutoYield(key, !autoYield);
|
||||
if (!autoYield && stack.peekAbility() == ability) {
|
||||
if (!autoYield && game.peekStack() == item) {
|
||||
//auto-pass priority if ability is on top of stack
|
||||
CPrompt.SINGLETON_INSTANCE.getInputControl().passPriority();
|
||||
}
|
||||
@@ -273,7 +277,7 @@ public enum VStack implements IVDoc<CStack> {
|
||||
}
|
||||
else {
|
||||
controller.setShouldAlwaysAcceptTrigger(triggerID);
|
||||
if (stack.peekAbility() == ability &&
|
||||
if (game.peekStack() == item &&
|
||||
Singletons.getControl().getInputQueue().getInput() instanceof InputConfirm) {
|
||||
//auto-yes if ability is on top of stack
|
||||
CPrompt.SINGLETON_INSTANCE.getInputControl().selectButtonOK();
|
||||
@@ -292,7 +296,7 @@ public enum VStack implements IVDoc<CStack> {
|
||||
}
|
||||
else {
|
||||
controller.setShouldAlwaysDeclineTrigger(triggerID);
|
||||
if (stack.peekAbility() == ability &&
|
||||
if (game.peekStack() == item &&
|
||||
Singletons.getControl().getInputQueue().getInput() instanceof InputConfirm) {
|
||||
//auto-no if ability is on top of stack
|
||||
CPrompt.SINGLETON_INSTANCE.getInputControl().selectButtonOK();
|
||||
@@ -303,15 +307,15 @@ public enum VStack implements IVDoc<CStack> {
|
||||
add(jmiAlwaysNo);
|
||||
}
|
||||
|
||||
public void setStackInstance(final MagicStack stack0, final SpellAbility ability0, final Player localPlayer) {
|
||||
stack = stack0;
|
||||
ability = ability0;
|
||||
public void setStackInstance(final IGameView game, final StackItemView item, final PlayerView localPlayer) {
|
||||
this.game = game;
|
||||
this.item = item;
|
||||
controller = localPlayer.getController();
|
||||
triggerID = ability.getSourceTrigger();
|
||||
triggerID = Integer.valueOf(item.getSourceTrigger());
|
||||
|
||||
jmiAutoYield.setSelected(controller.shouldAutoYield(ability.toUnsuppressedString()));
|
||||
jmiAutoYield.setSelected(controller.shouldAutoYield(item.getKey()));
|
||||
|
||||
if (ability.isOptionalTrigger() && ability.getActivatingPlayer() == localPlayer) {
|
||||
if (item.isOptionalTrigger() && item.getActivatingPlayer().equals(localPlayer)) {
|
||||
jmiAlwaysYes.setSelected(controller.shouldAlwaysAcceptTrigger(triggerID));
|
||||
jmiAlwaysNo.setSelected(controller.shouldAlwaysDeclineTrigger(triggerID));
|
||||
jmiAlwaysYes.setVisible(true);
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
package forge.toolbox.imaging;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.game.card.Card;
|
||||
@@ -25,10 +29,7 @@ import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.toolbox.CardFaceSymbols;
|
||||
import forge.toolbox.FSkin.SkinIcon;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.ColorModel;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
/**
|
||||
* Common image-related routines specific to Forge images.
|
||||
@@ -38,7 +39,8 @@ import java.awt.image.ColorModel;
|
||||
*/
|
||||
public final class FImageUtil {
|
||||
private FImageUtil() {}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public static BufferedImage getImage(Card card, CardCharacteristicName state) {
|
||||
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(state), true);
|
||||
int foilIndex = card.getFoil();
|
||||
@@ -56,6 +58,7 @@ public final class FImageUtil {
|
||||
* For double-sided cards, returns the front-side image.<br>
|
||||
* For flip cards, returns the un-flipped image.
|
||||
*/
|
||||
@Deprecated
|
||||
public static BufferedImage getImage(Card card) {
|
||||
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), true);
|
||||
int foilIndex = card.getFoil();
|
||||
@@ -64,7 +67,24 @@ public final class FImageUtil {
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the image associated with a card.
|
||||
* <p>
|
||||
* Adds a random foil effect if enabled.
|
||||
* <p>
|
||||
* For double-sided cards, returns the front-side image.<br>
|
||||
* For flip cards, returns the un-flipped image.
|
||||
*/
|
||||
public static BufferedImage getImage(final CardStateView card) {
|
||||
BufferedImage image = ImageCache.getOriginalImage(card.getImageKey(), true);
|
||||
final int foilIndex = card.getCard().getFoilIndex();
|
||||
if (image != null && foilIndex > 0) {
|
||||
image = getImageWithFoilEffect(image, foilIndex);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a foil effect to a card image.
|
||||
*/
|
||||
|
||||
@@ -56,7 +56,7 @@ public class CardViewer extends JPanel {
|
||||
public CardViewer(final List<PaperCard> list) {
|
||||
this.list = Collections.unmodifiableList(list);
|
||||
this.jList = new JList<PaperCard>(new ChooserListModel());
|
||||
this.detail = new CardDetailPanel(null);
|
||||
this.detail = new CardDetailPanel();
|
||||
this.picture = new CardPicturePanel();
|
||||
|
||||
this.add(new FScrollPane(this.jList, true));
|
||||
|
||||
@@ -18,23 +18,29 @@
|
||||
|
||||
package forge.toolbox.special;
|
||||
|
||||
import forge.Singletons;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.card.CardDetailUtil;
|
||||
import forge.game.card.Card;
|
||||
import forge.gui.SOverlayUtils;
|
||||
import forge.toolbox.FOverlay;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedLabel;
|
||||
import forge.toolbox.imaging.FImagePanel;
|
||||
import forge.toolbox.imaging.FImageUtil;
|
||||
import forge.toolbox.imaging.FImagePanel.AutoSizeImageMode;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.event.*;
|
||||
import forge.toolbox.imaging.FImageUtil;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
/**
|
||||
* Displays card image at its original size and correct orientation.
|
||||
@@ -46,30 +52,28 @@ import java.awt.event.*;
|
||||
*
|
||||
*/
|
||||
public enum CardZoomer {
|
||||
SINGLETON_INSTANCE;
|
||||
SINGLETON_INSTANCE;
|
||||
|
||||
// Gui controls
|
||||
private final JPanel overlay = FOverlay.SINGLETON_INSTANCE.getPanel();
|
||||
private JPanel pnlMain;
|
||||
private FImagePanel imagePanel;
|
||||
private SkinnedLabel lblFlipcard = new SkinnedLabel();
|
||||
|
||||
|
||||
// Details about the current card being displayed.
|
||||
private Card thisCard;
|
||||
private CardCharacteristicName cardState = CardCharacteristicName.Original;
|
||||
private boolean isImageFlipped = false;
|
||||
private boolean isFaceDownCard = false;
|
||||
|
||||
private CardView thisCard;
|
||||
private boolean isInAltState;
|
||||
|
||||
// The zoomer is in button mode when it is activated by holding down the
|
||||
// middle mouse button or left and right mouse buttons simultaneously.
|
||||
private boolean isButtonMode = false;
|
||||
private boolean isOpen = false;
|
||||
private long lastClosedTime;
|
||||
|
||||
|
||||
// Used to ignore mouse wheel rotation for a short period of time.
|
||||
private Timer mouseWheelCoolDownTimer;
|
||||
private boolean isMouseWheelEnabled = false;
|
||||
|
||||
|
||||
// ctr
|
||||
private CardZoomer() {
|
||||
lblFlipcard.setIcon(FSkin.getIcon(FSkinProp.ICO_FLIPCARD));
|
||||
@@ -77,7 +81,7 @@ public enum CardZoomer {
|
||||
setMouseWheelListener();
|
||||
setKeyListeners();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates listener for keys that are recognised by zoomer.
|
||||
* <p><ul>
|
||||
@@ -103,30 +107,33 @@ public enum CardZoomer {
|
||||
/**
|
||||
* Creates listener for mouse button events.
|
||||
* <p>
|
||||
* NOTE: Needed even if ButtonMode to prevent Zoom getting stuck open on certain systems.
|
||||
* NOTE: Needed even if ButtonMode to prevent Zoom getting stuck open on
|
||||
* certain systems.
|
||||
*/
|
||||
private void setMouseButtonListener() {
|
||||
overlay.addMouseListener(new MouseAdapter() {
|
||||
overlay.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
closeZoomer();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates listener for mouse wheel events.
|
||||
* <p>
|
||||
* If the zoomer is opened using the mouse wheel then additional
|
||||
* actions can be performed dependent on the card type -
|
||||
* <p><ul>
|
||||
* If the zoomer is opened using the mouse wheel then additional actions can
|
||||
* be performed dependent on the card type -
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li>If mouse wheel is rotated back then close zoomer.
|
||||
* <li>If mouse wheel is rotated forward and...<ul>
|
||||
* <li>if image is a flip card then rotate 180 degrees.
|
||||
* <li>if image is a double-sided card then show other side.
|
||||
* <li>If mouse wheel is rotated forward and...
|
||||
* <ul>
|
||||
* <li>if image is a flip card then rotate 180 degrees.
|
||||
* <li>if image is a double-sided card then show other side.
|
||||
*/
|
||||
private void setMouseWheelListener() {
|
||||
overlay.addMouseWheelListener(new MouseWheelListener() {
|
||||
overlay.addMouseWheelListener(new MouseWheelListener() {
|
||||
@Override
|
||||
public void mouseWheelMoved(MouseWheelEvent e) {
|
||||
if (!isButtonMode) {
|
||||
@@ -136,111 +143,86 @@ public enum CardZoomer {
|
||||
closeZoomer();
|
||||
} else {
|
||||
toggleCardImage();
|
||||
startMouseWheelCoolDownTimer(250);
|
||||
}
|
||||
}
|
||||
startMouseWheelCoolDownTimer(250);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Opens zoomer in mouse wheel mode and displays the image associated with
|
||||
* the given card based on its current {@code CardCharacteristicName} state.
|
||||
* the given card based.
|
||||
* <p>
|
||||
* This method should be called if the zoomer is activated by rotating the mouse wheel.
|
||||
* This method should be called if the zoomer is activated by rotating the
|
||||
* mouse wheel.
|
||||
*/
|
||||
public void doMouseWheelZoom(Card newCard) {
|
||||
doMouseWheelZoom(newCard, newCard.getCurState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens zoomer in mouse wheel mode and displays the image associated with
|
||||
* the given card based on the specified {@code CardCharacteristicName} state.
|
||||
* <p>
|
||||
* This method should be called if the zoomer is activated by rotating the mouse wheel.
|
||||
*/
|
||||
public void doMouseWheelZoom(Card newCard, CardCharacteristicName state) {
|
||||
public void doMouseWheelZoom(final CardView card) {
|
||||
isButtonMode = false;
|
||||
isFaceDownCard = (state == CardCharacteristicName.FaceDown);
|
||||
cardState = state;
|
||||
displayCard(newCard);
|
||||
startMouseWheelCoolDownTimer(200);
|
||||
displayCard(card);
|
||||
startMouseWheelCoolDownTimer(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens zoomer in mouse button mode and displays the image associated with
|
||||
* the given card based on its current {@code CardCharacteristicName} state.
|
||||
* <p>
|
||||
* This method should be called if the zoomer is activated by holding down
|
||||
* the middle mouse button or left and right mouse buttons simultaneously.
|
||||
*/
|
||||
public void doMouseButtonZoom(Card newCard) {
|
||||
doMouseButtonZoom(newCard, newCard.getCurState());
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens zoomer in mouse button mode and displays the image associated with
|
||||
* the given card based on the specified {@code CardCharacteristicName} state.
|
||||
* the given card.
|
||||
* <p>
|
||||
* This method should be called if the zoomer is activated by holding down
|
||||
* the middle mouse button or left and right mouse buttons simultaneously.
|
||||
*/
|
||||
public void doMouseButtonZoom(Card newCard, CardCharacteristicName state) {
|
||||
|
||||
public void doMouseButtonZoom(final CardView newCard) {
|
||||
|
||||
// don't display zoom if already zoomed or just closed zoom
|
||||
// (handles mouse wheeling while middle clicking)
|
||||
if (isOpen || System.currentTimeMillis() - lastClosedTime < 250) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
isButtonMode = true;
|
||||
isFaceDownCard = (state == CardCharacteristicName.FaceDown);
|
||||
cardState = state;
|
||||
displayCard(newCard);
|
||||
}
|
||||
|
||||
|
||||
public boolean isZoomerOpen() {
|
||||
return isOpen;
|
||||
}
|
||||
|
||||
private void displayCard(Card card) {
|
||||
|
||||
private void displayCard(final CardView newCard) {
|
||||
isMouseWheelEnabled = false;
|
||||
isImageFlipped = false;
|
||||
thisCard = card.getCardForUi();
|
||||
thisCard = newCard;
|
||||
isInAltState = false;
|
||||
setLayout();
|
||||
setImage();
|
||||
SOverlayUtils.showOverlay();
|
||||
isOpen = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays a graphical indicator that shows whether the current card can be flipped or transformed.
|
||||
*/
|
||||
private void setFlipIndicator() {
|
||||
boolean isFaceDownFlippable = (isFaceDownCard && Singletons.getControl().mayShowCard(thisCard));
|
||||
if (thisCard.isFlipCard() || thisCard.isDoubleFaced() || isFaceDownFlippable ) {
|
||||
if (thisCard.hasAltState()) {
|
||||
imagePanel.setLayout(new MigLayout("insets 0, w 100%!, h 100%!"));
|
||||
imagePanel.add(lblFlipcard, "pos (100% - 100px) 0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Needs to be called whenever the source image changes.
|
||||
*/
|
||||
private void setImage() {
|
||||
imagePanel = new FImagePanel();
|
||||
imagePanel.setImage(FImageUtil.getImage(thisCard, cardState), getInitialRotation(), AutoSizeImageMode.SOURCE);
|
||||
imagePanel.setImage(FImageUtil.getImage(getState()), getInitialRotation(), AutoSizeImageMode.SOURCE);
|
||||
pnlMain.removeAll();
|
||||
pnlMain.add(imagePanel, "w 80%!, h 80%!");
|
||||
pnlMain.validate();
|
||||
setFlipIndicator();
|
||||
}
|
||||
|
||||
|
||||
private int getInitialRotation() {
|
||||
return (thisCard.isSplitCard() || thisCard.isPlane() || thisCard.isPhenomenon() ? 90 : 0);
|
||||
return (thisCard.isSplitCard() || getState().isPlane() || getState().isPhenomenon() ? 90 : 0);
|
||||
}
|
||||
|
||||
|
||||
private void setLayout() {
|
||||
overlay.removeAll();
|
||||
pnlMain = new JPanel();
|
||||
@@ -283,53 +265,35 @@ public enum CardZoomer {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void stopMouseWheelCoolDownTimer() {
|
||||
if (mouseWheelCoolDownTimer != null && mouseWheelCoolDownTimer.isRunning()) {
|
||||
mouseWheelCoolDownTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggles between primary and alternate image associated with card if applicable.
|
||||
*/
|
||||
private void toggleCardImage() {
|
||||
if (thisCard.isFlipCard()) {
|
||||
if (thisCard.hasAltState()) {
|
||||
toggleFlipCard();
|
||||
} else if (thisCard.isDoubleFaced()) {
|
||||
toggleDoubleFacedCard();
|
||||
} else if (isFaceDownCard) {
|
||||
toggleFaceDownCard();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Flips image by rotating 180 degrees each time.
|
||||
* <p>
|
||||
* No need to get the alternate card image from cache.
|
||||
* Can simply rotate current card image in situ to get same effect.
|
||||
*/
|
||||
private void toggleFlipCard() {
|
||||
isImageFlipped = !isImageFlipped;
|
||||
imagePanel.setRotation(isImageFlipped ? 180 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles between the front and back image of a card that can be
|
||||
* played face-down (eg. morph).
|
||||
* <p>
|
||||
* Uses constraint that prevents a player from identifying opponent's face-down cards.
|
||||
*/
|
||||
private void toggleFaceDownCard() {
|
||||
cardState = CardDetailUtil.getAlternateState(thisCard, cardState);
|
||||
private void toggleFlipCard() {
|
||||
isInAltState = !isInAltState;
|
||||
imagePanel.setRotation(thisCard.isFlipCard() && isInAltState ? 180 : 0);
|
||||
setImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles between the front and back image of a double-sided card.
|
||||
*/
|
||||
private void toggleDoubleFacedCard() {
|
||||
cardState = CardDetailUtil.getAlternateState(thisCard, cardState);
|
||||
setImage();
|
||||
|
||||
private CardStateView getState() {
|
||||
return thisCard.getState(isButtonMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
package forge.toolbox.special;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.card.MagicColor;
|
||||
import forge.game.mana.ManaPool;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.gui.ForgeAction;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.screens.match.controllers.CPlayers;
|
||||
import forge.toolbox.FLabel;
|
||||
import forge.toolbox.FSkin;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
|
||||
public class PlayerDetailsPanel extends JPanel {
|
||||
private static final long serialVersionUID = 8444559244193214459L;
|
||||
|
||||
private Player player;
|
||||
private PlayerView player;
|
||||
|
||||
// Info labels
|
||||
private FLabel lblHand = getBuiltFLabel(FSkinProp.IMG_ZONE_HAND, "99", "Cards in hand");
|
||||
@@ -47,8 +48,7 @@ public class PlayerDetailsPanel extends JPanel {
|
||||
.text(s0).tooltip(s1).fontAlign(SwingConstants.RIGHT).build();
|
||||
}
|
||||
|
||||
public PlayerDetailsPanel(Player player) {
|
||||
|
||||
public PlayerDetailsPanel(final PlayerView player) {
|
||||
this.player = player;
|
||||
|
||||
manaLabels.add(Pair.of(getBuiltFLabel(FSkinProp.IMG_MANA_B, "99", "Black mana"), MagicColor.BLACK));
|
||||
@@ -121,14 +121,14 @@ public class PlayerDetailsPanel extends JPanel {
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
*/
|
||||
public void updateZones() {
|
||||
this.getLblHand().setText("" + player.getZone(ZoneType.Hand).size());
|
||||
final String handMaxToolTip = player.isUnlimitedHandSize()
|
||||
this.getLblHand().setText("" + player.getHandCards().size());
|
||||
final String handMaxToolTip = player.hasUnlimitedHandSize()
|
||||
? "no maximum hand size" : String.valueOf(player.getMaxHandSize());
|
||||
this.getLblHand().setToolTipText("Cards in hand (max: " + handMaxToolTip + ")");
|
||||
this.getLblGraveyard().setText("" + player.getZone(ZoneType.Graveyard).size());
|
||||
this.getLblLibrary().setText("" + player.getZone(ZoneType.Library).size());
|
||||
this.getLblFlashback().setText("" + player.getCardsActivableInExternalZones(true).size());
|
||||
this.getLblExile().setText("" + player.getZone(ZoneType.Exile).size());
|
||||
this.getLblHand().setToolTipText("Cards in hand (max: " + handMaxToolTip + ")");
|
||||
this.getLblGraveyard().setText("" + player.getGraveCards().size());
|
||||
this.getLblLibrary().setText("" + player.getLibraryCards().size());
|
||||
this.getLblFlashback().setText("" + player.getFlashbackCards().size());
|
||||
this.getLblExile().setText("" + player.getExileCards().size());
|
||||
}
|
||||
|
||||
|
||||
@@ -158,9 +158,8 @@ public class PlayerDetailsPanel extends JPanel {
|
||||
* @param p0   {@link forge.game.player.Player}
|
||||
*/
|
||||
public void updateManaPool() {
|
||||
ManaPool m = player.getManaPool();
|
||||
for(Pair<FLabel, Byte> label : manaLabels)
|
||||
label.getKey().setText(Integer.toString(m.getAmountOfColor(label.getRight())));
|
||||
for (final Pair<FLabel, Byte> label : manaLabels)
|
||||
label.getKey().setText(Integer.toString(player.getMana(label.getRight())));
|
||||
}
|
||||
|
||||
public FLabel getLblHand() {
|
||||
|
||||
@@ -17,31 +17,38 @@
|
||||
*/
|
||||
package forge.view.arcane;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardCharacteristicName;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.gui.CardContainer;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.CardFaceSymbols;
|
||||
import forge.toolbox.IDisposable;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.view.arcane.util.OutlinedLabel;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.ImageCache;
|
||||
import forge.Singletons;
|
||||
import forge.card.CardEdition;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.gui.CardContainer;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.CardFaceSymbols;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.toolbox.IDisposable;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
import forge.view.arcane.util.OutlinedLabel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* CardPanel class.
|
||||
@@ -85,7 +92,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
*/
|
||||
private static final float ROT_CENTER_TO_BOTTOM_CORNER = 0.7071067811865475244008443621048f;
|
||||
|
||||
private Card card;
|
||||
private CardView card;
|
||||
private CardPanel attachedToPanel;
|
||||
private List<CardPanel> attachedPanels = new ArrayList<CardPanel>();
|
||||
private boolean tapped;
|
||||
@@ -110,7 +117,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
* @param newCard
|
||||
* a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
public CardPanel(final Card card0) {
|
||||
public CardPanel(final CardView card0) {
|
||||
this.card = card0;
|
||||
|
||||
this.setBackground(Color.black);
|
||||
@@ -321,8 +328,8 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
|
||||
// White border if card is known to have it.
|
||||
if (this.getCard() != null && Singletons.getControl().mayShowCard(this.getCard()) && !this.getCard().isFaceDown()) {
|
||||
CardEdition ed = FModel.getMagicDb().getEditions().get(this.getCard().getCurSetCode());
|
||||
if (ed != null && ed.isWhiteBorder() && this.getCard().getFoil() == 0) {
|
||||
CardEdition ed = FModel.getMagicDb().getEditions().get(this.getCard().getSetCode());
|
||||
if (ed != null && ed.isWhiteBorder() && this.getCard().getFoilIndex() == 0) {
|
||||
g2d.setColor(Color.white);
|
||||
int ins = 1;
|
||||
g2d.fillRoundRect(this.cardXOffset + ins, this.cardYOffset + ins, this.cardWidth - ins*2, this.cardHeight - ins*2, cornerSize-ins, cornerSize-ins);
|
||||
@@ -351,12 +358,12 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
}
|
||||
|
||||
if (showCardManaCostOverlay() && this.cardWidth < 200) {
|
||||
boolean showSplitMana = card.isSplitCard() && card.getCurState() == CardCharacteristicName.Original;
|
||||
final boolean showSplitMana = card.isSplitCard();
|
||||
if (!showSplitMana) {
|
||||
drawManaCost(g, card.getManaCost(), 0);
|
||||
drawManaCost(g, card.getState().getManaCost(), 0);
|
||||
} else {
|
||||
drawManaCost(g, card.getRules().getMainPart().getManaCost(), +12);
|
||||
drawManaCost(g, card.getRules().getOtherPart().getManaCost(), -12);
|
||||
drawManaCost(g, card.getOriginal().getManaCost(), +12);
|
||||
drawManaCost(g, card.getAlternate().getManaCost(), -12);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,17 +389,14 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
final int stateXSymbols = (this.cardXOffset + (this.cardWidth / 2)) - 16;
|
||||
final int ySymbols = (this.cardYOffset + this.cardHeight) - (this.cardHeight / 8) - 16;
|
||||
|
||||
Combat combat = card.getGame().getCombat();
|
||||
if (combat != null) {
|
||||
if (combat.isAttacking(card)) {
|
||||
CardFaceSymbols.drawSymbol("attack", g, combatXSymbols, ySymbols);
|
||||
}
|
||||
if (combat.isBlocking(card)) {
|
||||
CardFaceSymbols.drawSymbol("defend", g, combatXSymbols, ySymbols);
|
||||
}
|
||||
if (card.isAttacking()) {
|
||||
CardFaceSymbols.drawSymbol("attack", g, combatXSymbols, ySymbols);
|
||||
}
|
||||
if (card.isBlocking()) {
|
||||
CardFaceSymbols.drawSymbol("defend", g, combatXSymbols, ySymbols);
|
||||
}
|
||||
|
||||
if (card.isSick() && card.isInPlay()) {
|
||||
if (card.isSick()) {
|
||||
CardFaceSymbols.drawSymbol("summonsick", g, stateXSymbols, ySymbols);
|
||||
}
|
||||
|
||||
@@ -409,9 +413,9 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
this.cardWidth, this.cardHeight, Math.round(this.cardWidth * BLACK_BORDER_SIZE));
|
||||
}
|
||||
|
||||
public static void drawFoilEffect(Graphics g, Card card, int x, int y, int width, int height, int borderSize) {
|
||||
public static void drawFoilEffect(final Graphics g, final CardView card2, final int x, final int y, final int width, final int height, final int borderSize) {
|
||||
if (isPreferenceEnabled(FPref.UI_OVERLAY_FOIL_EFFECT)) {
|
||||
int foil = card.getFoil();
|
||||
int foil = card2.getFoilIndex();
|
||||
if (foil > 0) {
|
||||
CardFaceSymbols.drawOther(g, String.format("foil%02d", foil),
|
||||
x + borderSize, y + borderSize, width - 2 * borderSize, height - 2 * borderSize);
|
||||
@@ -479,7 +483,7 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return this.getCard().getName();
|
||||
return this.getCard().toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -610,27 +614,28 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
this.titleText.setText("");
|
||||
}
|
||||
else {
|
||||
this.titleText.setText(card.getName());
|
||||
this.titleText.setText(card.getState().getName());
|
||||
}
|
||||
|
||||
int damage = card.getDamage();
|
||||
this.damageText.setText(damage > 0 ? "\u00BB " + String.valueOf(damage) + " \u00AB" : "");
|
||||
|
||||
// Card Id overlay
|
||||
this.cardIdText.setText(Integer.toString(card.getUniqueNumber()));
|
||||
this.cardIdText.setText(Integer.toString(card.getId()));
|
||||
}
|
||||
|
||||
public final void updatePTOverlay() {
|
||||
// P/T overlay
|
||||
final CardStateView state = card.getState();
|
||||
String sPt = "";
|
||||
if (card.isCreature() && card.isPlaneswalker()) {
|
||||
sPt = String.format("%d/%d (%d)", card.getNetAttack(), card.getNetDefense(), card.getCurrentLoyalty());
|
||||
if (state.isCreature() && state.isPlaneswalker()) {
|
||||
sPt = String.format("%d/%d (%d)", state.getPower(), state.getToughness(), state.getLoyalty());
|
||||
}
|
||||
else if (card.isCreature()) {
|
||||
sPt = String.format("%d/%d", card.getNetAttack(), card.getNetDefense());
|
||||
else if (state.isCreature()) {
|
||||
sPt = String.format("%d/%d", state.getPower(), state.getToughness());
|
||||
}
|
||||
else if (card.isPlaneswalker()) {
|
||||
sPt = String.valueOf(card.getCurrentLoyalty());
|
||||
else if (state.isPlaneswalker()) {
|
||||
sPt = String.valueOf(state.getLoyalty());
|
||||
}
|
||||
this.ptText.setText(sPt);
|
||||
}
|
||||
@@ -641,28 +646,28 @@ public class CardPanel extends SkinnedPanel implements CardContainer, IDisposabl
|
||||
* @return the card
|
||||
*/
|
||||
@Override
|
||||
public final Card getCard() {
|
||||
public final CardView getCard() {
|
||||
return this.card;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public final void setCard(final Card card) {
|
||||
if ((this.getCard() != null) && this.getCard().equals(card) && this.isAnimationPanel
|
||||
public final void setCard(final CardView cardView) {
|
||||
if ((this.getCard() != null) && this.getCard().equals(cardView) && this.isAnimationPanel
|
||||
&& this.imagePanel.hasImage()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.card != card) {
|
||||
if (this.card != cardView) {
|
||||
this.updatePTOverlay(); //update PT Overlay if card changes
|
||||
}
|
||||
|
||||
this.card = card;
|
||||
this.card = cardView;
|
||||
if (!this.isShowing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final BufferedImage image = card == null ? null : ImageCache.getImage(card, imagePanel.getWidth(), imagePanel.getHeight());
|
||||
final BufferedImage image = cardView == null ? null : ImageCache.getImage(cardView, imagePanel.getWidth(), imagePanel.getHeight());
|
||||
this.updateText();
|
||||
|
||||
this.setImage(image);
|
||||
|
||||
@@ -17,21 +17,26 @@
|
||||
*/
|
||||
package forge.view.arcane;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
import java.awt.event.MouseWheelEvent;
|
||||
import java.awt.event.MouseWheelListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.card.Card;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.FSkin.SkinnedPanel;
|
||||
import forge.toolbox.special.CardZoomer;
|
||||
import forge.view.CardView;
|
||||
import forge.view.arcane.util.CardPanelMouseListener;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages mouse events and common functionality for CardPanel containing
|
||||
* components.
|
||||
@@ -278,6 +283,29 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
protected abstract CardPanel getCardPanel(int x, int y);
|
||||
|
||||
/**
|
||||
<<<<<<< .mine
|
||||
* Must call from the Swing event thread.
|
||||
*
|
||||
* @param card
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @return a {@link forge.view.arcane.CardPanel} object.
|
||||
*/
|
||||
public CardPanel addCard(final CardView card) {
|
||||
final CardPanel placeholder = new CardPanel(card);
|
||||
placeholder.setDisplayEnabled(false);
|
||||
this.getCardPanels().add(placeholder);
|
||||
this.add(placeholder);
|
||||
this.doLayout();
|
||||
// int y = Math.min(placeholder.getHeight(),
|
||||
// scrollPane.getVisibleRect().height);
|
||||
this.scrollRectToVisible(new Rectangle(placeholder.getCardX(), placeholder.getCardY(), placeholder
|
||||
.getCardWidth(), placeholder.getCardHeight()));
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
/**
|
||||
=======
|
||||
>>>>>>> .r27195
|
||||
* <p>
|
||||
* getCardPanel.
|
||||
* </p>
|
||||
@@ -288,7 +316,7 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
*/
|
||||
public final CardPanel getCardPanel(final int gameCardID) {
|
||||
for (final CardPanel panel : this.getCardPanels()) {
|
||||
if (panel.getCard().getUniqueNumber() == gameCardID) {
|
||||
if (panel.getCard().getId() == gameCardID) {
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
@@ -584,7 +612,7 @@ public abstract class CardPanelContainer extends SkinnedPanel {
|
||||
*
|
||||
* @return a {@link forge.game.card.Card} object.
|
||||
*/
|
||||
public final Card getHoveredCard(MouseEvent e) {
|
||||
public final CardView getHoveredCard(final MouseEvent e) {
|
||||
// re-evaluate cursor position so if we hovered over a card, alt-tabbed out of the application, then
|
||||
// clicked back on the application somewhere else, the last hovered card won't register the click
|
||||
// this cannot protect against alt tabbing off then re-focusing on the application by clicking on
|
||||
|
||||
@@ -17,20 +17,26 @@
|
||||
*/
|
||||
package forge.view.arcane;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.game.card.Card;
|
||||
import forge.screens.match.CMatchUI;
|
||||
import forge.screens.match.controllers.CPrompt;
|
||||
import forge.toolbox.FScrollPane;
|
||||
import forge.toolbox.MouseTriggerEvent;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
import forge.view.arcane.util.Animation;
|
||||
import forge.view.arcane.util.CardPanelMouseListener;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* PlayArea class.
|
||||
@@ -69,8 +75,8 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
private int extraCardSpacingX, cardSpacingX, cardSpacingY;
|
||||
private int stackSpacingX, stackSpacingY;
|
||||
|
||||
private List<Card> model;
|
||||
|
||||
private final List<CardView> model;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Constructor for PlayArea.
|
||||
@@ -78,13 +84,13 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
*
|
||||
* @param scrollPane
|
||||
* @param mirror
|
||||
* @param modelRef
|
||||
* @param list
|
||||
*/
|
||||
public PlayArea(final FScrollPane scrollPane, final boolean mirror, List<Card> modelRef) {
|
||||
public PlayArea(final FScrollPane scrollPane, final boolean mirror, final List<CardView> list) {
|
||||
super(scrollPane);
|
||||
this.setBackground(Color.white);
|
||||
this.mirror = mirror;
|
||||
this.model = modelRef;
|
||||
this.model = list;
|
||||
}
|
||||
|
||||
private final CardStackRow collectAllLands() {
|
||||
@@ -93,7 +99,10 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
outerLoop:
|
||||
//
|
||||
for (final CardPanel panel : this.getCardPanels()) {
|
||||
if (!panel.getCard().isLand() || panel.getCard().isCreature()) {
|
||||
final CardView card = panel.getCard();
|
||||
final CardStateView state = card.getState();
|
||||
|
||||
if (!state.isLand() || state.isCreature()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -103,7 +112,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
for (int i = 0, n = allLands.size(); i < n; i++) {
|
||||
final CardStack stack = allLands.get(i);
|
||||
final CardPanel firstPanel = stack.get(0);
|
||||
if (firstPanel.getCard().getName().equals(panel.getCard().getName())) {
|
||||
if (firstPanel.getCard().getState().getName().equals(state.getName())) {
|
||||
if (!firstPanel.getAttachedPanels().isEmpty() || firstPanel.getCard().isEnchanted()) {
|
||||
// Put this land to the left of lands with the same name
|
||||
// and attachments.
|
||||
@@ -139,7 +148,10 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
outerLoop:
|
||||
//
|
||||
for (final CardPanel panel : this.getCardPanels()) {
|
||||
if (!panel.getCard().isToken()) {
|
||||
final CardView card = panel.getCard();
|
||||
final CardStateView state = card.getState();
|
||||
|
||||
if (!card.isToken()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -149,7 +161,10 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
for (int i = 0, n = allTokens.size(); i < n; i++) {
|
||||
final CardStack stack = allTokens.get(i);
|
||||
final CardPanel firstPanel = stack.get(0);
|
||||
if (firstPanel.getCard().getName().equals(panel.getCard().getName())) {
|
||||
final CardView firstCard = firstPanel.getCard();
|
||||
final CardStateView firstState = firstCard.getState();
|
||||
|
||||
if (firstPanel.getCard().getState().getName().equals(state.getName())) {
|
||||
if (!firstPanel.getAttachedPanels().isEmpty()) {
|
||||
// Put this token to the left of tokens with the same
|
||||
// name and attachments.
|
||||
@@ -157,15 +172,15 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
break;
|
||||
}
|
||||
|
||||
Set<String> keywords = new HashSet<>(panel.getCard().getIntrinsicKeyword());
|
||||
Set<String> firstKeywords = new HashSet<>(firstPanel.getCard().getIntrinsicKeyword());
|
||||
|
||||
final String text = state.getText();
|
||||
final String firstText = firstState.getText();
|
||||
|
||||
if (!panel.getAttachedPanels().isEmpty()
|
||||
|| !panel.getCard().getCounters().equals(firstPanel.getCard().getCounters())
|
||||
|| (panel.getCard().isSick() != firstPanel.getCard().isSick())
|
||||
|| (panel.getCard().getNetAttack() != firstPanel.getCard().getNetAttack())
|
||||
|| (panel.getCard().getNetDefense() != firstPanel.getCard().getNetDefense())
|
||||
|| !(keywords.equals(firstKeywords))
|
||||
|| !card.getCounters().equals(firstPanel.getCard().getCounters())
|
||||
|| (card.isSick() != firstCard.isSick())
|
||||
|| (state.getPower() != firstState.getPower())
|
||||
|| (state.getToughness() != firstState.getToughness())
|
||||
|| !(text.equals(firstText))
|
||||
|| (stack.size() == tokenStackMax)) {
|
||||
// If this token has attachments or the stack is full,
|
||||
// put it to the right.
|
||||
@@ -241,6 +256,15 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public final CardPanel addCard(final CardView card) {
|
||||
final CardPanel placeholder = new CardPanel(card);
|
||||
placeholder.setDisplayEnabled(false);
|
||||
this.getCardPanels().add(placeholder);
|
||||
this.add(placeholder);
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void doLayout() {
|
||||
final Rectangle rect = this.getScrollPane().getVisibleRect();
|
||||
|
||||
@@ -323,7 +347,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
for (int stackIndex = 0, stackCount = row.size(); stackIndex < stackCount; stackIndex++) {
|
||||
final CardStack stack = row.get(stackIndex);
|
||||
// Align others to the right.
|
||||
if (RowType.Other.isGoodFor(stack.get(0).getCard())) {
|
||||
if (RowType.Other.isGoodFor(stack.get(0).getCard().getState())) {
|
||||
x = (this.playAreaWidth - PlayArea.GUTTER_X) + this.extraCardSpacingX;
|
||||
for (int i = stackIndex, n = row.size(); i < n; i++) {
|
||||
CardStack r = row.get(i);
|
||||
@@ -570,20 +594,19 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
recalculateCardPanels(model);
|
||||
}
|
||||
|
||||
private void recalculateCardPanels(final List<Card> model) {
|
||||
List<Card> oldCards, toDelete;
|
||||
oldCards = new ArrayList<Card>();
|
||||
private void recalculateCardPanels(final List<CardView> model) {
|
||||
final List<CardView> oldCards = Lists.newArrayList();
|
||||
for (final CardPanel cpa : getCardPanels()) {
|
||||
oldCards.add(cpa.getCard());
|
||||
}
|
||||
toDelete = new ArrayList<Card>(oldCards);
|
||||
List<Card> toReplace = new ArrayList<Card>();
|
||||
|
||||
final List<CardView> toDelete = Lists.newArrayList(oldCards);
|
||||
final List<CardView> toReplace = Lists.newArrayList();
|
||||
|
||||
// delete all cards that differ in timestamp (they have been blinked)
|
||||
for (final Card c : model) {
|
||||
for (final CardView c : model) {
|
||||
for (int i = 0; i < toDelete.size(); i++) {
|
||||
final Card c2 = toDelete.get(i);
|
||||
if (c.equals(c2)) {
|
||||
final CardView c2 = toDelete.get(i);
|
||||
if (c.getId() == c2.getId()) {
|
||||
if (c.getTimestamp() == c2.getTimestamp()) {
|
||||
toDelete.remove(i);
|
||||
} else {
|
||||
@@ -595,17 +618,17 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
if (toDelete.size() == getCardPanels().size()) {
|
||||
clear();
|
||||
} else {
|
||||
for (final Card card : toDelete) {
|
||||
removeCardPanel(getCardPanel(card.getUniqueNumber()));
|
||||
for (final CardView card : toDelete) {
|
||||
removeCardPanel(getCardPanel(card.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
List<Card> toAdd = new ArrayList<Card>(model);
|
||||
List<CardView> toAdd = new ArrayList<CardView>(model);
|
||||
toAdd.removeAll(oldCards);
|
||||
toAdd.addAll(toReplace);
|
||||
|
||||
List<CardPanel> newPanels = new ArrayList<CardPanel>();
|
||||
for (final Card card : toAdd) {
|
||||
for (final CardView card : toAdd) {
|
||||
if (card.getCardForUi() == card) { //only include cards that are meant for display
|
||||
final CardPanel placeholder = new CardPanel(card);
|
||||
placeholder.setDisplayEnabled(false);
|
||||
@@ -624,15 +647,15 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
}
|
||||
}
|
||||
|
||||
for (final Card card : model) {
|
||||
for (final CardView card : model) {
|
||||
updateCard(card, true);
|
||||
}
|
||||
invalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
public void updateCard(final Card card, boolean fromRefresh) {
|
||||
final CardPanel toPanel = getCardPanel(card.getUniqueNumber());
|
||||
public void updateCard(final CardView card, boolean fromRefresh) {
|
||||
final CardPanel toPanel = getCardPanel(card.getId());
|
||||
if (null == toPanel) { return; }
|
||||
|
||||
if (card.isTapped()) {
|
||||
@@ -643,42 +666,37 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
toPanel.setTappedAngle(0);
|
||||
}
|
||||
toPanel.getAttachedPanels().clear();
|
||||
if (card.isEnchanted()) {
|
||||
final ArrayList<Card> enchants = card.getEnchantedBy();
|
||||
for (final Card e : enchants) {
|
||||
final forge.view.arcane.CardPanel cardE = getCardPanel(e.getUniqueNumber());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (card.isEquipped()) {
|
||||
final ArrayList<Card> enchants = card.getEquippedBy();
|
||||
for (final Card e : enchants) {
|
||||
final forge.view.arcane.CardPanel cardE = getCardPanel(e.getUniqueNumber());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
|
||||
final Iterable<CardView> enchants = card.getEnchantedBy();
|
||||
for (final CardView e : enchants) {
|
||||
final CardPanel cardE = getCardPanel(e.getId());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
}
|
||||
|
||||
if (card.isFortified()) {
|
||||
final ArrayList<Card> fortifications = card.getFortifiedBy();
|
||||
for (final Card e : fortifications) {
|
||||
final forge.view.arcane.CardPanel cardE = getCardPanel(e.getUniqueNumber());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
final Iterable<CardView> equips = card.getEquippedBy();
|
||||
for (final CardView e : equips) {
|
||||
final CardPanel cardE = getCardPanel(e.getId());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
}
|
||||
|
||||
if (card.isEnchantingCard()) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getEnchantingCard().getUniqueNumber()));
|
||||
} else if (card.isEquipping()) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getEquipping().get(0).getUniqueNumber()));
|
||||
} else if (card.isFortifying()) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getFortifying().get(0).getUniqueNumber()));
|
||||
final Iterable<CardView> fortifications = card.getFortifiedBy();
|
||||
for (final CardView f : fortifications) {
|
||||
final CardPanel cardE = getCardPanel(f.getId());
|
||||
if (cardE != null) {
|
||||
toPanel.getAttachedPanels().add(cardE);
|
||||
}
|
||||
}
|
||||
|
||||
if (card.getEnchantingCard() != null) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getEnchantingCard().getId()));
|
||||
} else if (card.getEquipping() != null) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getEquipping().getId()));
|
||||
} else if (card.getFortifying() != null) {
|
||||
toPanel.setAttachedToPanel(getCardPanel(card.getFortifying().getId()));
|
||||
} else {
|
||||
toPanel.setAttachedToPanel(null);
|
||||
}
|
||||
@@ -695,12 +713,12 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
CreatureNonToken,
|
||||
Other;
|
||||
|
||||
public boolean isGoodFor(final Card card) {
|
||||
public boolean isGoodFor(final CardStateView stateView) {
|
||||
switch (this) {
|
||||
case Land: return card.isLand();
|
||||
case Creature: return card.isCreature();
|
||||
case CreatureNonToken: return card.isCreature() && !card.isToken();
|
||||
case Other: return !card.isLand() && !card.isCreature();
|
||||
case Land: return stateView.isLand();
|
||||
case Creature: return stateView.isCreature();
|
||||
case CreatureNonToken: return stateView.isCreature() && !stateView.getCard().isToken();
|
||||
case Other: return !stateView.isLand() && !stateView.isCreature();
|
||||
default: throw new RuntimeException("Unhandled type: " + this);
|
||||
}
|
||||
}
|
||||
@@ -724,7 +742,7 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
|
||||
private void addAll(final List<CardPanel> cardPanels, final RowType type) {
|
||||
for (final CardPanel panel : cardPanels) {
|
||||
if (!type.isGoodFor(panel.getCard()) || (panel.getAttachedToPanel() != null)) {
|
||||
if (!type.isGoodFor(panel.getCard().getState()) || (panel.getAttachedToPanel() != null)) {
|
||||
continue;
|
||||
}
|
||||
final CardStack stack = new CardStack();
|
||||
@@ -741,14 +759,16 @@ public class PlayArea extends CardPanelContainer implements CardPanelMouseListen
|
||||
*/
|
||||
private void addAllOthers(final List<CardPanel> cardPanels, final RowType type) {
|
||||
for (final CardPanel panel : cardPanels) {
|
||||
if (!type.isGoodFor(panel.getCard()) || (panel.getAttachedToPanel() != null)) {
|
||||
if (!type.isGoodFor(panel.getCard().getState()) || (panel.getAttachedToPanel() != null)) {
|
||||
continue;
|
||||
}
|
||||
boolean stackable = false;
|
||||
for (CardStack s : this) {
|
||||
Card otherCard = s.get(0).getCard();
|
||||
Card thisCard = panel.getCard();
|
||||
if (otherCard.getName().equals(thisCard.getName()) && s.size() < othersStackMax) {
|
||||
for (final CardStack s : this) {
|
||||
final CardView otherCard = s.get(0).getCard();
|
||||
final CardStateView otherState = otherCard.getState();
|
||||
final CardView thisCard = panel.getCard();
|
||||
final CardStateView thisState = thisCard.getState();
|
||||
if (otherState.getName().equals(thisState.getName()) && s.size() < othersStackMax) {
|
||||
if (panel.getAttachedPanels().isEmpty()
|
||||
&& thisCard.getCounters().equals(otherCard.getCounters())
|
||||
&& (thisCard.isSick() == otherCard.isSick())
|
||||
|
||||
@@ -16,7 +16,7 @@ public class CardDetailPanelTest {
|
||||
@Test(groups = { "UnitTest", "fast" }, enabled = false)
|
||||
public void cardDetailPanelTest1() {
|
||||
try {
|
||||
CardDetailPanel dialog = new CardDetailPanel(null);
|
||||
CardDetailPanel dialog = new CardDetailPanel();
|
||||
// dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||
dialog.setVisible(true);
|
||||
Assert.assertNotNull(dialog);
|
||||
|
||||
@@ -8,8 +8,6 @@ import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
@@ -20,6 +18,8 @@ import forge.item.InventoryItemFromSet;
|
||||
import forge.item.PreconDeck;
|
||||
import forge.item.SealedProduct;
|
||||
import forge.util.Lang;
|
||||
import forge.view.CardView;
|
||||
import forge.view.CardView.CardStateView;
|
||||
|
||||
public class CardDetailUtil {
|
||||
private CardDetailUtil() {
|
||||
@@ -51,12 +51,17 @@ public class CardDetailUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static DetailColors getBorderColor(final CardStateView card, final boolean canShow) {
|
||||
return getBorderColors(card.getColors(), card.isLand(), canShow, false).iterator().next();
|
||||
}
|
||||
@Deprecated
|
||||
public static DetailColors getBorderColor(final Card card, boolean canShow) {
|
||||
return getBorderColors(card.determineColor(), card.isLand(), canShow, false).get(0);
|
||||
}
|
||||
public static DetailColors getBorderColor(final ColorSet cardColors, final boolean isLand, boolean canShow) {
|
||||
return getBorderColors(cardColors, isLand, canShow, false).get(0);
|
||||
}
|
||||
@Deprecated
|
||||
public static List<DetailColors> getBorderColors(final Card card, boolean canShow, boolean supportMultiple) {
|
||||
return getBorderColors(card.determineColor(), card.isLand(), canShow, supportMultiple);
|
||||
}
|
||||
@@ -157,6 +162,7 @@ public class CardDetailUtil {
|
||||
return item.getName();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String formatCardType(final Card card) {
|
||||
final ArrayList<String> list = card.getType();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
@@ -200,6 +206,50 @@ public class CardDetailUtil {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String formatCardType(final CardStateView card) {
|
||||
final List<String> list = card.getType();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
final List<String> superTypes = new ArrayList<String>();
|
||||
final List<String> cardTypes = new ArrayList<String>();
|
||||
final List<String> subTypes = new ArrayList<String>();
|
||||
final boolean allCreatureTypes = list.contains("AllCreatureTypes");
|
||||
|
||||
for (final String t : list) {
|
||||
if (allCreatureTypes && t.equals("AllCreatureTypes")) {
|
||||
continue;
|
||||
}
|
||||
if (CardType.isASuperType(t) && !superTypes.contains(t)) {
|
||||
superTypes.add(t);
|
||||
}
|
||||
if (CardType.isACardType(t) && !cardTypes.contains(t)) {
|
||||
cardTypes.add(t);
|
||||
}
|
||||
if (CardType.isASubType(t) && !subTypes.contains(t) && (!allCreatureTypes || !CardType.isACreatureType(t))) {
|
||||
subTypes.add(t);
|
||||
}
|
||||
}
|
||||
|
||||
for (final String type : superTypes) {
|
||||
sb.append(type).append(" ");
|
||||
}
|
||||
for (final String type : cardTypes) {
|
||||
sb.append(type).append(" ");
|
||||
}
|
||||
if (!subTypes.isEmpty() || allCreatureTypes) {
|
||||
sb.append("- ");
|
||||
}
|
||||
if (allCreatureTypes) {
|
||||
sb.append("All creature types ");
|
||||
}
|
||||
for (final String type : subTypes) {
|
||||
sb.append(type).append(" ");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String formatPowerToughness(final Card card) {
|
||||
StringBuilder ptText = new StringBuilder();
|
||||
if (card.isCreature()) {
|
||||
@@ -219,11 +269,37 @@ public class CardDetailUtil {
|
||||
}
|
||||
return ptText.toString();
|
||||
}
|
||||
|
||||
|
||||
public static String formatPowerToughness(final CardStateView card) {
|
||||
StringBuilder ptText = new StringBuilder();
|
||||
if (card.isCreature()) {
|
||||
ptText.append(card.getPower()).append(" / ").append(card.getToughness());
|
||||
}
|
||||
|
||||
if (card.isPlaneswalker()) {
|
||||
if (ptText.length() > 0) {
|
||||
ptText.insert(0, "P/T: ");
|
||||
ptText.append(" - ").append("Loy: ");
|
||||
}
|
||||
else {
|
||||
ptText.append("Loyalty: ");
|
||||
}
|
||||
|
||||
ptText.append(card.getLoyalty());
|
||||
}
|
||||
return ptText.toString();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String formatCardId(final Card card) {
|
||||
return card.getUniqueNumber() > 0 ? "[" + card.getUniqueNumber() + "]" : "";
|
||||
}
|
||||
public static String formatCardId(final CardStateView card) {
|
||||
final int id = card.getCard().getId();
|
||||
return id > 0 ? "[" + id + "]" : "";
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String composeCardText(final Card card, final boolean canShow) {
|
||||
final StringBuilder area = new StringBuilder();
|
||||
|
||||
@@ -438,21 +514,7 @@ public class CardDetailUtil {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanting ");
|
||||
|
||||
if (entity instanceof Card) {
|
||||
final Card c = (Card) entity;
|
||||
if (!GuiBase.getInterface().mayShowCard(c)) {
|
||||
area.append("Morph (");
|
||||
area.append(card.getUniqueNumber());
|
||||
area.append(")");
|
||||
} else {
|
||||
area.append(entity);
|
||||
}
|
||||
} else {
|
||||
area.append(entity);
|
||||
}
|
||||
area.append("*");
|
||||
area.append("*Enchanting ").append(entity).append("*");
|
||||
}
|
||||
|
||||
// enchanted by
|
||||
@@ -538,8 +600,8 @@ public class CardDetailUtil {
|
||||
area.append("Must block " + mustBlockThese);
|
||||
}
|
||||
|
||||
//show current storm count for storm cards
|
||||
if (card.getKeyword().contains("Storm")) {
|
||||
/*show current storm count for storm cards
|
||||
if (card.getKeyword().contains("Storm"))
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (game != null) {
|
||||
if (area.length() != 0) {
|
||||
@@ -547,51 +609,325 @@ public class CardDetailUtil {
|
||||
}
|
||||
area.append("Current Storm Count: " + game.getStack().getCardsCastThisTurn().size());
|
||||
}
|
||||
}
|
||||
}*/
|
||||
return area.toString();
|
||||
}
|
||||
|
||||
public static String composeCardText(final CardStateView state, final boolean canShow) {
|
||||
final CardView card = state.getCard();
|
||||
final StringBuilder area = new StringBuilder();
|
||||
|
||||
// Token
|
||||
if (card.isToken()) {
|
||||
area.append("Token");
|
||||
}
|
||||
|
||||
if (canShow) {
|
||||
// card text
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
String text = state.getText();
|
||||
// LEVEL [0-9]+-[0-9]+
|
||||
// LEVEL [0-9]+\+
|
||||
|
||||
String regex = "LEVEL [0-9]+-[0-9]+ ";
|
||||
text = text.replaceAll(regex, "$0\r\n");
|
||||
|
||||
regex = "LEVEL [0-9]+\\+ ";
|
||||
text = text.replaceAll(regex, "\r\n$0\r\n");
|
||||
|
||||
// displays keywords that have dots in them a little better:
|
||||
regex = "\\., ";
|
||||
text = text.replaceAll(regex, ".\r\n");
|
||||
|
||||
area.append(text);
|
||||
}
|
||||
|
||||
if (card.isPhasedOut()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Phased Out");
|
||||
}
|
||||
|
||||
// text changes
|
||||
final Map<String, String> changedColorWords = state.getChangedColorWords(),
|
||||
changedTypes = state.getChangedTypes();
|
||||
if (!(changedColorWords.isEmpty() && changedTypes.isEmpty())) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
}
|
||||
for (final Entry<String, String> e : Sets.union(changedColorWords.entrySet(), changedTypes.entrySet())) {
|
||||
// ignore lower case and plural form keys, to avoid duplicity
|
||||
if (Character.isUpperCase(e.getKey().charAt(0)) &&
|
||||
!CardUtil.singularTypes.containsKey(e.getKey())) {
|
||||
area.append("Text changed: all instances of ");
|
||||
if (e.getKey().equals("Any")) {
|
||||
if (changedColorWords.containsKey(e.getKey())) {
|
||||
area.append("color words");
|
||||
} else if (forge.card.CardType.getBasicTypes().contains(e.getValue())) {
|
||||
area.append("basic land types");
|
||||
} else {
|
||||
area.append("creature types");
|
||||
}
|
||||
} else {
|
||||
area.append(e.getKey());
|
||||
}
|
||||
area.append(" are replaced by ");
|
||||
area.append(e.getValue());
|
||||
area.append(".\n");
|
||||
}
|
||||
}
|
||||
|
||||
// counter text
|
||||
for (final Entry<CounterType, Integer> c : card.getCounters().entrySet()) {
|
||||
if (c.getValue().intValue() != 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append(c.getKey().getName() + " counters: ");
|
||||
area.append(c.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (state.isCreature()) {
|
||||
final int damage = card.getDamage();
|
||||
if (damage > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Damage: " + damage);
|
||||
}
|
||||
}
|
||||
if (state.isCreature() || state.isPlaneswalker()) {
|
||||
final int assigned = card.getAssignedDamage();
|
||||
if (assigned > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Assigned Damage: " + assigned);
|
||||
}
|
||||
}
|
||||
|
||||
// Regeneration Shields
|
||||
final int regenShields = card.getRegenerationShields();
|
||||
if (regenShields > 0) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Regeneration Shields: ").append(regenShields);
|
||||
}
|
||||
|
||||
// Damage Prevention
|
||||
final int preventNextDamage = card.getPreventNextDamage();
|
||||
if (preventNextDamage > 0) {
|
||||
area.append("\n");
|
||||
area.append("Prevent the next ").append(preventNextDamage).append(" damage that would be dealt to ");
|
||||
area.append(state.getName()).append(" this turn.");
|
||||
}
|
||||
|
||||
// top revealed
|
||||
/*
|
||||
if ((card.hasKeyword("Play with the top card of your library revealed.") || card
|
||||
.hasKeyword("Players play with the top card of their libraries revealed."))
|
||||
&& card.getController() != null
|
||||
&& (card.isInZone(ZoneType.Battlefield) || (card.isInZone(ZoneType.Command) && !card.isCommander()))
|
||||
&& !card.getController().getZone(ZoneType.Library).isEmpty()) {
|
||||
area.append("\r\nTop card of your library: ");
|
||||
area.append(card.getController().getCardsIn(ZoneType.Library, 1));
|
||||
if (card.hasKeyword("Players play with the top card of their libraries revealed.")) {
|
||||
for (final Player p : card.getController().getAllOtherPlayers()) {
|
||||
if (p.getZone(ZoneType.Library).isEmpty()) {
|
||||
area.append(p.getName());
|
||||
area.append("'s library is empty.");
|
||||
} else {
|
||||
area.append("\r\nTop card of ");
|
||||
area.append(p.getName());
|
||||
area.append("'s library: ");
|
||||
area.append(p.getCardsIn(ZoneType.Library, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// chosen type
|
||||
if (!card.getChosenType().equals("")) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(chosen type: ");
|
||||
area.append(card.getChosenType());
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
// chosen color
|
||||
if (!card.getChosenColors().isEmpty()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(chosen colors: ");
|
||||
area.append(Lang.joinHomogenous(card.getChosenColors()));
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
// chosen player
|
||||
if (card.getChosenPlayer() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(chosen player: " + card.getChosenPlayer() + ")");
|
||||
}
|
||||
|
||||
// named card
|
||||
if (!card.getNamedCard().equals("")) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("(named card: ");
|
||||
area.append(card.getNamedCard());
|
||||
area.append(")");
|
||||
}
|
||||
|
||||
// equipping
|
||||
if (card.getEquipping() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("=Equipping ");
|
||||
area.append(card.getEquipping());
|
||||
area.append("=");
|
||||
}
|
||||
|
||||
// equipped by
|
||||
if (card.getEquippedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("=Equipped by ");
|
||||
for (final Iterator<CardView> it = card.getEquippedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
}
|
||||
}
|
||||
area.append("=");
|
||||
}
|
||||
|
||||
// enchanting
|
||||
if (card.getEnchantingCard() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanting ").append(card.getEnchantingCard()).append("*");
|
||||
}
|
||||
if (card.getEnchantingPlayer() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanting ").append(card.getEnchantingPlayer()).append("*");
|
||||
}
|
||||
|
||||
// enchanted by
|
||||
if (card.getEnchantedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("*Enchanted by ");
|
||||
for (final Iterator<CardView> it = card.getEnchantedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
}
|
||||
}
|
||||
area.append("*");
|
||||
}
|
||||
|
||||
// controlling
|
||||
if (card.getGainControlTargets().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("+Controlling: ");
|
||||
for (final Iterator<CardView> it = card.getGainControlTargets().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
}
|
||||
}
|
||||
area.append("+");
|
||||
}
|
||||
|
||||
// cloned via
|
||||
if (card.getCloneOrigin() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("^Cloned via: ");
|
||||
area.append(card.getCloneOrigin().getState().getName());
|
||||
area.append("^");
|
||||
}
|
||||
|
||||
// Imprint
|
||||
if (card.getImprinted().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Imprinting: ");
|
||||
for (final Iterator<CardView> it = card.getImprinted().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Haunt
|
||||
if (card.getHauntedBy().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Haunted by: ");
|
||||
for (final Iterator<CardView> it = card.getHauntedBy().iterator(); it.hasNext();) {
|
||||
area.append(it.next());
|
||||
if (it.hasNext()) {
|
||||
area.append(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (card.getHaunting() != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
area.append("Haunting " + card.getHaunting());
|
||||
}
|
||||
|
||||
// must block
|
||||
if (card.getMustBlock().iterator().hasNext()) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n");
|
||||
}
|
||||
final String mustBlockThese = Lang.joinHomogenous(card.getMustBlock());
|
||||
area.append("Must block " + mustBlockThese);
|
||||
}
|
||||
|
||||
/*show current storm count for storm cards
|
||||
if (state.hasStorm()) {
|
||||
Game game = GuiBase.getInterface().getGame();
|
||||
if (game != null) {
|
||||
if (area.length() != 0) {
|
||||
area.append("\n\n");
|
||||
}
|
||||
area.append("Current Storm Count: " + game.getStack().getCardsCastThisTurn().size());
|
||||
}
|
||||
}*/
|
||||
return area.toString();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isCardFlippable(Card card) {
|
||||
return card.isDoubleFaced() || card.isFlipCard() || card.isFaceDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Card characteristic state machine.
|
||||
* <p>
|
||||
* Given a card and a state in terms of {@code CardCharacteristicName} this
|
||||
* will determine whether there is a valid alternate {@code CardCharacteristicName}
|
||||
* state for that card.
|
||||
*
|
||||
* @param card the {@code Card}
|
||||
* @param currentState not necessarily {@code card.getCurState()}
|
||||
* @return the alternate {@code CardCharacteristicName} state or default if not applicable
|
||||
*/
|
||||
public static CardCharacteristicName getAlternateState(final Card card, CardCharacteristicName currentState) {
|
||||
// Default. Most cards will only ever have an "Original" state represented by a single image.
|
||||
CardCharacteristicName alternateState = CardCharacteristicName.Original;
|
||||
|
||||
if (card.isDoubleFaced()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.Transformed;
|
||||
}
|
||||
}
|
||||
else if (card.isFlipCard()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.Flipped;
|
||||
}
|
||||
}
|
||||
else if (card.isFaceDown()) {
|
||||
if (currentState == CardCharacteristicName.Original) {
|
||||
alternateState = CardCharacteristicName.FaceDown;
|
||||
}
|
||||
else if (GuiBase.getInterface().mayShowCard(card)) {
|
||||
alternateState = CardCharacteristicName.Original;
|
||||
}
|
||||
else {
|
||||
alternateState = currentState;
|
||||
}
|
||||
}
|
||||
|
||||
return alternateState;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package forge.control;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import forge.FThreads;
|
||||
@@ -18,6 +19,7 @@ import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.Lang;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.maps.MapOfLists;
|
||||
import forge.view.CardView;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
@@ -76,12 +78,11 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
|
||||
if (turnUpdPlanned.getAndSet(true)) { return null; }
|
||||
|
||||
final Game game = GuiBase.getInterface().getGame(); // to make sure control gets a correct game instance
|
||||
FThreads.invokeInEdtNowOrLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
turnUpdPlanned.set(false);
|
||||
GuiBase.getInterface().updateTurn(event, game);
|
||||
GuiBase.getInterface().updateTurn(event);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
@@ -225,7 +226,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private final Set<Card> cardsToUpdate = new HashSet<Card>();
|
||||
private final Set<CardView> cardsToUpdate = Sets.newHashSet();
|
||||
private final Runnable updCards = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -288,7 +289,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private Void updateSingleCard(Card c) {
|
||||
private Void updateSingleCard(final CardView c) {
|
||||
boolean needUpdate = false;
|
||||
synchronized (cardsToUpdate) {
|
||||
needUpdate = cardsToUpdate.isEmpty();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package forge.events;
|
||||
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this type.
|
||||
@@ -9,16 +9,16 @@ import forge.game.card.Card;
|
||||
*/
|
||||
public class UiEventAttackerDeclared extends UiEvent {
|
||||
|
||||
public final Card attacker;
|
||||
public final GameEntity defender;
|
||||
public final CardView attacker;
|
||||
public final GameEntityView defender;
|
||||
|
||||
public UiEventAttackerDeclared(Card card, GameEntity currentDefender) {
|
||||
public UiEventAttackerDeclared(final CardView card, final GameEntityView currentDefender) {
|
||||
attacker = card;
|
||||
defender = currentDefender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IUiEventVisitor<T> visitor) {
|
||||
public <T> T visit(final IUiEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ public class UiEventAttackerDeclared extends UiEvent {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return attacker.toString() + ( defender == null ? " removed from combat" : " declared to attack " + defender.getName() );
|
||||
return attacker.toString() + ( defender == null ? " removed from combat" : " declared to attack " + defender );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package forge.events;
|
||||
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
|
||||
public class UiEventBlockerAssigned extends UiEvent {
|
||||
|
||||
public final Card blocker;
|
||||
public final Card attackerBeingBlocked;
|
||||
public final CardView blocker;
|
||||
public final CardView attackerBeingBlocked;
|
||||
|
||||
public UiEventBlockerAssigned(Card card, Card currentAttacker) {
|
||||
public UiEventBlockerAssigned(final CardView card, final CardView currentAttacker) {
|
||||
blocker = card;
|
||||
attackerBeingBlocked = currentAttacker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T visit(IUiEventVisitor<T> visitor) {
|
||||
public <T> T visit(final IUiEventVisitor<T> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,22 +8,21 @@ import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.deck.Deck;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IGuiBase;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.model.FModel;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public abstract class GauntletWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final IGameView lastGame;
|
||||
private final IWinLoseView<? extends IButton> view;
|
||||
|
||||
public GauntletWinLoseController(IWinLoseView<? extends IButton> view0, Game lastGame0) {
|
||||
public GauntletWinLoseController(IWinLoseView<? extends IButton> view0, final IGameView game0) {
|
||||
view = view0;
|
||||
lastGame = lastGame0;
|
||||
lastGame = game0;
|
||||
}
|
||||
|
||||
public void showOutcome() {
|
||||
@@ -43,8 +42,6 @@ public abstract class GauntletWinLoseController {
|
||||
// Generic event record.
|
||||
lstEventRecords.set(gd.getCompleted(), "Ongoing");
|
||||
|
||||
final Match match = lastGame.getMatch();
|
||||
|
||||
// Match won't be saved until it is over. This opens up a cheat
|
||||
// or failsafe mechanism (depending on your perspective) in which
|
||||
// the player can restart Forge to replay a match.
|
||||
@@ -53,14 +50,14 @@ public abstract class GauntletWinLoseController {
|
||||
LobbyPlayer questPlayer = GuiBase.getInterface().getQuestPlayer();
|
||||
|
||||
// In all cases, update stats.
|
||||
lstEventRecords.set(gd.getCompleted(), match.getGamesWonBy(questPlayer) + " - "
|
||||
+ (match.getPlayedGames().size() - match.getGamesWonBy(questPlayer)));
|
||||
lstEventRecords.set(gd.getCompleted(), lastGame.getGamesWonBy(questPlayer) + " - "
|
||||
+ (lastGame.getNumPlayedGamesInMatch() - lastGame.getGamesWonBy(questPlayer)));
|
||||
|
||||
if (match.isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
gd.setCompleted(gd.getCompleted() + 1);
|
||||
|
||||
// Win match case
|
||||
if (match.isWonBy(questPlayer)) {
|
||||
if (lastGame.isMatchWonBy(questPlayer)) {
|
||||
// Gauntlet complete: Remove save file
|
||||
if (gd.getCompleted() == lstDecks.size()) {
|
||||
icon = FSkinProp.ICO_QUEST_COIN;
|
||||
@@ -112,7 +109,7 @@ public abstract class GauntletWinLoseController {
|
||||
}
|
||||
|
||||
public final boolean actionOnContinue() {
|
||||
if (lastGame.getMatch().isMatchOver()) {
|
||||
if (lastGame.isMatchOver()) {
|
||||
// To change the AI deck, we have to create a new match.
|
||||
GauntletData gd = FModel.getGauntletData();
|
||||
Deck aiDeck = gd.getDecks().get(gd.getCompleted());
|
||||
|
||||
@@ -15,16 +15,11 @@ import forge.assets.FSkinProp;
|
||||
import forge.assets.ISkinImage;
|
||||
import forge.deck.CardPool;
|
||||
import forge.events.UiEvent;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameType;
|
||||
import forge.game.Match;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.combat.Combat;
|
||||
import forge.game.event.GameEventTurnBegan;
|
||||
import forge.game.phase.PhaseType;
|
||||
import forge.game.player.IHasIcon;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
@@ -33,7 +28,10 @@ import forge.match.input.InputQueue;
|
||||
import forge.sound.IAudioClip;
|
||||
import forge.sound.IAudioMusic;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public interface IGuiBase {
|
||||
boolean isRunningOnDesktop();
|
||||
@@ -42,55 +40,55 @@ public interface IGuiBase {
|
||||
void invokeInEdtAndWait(final Runnable proc);
|
||||
boolean isGuiThread();
|
||||
String getAssetsDir();
|
||||
boolean mayShowCard(Card card);
|
||||
boolean mayShowCard(CardView card);
|
||||
ISkinImage getSkinIcon(FSkinProp skinProp);
|
||||
ISkinImage getUnskinnedIcon(String path);
|
||||
void showBugReportDialog(String title, String text, boolean showExitAppBtn);
|
||||
int showOptionDialog(String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
int showCardOptionDialog(Card card, String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption);
|
||||
<T> T showInputDialog(String message, String title, FSkinProp icon, T initialInput, T[] inputOptions);
|
||||
<T> List<T> getChoices(final String message, final int min, final int max, final Collection<T> choices, final T selected, final Function<T, String> display);
|
||||
<T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode);
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode);
|
||||
List<PaperCard> sideboard(CardPool sideboard, CardPool main);
|
||||
String showFileDialog(String title, String defaultDir);
|
||||
File getSaveFile(File defaultFile);
|
||||
void showCardList(final String title, final String message, final List<PaperCard> list);
|
||||
boolean showBoxedProduct(final String title, final String message, final List<PaperCard> list);
|
||||
void fireEvent(UiEvent e);
|
||||
void setCard(Card card);
|
||||
void setCard(CardView card);
|
||||
void showCombat(Combat combat);
|
||||
void setUsedToPay(Card card, boolean b);
|
||||
void setHighlighted(Player player, boolean b);
|
||||
void setUsedToPay(CardView card, boolean b);
|
||||
void setHighlighted(PlayerView player, boolean b);
|
||||
void showPromptMessage(String message);
|
||||
boolean stopAtPhase(Player playerTurn, PhaseType phase);
|
||||
boolean stopAtPhase(PlayerView playerTurn, PhaseType phase);
|
||||
InputQueue getInputQueue();
|
||||
Game getGame();
|
||||
IGameView getGame();
|
||||
IButton getBtnOK();
|
||||
IButton getBtnCancel();
|
||||
void focusButton(IButton button);
|
||||
void flashIncorrectAction();
|
||||
void updatePhase();
|
||||
void updateTurn(GameEventTurnBegan event, Game game);
|
||||
void updateTurn(PlayerView player);
|
||||
void updatePlayerControl();
|
||||
void enableOverlay();
|
||||
void disableOverlay();
|
||||
void finishGame();
|
||||
Object showManaPool(Player player);
|
||||
void hideManaPool(Player player, Object zoneToRestore);
|
||||
boolean openZones(List<ZoneType> zones, Map<Player, Object> players);
|
||||
void restoreOldZones(Map<Player, Object> playersToRestoreZonesFor);
|
||||
Object showManaPool(PlayerView player);
|
||||
void hideManaPool(PlayerView player, Object zoneToRestore);
|
||||
boolean openZones(List<ZoneType> zones, Map<PlayerView, Object> players);
|
||||
void restoreOldZones(Map<PlayerView, Object> playersToRestoreZonesFor);
|
||||
void updateStack();
|
||||
void updateZones(List<Pair<Player, ZoneType>> zonesToUpdate);
|
||||
void updateCards(Set<Card> cardsToUpdate);
|
||||
void refreshCardDetails(Collection<Card> cards);
|
||||
void updateManaPool(List<Player> manaPoolUpdate);
|
||||
void updateLives(List<Player> livesUpdate);
|
||||
void updateZones(List<Pair<PlayerView, ZoneType>> zonesToUpdate);
|
||||
void updateCards(Set<CardView> cardsToUpdate);
|
||||
void refreshCardDetails(Collection<CardView> cards);
|
||||
void updateManaPool(List<PlayerView> manaPoolUpdate);
|
||||
void updateLives(List<PlayerView> livesUpdate);
|
||||
void endCurrentGame();
|
||||
void startMatch(GameType gauntletType, List<RegisteredPlayer> starter);
|
||||
void setPanelSelection(Card hostCard);
|
||||
Map<Card, Integer> getDamageToAssign(Card attacker, List<Card> blockers,
|
||||
int damageDealt, GameEntity defender, boolean overrideOrder);
|
||||
void setPanelSelection(CardView hostCard);
|
||||
Map<CardView, Integer> getDamageToAssign(CardView attacker, List<CardView> blockers,
|
||||
int damageDealt, GameEntityView defender, boolean overrideOrder);
|
||||
SpellAbility getAbilityToPlay(List<SpellAbility> abilities, ITriggerEvent triggerEvent);
|
||||
void hear(LobbyPlayer player, String message);
|
||||
int getAvatarCount();
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
package forge.limited;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.interfaces.IButton;
|
||||
import forge.interfaces.IWinLoseView;
|
||||
import forge.model.FModel;
|
||||
import forge.view.IGameView;
|
||||
|
||||
public abstract class LimitedWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final IGameView lastGame;
|
||||
private final boolean wonMatch;
|
||||
private final IWinLoseView<? extends IButton> view;
|
||||
private GauntletMini gauntlet;
|
||||
private boolean nextRound = false;
|
||||
|
||||
public LimitedWinLoseController(IWinLoseView<? extends IButton> view0, Game lastGame0) {
|
||||
public LimitedWinLoseController(IWinLoseView<? extends IButton> view0, final IGameView game0) {
|
||||
view = view0;
|
||||
lastGame = lastGame0;
|
||||
lastGame = game0;
|
||||
gauntlet = FModel.getGauntletMini();
|
||||
wonMatch = lastGame.getMatch().isWonBy(GuiBase.getInterface().getGuiPlayer());
|
||||
wonMatch = lastGame.isMatchWonBy(GuiBase.getInterface().getGuiPlayer());
|
||||
}
|
||||
|
||||
public void showOutcome() {
|
||||
@@ -29,10 +29,9 @@ public abstract class LimitedWinLoseController {
|
||||
resetView();
|
||||
nextRound = false;
|
||||
|
||||
if (lastGame.getOutcome().isWinner(GuiBase.getInterface().getGuiPlayer())) {
|
||||
if (lastGame.isWinner(GuiBase.getInterface().getGuiPlayer())) {
|
||||
gauntlet.addWin();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
gauntlet.addLoss();
|
||||
}
|
||||
|
||||
@@ -41,7 +40,7 @@ public abstract class LimitedWinLoseController {
|
||||
showOutcome(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!lastGame.getMatch().isMatchOver()) {
|
||||
if (!lastGame.isMatchOver()) {
|
||||
showTournamentInfo("Tournament Info");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,12 +5,11 @@ import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.ITriggerEvent;
|
||||
|
||||
|
||||
public interface Input {
|
||||
void showMessageInitial();
|
||||
|
||||
boolean selectCard(Card c, ITriggerEvent triggerEvent);
|
||||
|
||||
boolean selectCard(Card card, ITriggerEvent triggerEvent);
|
||||
|
||||
void selectAbility(SpellAbility ab);
|
||||
|
||||
void selectPlayer(Player player, ITriggerEvent triggerEvent);
|
||||
|
||||
@@ -248,9 +248,9 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
return false;
|
||||
}
|
||||
|
||||
private final void setCurrentDefender(GameEntity def) {
|
||||
private final void setCurrentDefender(final GameEntity def) {
|
||||
currentDefender = def;
|
||||
for (GameEntity ge : defenders) {
|
||||
for (final GameEntity ge : defenders) {
|
||||
if (ge instanceof Card) {
|
||||
GuiBase.getInterface().setUsedToPay((Card)ge, ge == def);
|
||||
}
|
||||
@@ -262,16 +262,16 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
updateMessage();
|
||||
}
|
||||
|
||||
private final void activateBand(AttackingBand band) {
|
||||
private final void activateBand(final AttackingBand band) {
|
||||
if (activeBand != null) {
|
||||
for (Card card : activeBand.getAttackers()) {
|
||||
for (final Card card : activeBand.getAttackers()) {
|
||||
GuiBase.getInterface().setUsedToPay(card, false);
|
||||
}
|
||||
}
|
||||
activeBand = band;
|
||||
|
||||
if (activeBand != null) {
|
||||
for(Card card : activeBand.getAttackers()) {
|
||||
for (final Card card : activeBand.getAttackers()) {
|
||||
GuiBase.getInterface().setUsedToPay(card, true);
|
||||
}
|
||||
}
|
||||
@@ -279,8 +279,8 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
|
||||
//only enable banding message and actions if a creature that can attack has banding
|
||||
private boolean isBandingPossible() {
|
||||
List<Card> possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield);
|
||||
for (Card c : Iterables.filter(possibleAttackers, CardPredicates.hasKeyword("Banding"))) {
|
||||
final List<Card> possibleAttackers = playerAttacks.getCardsIn(ZoneType.Battlefield);
|
||||
for (final Card c : Iterables.filter(possibleAttackers, CardPredicates.hasKeyword("Banding"))) {
|
||||
if (c.isCreature() && CombatUtil.canAttack(c, currentDefender, combat)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectAbility(SpellAbility ab) { }
|
||||
public void selectAbility(final SpellAbility ab) { }
|
||||
|
||||
@Override
|
||||
public final void selectButtonCancel() {
|
||||
@@ -131,12 +131,12 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
protected boolean onCardSelected(final Card c, final ITriggerEvent triggerEvent) {
|
||||
return false;
|
||||
}
|
||||
protected void onPlayerSelected(final Player p, final ITriggerEvent triggerEvent) {}
|
||||
protected void onPlayerSelected(final Player player, final ITriggerEvent triggerEvent) {}
|
||||
protected void onCancel() {}
|
||||
protected void onOk() {}
|
||||
|
||||
// to remove need for CMatchUI dependence
|
||||
protected final void showMessage(String message) {
|
||||
protected final void showMessage(final String message) {
|
||||
GuiBase.getInterface().showPromptMessage(message);
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
|
||||
GuiBase.getInterface().flashIncorrectAction();
|
||||
}
|
||||
|
||||
protected String getTurnPhasePriorityMessage(Game game) {
|
||||
protected String getTurnPhasePriorityMessage(final Game game) {
|
||||
final PhaseHandler ph = game.getPhaseHandler();
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
|
||||
@@ -17,19 +17,19 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.Game;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.GuiBase;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.ITriggerEvent;
|
||||
import forge.util.gui.SOptionPane;
|
||||
import forge.view.CardView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* GuiInput class.
|
||||
@@ -42,11 +42,11 @@ public class InputProxy implements Observer {
|
||||
|
||||
/** The input. */
|
||||
private AtomicReference<Input> input = new AtomicReference<Input>();
|
||||
private Game game = null;
|
||||
private IGameView game = null;
|
||||
|
||||
// private static final boolean DEBUG_INPUT = true; // false;
|
||||
|
||||
public void setGame(Game game0) {
|
||||
public void setGame(IGameView game0) {
|
||||
game = game0;
|
||||
GuiBase.getInterface().getInputQueue().addObserver(this);
|
||||
}
|
||||
@@ -120,8 +120,8 @@ public class InputProxy implements Observer {
|
||||
* @param player
|
||||
* a {@link forge.game.player.Player} object.
|
||||
*/
|
||||
public final void selectPlayer(final Player player, final ITriggerEvent triggerEvent) {
|
||||
Input inp = getInput();
|
||||
public final void selectPlayer(final PlayerView player, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectPlayer(player, triggerEvent);
|
||||
}
|
||||
@@ -132,20 +132,20 @@ public class InputProxy implements Observer {
|
||||
* selectCard.
|
||||
* </p>
|
||||
*
|
||||
* @param card
|
||||
* @param cardView
|
||||
* a {@link forge.game.card.Card} object.
|
||||
* @param triggerEvent
|
||||
*/
|
||||
public final boolean selectCard(final Card card, final ITriggerEvent triggerEvent) {
|
||||
Input inp = getInput();
|
||||
public final boolean selectCard(final CardView cardView, final ITriggerEvent triggerEvent) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
return inp.selectCard(card, triggerEvent);
|
||||
return inp.selectCard(cardView, triggerEvent);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void selectAbility(SpellAbility ab) {
|
||||
Input inp = getInput();
|
||||
public final void selectAbility(final SpellAbility ab) {
|
||||
final Input inp = getInput();
|
||||
if (inp != null) {
|
||||
inp.selectAbility(ab);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
package forge.match.input;
|
||||
|
||||
import forge.game.Game;
|
||||
import forge.view.IGameView;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.concurrent.BlockingDeque;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
@@ -63,7 +64,7 @@ public class InputQueue extends Observable {
|
||||
*
|
||||
* @return a {@link forge.gui.input.InputBase} object.
|
||||
*/
|
||||
public final Input getActualInput(Game game) {
|
||||
public final Input getActualInput(IGameView game) {
|
||||
Input topMost = inputStack.peek(); // incoming input to Control
|
||||
if (topMost != null && !game.isGameOver()) {
|
||||
return topMost;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package forge.player;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.game.Game;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -69,13 +65,4 @@ public final class GamePlayerUtil {
|
||||
return newName;
|
||||
}
|
||||
|
||||
public static RegisteredPlayer getGuiRegisteredPlayer(Game game) {
|
||||
LobbyPlayer guiPlayer = GuiBase.getInterface().getGuiPlayer();
|
||||
for (RegisteredPlayer player : game.getMatch().getPlayers()) {
|
||||
if (player.getPlayer() == guiPlayer) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
package forge.player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import forge.LobbyPlayer;
|
||||
import forge.GuiBase;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
@@ -20,11 +36,14 @@ import forge.deck.DeckSection;
|
||||
import forge.events.UiEventAttackerDeclared;
|
||||
import forge.game.Game;
|
||||
import forge.game.GameEntity;
|
||||
import forge.game.GameLog;
|
||||
import forge.game.GameLogEntryType;
|
||||
import forge.game.GameObject;
|
||||
import forge.game.GameOutcome;
|
||||
import forge.game.GameType;
|
||||
import forge.game.ability.effects.CharmEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardFactoryUtil;
|
||||
import forge.game.card.CardShields;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.combat.Combat;
|
||||
@@ -37,6 +56,7 @@ import forge.game.phase.PhaseType;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.player.PlayerActionConfirmMode;
|
||||
import forge.game.player.PlayerController;
|
||||
import forge.game.player.RegisteredPlayer;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.spellability.AbilitySub;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
@@ -48,7 +68,17 @@ import forge.game.zone.MagicStack;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.match.input.*;
|
||||
import forge.match.input.ButtonUtil;
|
||||
import forge.match.input.InputAttack;
|
||||
import forge.match.input.InputBase;
|
||||
import forge.match.input.InputBlock;
|
||||
import forge.match.input.InputConfirm;
|
||||
import forge.match.input.InputConfirmMulligan;
|
||||
import forge.match.input.InputPassPriority;
|
||||
import forge.match.input.InputProliferate;
|
||||
import forge.match.input.InputSelectCardsForConvoke;
|
||||
import forge.match.input.InputSelectCardsFromList;
|
||||
import forge.match.input.InputSelectEntitiesFromList;
|
||||
import forge.model.FModel;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
import forge.util.ITriggerEvent;
|
||||
@@ -57,13 +87,12 @@ import forge.util.TextUtil;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.util.gui.SGuiDialog;
|
||||
import forge.util.gui.SOptionPane;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.*;
|
||||
import forge.view.CardView;
|
||||
import forge.view.GameEntityView;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
import forge.view.StackItemView;
|
||||
import forge.view.ViewUtil;
|
||||
|
||||
|
||||
/**
|
||||
@@ -71,13 +100,21 @@ import java.util.*;
|
||||
*
|
||||
* Handles phase skips for now.
|
||||
*/
|
||||
public class PlayerControllerHuman extends PlayerController {
|
||||
public class PlayerControllerHuman extends PlayerController implements IGameView {
|
||||
public PlayerControllerHuman(Game game0, Player p, LobbyPlayer lp) {
|
||||
super(game0, p, lp);
|
||||
// aggressively cache a view for each player
|
||||
for (final Player player : game.getRegisteredPlayers()) {
|
||||
getPlayerView(player);
|
||||
}
|
||||
// aggressively cache a view for each card
|
||||
for (final Card c : game.getCardsInGame()) {
|
||||
getCardView(c);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isUiSetToSkipPhase(final Player turn, final PhaseType phase) {
|
||||
return !GuiBase.getInterface().stopAtPhase(turn, phase);
|
||||
return !GuiBase.getInterface().stopAtPhase(getPlayerView(turn), phase);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -162,27 +199,31 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
* @see forge.game.player.PlayerController#assignCombatDamage()
|
||||
*/
|
||||
@Override
|
||||
public Map<Card, Integer> assignCombatDamage(Card attacker, List<Card> blockers, int damageDealt, GameEntity defender, boolean overrideOrder) {
|
||||
public Map<Card, Integer> assignCombatDamage(final Card attacker,
|
||||
final List<Card> blockers, 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.
|
||||
Map<Card, Integer> map;
|
||||
final Map<Card, Integer> map = Maps.newHashMap();
|
||||
if (defender != null && assignDamageAsIfNotBlocked(attacker)) {
|
||||
map = new HashMap<Card, Integer>();
|
||||
map.put(null, damageDealt);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
final List<CardView> vBlockers = Lists.transform(blockers, FN_GET_CARD_VIEW);
|
||||
if ((attacker.hasKeyword("Trample") && defender != null) || (blockers.size() > 1)) {
|
||||
map = GuiBase.getInterface().getDamageToAssign(attacker, blockers, damageDealt, defender, overrideOrder);
|
||||
}
|
||||
else {
|
||||
map = new HashMap<Card, Integer>();
|
||||
final CardView vAttacker = getCardView(attacker);
|
||||
final GameEntityView vDefender = getGameEntityView(defender);
|
||||
final Map<CardView, Integer> result = GuiBase.getInterface().getDamageToAssign(vAttacker, vBlockers, damageDealt, vDefender, overrideOrder);
|
||||
for (final Entry<CardView, Integer> e : result.entrySet()) {
|
||||
map.put(getCard(e.getKey()), e.getValue());
|
||||
}
|
||||
} else {
|
||||
map.put(blockers.get(0), damageDealt);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private final boolean assignDamageAsIfNotBlocked(Card attacker) {
|
||||
private final boolean assignDamageAsIfNotBlocked(final Card attacker) {
|
||||
return attacker.hasKeyword("CARDNAME assigns its combat damage as though it weren't blocked.")
|
||||
|| (attacker.hasKeyword("You may have CARDNAME assign its combat damage as though it weren't blocked.")
|
||||
&& SGuiDialog.confirm(attacker, "Do you want to assign its combat damage as though it weren't blocked?"));
|
||||
@@ -235,8 +276,9 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
Card singleChosen = chooseSingleEntityForEffect(sourceList, sa, title, isOptional);
|
||||
return singleChosen == null ? Lists.<Card>newArrayList() : Lists.newArrayList(singleChosen);
|
||||
}
|
||||
GuiBase.getInterface().setPanelSelection(sa.getHostCard());
|
||||
|
||||
|
||||
GuiBase.getInterface().setPanelSelection(getCardView(sa.getHostCard()));
|
||||
|
||||
// try to use InputSelectCardsFromList when possible
|
||||
boolean cardsAreInMyHandOrBattlefield = true;
|
||||
for(Card c : sourceList) {
|
||||
@@ -255,7 +297,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
return Lists.newArrayList(sc.getSelected());
|
||||
}
|
||||
|
||||
return SGuiChoose.many(title, "Chosen Cards", min, max, sourceList, sa.getHostCard());
|
||||
return SGuiChoose.many(title, "Chosen Cards", min, max, sourceList, getCardView(sa.getHostCard()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -384,21 +426,27 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlockers(Card attacker, List<Card> blockers) {
|
||||
GuiBase.getInterface().setPanelSelection(attacker);
|
||||
return SGuiChoose.order("Choose Damage Order for " + attacker, "Damaged First", blockers, attacker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderBlocker(final Card attacker, final Card blocker, final List<Card> oldBlockers) {
|
||||
GuiBase.getInterface().setPanelSelection(attacker);
|
||||
return SGuiChoose.insertInList("Choose blocker after which to place " + attacker + " in damage order; cancel to place it first", blocker, oldBlockers);
|
||||
public List<Card> orderBlockers(final Card attacker, final List<Card> blockers) {
|
||||
final CardView vAttacker = getCardView(attacker);
|
||||
GuiBase.getInterface().setPanelSelection(vAttacker);
|
||||
final List<CardView> choices = SGuiChoose.order("Choose Damage Order for " + vAttacker, "Damaged First", getCardViews(blockers), vAttacker);
|
||||
return getCards(choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderAttackers(Card blocker, List<Card> attackers) {
|
||||
GuiBase.getInterface().setPanelSelection(blocker);
|
||||
return SGuiChoose.order("Choose Damage Order for " + blocker, "Damaged First", attackers, blocker);
|
||||
public List<Card> orderBlocker(final Card attacker, final Card blocker, final List<Card> oldBlockers) {
|
||||
final CardView vAttacker = getCardView(attacker);
|
||||
GuiBase.getInterface().setPanelSelection(vAttacker);
|
||||
final List<CardView> choices = SGuiChoose.insertInList("Choose blocker after which to place " + vAttacker + " in damage order; cancel to place it first", getCardView(blocker), getCardViews(oldBlockers));
|
||||
return getCards(choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Card> orderAttackers(final Card blocker, final List<Card> attackers) {
|
||||
final CardView vBlocker = getCardView(blocker);
|
||||
GuiBase.getInterface().setPanelSelection(vBlocker);
|
||||
final List<CardView> choices = SGuiChoose.order("Choose Damage Order for " + vBlocker, "Damaged First", getCardViews(attackers), vBlocker);
|
||||
return getCards(choices);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@@ -630,7 +678,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
//ensure they're declared and then delay slightly so user can see as much
|
||||
for (Pair<Card, GameEntity> attacker : mandatoryAttackers) {
|
||||
combat.addAttacker(attacker.getLeft(), attacker.getRight());
|
||||
GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(attacker.getLeft(), attacker.getRight()));
|
||||
GuiBase.getInterface().fireEvent(new UiEventAttackerDeclared(getCardView(attacker.getLeft()), getGameEntityView(attacker.getRight())));
|
||||
}
|
||||
try {
|
||||
Thread.sleep(FControlGamePlayback.combatDelay);
|
||||
@@ -1168,4 +1216,342 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
public boolean isGuiPlayer() {
|
||||
return lobbyPlayer == GuiBase.getInterface().getGuiPlayer();
|
||||
}
|
||||
|
||||
/*
|
||||
* What follows are the View methods.
|
||||
*/
|
||||
|
||||
/** Cache of players. */
|
||||
private final BiMap<Player, PlayerView> players
|
||||
= HashBiMap.create();
|
||||
/** Cache of cards. */
|
||||
private final BiMap<Card, CardView> cards
|
||||
= HashBiMap.create();
|
||||
/** Cache of stack items. */
|
||||
private final BiMap<SpellAbilityStackInstance, StackItemView> stackItems
|
||||
= HashBiMap.create();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isCommander()
|
||||
*/
|
||||
@Override
|
||||
public boolean isCommander() {
|
||||
return game.getRules().hasAppliedVariant(GameType.Commander);
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getGameType()
|
||||
*/
|
||||
@Override
|
||||
public GameType getGameType() {
|
||||
return this.game.getMatch().getRules().getGameType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWinner(final LobbyPlayer p) {
|
||||
return game.getOutcome() == null ? null : game.getOutcome().isWinner(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LobbyPlayer getWinningPlayer() {
|
||||
return game.getOutcome() == null ? null : game.getOutcome().getWinningLobbyPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWinningTeam() {
|
||||
return game.getOutcome() == null ? -1 : game.getOutcome().getWinningTeam();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isFirstGameInMatch()
|
||||
*/
|
||||
@Override
|
||||
public boolean isFirstGameInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchOver() {
|
||||
return this.game.getMatch().isMatchOver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumPlayedGamesInMatch() {
|
||||
return this.game.getMatch().getPlayedGames().size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatchWonBy(final LobbyPlayer p) {
|
||||
return this.game.getMatch().isWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGamesWonBy(LobbyPlayer p) {
|
||||
return this.game.getMatch().getGamesWonBy(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GameOutcome.AnteResult getAnteResult() {
|
||||
return this.game.getOutcome().anteResult.get(player);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isCombatDeclareAttackers()
|
||||
*/
|
||||
@Override
|
||||
public boolean isCombatDeclareAttackers() {
|
||||
return game.getPhaseHandler().is(PhaseType.COMBAT_DECLARE_ATTACKERS)
|
||||
&& game.getCombat() != null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#isGameOver()
|
||||
*/
|
||||
@Override
|
||||
public boolean isGameOver() {
|
||||
return game.isGameOver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPoisonCountersToLose() {
|
||||
return game.getRules().getPoisonCountersToLose();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#subscribeToEvents(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void subscribeToEvents(final Object subscriber) {
|
||||
game.subscribeToEvents(subscriber);
|
||||
}
|
||||
|
||||
// the following methods should eventually be replaced by methods returning
|
||||
// View classes
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getCombat()
|
||||
*/
|
||||
@Override
|
||||
public Combat getCombat() {
|
||||
return game.getCombat();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getGameLog()
|
||||
*/
|
||||
@Override
|
||||
public GameLog getGameLog() {
|
||||
return game.getGameLog();
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getGuiRegisteredPlayer(forge.LobbyPlayer)
|
||||
*/
|
||||
@Override
|
||||
public RegisteredPlayer getGuiRegisteredPlayer(final LobbyPlayer p) {
|
||||
for (final RegisteredPlayer player : game.getMatch().getPlayers()) {
|
||||
if (player.getPlayer() == p) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getRegisteredPlayers()
|
||||
*/
|
||||
@Override
|
||||
public List<PlayerView> getPlayers() {
|
||||
return Lists.transform(game.getRegisteredPlayers(), FN_GET_PLAYER_VIEW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerView getPlayerTurn() {
|
||||
return getPlayerView(game.getPhaseHandler().getPlayerTurn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PhaseType getPhase() {
|
||||
return game.getPhaseHandler().getPhase();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#getStack()
|
||||
*/
|
||||
@Override
|
||||
public List<StackItemView> getStack() {
|
||||
final List<StackItemView> items = Collections.unmodifiableList(getStack(game.getStack()));
|
||||
// clear the cache
|
||||
stackItems.keySet().retainAll(items);
|
||||
return items;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see forge.view.IGameView#peekStack()
|
||||
*/
|
||||
@Override
|
||||
public StackItemView peekStack() {
|
||||
final SpellAbilityStackInstance top =
|
||||
Iterables.getFirst(game.getStack(), null);
|
||||
if (top == null) {
|
||||
return null;
|
||||
}
|
||||
return getStack(Lists.newArrayList(top)).iterator().next();
|
||||
}
|
||||
|
||||
private List<StackItemView> getStack(final Iterable<SpellAbilityStackInstance> stack) {
|
||||
final List<StackItemView> items = Lists.newLinkedList();
|
||||
for (final SpellAbilityStackInstance si : stack) {
|
||||
if (stackItems.containsKey(si)) {
|
||||
items.add(stackItems.get(si));
|
||||
} else {
|
||||
final StackItemView newItem = new StackItemView(
|
||||
si.getSpellAbility().toUnsuppressedString(),
|
||||
si.getSpellAbility().getSourceTrigger(),
|
||||
si.getStackDescription(), getCardView(si.getSourceCard()),
|
||||
getPlayerView(si.getActivator()), si.isAbility(),
|
||||
si.isOptionalTrigger());
|
||||
items.add(newItem);
|
||||
stackItems.put(si, newItem);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
private GameEntityView getGameEntityView(final GameEntity e) {
|
||||
if (e instanceof Card) {
|
||||
return getCardView((Card)e);
|
||||
} else if (e instanceof Player) {
|
||||
return getPlayerView((Player)e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private PlayerView getPlayerView(final Player p) {
|
||||
if (p == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PlayerView view;
|
||||
if (players.containsKey(p)) {
|
||||
view = players.get(p);
|
||||
getPlayerView(p, view);
|
||||
} else {
|
||||
view = new PlayerView(p.getLobbyPlayer(), p.getController());
|
||||
getPlayerView(p, view);
|
||||
players.put(p, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private final Function<Player, PlayerView> FN_GET_PLAYER_VIEW = new Function<Player, PlayerView>() {
|
||||
@Override
|
||||
public PlayerView apply(final Player input) {
|
||||
return getPlayerView(input);
|
||||
}
|
||||
};
|
||||
|
||||
private Player getPlayer(final PlayerView p) {
|
||||
return players.inverse().get(p);
|
||||
}
|
||||
|
||||
private void getPlayerView(final Player p, final PlayerView view) {
|
||||
view.setCommanderInfo(CardFactoryUtil.getCommanderInfo(p).trim().replace("\r\n", "; "));
|
||||
view.setKeywords(p.getKeywords());
|
||||
view.setLife(p.getLife());
|
||||
view.setMaxHandSize(p.getMaxHandSize());
|
||||
view.setNumDrawnThisTurn(p.getNumDrawnThisTurn());
|
||||
view.setPoisonCounters(p.getPoisonCounters());
|
||||
view.setPreventNextDamage(p.getPreventNextDamageTotalShields());
|
||||
view.setHasUnlimitedHandSize(p.isUnlimitedHandSize());
|
||||
view.setAnteCards(getCardViews(p.getCardsIn(ZoneType.Ante)));
|
||||
view.setBfCards(getCardViews(p.getCardsIn(ZoneType.Battlefield)));
|
||||
view.setExileCards(getCardViews(p.getCardsIn(ZoneType.Exile)));
|
||||
view.setFlashbackCards(getCardViews(p.getCardsActivableInExternalZones(false)));
|
||||
view.setGraveCards(getCardViews(p.getCardsIn(ZoneType.Graveyard)));
|
||||
view.setHandCards(getCardViews(p.getCardsIn(ZoneType.Hand)));
|
||||
view.setLibraryCards(getCardViews(p.getCardsIn(ZoneType.Library)));
|
||||
}
|
||||
|
||||
private CardView getCardView(final Card c) {
|
||||
if (c == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final CardView view;
|
||||
if (cards.containsKey(c)) {
|
||||
view = cards.get(c);
|
||||
writeCardToView(c, view);
|
||||
} else {
|
||||
view = new CardView(c, c.getUniqueNumber());
|
||||
writeCardToView(c, view);
|
||||
cards.put(c, view);
|
||||
}
|
||||
return view;
|
||||
}
|
||||
|
||||
private final Function<Card, CardView> FN_GET_CARD_VIEW = new Function<Card, CardView>() {
|
||||
@Override
|
||||
public CardView apply(final Card input) {
|
||||
return getCardView(input);
|
||||
}
|
||||
};
|
||||
|
||||
private List<CardView> getCardViews(final List<Card> cards) {
|
||||
return Lists.transform(cards, FN_GET_CARD_VIEW);
|
||||
}
|
||||
|
||||
private Card getCard(final CardView c) {
|
||||
return cards.inverse().get(c);
|
||||
}
|
||||
|
||||
private final Function<CardView, Card> FN_GET_CARD = new Function<CardView, Card>() {
|
||||
@Override
|
||||
public Card apply(final CardView input) {
|
||||
return getCard(input);
|
||||
}
|
||||
};
|
||||
|
||||
private List<Card> getCards(final List<CardView> cards) {
|
||||
return Lists.transform(cards, FN_GET_CARD);
|
||||
}
|
||||
|
||||
private void writeCardToView(final Card c, final CardView view) {
|
||||
if (!c.canBeShownTo(player)) {
|
||||
view.getOriginal().reset();
|
||||
view.getAlternate().reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// First, write the values independent of other views.
|
||||
ViewUtil.writeNonDependentCardViewProperties(c, view);
|
||||
// Next, write the values that depend on other views.
|
||||
view.setOwner(getPlayerView(c.getOwner()));
|
||||
view.setController(getPlayerView(c.getController()));
|
||||
view.setAttacking(game.getCombat() != null && game.getCombat().isAttacking(c));
|
||||
view.setBlocking(game.getCombat() != null && game.getCombat().isBlocking(c));
|
||||
view.setChosenPlayer(getPlayerView(c.getChosenPlayer()));
|
||||
view.setEquipping(getCardView(Iterables.getFirst(c.getEquipping(), null)));
|
||||
view.setEquippedBy(getCardViews(c.getEquippedBy()));
|
||||
view.setEnchantingCard(getCardView(c.getEnchantingCard()));
|
||||
view.setEnchantingPlayer(getPlayerView(c.getEnchantingPlayer()));
|
||||
view.setEnchantedBy(getCardViews(c.getEnchantedBy()));
|
||||
view.setFortifiedBy(getCardViews(c.getFortifiedBy()));
|
||||
view.setGainControlTargets(getCardViews(c.getGainControlTargets()));
|
||||
view.setCloneOrigin(getCardView(c.getCloneOrigin()));
|
||||
view.setImprinted(getCardViews(c.getImprinted()));
|
||||
view.setHauntedBy(getCardViews(c.getHauntedBy()));
|
||||
view.setHaunting(getCardView(c.getHaunting()));
|
||||
view.setMustBlock(c.getMustBlockCards() == null ? Collections.<CardView>emptySet() : Iterables.transform(c.getMustBlockCards(), FN_GET_CARD_VIEW));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mayShowCard(final CardView c, final Player viewer) {
|
||||
return cards.inverse().get(c).canBeShownTo(viewer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDisableAutoYields() {
|
||||
return this.game.getDisableAutoYields();
|
||||
}
|
||||
@Override
|
||||
public void setDisableAutoYields(final boolean b) {
|
||||
this.game.setDisableAutoYields(b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import forge.game.zone.ZoneType;
|
||||
import forge.match.input.InputSelectTargets;
|
||||
import forge.util.Aggregates;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.view.CardView;
|
||||
import forge.view.SpellAbilityView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -51,9 +53,8 @@ import java.util.Map;
|
||||
public class TargetSelection {
|
||||
private final SpellAbility ability;
|
||||
|
||||
|
||||
public TargetSelection(final SpellAbility sa) {
|
||||
this.ability = sa;
|
||||
public TargetSelection(final SpellAbility currentAbility) {
|
||||
this.ability = currentAbility;
|
||||
}
|
||||
|
||||
private final TargetRestrictions getTgt() {
|
||||
@@ -70,7 +71,7 @@ public class TargetSelection {
|
||||
*/
|
||||
|
||||
public final boolean chooseTargets(Integer numTargets) {
|
||||
TargetRestrictions tgt = getTgt();
|
||||
final TargetRestrictions tgt = getTgt();
|
||||
final boolean canTarget = tgt != null && tgt.doesTarget();
|
||||
if (!canTarget) {
|
||||
throw new RuntimeException("TargetSelection.chooseTargets called for ability that does not target - " + ability);
|
||||
@@ -81,8 +82,8 @@ public class TargetSelection {
|
||||
final int maxTargets = numTargets != null ? numTargets.intValue() : tgt.getMaxTargets(ability.getHostCard(), ability);
|
||||
final int numTargeted = ability.getTargets().getNumTargeted();
|
||||
|
||||
boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets;
|
||||
boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0;
|
||||
final boolean hasEnoughTargets = minTargets == 0 || numTargeted >= minTargets;
|
||||
final boolean hasAllTargets = numTargeted == maxTargets && maxTargets > 0;
|
||||
if (maxTargets == 0) { return true; }
|
||||
|
||||
// if not enough targets chosen, cancel Ability
|
||||
@@ -105,8 +106,8 @@ public class TargetSelection {
|
||||
final boolean choiceResult;
|
||||
final boolean random = tgt.isRandomTarget();
|
||||
if (random) {
|
||||
List<GameObject> candidates = tgt.getAllCandidates(this.ability, true);
|
||||
GameObject choice = Aggregates.random(candidates);
|
||||
final List<GameObject> candidates = tgt.getAllCandidates(this.ability, true);
|
||||
final GameObject choice = Aggregates.random(candidates);
|
||||
return ability.getTargets().add(choice);
|
||||
}
|
||||
else if (zone.size() == 1 && zone.get(0) == ZoneType.Stack) {
|
||||
@@ -115,7 +116,7 @@ public class TargetSelection {
|
||||
return this.chooseCardFromStack(mandatory);
|
||||
}
|
||||
else {
|
||||
final List<Card> validTargets = this.getValidCardsToTarget();
|
||||
final List<CardView> validTargets = this.getValidCardsToTarget();
|
||||
if (validTargets.isEmpty()) {
|
||||
//if no valid cards to target and only one valid non-card, auto-target the non-card
|
||||
//this handles "target opponent" cards, along with any other cards that can only target a single non-card game entity
|
||||
@@ -162,7 +163,7 @@ public class TargetSelection {
|
||||
* </p>
|
||||
* @return
|
||||
*/
|
||||
private final List<Card> getValidCardsToTarget() {
|
||||
private final List<CardView> getValidCardsToTarget() {
|
||||
final TargetRestrictions tgt = this.getTgt();
|
||||
final Game game = ability.getActivatingPlayer().getGame();
|
||||
final List<ZoneType> zone = tgt.getZone();
|
||||
|
||||
@@ -7,22 +7,28 @@ import org.apache.commons.lang3.StringUtils;
|
||||
*
|
||||
*/
|
||||
public enum QuestEventDifficulty {
|
||||
EASY("easy"),
|
||||
MEDIUM("medium"),
|
||||
HARD("hard"),
|
||||
EXPERT("very hard");
|
||||
|
||||
String inFile;
|
||||
|
||||
private QuestEventDifficulty(String storedInFile) {
|
||||
EASY ("easy", 1. ),
|
||||
MEDIUM("medium", 1.5),
|
||||
HARD ("hard", 2. ),
|
||||
EXPERT("very hard", 3. );
|
||||
|
||||
private final String inFile;
|
||||
private final double multiplier;
|
||||
|
||||
private QuestEventDifficulty(final String storedInFile, final double multiplier) {
|
||||
inFile = storedInFile;
|
||||
this.multiplier = multiplier;
|
||||
}
|
||||
|
||||
|
||||
public final String getTitle() {
|
||||
return inFile;
|
||||
}
|
||||
|
||||
public static QuestEventDifficulty fromString(String src) {
|
||||
|
||||
public final double getMultiplier() {
|
||||
return this.multiplier;
|
||||
}
|
||||
|
||||
public static QuestEventDifficulty fromString(final String src) {
|
||||
if ( StringUtils.isBlank(src) )
|
||||
return MEDIUM; // player have custom files, that didn't specify a valid difficulty
|
||||
|
||||
|
||||
@@ -37,19 +37,21 @@ import forge.quest.data.QuestPreferences.DifficultyPrefs;
|
||||
import forge.quest.data.QuestPreferences.QPref;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.gui.SGuiChoose;
|
||||
import forge.view.IGameView;
|
||||
import forge.view.PlayerView;
|
||||
|
||||
public abstract class QuestWinLoseController {
|
||||
private final Game lastGame;
|
||||
private final IGameView lastGame;
|
||||
private final transient boolean wonMatch;
|
||||
private final transient boolean isAnte;
|
||||
private final transient QuestController qData;
|
||||
private final transient QuestEvent qEvent;
|
||||
|
||||
public QuestWinLoseController(Game lastGame0) {
|
||||
lastGame = lastGame0;
|
||||
public QuestWinLoseController(final IGameView game0) {
|
||||
lastGame = game0;
|
||||
qData = FModel.getQuest();
|
||||
qEvent = qData.getCurrentEvent();
|
||||
wonMatch = lastGame.getMatch().isWonBy(GuiBase.getInterface().getQuestPlayer());
|
||||
wonMatch = lastGame.isMatchWonBy(GuiBase.getInterface().getQuestPlayer());
|
||||
isAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE);
|
||||
}
|
||||
|
||||
@@ -58,21 +60,21 @@ public abstract class QuestWinLoseController {
|
||||
final QuestController qc = FModel.getQuest();
|
||||
|
||||
// After the first game, reset the card shop pool to be able to buy back anted cards
|
||||
if (lastGame.getMatch().getPlayedGames().size() == 1) {
|
||||
if (lastGame.getNumPlayedGamesInMatch() == 1) {
|
||||
qc.getCards().clearShopList();
|
||||
qc.getCards().getShopList();
|
||||
}
|
||||
|
||||
final LobbyPlayer questLobbyPlayer = GuiBase.getInterface().getQuestPlayer();
|
||||
Player player = null;
|
||||
for (Player p : lastGame.getRegisteredPlayers()) {
|
||||
PlayerView player = null;
|
||||
for (final PlayerView p : lastGame.getPlayers()) {
|
||||
if (p.getLobbyPlayer().equals(questLobbyPlayer)) {
|
||||
player = p;
|
||||
}
|
||||
}
|
||||
final Player questPlayer = player;
|
||||
final PlayerView questPlayer = player;
|
||||
|
||||
final boolean matchIsNotOver = !lastGame.getMatch().isMatchOver();
|
||||
final boolean matchIsNotOver = !lastGame.isMatchOver();
|
||||
if (matchIsNotOver) {
|
||||
view.getBtnQuit().setText("Quit (-15 Credits)");
|
||||
}
|
||||
@@ -91,11 +93,8 @@ public abstract class QuestWinLoseController {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAnte) {
|
||||
//do per-game actions
|
||||
GameOutcome outcome = lastGame.getOutcome();
|
||||
|
||||
// Won/lost cards should already be calculated (even in a draw)
|
||||
GameOutcome.AnteResult anteResult = outcome.anteResult.get(questPlayer);
|
||||
GameOutcome.AnteResult anteResult = lastGame.getAnteResult();
|
||||
if (anteResult != null) {
|
||||
if (anteResult.wonCards != null) {
|
||||
qc.getCards().addAllCards(anteResult.wonCards);
|
||||
@@ -103,7 +102,7 @@ public abstract class QuestWinLoseController {
|
||||
if (anteResult.lostCards != null) {
|
||||
qc.getCards().loseCards(anteResult.lostCards);
|
||||
}
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.equals(outcome.getWinningPlayer()));
|
||||
anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.getLobbyPlayer().equals(lastGame.getWinningPlayer()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,21 +222,14 @@ public abstract class QuestWinLoseController {
|
||||
|
||||
// Basic win bonus
|
||||
final int base = FModel.getQuestPreferences().getPrefInt(QPref.REWARDS_BASE);
|
||||
double multiplier = 1;
|
||||
|
||||
switch (qEvent.getDifficulty()) {
|
||||
case EASY: multiplier = 1; break;
|
||||
case MEDIUM: multiplier = 1.5; break;
|
||||
case HARD: multiplier = 2; break;
|
||||
case EXPERT: multiplier = 3; break;
|
||||
}
|
||||
final double multiplier = qEvent.getDifficulty().getMultiplier();
|
||||
|
||||
credBase = (int) (base * multiplier);
|
||||
|
||||
sb.append(StringUtils.capitalize(qEvent.getDifficulty().getTitle()));
|
||||
sb.append(" opponent: ").append(credBase).append(" credits.\n");
|
||||
|
||||
int creditsForPreviousWins = (int) ((Double.parseDouble(FModel.getQuestPreferences()
|
||||
final int creditsForPreviousWins = (int) ((Double.parseDouble(FModel.getQuestPreferences()
|
||||
.getPref(QPref.REWARDS_WINS_MULTIPLIER)) * qData.getAchievements().getWin()));
|
||||
credBase += creditsForPreviousWins;
|
||||
|
||||
@@ -247,8 +239,8 @@ public abstract class QuestWinLoseController {
|
||||
// Gameplay bonuses (for each game win)
|
||||
boolean hasNeverLost = true;
|
||||
int lifeDifferenceCredits = 0;
|
||||
|
||||
LobbyPlayer localHuman = GuiBase.getInterface().getQuestPlayer();
|
||||
|
||||
final LobbyPlayer localHuman = GuiBase.getInterface().getQuestPlayer();
|
||||
for (final GameOutcome game : lastGame.getMatch().getPlayedGames()) {
|
||||
if (!game.isWinner(localHuman)) {
|
||||
hasNeverLost = false;
|
||||
|
||||
@@ -14,7 +14,7 @@ import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.game.card.Card;
|
||||
import forge.view.CardView;
|
||||
|
||||
public class SGuiChoose {
|
||||
/**
|
||||
@@ -181,17 +181,17 @@ public class SGuiChoose {
|
||||
return GuiBase.getInterface().getChoices(message, min, max, choices, selected, display);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> many(final String title, final String topCaption, int cnt, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(title, topCaption, cnt, cnt, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> many(final String title, final String topCaption, int min, int max, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
int m2 = min >= 0 ? sourceChoices.size() - min : -1;
|
||||
int m1 = max >= 0 ? sourceChoices.size() - max : -1;
|
||||
return order(title, topCaption, m1, m2, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, Card referenceCard) {
|
||||
public static <T> List<T> order(final String title, final String top, final List<T> sourceChoices, final CardView referenceCard) {
|
||||
return order(title, top, 0, 0, sourceChoices, null, referenceCard, false);
|
||||
}
|
||||
|
||||
@@ -215,11 +215,10 @@ public class SGuiChoose {
|
||||
}
|
||||
|
||||
private static <T> List<T> order(final String title, final String top, final int remainingObjectsMin, final int remainingObjectsMax,
|
||||
final List<T> sourceChoices, final List<T> destChoices, final Card referenceCard, final boolean sideboardingMode) {
|
||||
final List<T> sourceChoices, final List<T> destChoices, final CardView referenceCard, final boolean sideboardingMode) {
|
||||
return GuiBase.getInterface().order(title, top, remainingObjectsMin, remainingObjectsMax, sourceChoices, destChoices, referenceCard, sideboardingMode);
|
||||
}
|
||||
|
||||
|
||||
// If comparer is NULL, T has to be comparable. Otherwise you'll get an exception from inside the Arrays.sort() routine
|
||||
public static <T> T sortedOneOrNone(final String message, final T[] choices, Comparator<T> comparer) {
|
||||
if ((choices == null) || (choices.length == 0)) {
|
||||
|
||||
@@ -2,8 +2,7 @@ package forge.util.gui;
|
||||
|
||||
import forge.GuiBase;
|
||||
import forge.assets.FSkinProp;
|
||||
import forge.game.card.Card;
|
||||
|
||||
import forge.view.CardView;
|
||||
|
||||
public class SOptionPane {
|
||||
public static final FSkinProp QUESTION_ICON = FSkinProp.ICO_QUESTION;
|
||||
@@ -61,7 +60,7 @@ public class SOptionPane {
|
||||
return GuiBase.getInterface().showOptionDialog(message, title, icon, options, defaultOption);
|
||||
}
|
||||
|
||||
public static int showCardOptionDialog(Card card, String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
public static int showCardOptionDialog(CardView card, String message, String title, FSkinProp icon, String[] options, int defaultOption) {
|
||||
return GuiBase.getInterface().showCardOptionDialog(card, message, title, icon, options, defaultOption);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user