- replaced DuelDialog with new DuelPlayersScreen which improves managment of player profiles (both human and AI).
- new avatar selection screen. - improved player stats presentation. - Now uses persistent AI personas with their own stats. - If a duel consists of X games then is played as best of X instead of first to X. - can now play a single game duel. - improved layout of player tabs in DuelDecksScreen. Current score is now integrated into the tabs.master
After Width: | Height: | Size: 738 B |
Before Width: | Height: | Size: 849 B After Width: | Height: | Size: 849 B |
After Width: | Height: | Size: 695 B |
After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 687 B After Width: | Height: | Size: 687 B |
After Width: | Height: | Size: 494 B |
Before Width: | Height: | Size: 362 B After Width: | Height: | Size: 362 B |
Before Width: | Height: | Size: 519 B After Width: | Height: | Size: 519 B |
After Width: | Height: | Size: 737 B |
Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 465 B |
Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 550 B |
After Width: | Height: | Size: 353 B |
After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 233 B After Width: | Height: | Size: 233 B |
|
@ -6,7 +6,6 @@ import magic.data.DeckGenerators;
|
|||
import magic.data.DeckUtils;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.data.History;
|
||||
import magic.data.KeywordDefinitions;
|
||||
import magic.model.MagicGameLog;
|
||||
import magic.test.TestGameBuilder;
|
||||
|
@ -43,6 +42,8 @@ public class MagicMain {
|
|||
private static final String SCRIPTS_PATH = "scripts";
|
||||
private static final String LOGS_PATH = "logs";
|
||||
private static final String SAVED_DUELS_PATH = "duels";
|
||||
private static final String PLAYER_PROFILES_PATH = "players";
|
||||
private static final String AVATAR_SETS_PATH = "avatars";
|
||||
private static final String GAME_PATH =
|
||||
(System.getProperty("magarena.dir") != null ?
|
||||
System.getProperty("magarena.dir") :
|
||||
|
@ -113,9 +114,7 @@ public class MagicMain {
|
|||
if (testGame != null) {
|
||||
magicFrame.openGame(TestGameBuilder.buildGame(testGame));
|
||||
}
|
||||
// add "-DselfMode=true" VM argument for AI vs AI mode.
|
||||
// in selfMode start game immediately based on configuration from duel.cfg
|
||||
if (Boolean.getBoolean("selfMode")) {
|
||||
if (MagicUtility.isAiVersusAi()) {
|
||||
final DuelConfig config = DuelConfig.getInstance();
|
||||
config.load();
|
||||
magicFrame.newDuel(config);
|
||||
|
@ -156,6 +155,14 @@ public class MagicMain {
|
|||
return getDataPath(SAVED_DUELS_PATH);
|
||||
}
|
||||
|
||||
public static String getPlayerProfilesPath() {
|
||||
return getDataPath(PLAYER_PROFILES_PATH);
|
||||
}
|
||||
|
||||
public static String getAvatarSetsPath() {
|
||||
return getDataPath(AVATAR_SETS_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets path to a specified data directory. If the directory does not exist it
|
||||
* attempts to create it. If that fails then it uses the GAME_PATH directory instead.
|
||||
|
@ -201,7 +208,6 @@ public class MagicMain {
|
|||
}
|
||||
|
||||
DeckUtils.createDeckFolder();
|
||||
History.createHistoryFolder();
|
||||
initializeEngine();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,16 +1,43 @@
|
|||
package magic;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.GradientPaint;
|
||||
import java.awt.Paint;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
final public class MagicUtility {
|
||||
private MagicUtility() {}
|
||||
|
||||
public static final boolean IS_WINDOWS_OS = System.getProperty("os.name").toLowerCase().startsWith("windows");
|
||||
|
||||
private static final Paint debugBorderPaint = new GradientPaint(0, 0, Color.red, 100, 100, Color.white, true);
|
||||
|
||||
public static void setBusyMouseCursor(final boolean b) {
|
||||
MagicMain.rootFrame.setCursor(
|
||||
b ? Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) :
|
||||
Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
|
||||
public static void setDebugBorder(final JComponent component) {
|
||||
component.setBorder(BorderFactory.createDashedBorder(debugBorderPaint));
|
||||
}
|
||||
|
||||
public static boolean isTestGame() {
|
||||
return (System.getProperty("testGame") != null);
|
||||
}
|
||||
|
||||
public static boolean isDevMode() {
|
||||
return Boolean.getBoolean("devMode");
|
||||
}
|
||||
|
||||
/**
|
||||
* add "-DselfMode=true" VM argument for AI vs AI mode.
|
||||
*/
|
||||
public static boolean isAiVersusAi() {
|
||||
return Boolean.getBoolean("selfMode");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ public enum MagicAIImpl {
|
|||
MCTSC2("monte carlo tree search (cheat)", new MCTSAI2(true)),
|
||||
;
|
||||
|
||||
private static final MagicAIImpl[] SUPPORTED_AIS = {MMAB, MMABC, MCTS, MCTSC, VEGAS, VEGASC};
|
||||
public static final MagicAIImpl[] SUPPORTED_AIS = {MMAB, MMABC, MCTS, MCTSC, VEGAS, VEGASC};
|
||||
|
||||
private final String name;
|
||||
private final MagicAI ai;
|
||||
|
@ -49,4 +49,10 @@ public enum MagicAIImpl {
|
|||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import magic.ai.MagicAI;
|
|||
import magic.ai.MagicAIImpl;
|
||||
import magic.model.MagicColor;
|
||||
import magic.model.MagicPlayerProfile;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.model.player.PlayerProfiles;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -19,9 +21,7 @@ public class DuelConfig {
|
|||
private static final String ANY_TWO="**";
|
||||
private static final String ANY_ONE="*";
|
||||
|
||||
private static final String CONFIG_FILENAME="duel.cfg";
|
||||
private static final String AVATAR="avatar";
|
||||
private static final String NAME="name";
|
||||
private static final String CONFIG_FILENAME="newduel.cfg";
|
||||
private static final String START_LIFE="life";
|
||||
private static final String HAND_SIZE="hand";
|
||||
private static final String GAMES="games";
|
||||
|
@ -30,44 +30,46 @@ public class DuelConfig {
|
|||
private static final String CUBE="cube";
|
||||
private static final String AI="ai";
|
||||
|
||||
private int avatar;
|
||||
private String name="Player";
|
||||
private int startLife=20;
|
||||
private int handSize=7;
|
||||
private int games=7;
|
||||
private String playerColors=ANY_THREE;
|
||||
private String opponentColors=ANY_THREE;
|
||||
private String cube=CubeDefinitions.DEFAULT_NAME;
|
||||
private String ai="minimax";
|
||||
// default values.
|
||||
private int startLife = 20;
|
||||
private int handSize = 7;
|
||||
private int games = 7;
|
||||
private String playerOneDeckGenerator = ANY_THREE;
|
||||
private String playerTwoDeckGenerator = ANY_THREE;
|
||||
private String cube = CubeDefinitions.getCubeNames()[0];
|
||||
private String ai = "minimax";
|
||||
private PlayerProfile playerOne = null;
|
||||
private PlayerProfile playerTwo = null;
|
||||
|
||||
// CTR
|
||||
public DuelConfig() {
|
||||
|
||||
// Ensure DuelConfig has valid PlayerProfile references.
|
||||
// If missing then creates default profiles.
|
||||
PlayerProfiles.refreshMap();
|
||||
}
|
||||
|
||||
// CTR: copy constructor - a common way of creating a copy of an existing object.
|
||||
public DuelConfig(final DuelConfig duelConfig) {
|
||||
avatar=duelConfig.avatar;
|
||||
startLife=duelConfig.startLife;
|
||||
handSize=duelConfig.handSize;
|
||||
games=duelConfig.games;
|
||||
playerColors=duelConfig.playerColors;
|
||||
opponentColors=duelConfig.opponentColors;
|
||||
playerOneDeckGenerator=duelConfig.playerOneDeckGenerator;
|
||||
playerTwoDeckGenerator=duelConfig.playerTwoDeckGenerator;
|
||||
ai=duelConfig.ai;
|
||||
}
|
||||
|
||||
public int getAvatar() {
|
||||
return avatar;
|
||||
public PlayerProfile getPlayerOneProfile() {
|
||||
return playerOne;
|
||||
}
|
||||
public void setPlayerOneProfile(PlayerProfile playerProfile) {
|
||||
this.playerOne = playerProfile;
|
||||
}
|
||||
|
||||
public void setAvatar(final int avatar) {
|
||||
this.avatar = avatar;
|
||||
public PlayerProfile getPlayerTwoProfile() {
|
||||
return playerTwo;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(final String name) {
|
||||
this.name=name;
|
||||
public void setPlayerTwoProfile(PlayerProfile playerProfile) {
|
||||
this.playerTwo = playerProfile;
|
||||
}
|
||||
|
||||
public int getStartLife() {
|
||||
|
@ -94,7 +96,7 @@ public class DuelConfig {
|
|||
return games;
|
||||
}
|
||||
|
||||
private static MagicPlayerProfile getProfile(final String colorText) {
|
||||
private static MagicPlayerProfile getMagicPlayerProfile(final String colorText) {
|
||||
if (ANY_DECK.equals(colorText)) {
|
||||
return new MagicPlayerProfile("");
|
||||
} else if (ANY_THREE.equals(colorText)) {
|
||||
|
@ -110,28 +112,28 @@ public class DuelConfig {
|
|||
return new MagicPlayerProfile(colorText);
|
||||
}
|
||||
|
||||
public String getPlayerColors() {
|
||||
return playerColors;
|
||||
public MagicPlayerProfile getMagicPlayerProfile() {
|
||||
return getMagicPlayerProfile(playerOneDeckGenerator);
|
||||
}
|
||||
|
||||
public void setPlayerColors(final String colors) {
|
||||
playerColors=colors;
|
||||
public String getPlayerOneDeckGenerator() {
|
||||
return playerOneDeckGenerator;
|
||||
}
|
||||
|
||||
public MagicPlayerProfile getPlayerProfile() {
|
||||
return getProfile(playerColors);
|
||||
public void setPlayerOneDeckGenerator(final String deckGenerator) {
|
||||
playerOneDeckGenerator = deckGenerator;
|
||||
}
|
||||
|
||||
public String getOpponentColors() {
|
||||
return opponentColors;
|
||||
public String getPlayerTwoDeckGenerator() {
|
||||
return playerTwoDeckGenerator;
|
||||
}
|
||||
|
||||
public void setOpponentColors(final String colors) {
|
||||
opponentColors=colors;
|
||||
public void setPlayerTwoDeckGenerator(final String deckGenerator) {
|
||||
playerTwoDeckGenerator = deckGenerator;
|
||||
}
|
||||
|
||||
public MagicPlayerProfile getOpponentProfile() {
|
||||
return getProfile(opponentColors);
|
||||
public MagicPlayerProfile getMagicOpponentProfile() {
|
||||
return getMagicPlayerProfile(playerTwoDeckGenerator);
|
||||
}
|
||||
|
||||
public String getCube() {
|
||||
|
@ -156,31 +158,33 @@ public class DuelConfig {
|
|||
}
|
||||
|
||||
public void load(final Properties properties) {
|
||||
avatar=Integer.parseInt(properties.getProperty(AVATAR,Integer.toString(avatar)));
|
||||
name=properties.getProperty(NAME,name);
|
||||
setPlayerOneProfile(PlayerProfile.getHumanPlayer(properties.getProperty("HumanPlayer")));
|
||||
setPlayerTwoProfile(PlayerProfile.getAiPlayer(properties.getProperty("AiPlayer")));
|
||||
startLife=Integer.parseInt(properties.getProperty(START_LIFE,Integer.toString(startLife)));
|
||||
handSize=Integer.parseInt(properties.getProperty(HAND_SIZE,Integer.toString(handSize)));
|
||||
games=Integer.parseInt(properties.getProperty(GAMES,Integer.toString(games)));
|
||||
playerColors=properties.getProperty(PLAYER,playerColors);
|
||||
opponentColors=properties.getProperty(OPPONENT,opponentColors);
|
||||
playerOneDeckGenerator=properties.getProperty(PLAYER,playerOneDeckGenerator);
|
||||
playerTwoDeckGenerator=properties.getProperty(OPPONENT,playerTwoDeckGenerator);
|
||||
cube=properties.getProperty(CUBE,cube);
|
||||
ai=properties.getProperty(AI,ai);
|
||||
}
|
||||
|
||||
public void load() {
|
||||
load(FileIO.toProp(getConfigFile()));
|
||||
final File configFile = getConfigFile();
|
||||
final Properties properties = configFile.exists() ? FileIO.toProp(configFile) : new Properties();
|
||||
load(properties);
|
||||
}
|
||||
|
||||
public void save(final Properties properties) {
|
||||
properties.setProperty(AVATAR,Integer.toString(avatar));
|
||||
properties.setProperty(NAME,name);
|
||||
properties.setProperty(START_LIFE,Integer.toString(startLife));
|
||||
properties.setProperty(HAND_SIZE,Integer.toString(handSize));
|
||||
properties.setProperty("HumanPlayer", getPlayerOneProfile().getId());
|
||||
properties.setProperty("AiPlayer", getPlayerTwoProfile().getId());
|
||||
properties.setProperty(START_LIFE, Integer.toString(startLife));
|
||||
properties.setProperty(HAND_SIZE, Integer.toString(handSize));
|
||||
properties.setProperty(GAMES, Integer.toString(games));
|
||||
properties.setProperty(PLAYER,playerColors);
|
||||
properties.setProperty(OPPONENT,opponentColors);
|
||||
properties.setProperty(CUBE,cube);
|
||||
properties.setProperty(AI,ai);
|
||||
properties.setProperty(PLAYER, playerOneDeckGenerator);
|
||||
properties.setProperty(OPPONENT, playerTwoDeckGenerator);
|
||||
properties.setProperty(CUBE, cube);
|
||||
properties.setProperty(AI, ai);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
|
|
@ -19,15 +19,22 @@ public class IconImages {
|
|||
public static final BufferedImage OPAL=loadImage("textures/opal.jpg");
|
||||
public static final BufferedImage OPAL2=loadImage("textures/opal2.jpg");
|
||||
|
||||
// Icons used by various components of AbstractScreen.
|
||||
public static final ImageIcon HEADER_ICON = loadIcon("headerIcon.png");
|
||||
public static final ImageIcon OPTIONS_ICON = loadIcon("book.png");
|
||||
public static final ImageIcon REFRESH_ICON = loadIcon("refresh.png");
|
||||
public static final ImageIcon MULLIGAN_ICON = loadIcon("mulligan.png");
|
||||
public static final ImageIcon HAND_ICON = loadIcon("hand.png");
|
||||
public static final ImageIcon TILED_ICON = loadIcon("tiled.png");
|
||||
public static final ImageIcon SAVE_ICON = loadIcon("save.png");
|
||||
public static final ImageIcon LOAD_ICON = loadIcon("load.png");
|
||||
// White transparent icons used by various components of AbstractScreen.
|
||||
public static final ImageIcon HEADER_ICON = loadIcon("headerIcon.png");
|
||||
public static final ImageIcon OPTIONS_ICON = loadIcon("w_book.png");
|
||||
public static final ImageIcon REFRESH_ICON = loadIcon("w_refresh.png");
|
||||
public static final ImageIcon MULLIGAN_ICON = loadIcon("w_mulligan.png");
|
||||
public static final ImageIcon HAND_ICON = loadIcon("w_hand.png");
|
||||
public static final ImageIcon TILED_ICON = loadIcon("w_tiled.png");
|
||||
public static final ImageIcon SAVE_ICON = loadIcon("w_save.png");
|
||||
public static final ImageIcon LOAD_ICON = loadIcon("w_load.png");
|
||||
public static final ImageIcon SWAP_ICON = loadIcon("w_swap.png");
|
||||
public static final ImageIcon DECK_ICON = loadIcon("w_deck.png");
|
||||
public static final ImageIcon NEXT_ICON = loadIcon("w_next.png");
|
||||
public static final ImageIcon BACK_ICON = loadIcon("w_back.png");
|
||||
public static final ImageIcon LIFE_ICON = loadIcon("w_life.png");
|
||||
public static final ImageIcon TARGET_ICON = loadIcon("w_target.png");
|
||||
public static final ImageIcon CUBE_ICON = loadIcon("w_cube.png");
|
||||
|
||||
public static final ImageIcon ARENA=loadIcon("arena.png");
|
||||
public static final ImageIcon CUBE=loadIcon("cube.png");
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
package magic.model;
|
||||
|
||||
import magic.MagicMain;
|
||||
import magic.MagicUtility;
|
||||
import magic.ai.MagicAI;
|
||||
import magic.data.CubeDefinitions;
|
||||
import magic.data.DeckUtils;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.data.History;
|
||||
import magic.generator.DefaultDeckGenerator;
|
||||
import magic.model.phase.MagicDefaultGameplay;
|
||||
import magic.ui.theme.Theme;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.viewer.DeckStrengthViewer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class MagicDuel {
|
||||
|
||||
|
@ -26,10 +26,8 @@ public class MagicDuel {
|
|||
private static final String PLAYED="played";
|
||||
private static final String WON="won";
|
||||
private static final String START="start";
|
||||
private static final String COMPUTER="Computer";
|
||||
|
||||
private final DuelConfig configuration;
|
||||
private final History history;
|
||||
private MagicPlayerDefinition[] playerDefinitions;
|
||||
private MagicAI[] ais;
|
||||
private int opponentIndex;
|
||||
|
@ -41,7 +39,6 @@ public class MagicDuel {
|
|||
|
||||
public MagicDuel(final DuelConfig configuration) {
|
||||
this.configuration=configuration;
|
||||
history = new History(this);
|
||||
ais=configuration.getPlayerAIs();
|
||||
restart();
|
||||
}
|
||||
|
@ -59,10 +56,6 @@ public class MagicDuel {
|
|||
return configuration;
|
||||
}
|
||||
|
||||
private MagicPlayerDefinition getOpponent() {
|
||||
return playerDefinitions[opponentIndex];
|
||||
}
|
||||
|
||||
public int getGameNr() {
|
||||
return gameNr;
|
||||
}
|
||||
|
@ -87,10 +80,6 @@ public class MagicDuel {
|
|||
this.startPlayer=startPlayer;
|
||||
}
|
||||
|
||||
private int getStartPlayer() {
|
||||
return startPlayer;
|
||||
}
|
||||
|
||||
public void setAIs(final MagicAI[] aAIs) {
|
||||
this.ais = aAIs;
|
||||
}
|
||||
|
@ -126,7 +115,16 @@ public class MagicDuel {
|
|||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return getGamesPlayed()==getGamesTotal();
|
||||
if (MagicUtility.isAiVersusAi()) {
|
||||
return getGamesPlayed()==getGamesTotal();
|
||||
} else {
|
||||
// if a duel consists of a total of X games, then in an interactive
|
||||
// game it should be "best of" X games, not first to X.
|
||||
final int player1GamesWon = getGamesWon();
|
||||
final int player2GamesWon = getGamesPlayed() - player1GamesWon;
|
||||
final int gamesRequiredToWin = (int)Math.ceil(getGamesTotal()/2.0);
|
||||
return (player1GamesWon >= gamesRequiredToWin) || (player2GamesWon >= gamesRequiredToWin);
|
||||
}
|
||||
}
|
||||
|
||||
void advance(final boolean won, final MagicGame game) {
|
||||
|
@ -143,35 +141,17 @@ public class MagicDuel {
|
|||
opponentIndex++;
|
||||
determineStartPlayer();
|
||||
}
|
||||
if (!DeckStrengthViewer.isRunning()) {
|
||||
history.update(won,game,configuration);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Integer> getAvatarIndices(final int avatars) {
|
||||
final List<Integer> indices=new ArrayList<Integer>();
|
||||
for (int index=0;index<avatars;index++) {
|
||||
|
||||
indices.add(index);
|
||||
if (!DeckStrengthViewer.isRunning() && !MagicUtility.isTestGame()) {
|
||||
configuration.getPlayerOneProfile().getStats().update(won, game.getPlayer(0), game);
|
||||
configuration.getPlayerTwoProfile().getStats().update(!won, game.getPlayer(1), game);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
||||
private MagicPlayerDefinition[] createPlayers() {
|
||||
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
|
||||
final List<Integer> avatars=getAvatarIndices(theme.getNumberOfAvatars());
|
||||
|
||||
final MagicPlayerDefinition[] players=new MagicPlayerDefinition[2];
|
||||
|
||||
final int playerFace=configuration.getAvatar()%theme.getNumberOfAvatars();
|
||||
final MagicPlayerDefinition player=new MagicPlayerDefinition(configuration.getName(),false,configuration.getPlayerProfile(),playerFace);
|
||||
players[0]=player;
|
||||
avatars.remove(playerFace);
|
||||
|
||||
final int findex=MagicRandom.nextRNGInt(avatars.size());
|
||||
final Integer computerFace=avatars.get(findex);
|
||||
players[1]=new MagicPlayerDefinition(COMPUTER,true,configuration.getOpponentProfile(),computerFace);
|
||||
|
||||
players[0] = new MagicPlayerDefinition(configuration.getPlayerOneProfile().getPlayerName(), false, configuration.getMagicPlayerProfile());
|
||||
players[1] = new MagicPlayerDefinition(configuration.getPlayerTwoProfile().getPlayerName(), true,configuration.getMagicOpponentProfile());
|
||||
return players;
|
||||
}
|
||||
|
||||
|
@ -212,6 +192,7 @@ public class MagicDuel {
|
|||
return playerDefinitions;
|
||||
}
|
||||
|
||||
// only used by magic.test classes.
|
||||
public void setPlayers(final MagicPlayerDefinition[] aPlayerDefinitions) {
|
||||
this.playerDefinitions=aPlayerDefinitions;
|
||||
}
|
||||
|
@ -241,11 +222,13 @@ public class MagicDuel {
|
|||
public void initialize() {
|
||||
playerDefinitions=createPlayers();
|
||||
buildDecks();
|
||||
history.loadHistory(configuration.getName());
|
||||
}
|
||||
|
||||
public static final File getDuelFile(final String filename) {
|
||||
return new File(MagicMain.getSavedDuelsPath(), filename);
|
||||
}
|
||||
public static final File getDuelFile() {
|
||||
return new File(MagicMain.getSavedDuelsPath(),"duel.txt");
|
||||
return getDuelFile("saved.duel");
|
||||
}
|
||||
|
||||
private static String getPlayerPrefix(final int index) {
|
||||
|
@ -267,16 +250,25 @@ public class MagicDuel {
|
|||
}
|
||||
|
||||
public void save(final File file) {
|
||||
final Properties properties=new Properties();
|
||||
final Properties properties = getNewSortedProperties();
|
||||
save(properties);
|
||||
try { //save to file
|
||||
try {
|
||||
magic.data.FileIO.toFile(file, properties, "Duel");
|
||||
System.err.println("Saved duel");
|
||||
} catch (final IOException ex) {
|
||||
System.err.println("ERROR! Unable save duel to " + file);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private Properties getNewSortedProperties() {
|
||||
return new Properties() {
|
||||
@Override
|
||||
public synchronized Enumeration<Object> keys() {
|
||||
return Collections.enumeration(new TreeSet<Object>(super.keySet()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void load(final Properties properties) {
|
||||
configuration.load(properties);
|
||||
|
||||
|
@ -291,7 +283,6 @@ public class MagicDuel {
|
|||
playerDefinitions[index]=new MagicPlayerDefinition();
|
||||
playerDefinitions[index].load(properties,getPlayerPrefix(index));
|
||||
}
|
||||
history.loadHistory(configuration.getName());
|
||||
}
|
||||
|
||||
public void load(final File file) {
|
||||
|
@ -305,4 +296,18 @@ public class MagicDuel {
|
|||
gamesWon=0;
|
||||
determineStartPlayer();
|
||||
}
|
||||
|
||||
public PlayerProfile getWinningPlayerProfile() {
|
||||
if (!isFinished()) {
|
||||
return null;
|
||||
} else {
|
||||
final int playerOneGamesWon = getGamesWon();
|
||||
final int playerTwoGamesWon = getGamesPlayed() - playerOneGamesWon;
|
||||
if (playerOneGamesWon > playerTwoGamesWon) {
|
||||
return getConfiguration().getPlayerOneProfile();
|
||||
} else {
|
||||
return getConfiguration().getPlayerTwoProfile();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@ public class MagicGame {
|
|||
private long[] keys;
|
||||
private long stateId;
|
||||
private long time = 1000000;
|
||||
private boolean isConceded = false;
|
||||
|
||||
|
||||
public static MagicGame getInstance() {
|
||||
|
@ -1289,4 +1290,11 @@ public class MagicGame {
|
|||
executeTrigger(trigger,permanent,permanent,data);
|
||||
}
|
||||
}
|
||||
|
||||
public void setConceded(final boolean b) {
|
||||
isConceded = true;
|
||||
}
|
||||
public boolean isConceded() {
|
||||
return isConceded;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package magic.model;
|
|||
import magic.data.CardDefinitions;
|
||||
import magic.data.DeckGenerators;
|
||||
import magic.generator.DefaultDeckGenerator;
|
||||
|
||||
import magic.ui.theme.PlayerAvatar;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MagicPlayerDefinition {
|
||||
|
@ -14,21 +14,24 @@ public class MagicPlayerDefinition {
|
|||
private static final String NAME="name";
|
||||
private static final String ARTIFICIAL="artificial";
|
||||
private static final String COLORS="colors";
|
||||
private static final String FACE="face";
|
||||
|
||||
private String name;
|
||||
private boolean artificial;
|
||||
private MagicPlayerProfile profile;
|
||||
private int face;
|
||||
private final MagicDeck deck = new MagicDeck();
|
||||
private PlayerAvatar avatar;
|
||||
|
||||
MagicPlayerDefinition() {}
|
||||
MagicPlayerDefinition() {
|
||||
|
||||
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile,final int face) {
|
||||
}
|
||||
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile) {
|
||||
this.name=name;
|
||||
this.artificial=artificial;
|
||||
this.profile=profile;
|
||||
this.face=face;
|
||||
}
|
||||
public MagicPlayerDefinition(final String name,final boolean artificial,final MagicPlayerProfile profile,final int face) {
|
||||
this(name, artificial, profile);
|
||||
this.avatar = new PlayerAvatar(face);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -51,10 +54,6 @@ public class MagicPlayerDefinition {
|
|||
return profile;
|
||||
}
|
||||
|
||||
public int getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
private void addBasicLandsToDeck() {
|
||||
// Calculate statistics per color.
|
||||
final int[] colorCount=new int[MagicColor.NR_COLORS];
|
||||
|
@ -140,7 +139,6 @@ public class MagicPlayerDefinition {
|
|||
artificial=Boolean.parseBoolean(properties.getProperty(prefix+ARTIFICIAL,"true"));
|
||||
final String colors=properties.getProperty(prefix+COLORS,"");
|
||||
profile=new MagicPlayerProfile(colors);
|
||||
face=Integer.parseInt(properties.getProperty(prefix+FACE));
|
||||
|
||||
final MagicDeck unsupported = new MagicDeck();
|
||||
deck.clear();
|
||||
|
@ -164,11 +162,18 @@ public class MagicPlayerDefinition {
|
|||
properties.setProperty(prefix+NAME,name);
|
||||
properties.setProperty(prefix+ARTIFICIAL,Boolean.toString(artificial));
|
||||
properties.setProperty(prefix+COLORS,getProfile().getColorText());
|
||||
properties.setProperty(prefix+FACE,Integer.toString(face));
|
||||
|
||||
int index=1;
|
||||
for (final MagicCardDefinition cardDefinition : deck) {
|
||||
properties.setProperty(getDeckPrefix(prefix,index++),cardDefinition.getFullName());
|
||||
}
|
||||
}
|
||||
|
||||
public void setAvatar(final PlayerAvatar avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
public PlayerAvatar getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package magic.model.player;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import magic.ai.MagicAIImpl;
|
||||
|
||||
public class AiPlayer extends PlayerProfile {
|
||||
|
||||
private static final String PLAYER_TYPE = "ai";
|
||||
|
||||
private static final String KEY_EXTRA_LIFE = "extraLife";
|
||||
private static final String KEY_AI_LEVEL = "aiLevel";
|
||||
private static final String KEY_AI_TYPE = "aiType";
|
||||
|
||||
private static final int DEFAULT_EXTRA_LIFE = 0;
|
||||
private static final int DEFAULT_AI_LEVEL = 6;
|
||||
private static final MagicAIImpl DEFAULT_AI_TYPE = MagicAIImpl.MMAB;
|
||||
|
||||
private int extraLife = DEFAULT_EXTRA_LIFE;
|
||||
private int aiLevel = DEFAULT_AI_LEVEL;
|
||||
private MagicAIImpl aiType = DEFAULT_AI_TYPE;
|
||||
|
||||
public AiPlayer(final String profileId) {
|
||||
super(profileId);
|
||||
loadProperties();
|
||||
}
|
||||
public AiPlayer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public int getExtraLife() {
|
||||
return extraLife;
|
||||
}
|
||||
public void setExtraLife(final int value) {
|
||||
extraLife = value;
|
||||
}
|
||||
|
||||
public int getAiLevel() {
|
||||
return aiLevel;
|
||||
}
|
||||
public void setAiLevel(final int value) {
|
||||
aiLevel = value;
|
||||
}
|
||||
|
||||
public MagicAIImpl getAiType() {
|
||||
return aiType;
|
||||
}
|
||||
public void setAiType(final MagicAIImpl value) {
|
||||
aiType = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty(KEY_EXTRA_LIFE, String.valueOf(getExtraLife()));
|
||||
properties.setProperty(KEY_AI_LEVEL, String.valueOf(getAiLevel()));
|
||||
properties.setProperty(KEY_AI_TYPE, getAiType().name());
|
||||
saveProperties(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadProperties() {
|
||||
final Properties properties = loadPlayerProperties();
|
||||
extraLife = Integer.parseInt(properties.getProperty(KEY_EXTRA_LIFE, Integer.toString(DEFAULT_EXTRA_LIFE)));
|
||||
aiLevel = Integer.parseInt(properties.getProperty(KEY_AI_LEVEL, Integer.toString(DEFAULT_AI_LEVEL)));
|
||||
aiType = MagicAIImpl.valueOf(properties.getProperty(KEY_AI_TYPE, DEFAULT_AI_TYPE.name()));
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* @see magic.model.player.PlayerProfile#getPlayerType()
|
||||
*/
|
||||
@Override
|
||||
protected String getPlayerType() {
|
||||
return PLAYER_TYPE;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package magic.model.player;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
public class HumanPlayer extends PlayerProfile {
|
||||
|
||||
private static final String PLAYER_TYPE = "human";
|
||||
|
||||
public HumanPlayer(final String profileId) {
|
||||
super(profileId);
|
||||
loadProperties();
|
||||
}
|
||||
public HumanPlayer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
saveProperties(new Properties());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void loadProperties() {
|
||||
loadPlayerProperties();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.model.player.PlayerProfile#getPlayerType()
|
||||
*/
|
||||
@Override
|
||||
protected String getPlayerType() {
|
||||
return PLAYER_TYPE;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package magic.model.player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
|
||||
import magic.MagicMain;
|
||||
import magic.data.FileIO;
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicGameReport;
|
||||
import magic.ui.theme.PlayerAvatar;
|
||||
|
||||
public abstract class PlayerProfile {
|
||||
|
||||
private static String lastId = "";
|
||||
|
||||
private Path profilePath = null;
|
||||
private String playerName = "";
|
||||
private PlayerStatistics stats;
|
||||
private PlayerAvatar avatar;
|
||||
|
||||
abstract protected void loadProperties();
|
||||
abstract public void save();
|
||||
abstract protected String getPlayerType();
|
||||
|
||||
protected PlayerProfile(final String profileId) {
|
||||
setProfilePath(profileId == null ? PlayerProfile.getNewPlayerProfileId() : profileId);
|
||||
loadStats();
|
||||
loadAvatar();
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return profilePath.getFileName().toString();
|
||||
}
|
||||
|
||||
private void setProfilePath(final String profileId) {
|
||||
profilePath = Paths.get(MagicMain.getPlayerProfilesPath()).resolve(getPlayerType());
|
||||
verifyProfilePath();
|
||||
profilePath = profilePath.resolve(profileId);
|
||||
}
|
||||
|
||||
private void verifyProfilePath() {
|
||||
if (!Files.exists(profilePath)) {
|
||||
try {
|
||||
Files.createDirectory(profilePath);
|
||||
} catch (IOException e) {
|
||||
MagicGameReport.reportException(Thread.currentThread(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void saveProperties(final Properties properties) {
|
||||
properties.setProperty("playerName", String.valueOf(getPlayerName()));
|
||||
final File file = new File(getProfilePath().resolve("player.profile").toString());
|
||||
verifyProfilePath();
|
||||
try {
|
||||
FileIO.toFile(file, properties, "Player profile settings");
|
||||
} catch (IOException e) {
|
||||
MagicGameReport.reportException(Thread.currentThread(), e);
|
||||
}
|
||||
}
|
||||
|
||||
protected Properties loadPlayerProperties() {
|
||||
final File propertiesFile = new File(getProfilePath().resolve("player.profile").toString());
|
||||
final Properties properties = propertiesFile.exists() ? FileIO.toProp(propertiesFile) : new Properties();
|
||||
playerName = properties.getProperty("playerName", "");
|
||||
return properties;
|
||||
}
|
||||
|
||||
public Path getProfilePath() {
|
||||
return profilePath;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
public void setPlayerName(final String playerName) {
|
||||
this.playerName = playerName == null ? "" : playerName;
|
||||
}
|
||||
|
||||
public PlayerStatistics getStats() {
|
||||
return stats;
|
||||
}
|
||||
|
||||
public PlayerAvatar getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
private void loadAvatar() {
|
||||
final File file = new File(profilePath.resolve("player.avatar").toString());
|
||||
if (file.exists()) {
|
||||
avatar = new PlayerAvatar(FileIO.toImg(file, IconImages.MISSING));
|
||||
} else {
|
||||
avatar = new PlayerAvatar(IconImages.MISSING);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadStats() {
|
||||
stats = new PlayerStatistics(this);
|
||||
}
|
||||
|
||||
public static String getNewPlayerProfileId() {
|
||||
String id = Long.toHexString(System.currentTimeMillis()).toUpperCase();
|
||||
while (id.equals(lastId)) {
|
||||
// wait a bit in order to generate a unique id based on current time.
|
||||
// required because currentTimeMillis() granularity dependent on OS.
|
||||
sleep(100);
|
||||
id = Long.toHexString(System.currentTimeMillis()).toUpperCase();
|
||||
}
|
||||
lastId = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
private static void sleep(final long milliseconds) {
|
||||
try {
|
||||
Thread.sleep(milliseconds);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerProfile getHumanPlayer(final String playerId) {
|
||||
if (playerId != null && PlayerProfiles.getPlayerProfile(playerId) != null) {
|
||||
return new HumanPlayer(playerId);
|
||||
} else {
|
||||
return PlayerProfiles.getDefaultHumanPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerProfile getAiPlayer(final String playerId) {
|
||||
if (playerId != null && PlayerProfiles.getPlayerProfile(playerId) != null) {
|
||||
return new AiPlayer(playerId);
|
||||
} else {
|
||||
return PlayerProfiles.getDefaultAiPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,179 @@
|
|||
package magic.model.player;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.DirectoryStream.Filter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import magic.MagicMain;
|
||||
import magic.ai.MagicAIImpl;
|
||||
import magic.model.MagicGameReport;
|
||||
|
||||
public final class PlayerProfiles {
|
||||
private PlayerProfiles() {}
|
||||
|
||||
// default AI avatars.
|
||||
private static final Path AVATARS_PATH = Paths.get(MagicMain.getAvatarSetsPath());
|
||||
private static final Path AVATAR_LesVegas = AVATARS_PATH.resolve("tux").resolve("tux25.png");
|
||||
private static final Path AVATAR_MontyCarlo = AVATARS_PATH.resolve("default").resolve("face09.png");
|
||||
private static final Path AVATAR_MiniMax = AVATARS_PATH.resolve("default").resolve("face18.png");
|
||||
|
||||
private static final Path profilesPath = Paths.get(MagicMain.getPlayerProfilesPath());
|
||||
private static final HashMap<String, PlayerProfile> profilesMap = new HashMap<String, PlayerProfile>();
|
||||
|
||||
public static void refreshMap() {
|
||||
setProfilesMap();
|
||||
}
|
||||
|
||||
private static void setProfilesMap() {
|
||||
profilesMap.clear();
|
||||
// Humans
|
||||
for (Path path : getProfilePaths("human")) {
|
||||
final String profileId = path.getFileName().toString();
|
||||
final HumanPlayer player = new HumanPlayer(profileId);
|
||||
profilesMap.put(profileId, player);
|
||||
}
|
||||
// AIs
|
||||
for (Path path : getProfilePaths("ai")) {
|
||||
final String profileId = path.getFileName().toString();
|
||||
final AiPlayer player = new AiPlayer(profileId);
|
||||
profilesMap.put(profileId, player);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Path> getProfilePaths(final String playerType) {
|
||||
final Path playersPath = profilesPath.resolve(playerType);
|
||||
List<Path> profilePaths = getDirectoryPaths(playersPath);
|
||||
if (profilePaths.size() == 0) {
|
||||
try {
|
||||
if (playerType.equals("human")) {
|
||||
createDefaultHumanPlayerProfiles();
|
||||
} else {
|
||||
createDefaultAiPlayerProfiles();
|
||||
}
|
||||
profilePaths = getDirectoryPaths(playersPath);
|
||||
} catch (IOException e) {
|
||||
MagicGameReport.reportException(Thread.currentThread(), e);
|
||||
}
|
||||
}
|
||||
return profilePaths;
|
||||
}
|
||||
|
||||
private static List<Path> getDirectoryPaths(final Path rootPath) {
|
||||
final List<Path> paths = new ArrayList<Path>();
|
||||
if (Files.exists(rootPath)) {
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(rootPath, new DirectoriesFilter())) {
|
||||
for (Path p : ds) {
|
||||
paths.add(p.getFileName());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
private static class DirectoriesFilter implements Filter<Path> {
|
||||
@Override
|
||||
public boolean accept(Path entry) throws IOException {
|
||||
return Files.isDirectory(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private static void createDefaultHumanPlayerProfiles() throws IOException {
|
||||
final HumanPlayer profile = new HumanPlayer();
|
||||
profile.setPlayerName(getDefaultPlayerProfileName());
|
||||
profile.save();
|
||||
}
|
||||
|
||||
private static String getDefaultPlayerProfileName() {
|
||||
final String systemUserName = System.getProperty("user.name");
|
||||
return systemUserName == null ? "Player" : systemUserName;
|
||||
|
||||
}
|
||||
|
||||
private static void createDefaultAiPlayerProfiles() throws IOException {
|
||||
// Les Vegas
|
||||
AiPlayer profile = new AiPlayer();
|
||||
profile.setPlayerName("Les Vegas");
|
||||
profile.setAiType(MagicAIImpl.VEGAS);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
setPlayerAvatar(profile, PlayerProfiles.AVATAR_LesVegas);
|
||||
// Mini Max
|
||||
profile = new AiPlayer();
|
||||
profile.setPlayerName("Mini Max");
|
||||
profile.setAiType(MagicAIImpl.MMAB);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
setPlayerAvatar(profile, PlayerProfiles.AVATAR_MiniMax);
|
||||
// Monty Carlo
|
||||
profile = new AiPlayer();
|
||||
profile.setPlayerName("Monty Carlo");
|
||||
profile.setAiType(MagicAIImpl.MCTS);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
setPlayerAvatar(profile, PlayerProfiles.AVATAR_MontyCarlo);
|
||||
}
|
||||
|
||||
public static void setPlayerAvatar(final PlayerProfile profile, final Path avatarPath) {
|
||||
final Path targetPath = profile.getProfilePath().resolve("player.avatar");
|
||||
try {
|
||||
Files.copy(avatarPath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PlayerProfile getDefaultHumanPlayer() {
|
||||
return getHumanPlayerProfiles().values().iterator().next();
|
||||
}
|
||||
|
||||
public static PlayerProfile getDefaultAiPlayer() {
|
||||
return getAiPlayerProfiles().values().iterator().next();
|
||||
}
|
||||
|
||||
public static HashMap<String, PlayerProfile> getHumanPlayerProfiles() {
|
||||
final HashMap<String, PlayerProfile> filteredProfiles = new HashMap<String, PlayerProfile>();
|
||||
final Iterator<PlayerProfile> itr = profilesMap.values().iterator();
|
||||
while (itr.hasNext()) {
|
||||
final PlayerProfile profile = itr.next();
|
||||
if (profile instanceof HumanPlayer) {
|
||||
filteredProfiles.put(profile.getId(), profile);
|
||||
}
|
||||
}
|
||||
return filteredProfiles;
|
||||
}
|
||||
|
||||
public static HashMap<String, PlayerProfile> getAiPlayerProfiles() {
|
||||
final HashMap<String, PlayerProfile> filteredProfiles = new HashMap<String, PlayerProfile>();
|
||||
final Iterator<PlayerProfile> itr = profilesMap.values().iterator();
|
||||
while (itr.hasNext()) {
|
||||
final PlayerProfile profile = itr.next();
|
||||
if (profile instanceof AiPlayer) {
|
||||
filteredProfiles.put(profile.getId(), profile);
|
||||
}
|
||||
}
|
||||
return filteredProfiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param duelConfigId
|
||||
* @return
|
||||
*/
|
||||
public static PlayerProfile getPlayerProfile(String duelConfigId) {
|
||||
return profilesMap.get(duelConfigId);
|
||||
}
|
||||
|
||||
public static HashMap<String, PlayerProfile> getPlayerProfiles() {
|
||||
return profilesMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
package magic.model.player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Properties;
|
||||
|
||||
import magic.data.FileIO;
|
||||
import magic.model.MagicCardDefinition;
|
||||
import magic.model.MagicColor;
|
||||
import magic.model.MagicDeck;
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
|
||||
public class PlayerStatistics {
|
||||
|
||||
private static final String TIMESTAMP = "timestamp";
|
||||
private static final String GAMES_PLAYED = "gamesPlayed";
|
||||
private static final String GAMES_WON = "gamesWon";
|
||||
private static final String GAMES_CONCEDED = "gamesConceded";
|
||||
private static final String DUELS_PLAYED = "duelsPlayed";
|
||||
private static final String DUELS_WON = "duelsWon";
|
||||
private static final String TURNS_PLAYED = "turnsPlayed";
|
||||
private static final String COLOR_BLACK = "colorBlack";
|
||||
private static final String COLOR_BLUE = "colorBlue";
|
||||
private static final String COLOR_GREEN = "colorGreen";
|
||||
private static final String COLOR_RED = "colorRed";
|
||||
private static final String COLOR_WHITE = "colorWhite";
|
||||
|
||||
private long millisecTimestamp;
|
||||
private final Path statsFilePath;
|
||||
private final PlayerProfile playerProfile;
|
||||
|
||||
public int gamesPlayed;
|
||||
public int gamesWon;
|
||||
public int gamesConceded;
|
||||
public int turnsPlayed;
|
||||
public int duelsPlayed;
|
||||
public int duelsWon;
|
||||
public int colorBlack;
|
||||
public int colorBlue;
|
||||
public int colorGreen;
|
||||
public int colorRed;
|
||||
public int colorWhite;
|
||||
|
||||
public PlayerStatistics(final PlayerProfile playerProfile) {
|
||||
this.playerProfile = playerProfile;
|
||||
statsFilePath = playerProfile.getProfilePath().resolve("player.stats");
|
||||
loadStats();
|
||||
}
|
||||
|
||||
private void loadStats() {
|
||||
final File statsFile = new File(statsFilePath.toString());
|
||||
final Properties properties = statsFile.exists() ? FileIO.toProp(statsFile) : new Properties();
|
||||
gamesPlayed = Integer.parseInt(properties.getProperty(GAMES_PLAYED,"0"));
|
||||
gamesWon = Integer.parseInt(properties.getProperty(GAMES_WON,"0"));
|
||||
gamesConceded = Integer.parseInt(properties.getProperty(GAMES_CONCEDED,"0"));
|
||||
turnsPlayed = Integer.parseInt(properties.getProperty(TURNS_PLAYED,"0"));
|
||||
duelsPlayed = Integer.parseInt(properties.getProperty(DUELS_PLAYED,"0"));
|
||||
duelsWon = Integer.parseInt(properties.getProperty(DUELS_WON,"0"));
|
||||
colorBlack = Integer.parseInt(properties.getProperty(COLOR_BLACK,"0"));
|
||||
colorBlue = Integer.parseInt(properties.getProperty(COLOR_BLUE,"0"));
|
||||
colorGreen = Integer.parseInt(properties.getProperty(COLOR_GREEN,"0"));
|
||||
colorRed = Integer.parseInt(properties.getProperty(COLOR_RED,"0"));
|
||||
colorWhite = Integer.parseInt(properties.getProperty(COLOR_WHITE,"0"));
|
||||
millisecTimestamp = Long.parseLong(properties.getProperty(TIMESTAMP, "0"));
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
final Properties properties = new Properties();
|
||||
properties.setProperty(GAMES_PLAYED, String.valueOf(gamesPlayed));
|
||||
properties.setProperty(GAMES_WON, String.valueOf(gamesWon));
|
||||
properties.setProperty(GAMES_CONCEDED, String.valueOf(gamesConceded));
|
||||
properties.setProperty(TURNS_PLAYED, String.valueOf(turnsPlayed));
|
||||
properties.setProperty(DUELS_PLAYED, String.valueOf(duelsPlayed));
|
||||
properties.setProperty(DUELS_WON, String.valueOf(duelsWon));
|
||||
properties.setProperty(COLOR_BLACK, String.valueOf(colorBlack));
|
||||
properties.setProperty(COLOR_BLUE, String.valueOf(colorBlue));
|
||||
properties.setProperty(COLOR_GREEN, String.valueOf(colorGreen));
|
||||
properties.setProperty(COLOR_RED, String.valueOf(colorRed));
|
||||
properties.setProperty(COLOR_WHITE, String.valueOf(colorWhite));
|
||||
properties.setProperty(TIMESTAMP, String.valueOf(System.currentTimeMillis()));
|
||||
|
||||
final File file = new File(statsFilePath.toString());
|
||||
try {
|
||||
FileIO.toFile(file, properties, "Player Statistics");
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void update(
|
||||
final boolean isPlayerWinner,
|
||||
final MagicPlayer player,
|
||||
final MagicGame game) {
|
||||
|
||||
gamesPlayed++;
|
||||
|
||||
if (isPlayerWinner) {
|
||||
gamesWon++;
|
||||
}
|
||||
|
||||
if (!player.getPlayerDefinition().isArtificial()) {
|
||||
if (game.isConceded()) {
|
||||
gamesConceded++;
|
||||
}
|
||||
}
|
||||
|
||||
turnsPlayed += game.getTurn();
|
||||
if (game.getDuel().isFinished()) {
|
||||
duelsPlayed++;
|
||||
if (isPlayerWinner) {
|
||||
duelsWon++;
|
||||
}
|
||||
}
|
||||
|
||||
final int[] colorCount = new int[MagicColor.NR_COLORS];
|
||||
final MagicDeck deck = player.getPlayerDefinition().getDeck();
|
||||
for (final MagicCardDefinition card : deck) {
|
||||
if (!card.isLand()) {
|
||||
for (final MagicColor color : MagicColor.values()) {
|
||||
if (color.hasColor(card.getColorFlags())) {
|
||||
colorCount[color.ordinal()]++;
|
||||
switch (color) {
|
||||
case Black:
|
||||
colorBlack++;
|
||||
break;
|
||||
case Blue:
|
||||
colorBlue++;
|
||||
break;
|
||||
case Green:
|
||||
colorGreen++;
|
||||
break;
|
||||
case Red:
|
||||
colorRed++;
|
||||
break;
|
||||
case White:
|
||||
colorWhite++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
final int gamesLost = gamesPlayed - gamesWon;
|
||||
final int gamesWinPercentage = getPercentage(gamesWon, gamesPlayed);
|
||||
final int averageTurns = (gamesPlayed > 0) ? turnsPlayed / gamesPlayed : 0;
|
||||
final int duelsLost = duelsPlayed - duelsWon;
|
||||
final int duelsWinPercentage = getPercentage(duelsWon, duelsPlayed);
|
||||
|
||||
final int[] colorCount = new int[MagicColor.NR_COLORS];
|
||||
colorCount[0] = colorWhite;
|
||||
colorCount[1] = colorBlue;
|
||||
colorCount[2] = colorBlack;
|
||||
colorCount[3] = colorGreen;
|
||||
colorCount[4] = colorRed;
|
||||
int mostCount = Integer.MIN_VALUE;
|
||||
MagicColor mostColor = null;
|
||||
for (final MagicColor color : MagicColor.values()) {
|
||||
final int count = colorCount[color.ordinal()];
|
||||
if (count > mostCount) {
|
||||
mostCount = count;
|
||||
mostColor = color;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean showStatValues = (gamesPlayed > 0);
|
||||
final StatsFormatter f = new StatsFormatter(showStatValues);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(f.getStatLine("Last played:\t", f.getTimestampString(millisecTimestamp)));
|
||||
sb.append(f.getStatLine("\nDuels completed:\t", duelsPlayed));
|
||||
sb.append(f.getStatLine("\nDuels won / lost:\t", duelsWon, " / ", duelsLost, " (", duelsWinPercentage, "%)"));
|
||||
sb.append(f.getStatLine("\nGames played:\t", gamesPlayed));
|
||||
sb.append(f.getStatLine("\nGames won / lost\t", gamesWon, " / ", gamesLost, " (", gamesWinPercentage, "%)"));
|
||||
sb.append(f.getStatLine("\nGames conceded:\t", playerProfile instanceof HumanPlayer ? gamesConceded : StatsFormatter.NO_VALUE));
|
||||
sb.append(f.getStatLine("\nTurns played:\t", turnsPlayed));
|
||||
sb.append(f.getStatLine("\nAverage turns per game:\t", averageTurns));
|
||||
sb.append(f.getStatLine("\nMost used color:\t", mostColor.getName()));
|
||||
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
private static final int getPercentage(final int value, final int total) {
|
||||
return total>0 ? (value*100)/total : 0;
|
||||
}
|
||||
|
||||
public String getLastPlayed() {
|
||||
final StatsFormatter f = new StatsFormatter(gamesPlayed > 0);
|
||||
return f.getTimestampString(millisecTimestamp);
|
||||
}
|
||||
|
||||
private class StatsFormatter {
|
||||
|
||||
public static final String NO_VALUE = "---";
|
||||
|
||||
private final boolean showValues;
|
||||
|
||||
public StatsFormatter(final boolean showValues) {
|
||||
this.showValues = showValues;
|
||||
}
|
||||
|
||||
public String getStatLine(final String stat, final Object...values) {
|
||||
final StringBuilder sb = new StringBuilder(stat);
|
||||
if (showValues) {
|
||||
for (Object obj : values) {
|
||||
sb.append(obj);
|
||||
}
|
||||
} else {
|
||||
sb.append(NO_VALUE);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getTimestampString(final long millisecs) {
|
||||
if (millisecs > 0) {
|
||||
final Date timestampDate = new Date(millisecTimestamp);
|
||||
String timestampString = new SimpleDateFormat("yyyy-MM-dd").format(timestampDate);
|
||||
final String currentString = new SimpleDateFormat("yyyy-MM-dd").format(System.currentTimeMillis());
|
||||
if (timestampString.equals(currentString)) {
|
||||
timestampString = new SimpleDateFormat("HH:mm").format(timestampDate);
|
||||
}
|
||||
return timestampString;
|
||||
} else {
|
||||
return NO_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package magic.ui;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
import magic.data.IconImages;
|
||||
import magic.ui.theme.PlayerAvatar;
|
||||
|
||||
public class AvatarImageSet {
|
||||
|
||||
private final static String IMAGES_FILTER = "*.{png,jpg}";
|
||||
|
||||
private final Path path;
|
||||
private ImageIcon sampleImage = IconImages.MISSING_ICON;
|
||||
|
||||
public AvatarImageSet(final Path path) {
|
||||
this.path = path;
|
||||
loadSampleImage();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return path.getFileName().toString();
|
||||
}
|
||||
|
||||
public ImageIcon getSampleImage() {
|
||||
return sampleImage;
|
||||
}
|
||||
|
||||
private void loadSampleImage() {
|
||||
// find first image file in directory using a try-with-resource block for safety.
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(this.path, IMAGES_FILTER)) {
|
||||
final Iterator<Path> itr = ds.iterator();
|
||||
if (itr.hasNext()) {
|
||||
final String filePath = itr.next().toAbsolutePath().toString();
|
||||
final InputStream ins = new FileInputStream(new File(filePath));
|
||||
final BufferedImage image = magic.data.FileIO.toImg(ins, IconImages.MISSING);
|
||||
this.sampleImage = new ImageIcon(magic.ui.utility.GraphicsUtilities.scale(image, PlayerAvatar.MEDIUM_SIZE, PlayerAvatar.MEDIUM_SIZE));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Path> getImagePaths() {
|
||||
final List<Path> paths = new ArrayList<Path>();
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(this.path, IMAGES_FILTER)) {
|
||||
for (Path path : ds) {
|
||||
paths.add(path);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
package magic.ui;
|
||||
|
||||
import magic.data.IconImages;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class DuelDialog extends JDialog implements ActionListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final MagicFrame frame;
|
||||
private final JButton okButton;
|
||||
private final JButton cancelButton;
|
||||
private final DuelSetupPanel duelSetupPanel;
|
||||
|
||||
public DuelDialog(final MagicFrame frame) {
|
||||
|
||||
super(frame,true);
|
||||
this.frame=frame;
|
||||
this.setTitle("New duel");
|
||||
this.setSize(500,500);
|
||||
this.setLocationRelativeTo(frame);
|
||||
this.setResizable(false);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
|
||||
final JPanel buttonPanel=new JPanel();
|
||||
buttonPanel.setPreferredSize(new Dimension(0,45));
|
||||
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT,15,0));
|
||||
okButton=new JButton("OK");
|
||||
okButton.setFocusable(false);
|
||||
okButton.setIcon(IconImages.OK);
|
||||
okButton.addActionListener(this);
|
||||
buttonPanel.add(okButton);
|
||||
cancelButton=new JButton("Cancel");
|
||||
cancelButton.setFocusable(false);
|
||||
cancelButton.setIcon(IconImages.CANCEL);
|
||||
cancelButton.addActionListener(this);
|
||||
buttonPanel.add(cancelButton);
|
||||
|
||||
duelSetupPanel = new DuelSetupPanel();
|
||||
duelSetupPanel.setOpaque(false);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(duelSetupPanel,BorderLayout.CENTER);
|
||||
getContentPane().add(buttonPanel,BorderLayout.SOUTH);
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
|
||||
final Object source=event.getSource();
|
||||
if (source==okButton) {
|
||||
frame.newDuel(duelSetupPanel.getNewDuelConfig());
|
||||
dispose();
|
||||
} else if (source==cancelButton) {
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,32 +1,39 @@
|
|||
package magic.ui;
|
||||
|
||||
import magic.data.CardImagesProvider;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.model.MagicCardDefinition;
|
||||
import magic.model.MagicDeck;
|
||||
import magic.model.MagicDuel;
|
||||
import magic.model.MagicPlayerDefinition;
|
||||
import magic.ui.theme.Theme;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import magic.model.player.HumanPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.viewer.CardViewer;
|
||||
import magic.ui.viewer.DeckDescriptionViewer;
|
||||
import magic.ui.viewer.DeckStatisticsViewer;
|
||||
import magic.ui.viewer.DeckStrengthViewer;
|
||||
import magic.ui.viewer.DuelDifficultyViewer;
|
||||
import magic.ui.viewer.HistoryViewer;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.PlayerDetailsPanel;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SpringLayout;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
|
@ -40,7 +47,6 @@ public class DuelPanel extends TexturedPanel {
|
|||
private final MagicDuel duel;
|
||||
private final JTabbedPane tabbedPane;
|
||||
private final DeckStrengthViewer strengthViewer;
|
||||
private final HistoryViewer historyViewer;
|
||||
private final DeckDescriptionViewer[] deckDescriptionViewers;
|
||||
private final CardViewer cardViewer;
|
||||
private final DuelDifficultyViewer duelDifficultyViewer;
|
||||
|
@ -80,9 +86,6 @@ public class DuelPanel extends TexturedPanel {
|
|||
|
||||
// games won info
|
||||
duelDifficultyViewer=new DuelDifficultyViewer(duel);
|
||||
duelDifficultyViewer.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
duelDifficultyViewer.setMaximumSize(DuelDifficultyViewer.PREFERRED_SIZE);
|
||||
leftPanel.add(duelDifficultyViewer);
|
||||
|
||||
// add scrolling to left side
|
||||
final JScrollPane leftScrollPane = new JScrollPane(leftPanel);
|
||||
|
@ -94,7 +97,6 @@ public class DuelPanel extends TexturedPanel {
|
|||
|
||||
// create tabs for each player
|
||||
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
|
||||
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
|
||||
|
||||
final MagicPlayerDefinition[] players = duel.getPlayers();
|
||||
cardTables = new CardTable[players.length];
|
||||
|
@ -106,12 +108,16 @@ public class DuelPanel extends TexturedPanel {
|
|||
strengthViewer=new DeckStrengthViewer(duel);
|
||||
strengthViewer.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
|
||||
historyViewer = new HistoryViewer();
|
||||
historyViewer.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||
|
||||
for(int i = 0; i < players.length; i++) {
|
||||
|
||||
final MagicPlayerDefinition player = players[i];
|
||||
|
||||
if (player.isArtificial()) {
|
||||
player.setAvatar(duel.getConfiguration().getPlayerTwoProfile().getAvatar());
|
||||
} else {
|
||||
player.setAvatar(duel.getConfiguration().getPlayerOneProfile().getAvatar());
|
||||
}
|
||||
|
||||
// deck description
|
||||
deckDescriptionViewers[i] = new DeckDescriptionViewer();
|
||||
deckDescriptionViewers[i].setPlayer(player);
|
||||
|
@ -150,9 +156,6 @@ public class DuelPanel extends TexturedPanel {
|
|||
rightPanel.add(strengthViewer);
|
||||
rightPanel.add(Box.createVerticalStrut(SPACING));
|
||||
|
||||
rightPanel.add(historyViewer);
|
||||
rightPanel.add(Box.createVerticalStrut(SPACING));
|
||||
|
||||
// show card
|
||||
cardViewer.setCard(player.getDeck().get(0),0);
|
||||
}
|
||||
|
@ -201,7 +204,10 @@ public class DuelPanel extends TexturedPanel {
|
|||
-SPACING, SpringLayout.SOUTH, tabPanel);
|
||||
|
||||
// add as a tab
|
||||
tabbedPane.addTab(player.getName() + " ", theme.getAvatarIcon(player.getFace(), 2), tabPanel);
|
||||
tabbedPane.addTab(null, tabPanel);
|
||||
final DuelConfig duelConfig = duel.getConfiguration();
|
||||
final PlayerProfile profile = (i == 0 ? duelConfig.getPlayerOneProfile() : duelConfig.getPlayerTwoProfile());
|
||||
tabbedPane.setTabComponentAt(i, new PlayerPanel(profile));
|
||||
}
|
||||
|
||||
add(tabbedPane);
|
||||
|
@ -268,4 +274,33 @@ public class DuelPanel extends TexturedPanel {
|
|||
strengthViewer.halt();
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private class PlayerPanel extends JPanel {
|
||||
|
||||
public PlayerPanel(final PlayerProfile profile) {
|
||||
setLayout(new MigLayout("insets 0"));
|
||||
setOpaque(false);
|
||||
add(new JLabel(profile.getAvatar().getIcon(4)));
|
||||
add(new PlayerDetailsPanel(profile, Color.BLACK), "w 100%");
|
||||
add(getScoreLabel(getScore(profile)), "w 100%");
|
||||
setPreferredSize(new Dimension(250, 54));
|
||||
}
|
||||
|
||||
private int getScore(final PlayerProfile profile) {
|
||||
if (profile instanceof HumanPlayer) {
|
||||
return duel.getGamesWon();
|
||||
} else {
|
||||
return duel.getGamesPlayed() - duel.getGamesWon();
|
||||
}
|
||||
}
|
||||
|
||||
private JLabel getScoreLabel(final int score) {
|
||||
final JLabel lbl = new JLabel(Integer.toString(score));
|
||||
lbl.setFont(new Font("Dialog", Font.PLAIN, 24));
|
||||
lbl.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,315 +0,0 @@
|
|||
package magic.ui;
|
||||
|
||||
import magic.ai.MagicAIImpl;
|
||||
import magic.data.CubeDefinitions;
|
||||
import magic.data.DeckGenerators;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicColor;
|
||||
import magic.ui.theme.Theme;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.SliderPanel;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.ListCellRenderer;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class DuelSetupPanel extends TexturedPanel {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final String SEPARATOR = "----";
|
||||
|
||||
private final AvatarPanel avatarPanel;
|
||||
private final JTextField nameTextField;
|
||||
private final SliderPanel lifeSlider;
|
||||
private final SliderPanel handSlider;
|
||||
private final SliderPanel gameSlider;
|
||||
private final ColorsChooser playerColorsChooser;
|
||||
private final ColorsChooser opponentColorsChooser;
|
||||
private final JComboBox<String> cubeComboBox;
|
||||
private final JComboBox<String> aiComboBox;
|
||||
private final Theme theme;
|
||||
|
||||
public DuelSetupPanel() {
|
||||
|
||||
theme=ThemeFactory.getInstance().getCurrentTheme();
|
||||
|
||||
final DuelConfig config=DuelConfig.getInstance();
|
||||
config.load();
|
||||
|
||||
final JPanel mainPanel=new JPanel();
|
||||
mainPanel.setOpaque(false);
|
||||
mainPanel.setLayout(null);
|
||||
|
||||
nameTextField=new JTextField(config.getName());
|
||||
nameTextField.setPreferredSize(new Dimension(0,25));
|
||||
nameTextField.setBounds(35,20,120,25);
|
||||
mainPanel.add(nameTextField);
|
||||
|
||||
avatarPanel=new AvatarPanel(config.getAvatar());
|
||||
avatarPanel.setBounds(35,50,120,180);
|
||||
mainPanel.add(avatarPanel);
|
||||
avatarPanel.setOpaque(false);
|
||||
|
||||
lifeSlider=new SliderPanel("Life",theme.getIcon(Theme.ICON_LIFE),10,30,5,config.getStartLife());
|
||||
lifeSlider.setBounds(190,25,270,50);
|
||||
mainPanel.add(lifeSlider);
|
||||
lifeSlider.setOpaque(false);
|
||||
|
||||
handSlider=new SliderPanel("Hand",theme.getIcon(Theme.ICON_HAND),6,8,1,config.getHandSize());
|
||||
handSlider.setBounds(190,95,270,50);
|
||||
mainPanel.add(handSlider);
|
||||
handSlider.setOpaque(false);
|
||||
|
||||
gameSlider=new SliderPanel("Games",IconImages.NUMBER,3,11,2,config.getNrOfGames());
|
||||
gameSlider.setBounds(190,165,270,50);
|
||||
mainPanel.add(gameSlider);
|
||||
gameSlider.setOpaque(false);
|
||||
|
||||
playerColorsChooser=new ColorsChooser(config.getPlayerColors());
|
||||
playerColorsChooser.setBounds(55,255,130,50);
|
||||
mainPanel.add(playerColorsChooser);
|
||||
|
||||
final JLabel versusLabel=new JLabel("versus");
|
||||
versusLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
versusLabel.setFont(FontsAndBorders.FONT4);
|
||||
versusLabel.setBounds(185,255,120,50);
|
||||
mainPanel.add(versusLabel);
|
||||
|
||||
opponentColorsChooser=new ColorsChooser(config.getOpponentColors());
|
||||
opponentColorsChooser.setBounds(305,255,130,50);
|
||||
mainPanel.add(opponentColorsChooser);
|
||||
|
||||
final JLabel cubeLabel=new JLabel("Cube");
|
||||
cubeLabel.setIcon(IconImages.CUBE);
|
||||
cubeLabel.setBounds(55,330,80,25);
|
||||
mainPanel.add(cubeLabel);
|
||||
cubeComboBox=new JComboBox<String>(CubeDefinitions.getCubeNames());
|
||||
cubeComboBox.setFocusable(false);
|
||||
cubeComboBox.setBounds(135,330,300,25);
|
||||
cubeComboBox.setSelectedItem(config.getCube());
|
||||
mainPanel.add(cubeComboBox);
|
||||
|
||||
final JLabel aiLabel=new JLabel("AI");
|
||||
aiLabel.setBounds(55,365,80,25);
|
||||
aiLabel.setIcon(IconImages.DIFFICULTY);
|
||||
mainPanel.add(aiLabel);
|
||||
aiComboBox=new JComboBox<String>(MagicAIImpl.getNames());
|
||||
aiComboBox.setFocusable(false);
|
||||
aiComboBox.setBounds(135,365,300,25);
|
||||
aiComboBox.setSelectedItem(config.getAI());
|
||||
mainPanel.add(aiComboBox);
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(mainPanel,BorderLayout.CENTER);
|
||||
|
||||
}
|
||||
|
||||
private class AvatarPanel extends JPanel implements ActionListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final JLabel avatarLabel;
|
||||
private final JButton leftButton;
|
||||
private final JButton rightButton;
|
||||
private int avatar;
|
||||
|
||||
public AvatarPanel(final int avatar) {
|
||||
|
||||
this.avatar=avatar;
|
||||
|
||||
setLayout(new BorderLayout(0,5));
|
||||
|
||||
avatarLabel=new JLabel();
|
||||
avatarLabel.setIcon(theme.getAvatarIcon(avatar,3));
|
||||
add(avatarLabel,BorderLayout.CENTER);
|
||||
|
||||
final JPanel buttonPanel=new JPanel();
|
||||
buttonPanel.setLayout(new GridLayout(1,2,10,0));
|
||||
add(buttonPanel,BorderLayout.SOUTH);
|
||||
buttonPanel.setOpaque(false);
|
||||
|
||||
leftButton=new JButton(IconImages.LEFT);
|
||||
leftButton.setFocusable(false);
|
||||
leftButton.addActionListener(this);
|
||||
buttonPanel.add(leftButton,BorderLayout.WEST);
|
||||
|
||||
rightButton=new JButton(IconImages.RIGHT);
|
||||
rightButton.setFocusable(false);
|
||||
rightButton.addActionListener(this);
|
||||
buttonPanel.add(rightButton,BorderLayout.EAST);
|
||||
}
|
||||
|
||||
public int getAvatar() {
|
||||
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent event) {
|
||||
|
||||
final Object source=event.getSource();
|
||||
if (source==leftButton) {
|
||||
avatar--;
|
||||
if (avatar<0) {
|
||||
avatar=theme.getNumberOfAvatars()-1;
|
||||
}
|
||||
} else {
|
||||
avatar++;
|
||||
if (avatar==theme.getNumberOfAvatars()) {
|
||||
avatar=0;
|
||||
}
|
||||
}
|
||||
avatarLabel.setIcon(theme.getAvatarIcon(avatar,3));
|
||||
}
|
||||
}
|
||||
|
||||
private static class ColorsChooser extends JComboBox<String> implements ListCellRenderer<String> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String lastSelected;
|
||||
|
||||
public ColorsChooser(final String colors) {
|
||||
|
||||
setRenderer(this);
|
||||
|
||||
final Vector<String> items = new Vector<String>();
|
||||
items.add("bug");
|
||||
items.add("bur");
|
||||
items.add("buw");
|
||||
items.add("bgr");
|
||||
items.add("bgw");
|
||||
items.add("brw");
|
||||
items.add("ugw");
|
||||
items.add("ugr");
|
||||
items.add("urw");
|
||||
items.add("grw");
|
||||
items.add("***");
|
||||
items.add("bu");
|
||||
items.add("bg");
|
||||
items.add("br");
|
||||
items.add("bw");
|
||||
items.add("ug");
|
||||
items.add("ur");
|
||||
items.add("uw");
|
||||
items.add("gr");
|
||||
items.add("gw");
|
||||
items.add("rw");
|
||||
items.add("**");
|
||||
items.add("b");
|
||||
items.add("u");
|
||||
items.add("g");
|
||||
items.add("r");
|
||||
items.add("w");
|
||||
items.add("*");
|
||||
items.add("@");
|
||||
|
||||
if (DeckGenerators.getInstance().getNrGenerators() > 0) {
|
||||
items.add(SEPARATOR);
|
||||
for(final String generatorName : DeckGenerators.getInstance().getGeneratorNames()) {
|
||||
items.add(generatorName);
|
||||
}
|
||||
}
|
||||
|
||||
setModel(new DefaultComboBoxModel<String>(items));
|
||||
setSelectedItem(colors);
|
||||
lastSelected = colors;
|
||||
this.setFocusable(false);
|
||||
addActionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedItem() {
|
||||
return getItemAt(getSelectedIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
final JList<? extends String> list,
|
||||
final String selectedVal,
|
||||
final int index,
|
||||
final boolean isSelected,
|
||||
final boolean cellHasFocus) {
|
||||
if(selectedVal.equals(SEPARATOR)) {
|
||||
return new javax.swing.JSeparator(javax.swing.JSeparator.HORIZONTAL);
|
||||
} else if(DeckGenerators.getInstance().getGeneratorNames().contains(selectedVal)) {
|
||||
final JPanel panel=new JPanel(new GridLayout(1,1));
|
||||
panel.setBorder(FontsAndBorders.EMPTY_BORDER);
|
||||
if (isSelected) {
|
||||
panel.setBackground(Color.LIGHT_GRAY);
|
||||
}
|
||||
|
||||
final JLabel label = new JLabel(selectedVal, JLabel.CENTER);
|
||||
label.setFont(FontsAndBorders.FONT1);
|
||||
panel.add(label);
|
||||
|
||||
return panel;
|
||||
} else {
|
||||
final JPanel panel=new JPanel(new GridLayout(1,3));
|
||||
for (int i=0;i<selectedVal.length();i++) {
|
||||
|
||||
final char ch = selectedVal.charAt(i);
|
||||
final ImageIcon icon;
|
||||
switch (ch) {
|
||||
case '*': icon=IconImages.ANY; break;
|
||||
case '@': icon=IconImages.FOLDER; break;
|
||||
default: icon=MagicColor.getColor(ch).getIcon(); break;
|
||||
}
|
||||
panel.add(new JLabel(icon));
|
||||
}
|
||||
panel.setBorder(FontsAndBorders.EMPTY_BORDER);
|
||||
if (isSelected) {
|
||||
panel.setBackground(Color.LIGHT_GRAY);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final String tempItem = getSelectedItem();
|
||||
|
||||
if (SEPARATOR.equals(tempItem)) {
|
||||
// don't select separator
|
||||
setSelectedItem(lastSelected);
|
||||
} else {
|
||||
lastSelected = tempItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public DuelConfig getNewDuelConfig() {
|
||||
final DuelConfig config=DuelConfig.getInstance();
|
||||
final String playerColors=playerColorsChooser.getSelectedItem();
|
||||
final String opponentColors=opponentColorsChooser.getSelectedItem();
|
||||
config.setAvatar(avatarPanel.getAvatar());
|
||||
config.setName(nameTextField.getText());
|
||||
config.setStartLife(lifeSlider.getValue());
|
||||
config.setHandSize(handSlider.getValue());
|
||||
config.setNrOfGames(gameSlider.getValue());
|
||||
config.setPlayerColors(playerColors);
|
||||
config.setOpponentColors(opponentColors);
|
||||
config.setCube(cubeComboBox.getItemAt(cubeComboBox.getSelectedIndex()));
|
||||
config.setAI(aiComboBox.getItemAt(aiComboBox.getSelectedIndex()));
|
||||
config.save();
|
||||
return config;
|
||||
}
|
||||
}
|
|
@ -466,6 +466,7 @@ public class GameController implements ILogBookListener {
|
|||
public void concede() {
|
||||
if (!gameConceded.get() && !game.isFinished()) {
|
||||
game.setLosingPlayer(game.getPlayer(0));
|
||||
game.setConceded(true);
|
||||
game.clearUndoPoints();
|
||||
gameConceded.set(true);
|
||||
resume(true);
|
||||
|
|
|
@ -12,21 +12,29 @@ import magic.model.MagicDeckConstructionRule;
|
|||
import magic.model.MagicDuel;
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicGameLog;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.choice.MulliganChoicePanel;
|
||||
import magic.ui.dialog.PreferencesDialog;
|
||||
import magic.ui.screen.AvatarImagesScreen;
|
||||
import magic.ui.screen.CardExplorerScreen;
|
||||
import magic.ui.screen.CardZoneScreen;
|
||||
import magic.ui.screen.DeckEditorScreen;
|
||||
import magic.ui.screen.DeckViewScreen;
|
||||
import magic.ui.screen.DuelDecksScreen;
|
||||
import magic.ui.screen.DuelGameScreen;
|
||||
import magic.ui.screen.DuelPlayersScreen;
|
||||
import magic.ui.screen.HelpMenuScreen;
|
||||
import magic.ui.screen.KeywordsScreen;
|
||||
import magic.ui.screen.AbstractScreen;
|
||||
import magic.ui.screen.MulliganScreen;
|
||||
import magic.ui.screen.SampleHandScreen;
|
||||
import magic.ui.screen.SelectAiPlayerScreen;
|
||||
import magic.ui.screen.SelectHumanPlayerScreen;
|
||||
import magic.ui.screen.SettingsMenuScreen;
|
||||
import magic.ui.screen.MainMenuScreen;
|
||||
import magic.ui.screen.ReadmeScreen;
|
||||
import magic.ui.screen.interfaces.IAvatarImageConsumer;
|
||||
import magic.ui.screen.interfaces.IPlayerProfileConsumer;
|
||||
import magic.ui.utility.GraphicsUtilities;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
|
@ -100,6 +108,18 @@ public class MagicFrame extends JFrame {
|
|||
//
|
||||
// The various (Mag)screens that can currently be displayed.
|
||||
//
|
||||
public void showDuelPlayersScreen() {
|
||||
activateMagScreen(new DuelPlayersScreen());
|
||||
}
|
||||
public void showSelectAiProfileScreen(final IPlayerProfileConsumer consumer, final PlayerProfile profile) {
|
||||
activateMagScreen(new SelectAiPlayerScreen(consumer, profile));
|
||||
}
|
||||
public void showAvatarImagesScreen(final IAvatarImageConsumer consumer) {
|
||||
activateMagScreen(new AvatarImagesScreen(consumer));
|
||||
}
|
||||
public void showSelectHumanPlayerScreen(final IPlayerProfileConsumer consumer, final PlayerProfile profile) {
|
||||
activateMagScreen(new SelectHumanPlayerScreen(consumer, profile));
|
||||
}
|
||||
public void showDeckView(final MagicDeck deck) {
|
||||
activateMagScreen(new DeckViewScreen(deck));
|
||||
}
|
||||
|
@ -205,10 +225,6 @@ public class MagicFrame extends JFrame {
|
|||
}
|
||||
}
|
||||
|
||||
public void showNewDuelDialog() {
|
||||
new DuelDialog(this);
|
||||
}
|
||||
|
||||
public void newDuel(final DuelConfig configuration) {
|
||||
duel = new MagicDuel(configuration);
|
||||
duel.initialize();
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package magic.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Insets;
|
||||
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* FlowLayout subclass that fully supports wrapping of components.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class WrapLayout extends FlowLayout {
|
||||
/**
|
||||
* Constructs a new <code>WrapLayout</code> with a left
|
||||
* alignment and a default 5-unit horizontal and vertical gap.
|
||||
*/
|
||||
public WrapLayout() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new <code>FlowLayout</code> with the specified
|
||||
* alignment and a default 5-unit horizontal and vertical gap.
|
||||
* The value of the alignment argument must be one of
|
||||
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.CENTER</code>,
|
||||
* or <code>FlowLayout.RIGHT</code>.
|
||||
* @param align the alignment value
|
||||
*/
|
||||
public WrapLayout(int align) {
|
||||
super(align);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new flow layout manager with the indicated alignment
|
||||
* and the indicated horizontal and vertical gaps.
|
||||
* <p>
|
||||
* The value of the alignment argument must be one of
|
||||
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.CENTER</code>,
|
||||
* or <code>FlowLayout.RIGHT</code>.
|
||||
* @param align the alignment value
|
||||
* @param hgap the horizontal gap between components
|
||||
* @param vgap the vertical gap between components
|
||||
*/
|
||||
public WrapLayout(int align, int hgap, int vgap) {
|
||||
super(align, hgap, vgap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the preferred dimensions for this layout given the
|
||||
* <i>visible</i> components in the specified target container.
|
||||
* @param target the component which needs to be laid out
|
||||
* @return the preferred dimensions to lay out the
|
||||
* subcomponents of the specified container
|
||||
*/
|
||||
@Override
|
||||
public Dimension preferredLayoutSize(Container target) {
|
||||
return layoutSize(target, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum dimensions needed to layout the <i>visible</i>
|
||||
* components contained in the specified target container.
|
||||
* @param target the component which needs to be laid out
|
||||
* @return the minimum dimensions to lay out the
|
||||
* subcomponents of the specified container
|
||||
*/
|
||||
@Override
|
||||
public Dimension minimumLayoutSize(Container target) {
|
||||
Dimension minimum = layoutSize(target, false);
|
||||
minimum.width -= (getHgap() + 1);
|
||||
return minimum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum or preferred dimension needed to layout the target
|
||||
* container.
|
||||
*
|
||||
* @param target target to get layout size for
|
||||
* @param preferred should preferred size be calculated
|
||||
* @return the dimension to layout the target container
|
||||
*/
|
||||
private Dimension layoutSize(Container target, boolean preferred) {
|
||||
synchronized (target.getTreeLock()) {
|
||||
// Each row must fit with the width allocated to the container.
|
||||
// When the container width = 0, the preferred width of the container
|
||||
// has not yet been calculated so we use a width guaranteed to be less
|
||||
// than we need so that it gets recalculated later when the widget is
|
||||
// shown.
|
||||
|
||||
int hgap = getHgap();
|
||||
Insets insets = target.getInsets();
|
||||
int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
|
||||
int targetWidth = Math.max(horizontalInsetsAndGap, target.getSize().width);
|
||||
int maxWidth = targetWidth - horizontalInsetsAndGap;
|
||||
|
||||
// Fit components into the allowed width
|
||||
Dimension dim = new Dimension(0, 0);
|
||||
int rowWidth = 0;
|
||||
int rowHeight = 0;
|
||||
|
||||
final int nmembers = target.getComponentCount();
|
||||
for (int i = 0; i < nmembers; i++) {
|
||||
Component m = target.getComponent(i);
|
||||
|
||||
if (!m.isVisible()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
|
||||
|
||||
// can't add the component to current row. Start a new row if
|
||||
// there's at least one component in this row.
|
||||
if (0 < rowWidth && rowWidth + d.width > maxWidth) {
|
||||
addRow(dim, rowWidth, rowHeight);
|
||||
rowWidth = 0;
|
||||
rowHeight = 0;
|
||||
}
|
||||
|
||||
// Add a horizontal gap for all components after the first
|
||||
if (rowWidth != 0) {
|
||||
rowWidth += hgap;
|
||||
}
|
||||
|
||||
rowWidth += d.width;
|
||||
rowHeight = Math.max(rowHeight, d.height);
|
||||
}
|
||||
|
||||
// add last row
|
||||
addRow(dim, rowWidth, rowHeight);
|
||||
|
||||
dim.width += horizontalInsetsAndGap;
|
||||
dim.height += insets.top + insets.bottom + getVgap() * 2;
|
||||
|
||||
// When using a scroll pane or the DecoratedLookAndFeel we need to
|
||||
// make sure the preferred size is less than the size of the
|
||||
// target container so shrinking the container size works
|
||||
// correctly. Removing the horizontal gap is an easy way to do this.
|
||||
|
||||
Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
|
||||
|
||||
if (scrollPane != null) {
|
||||
dim.width -= (hgap + 1);
|
||||
}
|
||||
|
||||
return dim;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A new row has been completed. Use the dimensions of this row
|
||||
* to update the preferred size for the container.
|
||||
*
|
||||
* @param dim update the width and height when appropriate
|
||||
* @param rowWidth the width of the row to add
|
||||
* @param rowHeight the height of the row to add
|
||||
*/
|
||||
private void addRow(Dimension dim, int rowWidth, int rowHeight) {
|
||||
dim.width = Math.max(dim.width, rowWidth);
|
||||
|
||||
if (dim.height > 0) {
|
||||
dim.height += getVgap();
|
||||
}
|
||||
dim.height += rowHeight;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,163 @@
|
|||
package magic.ui.dialog;
|
||||
|
||||
import magic.ai.MagicAIImpl;
|
||||
import magic.model.player.AiPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.widget.SliderPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AiPropertiesDialog extends JDialog {
|
||||
|
||||
private AiPlayer playerProfile;
|
||||
private final JTextField playerNameTextField;
|
||||
private final SliderPanel aiLevelSliderPanel;
|
||||
private final SliderPanel lifeSliderPanel;
|
||||
private final JComboBox<MagicAIImpl> aiComboBox;
|
||||
|
||||
// CTR : edit an existing profile.
|
||||
public AiPropertiesDialog(final MagicFrame frame, final AiPlayer profile) {
|
||||
|
||||
super(frame, true);
|
||||
this.setTitle("AI Profile");
|
||||
this.setSize(300, 260);
|
||||
this.setLocationRelativeTo(frame);
|
||||
this.setResizable(false);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
|
||||
this.playerProfile = profile == null ? new AiPlayer() : profile;
|
||||
playerNameTextField = new JTextField(playerProfile.getPlayerName());
|
||||
lifeSliderPanel = new SliderPanel("Life+", null, 0, 10, 1, playerProfile.getExtraLife());
|
||||
aiLevelSliderPanel = new SliderPanel("AI Level", null, 1, 8, 1, playerProfile.getAiLevel());
|
||||
|
||||
aiComboBox = new JComboBox<MagicAIImpl>();
|
||||
aiComboBox.setModel(new DefaultComboBoxModel<MagicAIImpl>(MagicAIImpl.SUPPORTED_AIS));
|
||||
aiComboBox.setLightWeightPopupEnabled(false);
|
||||
aiComboBox.setFocusable(false);
|
||||
aiComboBox.setSelectedItem(playerProfile.getAiType());
|
||||
|
||||
getContentPane().setLayout(new MigLayout("insets 0, flowy", "", "[][45!]"));
|
||||
getContentPane().add(getDataPanel(), "w 100%, h 100%");
|
||||
getContentPane().add(getButtonPanel(), "w 100%, h 40!");
|
||||
|
||||
setEscapeKeyAction();
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
public AiPropertiesDialog(final MagicFrame frame) {
|
||||
this(frame, null);
|
||||
}
|
||||
|
||||
public PlayerProfile getPlayerProfile() {
|
||||
return playerProfile;
|
||||
}
|
||||
|
||||
private void setEscapeKeyAction() {
|
||||
JRootPane root = getRootPane();
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), "closeDialog");
|
||||
root.getActionMap().put("closeDialog", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JPanel getButtonPanel() {
|
||||
final JPanel buttonPanel = new JPanel(new MigLayout("alignx right"));
|
||||
buttonPanel.add(getSaveButton(), "w 80!");
|
||||
buttonPanel.add(getCancelButton(), "w 80!");
|
||||
return buttonPanel;
|
||||
}
|
||||
|
||||
private JButton getCancelButton() {
|
||||
final JButton btn = new JButton("Cancel");
|
||||
btn.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
playerProfile = null;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
|
||||
private JButton getSaveButton() {
|
||||
final JButton btn = new JButton("Save");
|
||||
btn.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (isPlayerNameValid()) {
|
||||
savePlayerProfile();
|
||||
dispose();
|
||||
}
|
||||
}
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
|
||||
private boolean isPlayerNameValid() {
|
||||
final String newName = playerNameTextField.getText().trim();
|
||||
return !newName.isEmpty();
|
||||
}
|
||||
|
||||
private void savePlayerProfile() {
|
||||
playerProfile.setPlayerName(getVerifiedPlayerName(this.playerNameTextField.getText(), playerProfile.getPlayerName()));
|
||||
playerProfile.setExtraLife(lifeSliderPanel.getValue());
|
||||
playerProfile.setAiLevel(aiLevelSliderPanel.getValue());
|
||||
playerProfile.setAiType((MagicAIImpl)aiComboBox.getSelectedItem());
|
||||
playerProfile.save();
|
||||
}
|
||||
|
||||
private String getVerifiedPlayerName(String newName, String oldName) {
|
||||
if (newName == null) {
|
||||
newName = oldName;
|
||||
} else {
|
||||
newName = newName.trim();
|
||||
if (newName == null || newName.isEmpty() || newName.equalsIgnoreCase(oldName) ) {
|
||||
newName = oldName;
|
||||
}
|
||||
}
|
||||
return newName;
|
||||
}
|
||||
|
||||
private JPanel getDataPanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("flowy"));
|
||||
panel.add(getPlayerNamePanel(), "w 100%");
|
||||
panel.add(getAiTypePanel(), "w 100%");
|
||||
panel.add(lifeSliderPanel, "w 100%");
|
||||
panel.add(aiLevelSliderPanel, "w 100%");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel getAiTypePanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout());
|
||||
panel.add(new JLabel("AI Type:"));
|
||||
panel.add(aiComboBox, "w 100%, left");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel getPlayerNamePanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout());
|
||||
panel.add(new JLabel("AI Name:"));
|
||||
panel.add(playerNameTextField, "w 100%, left");
|
||||
return panel;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package magic.ui.dialog;
|
||||
|
||||
import magic.data.CubeDefinitions;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.widget.SliderPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.KeyStroke;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DuelPropertiesDialog extends JDialog {
|
||||
|
||||
private final SliderPanel handSizeSliderPanel;
|
||||
private final SliderPanel lifeSliderPanel;
|
||||
private final SliderPanel winsSliderPanel;
|
||||
private final JComboBox<String> cubeComboBox;
|
||||
private boolean isCancelled = false;
|
||||
|
||||
// CTR : edit an existing profile.
|
||||
public DuelPropertiesDialog(
|
||||
final MagicFrame frame,
|
||||
final int handSize,
|
||||
final int initialLife,
|
||||
final int maxGames,
|
||||
final String cube) {
|
||||
|
||||
super(frame, true);
|
||||
this.setTitle("Duel Properties");
|
||||
this.setSize(300, 280);
|
||||
this.setLocationRelativeTo(frame);
|
||||
this.setResizable(false);
|
||||
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||
|
||||
lifeSliderPanel = new SliderPanel("Initial life:", null, 10, 30, 5, initialLife);
|
||||
handSizeSliderPanel = new SliderPanel("Hand size:", null, 6, 8, 1, handSize);
|
||||
winsSliderPanel = new SliderPanel("Max. games:", null, 1, 11, 2, maxGames);
|
||||
|
||||
cubeComboBox = new JComboBox<String>(CubeDefinitions.getCubeNames());
|
||||
cubeComboBox.setLightWeightPopupEnabled(false);
|
||||
cubeComboBox.setFocusable(false);
|
||||
cubeComboBox.setSelectedItem(cube);
|
||||
|
||||
getContentPane().setLayout(new MigLayout("flowy", "", "[][45!]"));
|
||||
getContentPane().add(lifeSliderPanel, "w 100%");
|
||||
getContentPane().add(handSizeSliderPanel, "w 100%");
|
||||
getContentPane().add(winsSliderPanel, "w 100%");
|
||||
getContentPane().add(getCubePanel(), "w 100%");
|
||||
getContentPane().add(getButtonPanel(), "w 100%, h 40!");
|
||||
|
||||
setEscapeKeyAction();
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private JPanel getCubePanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout());
|
||||
panel.add(new JLabel("Cube:"));
|
||||
panel.add(cubeComboBox, "w 100%");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void setEscapeKeyAction() {
|
||||
JRootPane root = getRootPane();
|
||||
root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), "closeDialog");
|
||||
root.getActionMap().put("closeDialog", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JPanel getButtonPanel() {
|
||||
final JPanel buttonPanel = new JPanel(new MigLayout("alignx right"));
|
||||
buttonPanel.add(getSaveButton(), "w 80!");
|
||||
buttonPanel.add(getCancelButton(), "w 80!");
|
||||
return buttonPanel;
|
||||
}
|
||||
|
||||
private JButton getCancelButton() {
|
||||
final JButton btn = new JButton("Cancel");
|
||||
btn.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
isCancelled = true;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
|
||||
private JButton getSaveButton() {
|
||||
final JButton btn = new JButton("Save");
|
||||
btn.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
|
||||
public boolean isCancelled() {
|
||||
return isCancelled;
|
||||
}
|
||||
|
||||
public int getStartLife() {
|
||||
return lifeSliderPanel.getValue();
|
||||
}
|
||||
|
||||
public int getHandSize() {
|
||||
return handSizeSliderPanel.getValue();
|
||||
}
|
||||
|
||||
public int getNrOfGames() {
|
||||
return winsSliderPanel.getValue();
|
||||
}
|
||||
|
||||
public String getCube() {
|
||||
return cubeComboBox.getItemAt(cubeComboBox.getSelectedIndex());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
package magic.ui;
|
||||
package magic.ui.dialog;
|
||||
|
||||
import magic.data.AvatarImages;
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.data.IconImages;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import magic.ui.widget.SliderPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
@ -37,7 +37,6 @@ public class PreferencesDialog extends JDialog implements ActionListener {
|
|||
|
||||
private final MagicFrame frame;
|
||||
private JComboBox<String> themeComboBox;
|
||||
private JComboBox<String> avatarComboBox;
|
||||
private JComboBox<String> highlightComboBox;
|
||||
private JCheckBox confirmExitCheckBox;
|
||||
private JCheckBox soundCheckBox;
|
||||
|
@ -229,17 +228,6 @@ public class PreferencesDialog extends JDialog implements ActionListener {
|
|||
themeComboBox.setSelectedItem(config.getTheme());
|
||||
panel.add(themeComboBox);
|
||||
|
||||
Y += 35;
|
||||
final JLabel avatarLabel=new JLabel("Avatar");
|
||||
avatarLabel.setBounds(X,Y,W,H);
|
||||
avatarLabel.setIcon(IconImages.AVATAR);
|
||||
panel.add(avatarLabel);
|
||||
avatarComboBox=new JComboBox<String>(AvatarImages.getInstance().getNames());
|
||||
avatarComboBox.setFocusable(false);
|
||||
avatarComboBox.setBounds(X2,Y,W2,H);
|
||||
avatarComboBox.setSelectedItem(config.getAvatar());
|
||||
panel.add(avatarComboBox);
|
||||
|
||||
Y += 35;
|
||||
final JLabel highlightLabel = new JLabel("Highlight");
|
||||
highlightLabel.setBounds(X,Y,W,H);
|
||||
|
@ -288,7 +276,6 @@ public class PreferencesDialog extends JDialog implements ActionListener {
|
|||
if (source==okButton) {
|
||||
final GeneralConfig config=GeneralConfig.getInstance();
|
||||
config.setTheme(themeComboBox.getItemAt(themeComboBox.getSelectedIndex()));
|
||||
config.setAvatar(avatarComboBox.getItemAt(avatarComboBox.getSelectedIndex()));
|
||||
config.setHighlight(highlightComboBox.getItemAt(highlightComboBox.getSelectedIndex()));
|
||||
config.setConfirmExit(confirmExitCheckBox.isSelected());
|
||||
config.setSound(soundCheckBox.isSelected());
|
|
@ -32,6 +32,7 @@ public abstract class AbstractScreen extends JPanel {
|
|||
|
||||
private JPanel content;
|
||||
private final MagicFrame frame;
|
||||
private ActionBar actionbar;
|
||||
|
||||
// CTR
|
||||
public AbstractScreen() {
|
||||
|
@ -41,13 +42,19 @@ public abstract class AbstractScreen extends JPanel {
|
|||
setEscapeKeyInputMap();
|
||||
}
|
||||
|
||||
protected void refreshActionBar() {
|
||||
actionbar.refreshLayout();
|
||||
}
|
||||
|
||||
protected void setContent(final JPanel content) {
|
||||
this.content = content;
|
||||
doMagScreenLayout();
|
||||
doMigLayout();
|
||||
revalidate();
|
||||
repaint();
|
||||
setBusy(false);
|
||||
}
|
||||
|
||||
private void doMagScreenLayout() {
|
||||
private void doMigLayout() {
|
||||
removeAll();
|
||||
setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
||||
layoutMagStatusBar();
|
||||
|
@ -63,7 +70,8 @@ public abstract class AbstractScreen extends JPanel {
|
|||
|
||||
private void layoutMagActionBar() {
|
||||
if (hasActionBar()) {
|
||||
add(new ActionBar((IActionBar)this), "w 100%");
|
||||
this.actionbar = new ActionBar((IActionBar)this);
|
||||
add(actionbar, "w 100%");
|
||||
} else if (!(this instanceof DuelGameScreen)) {
|
||||
add(getKeysStrip(), "w 100%");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,358 @@
|
|||
package magic.ui.screen;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.DirectoryStream.Filter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import magic.MagicMain;
|
||||
import magic.data.IconImages;
|
||||
import magic.data.URLUtils;
|
||||
import magic.ui.AvatarImageSet;
|
||||
import magic.ui.WrapLayout;
|
||||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.screen.interfaces.IAvatarImageConsumer;
|
||||
import magic.ui.screen.interfaces.IStatusBar;
|
||||
import magic.ui.screen.widget.ActionBarButton;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.theme.PlayerAvatar;
|
||||
import magic.ui.utility.GraphicsUtilities;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AvatarImagesScreen
|
||||
extends AbstractScreen
|
||||
implements IStatusBar, IActionBar {
|
||||
|
||||
private JPanel viewer;
|
||||
private MenuButton rightActionButton = null;
|
||||
private JLabel selectedImageLabel = null;
|
||||
private final IAvatarImageConsumer consumer;
|
||||
private final Map<JLabel, Path> imagePathMap = new HashMap<JLabel, Path>();
|
||||
|
||||
public AvatarImagesScreen(final IAvatarImageConsumer consumer) {
|
||||
this.consumer = consumer;
|
||||
setContent(getScreenContent());
|
||||
}
|
||||
public AvatarImagesScreen() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
private JPanel getScreenContent() {
|
||||
// Layout content.
|
||||
final JPanel content = new JPanel(new MigLayout("insets 0, gap 0"));
|
||||
content.setOpaque(false);
|
||||
content.add(getAvatarImageSetsPanel(), "w 240!, h 100%");
|
||||
content.add(getAvatarImageSetViewer(), "w 100%, h 100%");
|
||||
return content;
|
||||
}
|
||||
|
||||
private JScrollPane getAvatarImageSetViewer() {
|
||||
|
||||
viewer = new TexturedPanel();
|
||||
viewer.setLayout(new WrapLayout());
|
||||
viewer.setBorder(FontsAndBorders.BLACK_BORDER);
|
||||
viewer.setBackground(FontsAndBorders.MAGSCREEN_FADE_COLOR);
|
||||
|
||||
final JScrollPane scroller = new JScrollPane(viewer);
|
||||
scroller.getViewport().setOpaque(false);
|
||||
scroller.setBorder(BorderFactory.createEmptyBorder());
|
||||
scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scroller.getVerticalScrollBar().setUnitIncrement(20);
|
||||
return scroller;
|
||||
}
|
||||
|
||||
private void displayImageSetIcons(final AvatarImageSet imageSet) {
|
||||
viewer.removeAll();
|
||||
imagePathMap.clear();
|
||||
for (Path imagePath : imageSet.getImagePaths()) {
|
||||
final String filePath = imagePath.toAbsolutePath().toString();
|
||||
try (final InputStream ins = new FileInputStream(new File(filePath))) {
|
||||
final BufferedImage image = magic.data.FileIO.toImg(ins, IconImages.MISSING);
|
||||
final ImageIcon icon = new ImageIcon(GraphicsUtilities.scale(image, PlayerAvatar.LARGE_SIZE, PlayerAvatar.LARGE_SIZE));
|
||||
final JLabel iconLabel = new JLabel(icon);
|
||||
imagePathMap.put(iconLabel, imagePath);
|
||||
iconLabel.setBorder(FontsAndBorders.EMPTY_BORDER);
|
||||
viewer.add(iconLabel);
|
||||
iconLabel.addMouseListener(new MouseAdapter() {
|
||||
private final Border defaultBorder = iconLabel.getBorder();
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
iconLabel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
|
||||
iconLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
iconLabel.setBorder(defaultBorder);
|
||||
}
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (e.getButton() == 1) {
|
||||
final JLabel imageLabel = (JLabel)e.getSource();
|
||||
if (imageLabel != selectedImageLabel) {
|
||||
setSelectedAvatar((JLabel)e.getSource());
|
||||
} else {
|
||||
notifyConsumer(imageLabel);
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
};
|
||||
}
|
||||
viewer.revalidate();
|
||||
viewer.repaint();
|
||||
}
|
||||
|
||||
private void setSelectedAvatar(final JLabel iconLabel) {
|
||||
final Icon icon = iconLabel.getIcon();
|
||||
final BufferedImage bi = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
|
||||
final Graphics g = bi.createGraphics();
|
||||
// paint the Icon to the BufferedImage.
|
||||
icon.paintIcon(null, g, 0,0);
|
||||
g.dispose();
|
||||
rightActionButton =
|
||||
new ActionBarButton(
|
||||
new ImageIcon(GraphicsUtilities.scale(bi, 46, 46)),
|
||||
"Select Avatar", "Click to select this avatar image.",
|
||||
new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
notifyConsumer(iconLabel);
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
|
||||
refreshActionBar();
|
||||
this.selectedImageLabel = iconLabel;
|
||||
}
|
||||
|
||||
private void notifyConsumer(final JLabel selectedLabel) {
|
||||
if (consumer != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
consumer.setSelectedAvatarPath(imagePathMap.get(selectedLabel));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private JPanel getAvatarImageSetsPanel() {
|
||||
|
||||
// List of avatar image sets.
|
||||
final JList<AvatarImageSet> imageSetsList = new JList<AvatarImageSet>(getAvatarImageSetsArray());
|
||||
imageSetsList.setOpaque(false);
|
||||
imageSetsList.addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (!e.getValueIsAdjusting()) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
displayImageSetIcons(imageSetsList.getSelectedValue());
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
imageSetsList.setSelectedIndex(0);
|
||||
|
||||
final ImageSetsListRenderer renderer = new ImageSetsListRenderer();
|
||||
imageSetsList.setCellRenderer(renderer);
|
||||
|
||||
final JScrollPane scrollPane = new JScrollPane();
|
||||
scrollPane.setViewportView(imageSetsList);
|
||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||
scrollPane.setOpaque(false);
|
||||
scrollPane.getViewport().setOpaque(false);
|
||||
|
||||
final JPanel container = new TexturedPanel();
|
||||
container.setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
||||
container.setBorder(FontsAndBorders.BLACK_BORDER);
|
||||
container.setBackground(FontsAndBorders.MENUPANEL_COLOR);
|
||||
container.add(scrollPane, "w 100%, h 100%");
|
||||
return container;
|
||||
|
||||
}
|
||||
|
||||
private AvatarImageSet[] getAvatarImageSetsArray() {
|
||||
final List<AvatarImageSet> imageSetsList = getAvatarImageSetsList();
|
||||
return imageSetsList.toArray(new AvatarImageSet[imageSetsList.size()]);
|
||||
}
|
||||
|
||||
private List<AvatarImageSet> getAvatarImageSetsList() {
|
||||
final List<AvatarImageSet> imageSets = new ArrayList<AvatarImageSet>();
|
||||
List<Path> directoryPaths = getDirectoryPaths(MagicMain.getAvatarSetsPath());
|
||||
for (Path path : directoryPaths) {
|
||||
imageSets.add(loadImageSet(path));
|
||||
}
|
||||
return imageSets;
|
||||
}
|
||||
|
||||
private AvatarImageSet loadImageSet(final Path imageSetDirectory) {
|
||||
final AvatarImageSet imageSet = new AvatarImageSet(imageSetDirectory);
|
||||
return imageSet;
|
||||
}
|
||||
|
||||
private List<Path> getDirectoryPaths(final String rootDirectory) {
|
||||
final List<Path> paths = new ArrayList<Path>();
|
||||
try (DirectoryStream<Path> ds =
|
||||
Files.newDirectoryStream(
|
||||
FileSystems.getDefault().getPath(rootDirectory),
|
||||
new DirectoriesOnlyFilter())) {
|
||||
for (Path p : ds) {
|
||||
paths.add(p);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
private static class DirectoriesOnlyFilter implements Filter<Path> {
|
||||
@Override
|
||||
public boolean accept(Path entry) throws IOException {
|
||||
return Files.isDirectory(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private class ImageSetsListRenderer extends JLabel implements ListCellRenderer<AvatarImageSet> {
|
||||
|
||||
public ImageSetsListRenderer() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean)
|
||||
*/
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends AvatarImageSet> list, AvatarImageSet value, int index,
|
||||
boolean isSelected, boolean cellHasFocus) {
|
||||
|
||||
final Color foreColor = isSelected ? Color.YELLOW : Color.WHITE;
|
||||
|
||||
final JLabel setNameLabel = new JLabel(value.getName());
|
||||
setNameLabel.setFont(FontsAndBorders.FONT2);
|
||||
setNameLabel.setForeground(foreColor);
|
||||
setNameLabel.setVerticalAlignment(SwingConstants.TOP);
|
||||
|
||||
final JPanel infoPanel = new JPanel(new MigLayout("insets 0, gap 0, flowy"));
|
||||
infoPanel.setOpaque(false);
|
||||
infoPanel.setForeground(foreColor);
|
||||
infoPanel.add(setNameLabel, "w 100%, gapbottom 4");
|
||||
|
||||
final JPanel itemPanel = new JPanel(new MigLayout("insets 0 0 0 6, gap 0"));
|
||||
itemPanel.setPreferredSize(new Dimension(0, 70));
|
||||
itemPanel.setOpaque(false);
|
||||
itemPanel.setForeground(foreColor);
|
||||
itemPanel.setBorder(isSelected ? BorderFactory.createLineBorder(Color.YELLOW, 1) : null);
|
||||
itemPanel.add(new JLabel(value.getSampleImage()), "w 70!, h 70!");
|
||||
itemPanel.add(infoPanel, "w 100%");
|
||||
return itemPanel;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagStatusBar#getScreenCaption()
|
||||
*/
|
||||
@Override
|
||||
public String getScreenCaption() {
|
||||
return "Avatars";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getLeftAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getLeftAction() {
|
||||
return new MenuButton("Cancel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getRightAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getRightAction() {
|
||||
return rightActionButton;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getMiddleActions()
|
||||
*/
|
||||
@Override
|
||||
public List<MenuButton> getMiddleActions() {
|
||||
final List<MenuButton> buttons = new ArrayList<MenuButton>();
|
||||
buttons.add(new MenuButton("Avatars online...", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
URLUtils.openURL("http://www.slightlymagic.net/forum/viewforum.php?f=89");
|
||||
}
|
||||
}, "Get more avatars from the Magarena forum."));
|
||||
return buttons;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.MagScreen#canScreenClose()
|
||||
*/
|
||||
@Override
|
||||
public boolean isScreenReadyToClose(final AbstractScreen nextScreen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import java.awt.event.ActionEvent;
|
|||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.ui.ExplorerPanel;
|
||||
import magic.ui.MagicFrame;
|
||||
|
@ -92,4 +93,12 @@ public class CardExplorerScreen
|
|||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.model.MagicCardList;
|
||||
|
@ -80,4 +81,12 @@ public class CardZoneScreen
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.data.DeckUtils;
|
||||
import magic.data.GeneralConfig;
|
||||
|
@ -342,4 +343,12 @@ public class DeckEditorScreen
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import java.util.List;
|
|||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.data.IconImages;
|
||||
|
@ -120,4 +121,12 @@ public class DeckViewScreen
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,11 @@ import java.util.List;
|
|||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.MagicUtility;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicDeck;
|
||||
import magic.model.MagicDeckConstructionRule;
|
||||
import magic.model.MagicDuel;
|
||||
|
@ -18,9 +22,10 @@ import magic.ui.ScreenOptionsOverlay;
|
|||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.screen.interfaces.IOptionsMenu;
|
||||
import magic.ui.screen.interfaces.IStatusBar;
|
||||
import magic.ui.screen.widget.ActionBarButton;
|
||||
import magic.ui.screen.widget.DuelSettingsPanel;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.screen.widget.MenuPanel;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DuelDecksScreen
|
||||
|
@ -32,6 +37,9 @@ public class DuelDecksScreen
|
|||
public DuelDecksScreen(final MagicDuel duel) {
|
||||
this.screenContent = new DuelPanel(duel);
|
||||
setContent(this.screenContent);
|
||||
if (duel.getGamesPlayed() > 0) {
|
||||
saveDuel(false);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -39,7 +47,7 @@ public class DuelDecksScreen
|
|||
*/
|
||||
@Override
|
||||
public String getScreenCaption() {
|
||||
return "Deck Settings";
|
||||
return "Duel Decks";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -48,17 +56,17 @@ public class DuelDecksScreen
|
|||
@Override
|
||||
public MenuButton getLeftAction() {
|
||||
if (screenContent.getDuel().getGamesPlayed() == 0) {
|
||||
return new MenuButton("< Main menu", new AbstractAction() {
|
||||
return new MenuButton("Main menu", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new MenuButton("< Quit duel", new AbstractAction() {
|
||||
return new MenuButton("Main Menu", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
getFrame().showMainMenuScreen();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -69,7 +77,7 @@ public class DuelDecksScreen
|
|||
*/
|
||||
@Override
|
||||
public void showOptionsMenuOverlay() {
|
||||
new ScreenOptions(getFrame(), this);
|
||||
new ScreenOptions(getFrame());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -78,32 +86,29 @@ public class DuelDecksScreen
|
|||
@Override
|
||||
public MenuButton getRightAction() {
|
||||
if (!screenContent.getDuel().isFinished()) {
|
||||
return new MenuButton(getStartDuelCaption() + " >", new AbstractAction() {
|
||||
return new MenuButton(getStartDuelCaption(), new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final MagicPlayerDefinition[] players = screenContent.getDuel().getPlayers();
|
||||
if(isLegalDeckAndShowErrors(players[0].getDeck(), players[0].getName()) &&
|
||||
isLegalDeckAndShowErrors(players[1].getDeck(), players[1].getName())) {
|
||||
saveDuel(false);
|
||||
getFrame().nextGame();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return new MenuButton("New Duel", new AbstractAction() {
|
||||
return new MenuButton("Restart duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().showNewDuelDialog();
|
||||
getFrame().restartDuel();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private String getStartDuelCaption() {
|
||||
if (screenContent.getDuel().getGamesPlayed() == 0) {
|
||||
return "Start duel";
|
||||
} else {
|
||||
return "Start game " + (screenContent.getDuel().getGamesPlayed() + 1);
|
||||
}
|
||||
return "Game " + (screenContent.getDuel().getGamesPlayed() + 1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -113,32 +118,42 @@ public class DuelDecksScreen
|
|||
public List<MenuButton> getMiddleActions() {
|
||||
final List<MenuButton> buttons = new ArrayList<MenuButton>();
|
||||
if (screenContent.getDuel().getGamesPlayed() == 0) {
|
||||
buttons.add(new MenuButton("Deck Editor", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().showDeckEditor(screenContent.getSelectedPlayer().getDeck());
|
||||
}
|
||||
}));
|
||||
buttons.add(new MenuButton("Swap Decks", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
swapDecks();
|
||||
}
|
||||
}));
|
||||
buttons.add(
|
||||
new ActionBarButton(
|
||||
IconImages.DECK_ICON,
|
||||
"Deck Editor", "Open the Deck Editor.",
|
||||
new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().showDeckEditor(screenContent.getSelectedPlayer().getDeck());
|
||||
}
|
||||
})
|
||||
);
|
||||
buttons.add(
|
||||
new ActionBarButton(
|
||||
IconImages.SWAP_ICON,
|
||||
"Swap Decks", "Swap your deck with your opponent's.",
|
||||
new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
swapDecks();
|
||||
}
|
||||
})
|
||||
);
|
||||
} else {
|
||||
buttons.add(new MenuButton("Save Duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
saveDuel();
|
||||
}
|
||||
}));
|
||||
buttons.add(new MenuButton("Restart duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().restartDuel();
|
||||
}
|
||||
}));
|
||||
if (screenContent.getDuel().isFinished()) {
|
||||
final MagicDuel duel = screenContent.getDuel();
|
||||
buttons.add(new MenuButton(duel.getWinningPlayerProfile().getPlayerName() + " wins the duel", null));
|
||||
} else {
|
||||
buttons.add(new MenuButton("Restart duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().restartDuel();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
|
@ -177,20 +192,17 @@ public class DuelDecksScreen
|
|||
return screenContent.getDuel().getGamesPlayed();
|
||||
}
|
||||
|
||||
public void saveDuel() {
|
||||
public void saveDuel(final boolean confirmSave) {
|
||||
screenContent.getDuel().save(MagicDuel.getDuelFile());
|
||||
JOptionPane.showMessageDialog(this, "Duel saved. Use Load Duel option in Main Menu to restore.", "Save Duel", JOptionPane.INFORMATION_MESSAGE);
|
||||
if (confirmSave) {
|
||||
JOptionPane.showMessageDialog(this, "<html><b>Duel saved.</b><br><br>Please use Resume Duel option in Main Menu to restore.", "Save Duel", JOptionPane.INFORMATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private class ScreenOptions extends ScreenOptionsOverlay {
|
||||
|
||||
private final MagicFrame frame;
|
||||
private final DuelDecksScreen screen;
|
||||
|
||||
public ScreenOptions(final MagicFrame frame0, final DuelDecksScreen screen0) {
|
||||
super(frame0);
|
||||
this.frame = frame0;
|
||||
this.screen = screen0;
|
||||
public ScreenOptions(final MagicFrame frame) {
|
||||
super(frame);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -198,43 +210,7 @@ public class DuelDecksScreen
|
|||
*/
|
||||
@Override
|
||||
protected MenuPanel getScreenMenu() {
|
||||
|
||||
final MenuPanel menu = new MenuPanel("Duel Options");
|
||||
|
||||
menu.addMenuItem("New Duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
hideAllMenuPanels();
|
||||
frame.showNewDuelDialog();
|
||||
hideOverlay();
|
||||
}
|
||||
});
|
||||
menu.addMenuItem("Load Duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
frame.loadDuel();
|
||||
hideOverlay();
|
||||
}
|
||||
});
|
||||
menu.addMenuItem("Save Duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
screen.saveDuel();
|
||||
hideOverlay();
|
||||
}
|
||||
});
|
||||
menu.addBlankItem();
|
||||
menu.addMenuItem("Close menu", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
hideOverlay();
|
||||
}
|
||||
});
|
||||
|
||||
menu.refreshLayout();
|
||||
menu.setBackground(FontsAndBorders.IMENUOVERLAY_MENUPANEL_COLOR);
|
||||
return menu;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -255,4 +231,15 @@ public class DuelDecksScreen
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
final DuelConfig config = screenContent.getDuel().getConfiguration();
|
||||
final DuelSettingsPanel panel = new DuelSettingsPanel(getFrame(), config);
|
||||
panel.setEnabled(false);
|
||||
return panel;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
package magic.ui.screen;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.screen.AbstractScreen;
|
||||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.screen.interfaces.IStatusBar;
|
||||
import magic.ui.screen.widget.DuelSettingsPanel;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.widget.DeckComboPanel;
|
||||
import magic.ui.widget.DuelPlayerPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DuelPlayersScreen
|
||||
extends AbstractScreen
|
||||
implements IStatusBar, IActionBar {
|
||||
|
||||
private static final DuelConfig duelConfig = DuelConfig.getInstance();
|
||||
|
||||
private ScreenContent content;
|
||||
|
||||
public DuelPlayersScreen() {
|
||||
duelConfig.load();
|
||||
content = new ScreenContent(duelConfig, getFrame());
|
||||
setContent(content);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagStatusBar#getScreenCaption()
|
||||
*/
|
||||
@Override
|
||||
public String getScreenCaption() {
|
||||
return "New Duel Settings";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getLeftAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getLeftAction() {
|
||||
return new MenuButton("Main Menu", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getRightAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getRightAction() {
|
||||
return new MenuButton("Next", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
saveDuelConfig();
|
||||
getFrame().closeActiveScreen(false);
|
||||
getFrame().newDuel(duelConfig);
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void saveDuelConfig() {
|
||||
duelConfig.setStartLife(content.getStartLife());
|
||||
duelConfig.setHandSize(content.getHandSize());
|
||||
duelConfig.setNrOfGames(content.getNrOfGames());
|
||||
duelConfig.setCube(content.getCube());
|
||||
duelConfig.setPlayerOneProfile(content.getPlayerProfile(0));
|
||||
duelConfig.setPlayerTwoProfile(content.getPlayerProfile(1));
|
||||
duelConfig.setPlayerOneDeckGenerator(content.getPlayerDeckGenerator(0));
|
||||
duelConfig.setPlayerTwoDeckGenerator(content.getPlayerDeckGenerator(1));
|
||||
duelConfig.save();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getMiddleActions()
|
||||
*/
|
||||
@Override
|
||||
public List<MenuButton> getMiddleActions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.MagScreen#canScreenClose()
|
||||
*/
|
||||
@Override
|
||||
public boolean isScreenReadyToClose(final AbstractScreen nextScreen) {
|
||||
saveDuelConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
private class ScreenContent extends JPanel {
|
||||
|
||||
private final DuelSettingsPanel duelSettingsPanel;
|
||||
private final DuelPlayerPanel[] playerPanels = new DuelPlayerPanel[2];
|
||||
private final DeckComboPanel[] playerDeckPanels = new DeckComboPanel[2];
|
||||
|
||||
public ScreenContent(final DuelConfig config, final MagicFrame frame) {
|
||||
|
||||
duelSettingsPanel = new DuelSettingsPanel(frame, config);
|
||||
playerPanels[0] = new DuelPlayerPanel(frame, config.getPlayerOneProfile());
|
||||
playerPanels[1] = new DuelPlayerPanel(frame, config.getPlayerTwoProfile());
|
||||
playerDeckPanels[0] = new DeckComboPanel(config.getPlayerOneDeckGenerator());
|
||||
playerDeckPanels[1] = new DeckComboPanel(config.getPlayerTwoDeckGenerator());
|
||||
|
||||
setOpaque(false);
|
||||
doMigLayout();
|
||||
}
|
||||
|
||||
public String getCube() {
|
||||
return duelSettingsPanel.getCube();
|
||||
}
|
||||
|
||||
public int getNrOfGames() {
|
||||
return duelSettingsPanel.getNrOfGames();
|
||||
}
|
||||
|
||||
public int getHandSize() {
|
||||
return duelSettingsPanel.getHandSize();
|
||||
}
|
||||
|
||||
public int getStartLife() {
|
||||
return duelSettingsPanel.getStartLife();
|
||||
}
|
||||
|
||||
public String getPlayerDeckGenerator(final int index) {
|
||||
return playerDeckPanels[index].getDeckGenerator();
|
||||
}
|
||||
|
||||
public PlayerProfile getPlayerProfile(final int index) {
|
||||
return playerPanels[index].getPlayerProfile();
|
||||
}
|
||||
|
||||
private void doMigLayout() {
|
||||
setLayout(new MigLayout("insets 0, center, center, wrap 2"));
|
||||
add(duelSettingsPanel, "w 548!, h 40!, span 2, gapbottom 4");
|
||||
layoutPlayerPanels();
|
||||
layoutPlayerDeckPanels();
|
||||
}
|
||||
|
||||
private void layoutPlayerPanels() {
|
||||
for (final DuelPlayerPanel panel : playerPanels) {
|
||||
add(panel, "w 270!, h 270!, gapright 4");
|
||||
}
|
||||
}
|
||||
|
||||
private void layoutPlayerDeckPanels() {
|
||||
for (final DeckComboPanel panel : playerDeckPanels) {
|
||||
add(panel, "w 270!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -189,4 +189,12 @@ public class KeywordsScreen extends AbstractScreen implements IStatusBar, IActio
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,10 +39,11 @@ public class MainMenuScreen extends AbstractScreen {
|
|||
menuPanel.addMenuItem("New duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().showNewDuelDialog();
|
||||
|
||||
getFrame().showDuelPlayersScreen();
|
||||
}
|
||||
});
|
||||
menuPanel.addMenuItem("Load duel", new AbstractAction() {
|
||||
menuPanel.addMenuItem("Resume duel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().loadDuel();
|
||||
|
@ -51,7 +52,6 @@ public class MainMenuScreen extends AbstractScreen {
|
|||
menuPanel.addMenuItem("Card explorer", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
System.out.println(getFrame());
|
||||
getFrame().showCardExplorerScreen();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -164,4 +164,12 @@ public class MulliganScreen
|
|||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -111,4 +111,12 @@ public class ReadmeScreen extends AbstractScreen implements IStatusBar, IActionB
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicCard;
|
||||
|
@ -115,4 +117,12 @@ public class SampleHandScreen
|
|||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
package magic.ui.screen;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.ai.MagicAIImpl;
|
||||
import magic.model.player.AiPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.model.player.PlayerProfiles;
|
||||
import magic.ui.dialog.AiPropertiesDialog;
|
||||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.screen.interfaces.IPlayerProfileConsumer;
|
||||
import magic.ui.screen.interfaces.IStatusBar;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.widget.AiPlayerJList;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class SelectAiPlayerScreen
|
||||
extends SelectPlayerAbstractScreen
|
||||
implements IStatusBar, IActionBar {
|
||||
|
||||
private AiPlayerJList profilesJList;
|
||||
private IPlayerProfileConsumer consumer;
|
||||
private final PlayerProfile playerProfile;
|
||||
|
||||
// CTR
|
||||
public SelectAiPlayerScreen(final IPlayerProfileConsumer consumer, final PlayerProfile playerProfile) {
|
||||
this.consumer = consumer;
|
||||
this.playerProfile = playerProfile;
|
||||
refreshProfilesJList(playerProfile.getId());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.PlayerScreenUtil#getProfilesListPanel()
|
||||
*/
|
||||
@Override
|
||||
protected JPanel getProfilesListPanel() {
|
||||
profilesJList = new AiPlayerJList();
|
||||
profilesJList.addMouseListener(getMouseAdapter());
|
||||
return getContainerPanel(profilesJList);
|
||||
}
|
||||
|
||||
private MouseAdapter getMouseAdapter() {
|
||||
return new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doNextAction();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void refreshProfilesJList(final String selectedProfileId) {
|
||||
profilesJList.setListData(getPlayerProfilesArray());
|
||||
setSelectedListItem(selectedProfileId);
|
||||
}
|
||||
private void refreshProfilesJList() {
|
||||
refreshProfilesJList(null);
|
||||
}
|
||||
|
||||
private void setSelectedListItem(final String selectedProfileId) {
|
||||
if (selectedProfileId == null || selectedProfileId.isEmpty()) {
|
||||
profilesJList.setSelectedIndex(0);
|
||||
} else {
|
||||
profilesJList.setSelectedValue(profilesMap.get(selectedProfileId), true);
|
||||
}
|
||||
setFocusInProfilesJList(profilesJList);
|
||||
}
|
||||
|
||||
private AiPlayer[] getPlayerProfilesArray() {
|
||||
setProfilesMap();
|
||||
final List<PlayerProfile> profilesByName = new ArrayList<PlayerProfile>(profilesMap.values());
|
||||
Collections.sort(profilesByName, new Comparator<PlayerProfile>() {
|
||||
@Override
|
||||
public int compare(PlayerProfile o1, PlayerProfile o2) {
|
||||
return o1.getPlayerName().toLowerCase().compareTo(o2.getPlayerName().toLowerCase());
|
||||
}
|
||||
});
|
||||
return profilesByName.toArray(new AiPlayer[profilesByName.size()]);
|
||||
}
|
||||
|
||||
private void setProfilesMap() {
|
||||
profilesMap = PlayerProfiles.getAiPlayerProfiles();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerAbstractScreen#createDefaultPlayerProfiles()
|
||||
*/
|
||||
@Override
|
||||
protected void createDefaultPlayerProfiles() throws IOException {
|
||||
// Les Vegas
|
||||
AiPlayer profile = new AiPlayer();
|
||||
profile.setPlayerName("Les Vegas");
|
||||
profile.setAiType(MagicAIImpl.VEGAS);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
// Mini Max
|
||||
profile = new AiPlayer();
|
||||
profile.setPlayerName("Mini Max");
|
||||
profile.setAiType(MagicAIImpl.MMAB);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
// Monty Carlo
|
||||
profile = new AiPlayer();
|
||||
profile.setPlayerName("Monty Carlo");
|
||||
profile.setAiType(MagicAIImpl.MCTS);
|
||||
profile.setAiLevel(6);
|
||||
profile.save();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagStatusBar#getScreenCaption()
|
||||
*/
|
||||
@Override
|
||||
public String getScreenCaption() {
|
||||
return "Select AI Player";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getLeftAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getLeftAction() {
|
||||
return new MenuButton("Cancel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getRightAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getRightAction() {
|
||||
return new MenuButton("Select", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doNextAction();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getMiddleActions()
|
||||
*/
|
||||
@Override
|
||||
public List<MenuButton> getMiddleActions() {
|
||||
final List<MenuButton> buttons = new ArrayList<MenuButton>();
|
||||
buttons.add(new MenuButton("New", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
createNewPlayerProfile();
|
||||
}
|
||||
}, "Create a new player profile."));
|
||||
buttons.add(new MenuButton("Edit", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new AiPropertiesDialog(getFrame(), getSelectedPlayerProfile());
|
||||
profilesJList.repaint();
|
||||
if (getSelectedPlayerProfile().getId().equals(playerProfile.getId())) {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
}
|
||||
}, "Update name and duel settings for selected player."));
|
||||
buttons.add(new MenuButton("Delete", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
deleteSelectedPlayerProfile();
|
||||
}
|
||||
}, "Delete selected player profile."));
|
||||
buttons.add(getAvatarActionButton());
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private void deleteSelectedPlayerProfile() {
|
||||
final PlayerProfile profile = getSelectedPlayerProfile();
|
||||
if (deleteSelectedPlayerProfile(profile)) {
|
||||
PlayerProfiles.getPlayerProfiles().remove(profile.getId());
|
||||
refreshProfilesJList();
|
||||
if (profile.getId().equals(playerProfile.getId())) {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewPlayerProfile() {
|
||||
final AiPropertiesDialog dialog = new AiPropertiesDialog(getFrame());
|
||||
final PlayerProfile newProfile = dialog.getPlayerProfile();
|
||||
if (newProfile != null) {
|
||||
PlayerProfiles.getPlayerProfiles().put(newProfile.getId(), newProfile);
|
||||
refreshProfilesJList(newProfile.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private AiPlayer getSelectedPlayerProfile() {
|
||||
return profilesJList.getSelectedValue();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.MagScreen#canScreenClose()
|
||||
*/
|
||||
@Override
|
||||
public boolean isScreenReadyToClose(final AbstractScreen nextScreen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.IAvatarImageConsumer#setSelectedAvatarPath(java.nio.file.Path)
|
||||
*/
|
||||
@Override
|
||||
public void setSelectedAvatarPath(final Path imagePath) {
|
||||
final PlayerProfile profile = getSelectedPlayerProfile();
|
||||
updateAvatarImage(imagePath, profile);
|
||||
PlayerProfiles.refreshMap();
|
||||
refreshProfilesJList(profile.getId());
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerScreen#getPlayerType()
|
||||
*/
|
||||
@Override
|
||||
protected String getPlayerType() {
|
||||
return "ai";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerAbstractScreen#doNextAction()
|
||||
*/
|
||||
@Override
|
||||
protected void doNextAction() {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,272 @@
|
|||
package magic.ui.screen;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import magic.model.player.HumanPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.model.player.PlayerProfiles;
|
||||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.screen.interfaces.IPlayerProfileConsumer;
|
||||
import magic.ui.screen.interfaces.IStatusBar;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.widget.HumanPlayerJList;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class SelectHumanPlayerScreen
|
||||
extends SelectPlayerAbstractScreen
|
||||
implements IStatusBar, IActionBar {
|
||||
|
||||
private HumanPlayerJList profilesJList;
|
||||
private IPlayerProfileConsumer consumer;
|
||||
private final PlayerProfile playerProfile;
|
||||
|
||||
// CTR
|
||||
public SelectHumanPlayerScreen(final IPlayerProfileConsumer consumer, final PlayerProfile playerProfile) {
|
||||
this.consumer = consumer;
|
||||
this.playerProfile = playerProfile;
|
||||
refreshProfilesJList(playerProfile.getId());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.PlayerScreenUtil#getProfilesListPanel()
|
||||
*/
|
||||
@Override
|
||||
protected JPanel getProfilesListPanel() {
|
||||
profilesJList = new HumanPlayerJList();
|
||||
profilesJList.addMouseListener(getMouseAdapter());
|
||||
return getContainerPanel(profilesJList);
|
||||
}
|
||||
|
||||
private MouseAdapter getMouseAdapter() {
|
||||
return new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
if (e.getClickCount() == 2) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doNextAction();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void refreshProfilesJList(final String selectedProfileId) {
|
||||
profilesJList.setListData(getPlayerProfilesArray());
|
||||
setSelectedListItem(selectedProfileId);
|
||||
}
|
||||
private void refreshProfilesJList() {
|
||||
refreshProfilesJList(null);
|
||||
}
|
||||
|
||||
private void setSelectedListItem(final String selectedProfileId) {
|
||||
if (selectedProfileId == null || selectedProfileId.isEmpty()) {
|
||||
profilesJList.setSelectedIndex(0);
|
||||
} else {
|
||||
profilesJList.setSelectedValue(profilesMap.get(selectedProfileId), true);
|
||||
}
|
||||
setFocusInProfilesJList(profilesJList);
|
||||
}
|
||||
|
||||
private HumanPlayer[] getPlayerProfilesArray() {
|
||||
setProfilesMap();
|
||||
final List<PlayerProfile> profilesByName = new ArrayList<PlayerProfile>(profilesMap.values());
|
||||
Collections.sort(profilesByName, new Comparator<PlayerProfile>() {
|
||||
@Override
|
||||
public int compare(PlayerProfile o1, PlayerProfile o2) {
|
||||
return o1.getPlayerName().toLowerCase().compareTo(o2.getPlayerName().toLowerCase());
|
||||
}
|
||||
});
|
||||
return profilesByName.toArray(new HumanPlayer[profilesByName.size()]);
|
||||
}
|
||||
|
||||
private void setProfilesMap() {
|
||||
profilesMap = PlayerProfiles.getHumanPlayerProfiles();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerAbstractScreen#createDefaultPlayerProfiles()
|
||||
*/
|
||||
@Override
|
||||
protected void createDefaultPlayerProfiles() throws IOException {
|
||||
final HumanPlayer profile = new HumanPlayer();
|
||||
profile.setPlayerName(getDefaultPlayerProfileName());
|
||||
profile.save();
|
||||
}
|
||||
|
||||
private String getDefaultPlayerProfileName() {
|
||||
final String systemUserName = System.getProperty("user.name");
|
||||
return systemUserName == null ? "Player" : systemUserName;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagStatusBar#getScreenCaption()
|
||||
*/
|
||||
@Override
|
||||
public String getScreenCaption() {
|
||||
return "Select Player";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getLeftAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getLeftAction() {
|
||||
return new MenuButton("Cancel", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getRightAction()
|
||||
*/
|
||||
@Override
|
||||
public MenuButton getRightAction() {
|
||||
return new MenuButton("Select", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doNextAction();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.IMagActionBar#getMiddleActions()
|
||||
*/
|
||||
@Override
|
||||
public List<MenuButton> getMiddleActions() {
|
||||
final List<MenuButton> buttons = new ArrayList<MenuButton>();
|
||||
buttons.add(new MenuButton("New", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
doNewPlayerProfile();
|
||||
}
|
||||
}, "Create a new player profile."));
|
||||
buttons.add(new MenuButton("Edit", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
doEditPlayerProfile();
|
||||
profilesJList.repaint();
|
||||
}
|
||||
}, "Update name and duel settings for selected player."));
|
||||
buttons.add(new MenuButton("Delete", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
deleteSelectedPlayerProfile();
|
||||
}
|
||||
}, "Delete selected player profile."));
|
||||
buttons.add(getAvatarActionButton());
|
||||
return buttons;
|
||||
}
|
||||
|
||||
private void doNewPlayerProfile() {
|
||||
final String newName = (String)JOptionPane.showInputDialog(
|
||||
getFrame(),
|
||||
"<html><b>Player Name</b><br></html>",
|
||||
"New Player",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
null, null, null);
|
||||
if (newName != null && !newName.trim().isEmpty()) {
|
||||
final PlayerProfile newProfile = new HumanPlayer();
|
||||
newProfile.setPlayerName(newName);
|
||||
newProfile.save();
|
||||
PlayerProfiles.getPlayerProfiles().put(newProfile.getId(), newProfile);
|
||||
refreshProfilesJList(newProfile.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void doEditPlayerProfile() {
|
||||
final PlayerProfile profile = getSelectedPlayerProfile();
|
||||
final String newName = (String)JOptionPane.showInputDialog(
|
||||
getFrame(),
|
||||
"<html><b>Player Name</b><br></html>",
|
||||
"Update Player",
|
||||
JOptionPane.PLAIN_MESSAGE,
|
||||
null, null, profile.getPlayerName());
|
||||
if (newName != null && !newName.trim().isEmpty()) {
|
||||
profile.setPlayerName(newName.trim());
|
||||
profile.save();
|
||||
if (profile.getId().equals(playerProfile.getId())) {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteSelectedPlayerProfile() {
|
||||
final PlayerProfile profile = getSelectedPlayerProfile();
|
||||
if (deleteSelectedPlayerProfile(profile)) {
|
||||
PlayerProfiles.getPlayerProfiles().remove(profile.getId());
|
||||
refreshProfilesJList();
|
||||
if (profile.getId().equals(playerProfile.getId())) {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private HumanPlayer getSelectedPlayerProfile() {
|
||||
return profilesJList.getSelectedValue();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.MagScreen#canScreenClose()
|
||||
*/
|
||||
@Override
|
||||
public boolean isScreenReadyToClose(final AbstractScreen nextScreen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.IAvatarImageConsumer#setSelectedAvatarPath(java.nio.file.Path)
|
||||
*/
|
||||
@Override
|
||||
public void setSelectedAvatarPath(final Path imagePath) {
|
||||
final PlayerProfile profile = getSelectedPlayerProfile();
|
||||
updateAvatarImage(imagePath, profile);
|
||||
PlayerProfiles.refreshMap();
|
||||
refreshProfilesJList(profile.getId());
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerScreen#getPlayerType()
|
||||
*/
|
||||
@Override
|
||||
protected String getPlayerType() {
|
||||
return "human";
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.SelectPlayerAbstractScreen#doNextAction()
|
||||
*/
|
||||
@Override
|
||||
protected void doNextAction() {
|
||||
consumer.setPlayerProfile(getSelectedPlayerProfile());
|
||||
getFrame().closeActiveScreen(false);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.interfaces.IStatusBar#getStatusPanel()
|
||||
*/
|
||||
@Override
|
||||
public JPanel getStatusPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package magic.ui.screen;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.FileVisitResult;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.SimpleFileVisitor;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.DirectoryStream.Filter;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import magic.MagicMain;
|
||||
import magic.model.player.AiPlayer;
|
||||
import magic.model.player.HumanPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.model.player.PlayerProfiles;
|
||||
import magic.ui.screen.interfaces.IAvatarImageConsumer;
|
||||
import magic.ui.screen.widget.MenuButton;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class SelectPlayerAbstractScreen
|
||||
extends AbstractScreen
|
||||
implements IAvatarImageConsumer {
|
||||
|
||||
protected final Path playersPath;
|
||||
protected HashMap<String, PlayerProfile> profilesMap = new HashMap<String, PlayerProfile>();
|
||||
|
||||
protected abstract JPanel getProfilesListPanel();
|
||||
protected abstract String getPlayerType();
|
||||
protected abstract void createDefaultPlayerProfiles() throws IOException;
|
||||
protected abstract void doNextAction();
|
||||
|
||||
// CTR
|
||||
protected SelectPlayerAbstractScreen() {
|
||||
this.playersPath = Paths.get(MagicMain.getPlayerProfilesPath()).resolve(getPlayerType());
|
||||
setContent(getScreenContent());
|
||||
setEnterKeyInputMap();
|
||||
}
|
||||
|
||||
private void setEnterKeyInputMap() {
|
||||
getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "EnterAction");
|
||||
getActionMap().put("EnterAction", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
||||
doNextAction();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private JPanel getScreenContent() {
|
||||
final JPanel content = new JPanel();
|
||||
content.setLayout(new MigLayout("insets 2, center, center"));
|
||||
content.setOpaque(false);
|
||||
content.add(getProfilesListPanel(), "w 460!, h 400!");
|
||||
return content;
|
||||
}
|
||||
|
||||
protected JPanel getContainerPanel(final JList<? extends PlayerProfile> profilesJList) {
|
||||
profilesJList.setOpaque(false);
|
||||
final JPanel container = new TexturedPanel();
|
||||
container.setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
||||
container.setBorder(FontsAndBorders.BLACK_BORDER);
|
||||
container.setBackground(FontsAndBorders.MENUPANEL_COLOR);
|
||||
container.add(getScrollPane(profilesJList), "w 100%, h 100%");
|
||||
return container;
|
||||
}
|
||||
|
||||
private JScrollPane getScrollPane(final JList<? extends PlayerProfile> profilesJList) {
|
||||
final JScrollPane scrollPane = new JScrollPane();
|
||||
scrollPane.setViewportView(profilesJList);
|
||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||
scrollPane.setOpaque(false);
|
||||
scrollPane.getViewport().setOpaque(false);
|
||||
return scrollPane;
|
||||
}
|
||||
|
||||
protected void setFocusInProfilesJList(final JList<? extends PlayerProfile> profilesJList) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
profilesJList.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updateAvatarImage(final Path imagePath, final PlayerProfile playerProfile) {
|
||||
final Path targetPath = playerProfile.getProfilePath().resolve("player.avatar");
|
||||
try {
|
||||
Files.copy(imagePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all directory contents and then directory itself.
|
||||
*/
|
||||
protected void deleteDirectory(final Path root) {
|
||||
try {
|
||||
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||
Files.delete(file);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
@Override
|
||||
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||
if(exc == null){
|
||||
Files.delete(dir);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
throw exc;
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean deleteSelectedPlayerProfile(final PlayerProfile playerProfile) {
|
||||
boolean isInvalidAction = false;
|
||||
if (playerProfile instanceof HumanPlayer) {
|
||||
isInvalidAction = (PlayerProfiles.getHumanPlayerProfiles().size() <= 1);
|
||||
} else if (playerProfile instanceof AiPlayer) {
|
||||
isInvalidAction = (PlayerProfiles.getAiPlayerProfiles().size() <= 1);
|
||||
}
|
||||
if (isInvalidAction) {
|
||||
JOptionPane.showMessageDialog(this, "There must be at least one player.", "Invalid Action", JOptionPane.WARNING_MESSAGE);
|
||||
return false;
|
||||
}
|
||||
if (playerProfile instanceof AiPlayer) {
|
||||
if (PlayerProfiles.getAiPlayerProfiles().size() <= 1) {
|
||||
JOptionPane.showMessageDialog(this, "There must be at least one player.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
final int action = JOptionPane.showOptionDialog(
|
||||
this,
|
||||
"<html>This will delete the <b>" + playerProfile.getPlayerName() + "</b> player profile.<br>" +
|
||||
"All associated information such as player stats will also be removed.<br><br>" +
|
||||
"<b>This action cannot be undone!</b></html>",
|
||||
"Delete Player Profile?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
null,
|
||||
new String[] {"Delete", "Cancel"}, "Cancel");
|
||||
if (action == JOptionPane.YES_OPTION) {
|
||||
final Path profilePath = playersPath.resolve(playerProfile.getId());
|
||||
deleteDirectory(profilePath);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Path> getDirectoryPaths(final Path rootPath) {
|
||||
final List<Path> paths = new ArrayList<Path>();
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(rootPath, new DirectoriesFilter())) {
|
||||
for (Path p : ds) {
|
||||
paths.add(p.getFileName());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return paths;
|
||||
}
|
||||
private static class DirectoriesFilter implements Filter<Path> {
|
||||
@Override
|
||||
public boolean accept(Path entry) throws IOException {
|
||||
return Files.isDirectory(entry);
|
||||
}
|
||||
}
|
||||
|
||||
protected MenuButton getAvatarActionButton() {
|
||||
return new MenuButton("Avatar", new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
getFrame().showAvatarImagesScreen(SelectPlayerAbstractScreen.this);
|
||||
}
|
||||
}, "Update avatar image of selected player profile.");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package magic.ui.screen.interfaces;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface IAvatarImageConsumer {
|
||||
void setSelectedAvatarPath(final Path imagePath);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package magic.ui.screen.interfaces;
|
||||
|
||||
import magic.model.player.PlayerProfile;
|
||||
|
||||
public interface IPlayerProfileConsumer {
|
||||
void setPlayerProfile(final PlayerProfile selectedPlayerProfile);
|
||||
}
|
|
@ -1,11 +1,17 @@
|
|||
package magic.ui.screen.interfaces;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
* A (Mag)screen that implements this interface will display MagStatusBar.
|
||||
* A screen that implements this interface will display MagStatusBar.
|
||||
*/
|
||||
public interface IStatusBar {
|
||||
/**
|
||||
* Name of the screen. If null then MagStatusBar will be hidden.
|
||||
*/
|
||||
String getScreenCaption();
|
||||
/**
|
||||
* Can use to display a panel of info in central section of status bar.
|
||||
*/
|
||||
JPanel getStatusPanel();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,9 @@ import java.util.List;
|
|||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import magic.data.IconImages;
|
||||
import magic.ui.screen.interfaces.IActionBar;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
|
@ -36,11 +38,20 @@ public class ActionBar extends TexturedPanel {
|
|||
addRightAction();
|
||||
|
||||
}
|
||||
public void refreshLayout() {
|
||||
setMagActionBarLayout();
|
||||
validate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private void addRightAction() {
|
||||
MenuButton action = actionProvider.getRightAction();
|
||||
if (action != null) {
|
||||
action.setEnabled(action.isRunnable());
|
||||
if (action.getIcon() == null) {
|
||||
action.setIcon(IconImages.NEXT_ICON);
|
||||
}
|
||||
action.setHorizontalTextPosition(SwingConstants.LEFT);
|
||||
add(action);
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +79,8 @@ public class ActionBar extends TexturedPanel {
|
|||
MenuButton action = actionProvider.getLeftAction();
|
||||
if (action != null) {
|
||||
action.setEnabled(action.isRunnable());
|
||||
action.setIcon(IconImages.BACK_ICON);
|
||||
action.setHorizontalTextPosition(SwingConstants.RIGHT);
|
||||
add(action);
|
||||
} else {
|
||||
JLabel lbl = new JLabel();
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
package magic.ui.screen.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Font;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import magic.MagicUtility;
|
||||
import magic.data.CubeDefinitions;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.data.IconImages;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.dialog.DuelPropertiesDialog;
|
||||
import magic.ui.widget.FontsAndBorders;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DuelSettingsPanel extends TexturedPanel {
|
||||
|
||||
private final MagicFrame frame;
|
||||
private final DuelConfig config;
|
||||
private int startLife;
|
||||
private int handSize;
|
||||
private int maxGames = 7;
|
||||
private String cube = CubeDefinitions.getCubeNames()[0];
|
||||
private final MouseAdapter mouseAdapter = getMouseAdapter();
|
||||
|
||||
public DuelSettingsPanel(final MagicFrame frame, final DuelConfig config) {
|
||||
|
||||
this.frame = frame;
|
||||
this.config = config;
|
||||
|
||||
startLife = config.getStartLife();
|
||||
handSize = config.getHandSize();
|
||||
maxGames = config.getNrOfGames();
|
||||
cube = config.getCube();
|
||||
|
||||
setBorder(FontsAndBorders.BLACK_BORDER);
|
||||
setBackground(FontsAndBorders.MAGSCREEN_BAR_COLOR);
|
||||
|
||||
addMouseListener(mouseAdapter);
|
||||
|
||||
setLayout(new MigLayout("insets 0 5 0 0, gap 30, center"));
|
||||
refreshDisplay();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnabled(boolean enabled) {
|
||||
removeMouseListener(mouseAdapter);
|
||||
if (enabled) {
|
||||
addMouseListener(mouseAdapter);
|
||||
} else {
|
||||
setBorder(null);
|
||||
setBackground(FontsAndBorders.TEXTAREA_TRANSPARENT_COLOR_HACK);
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append("<html><b>Duel Settings</b><br>");
|
||||
sb.append("Initial Player life: ").append(startLife).append("<br>");
|
||||
sb.append("Initial Hand size: ").append(handSize).append("<br>");
|
||||
sb.append("Maximum games: ").append(maxGames).append(" (first to ").append(getGamesRequiredToWinDuel()).append(")<br>");
|
||||
sb.append("Cube: ").append(cube).append("</html>");
|
||||
setToolTipText(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private int getGamesRequiredToWinDuel() {
|
||||
return (int)Math.ceil(maxGames/2.0);
|
||||
}
|
||||
|
||||
private void refreshDisplay() {
|
||||
removeAll();
|
||||
add(getDuelSettingsLabel(IconImages.LIFE_ICON, "" + startLife), "h 100%");
|
||||
add(getDuelSettingsLabel(IconImages.HAND_ICON, "" + handSize), "h 100%");
|
||||
add(getDuelSettingsLabel(IconImages.TARGET_ICON, "" + maxGames), "h 100%");
|
||||
add(getDuelSettingsLabel(IconImages.CUBE_ICON, " " + getCubeNameWithoutSize()), "h 100%");
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
|
||||
private MouseAdapter getMouseAdapter() {
|
||||
return new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
MagicUtility.setBusyMouseCursor(true);
|
||||
updateDuelSettings();
|
||||
MagicUtility.setBusyMouseCursor(false);
|
||||
}
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
setBorder(BorderFactory.createLineBorder(Color.YELLOW, 2));
|
||||
setBackground(FontsAndBorders.MENUPANEL_COLOR);
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
|
||||
setBackground(FontsAndBorders.MAGSCREEN_BAR_COLOR);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private JLabel getDuelSettingsLabel(final ImageIcon icon, final String text) {
|
||||
final JLabel lbl = new JLabel(text);
|
||||
lbl.setIcon(icon);
|
||||
lbl.setForeground(Color.WHITE);
|
||||
lbl.setFont(new Font("Dialog", Font.PLAIN, 18));
|
||||
lbl.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
public void updateDuelSettings() {
|
||||
final DuelPropertiesDialog dialog =
|
||||
new DuelPropertiesDialog(frame, handSize, startLife, maxGames, cube);
|
||||
if (!dialog.isCancelled()) {
|
||||
startLife = dialog.getStartLife();
|
||||
handSize = dialog.getHandSize();
|
||||
maxGames = dialog.getNrOfGames();
|
||||
cube = dialog.getCube();
|
||||
saveSettings();
|
||||
refreshDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveSettings() {
|
||||
config.setStartLife(startLife);
|
||||
config.setHandSize(handSize);
|
||||
config.setNrOfGames(maxGames);
|
||||
config.setCube(cube);
|
||||
config.save();
|
||||
}
|
||||
|
||||
public String getCube() {
|
||||
return cube;
|
||||
}
|
||||
|
||||
public int getStartLife() {
|
||||
return startLife;
|
||||
}
|
||||
|
||||
public int getHandSize() {
|
||||
return handSize;
|
||||
}
|
||||
|
||||
public int getNrOfGames() {
|
||||
return maxGames;
|
||||
}
|
||||
|
||||
private String getCubeNameWithoutSize() {
|
||||
String verboseCubeName = toTitleCase(cube);
|
||||
final int toIndex = verboseCubeName.indexOf("(");
|
||||
if (toIndex == -1) {
|
||||
return verboseCubeName;
|
||||
} else {
|
||||
return verboseCubeName.substring(0, toIndex).trim();
|
||||
}
|
||||
}
|
||||
|
||||
private String toTitleCase(final String text) {
|
||||
return text.substring(0, 1).toUpperCase() + text.substring(1);
|
||||
}
|
||||
|
||||
}
|
|
@ -28,8 +28,8 @@ public class MenuButton extends JButton {
|
|||
setButtonTransparent();
|
||||
setFocusable(true);
|
||||
setToolTipText(tooltip);
|
||||
setMouseAdapter();
|
||||
if (isRunnable) {
|
||||
setMouseAdapter();
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
addActionListener(action);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.awt.event.ActionEvent;
|
|||
import javax.swing.AbstractAction;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
@ -34,10 +35,15 @@ public class StatusBar extends TexturedPanel {
|
|||
|
||||
private void layoutMagStatusBar() {
|
||||
removeAll();
|
||||
setLayout(new MigLayout("insets 0 0 0 6, gap 6, flowx, aligny 50%", "[grow, fill][][]"));
|
||||
setLayout(new MigLayout("insets 0 0 0 6, gap 6, flowx, aligny 50%", "[32%][36%, center][32%, right]"));
|
||||
if (magScreen != null) {
|
||||
final IStatusBar screen = (IStatusBar)magScreen;
|
||||
add(new CaptionPanel(screen.getScreenCaption()));
|
||||
if (screen.getStatusPanel() != null) {
|
||||
add(screen.getStatusPanel());
|
||||
} else {
|
||||
add(new JLabel());
|
||||
}
|
||||
if (magScreen.hasOptionsMenu()) {
|
||||
add(getOptionsIconButton((IOptionsMenu)magScreen));
|
||||
}
|
||||
|
|
|
@ -5,15 +5,16 @@ import java.awt.image.BufferedImage;
|
|||
|
||||
public class PlayerAvatar {
|
||||
|
||||
private static final int LARGE_SIZE = 120;
|
||||
private static final int MEDIUM_SIZE = LARGE_SIZE/2;
|
||||
public static final int LARGE_SIZE = 120;
|
||||
public static final int MEDIUM_SIZE = LARGE_SIZE/2;
|
||||
private static final int SMALL_SIZE = LARGE_SIZE/4;
|
||||
private static final int CUSTOM_SIZE = 54;
|
||||
public static final int CUSTOM_SIZE = 54;
|
||||
|
||||
private final ImageIcon largeIcon;
|
||||
private final ImageIcon mediumIcon;
|
||||
private final ImageIcon smallIcon;
|
||||
private final ImageIcon turnIcon;
|
||||
private ImageIcon largeIcon;
|
||||
private ImageIcon mediumIcon;
|
||||
private ImageIcon smallIcon;
|
||||
private ImageIcon turnIcon;
|
||||
private int face = 0;
|
||||
|
||||
public PlayerAvatar(final BufferedImage image) {
|
||||
largeIcon = new ImageIcon(magic.ui.utility.GraphicsUtilities.scale(
|
||||
|
@ -26,13 +27,21 @@ public class PlayerAvatar {
|
|||
image,CUSTOM_SIZE,CUSTOM_SIZE));
|
||||
}
|
||||
|
||||
public PlayerAvatar(final int face) {
|
||||
this.face = face;
|
||||
}
|
||||
|
||||
public ImageIcon getIcon(final int size) {
|
||||
switch (size) {
|
||||
if (face > 0) {
|
||||
return ThemeFactory.getInstance().getCurrentTheme().getAvatarIcon(face, size);
|
||||
} else {
|
||||
switch (size) {
|
||||
case 1: return smallIcon;
|
||||
case 2: return mediumIcon;
|
||||
case 3: return largeIcon;
|
||||
case 4: return turnIcon;
|
||||
default: throw new RuntimeException("PlayerAvatar.getIcon: invalid size " + size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ import magic.model.MagicCardDefinition;
|
|||
import magic.model.MagicGame;
|
||||
import magic.model.phase.MagicPhaseType;
|
||||
import magic.ui.GameController;
|
||||
import magic.ui.theme.Theme;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import magic.ui.widget.TextLabel;
|
||||
import magic.ui.widget.TitleBar;
|
||||
|
||||
|
@ -47,7 +45,6 @@ public class GameViewer extends JPanel implements ActionListener {
|
|||
private final CardLayout actionCardLayout;
|
||||
private final JPanel contentPanel;
|
||||
private boolean actionEnabled;
|
||||
private final Theme theme = ThemeFactory.getInstance().getCurrentTheme();
|
||||
|
||||
public GameViewer(final MagicGame game,final GameController controller) {
|
||||
|
||||
|
@ -196,7 +193,7 @@ public class GameViewer extends JPanel implements ActionListener {
|
|||
* for use with the GameDuelViewer component.
|
||||
*/
|
||||
public ImageIcon getTurnSizedPlayerAvatar() {
|
||||
return theme.getAvatarIcon(game.getTurnPlayer().getPlayerDefinition().getFace(), 4);
|
||||
return game.getTurnPlayer().getPlayerDefinition().getAvatar().getIcon(4);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import magic.model.player.AiPlayer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class AiPlayerJList
|
||||
extends JList<AiPlayer> {
|
||||
|
||||
public AiPlayerJList() {
|
||||
setOpaque(false);
|
||||
setCellRenderer(new AiPlayerListRenderer());
|
||||
}
|
||||
|
||||
private class AiPlayerListRenderer extends JLabel implements ListCellRenderer<AiPlayer> {
|
||||
|
||||
private Color foreColor;
|
||||
private AiPlayer profile;
|
||||
|
||||
public AiPlayerListRenderer() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends AiPlayer> list,
|
||||
AiPlayer profile,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
|
||||
this.profile = profile;
|
||||
foreColor = isSelected ? Color.YELLOW : Color.WHITE;
|
||||
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0 0 0 6, gap 0"));
|
||||
panel.setPreferredSize(new Dimension(0, 70));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.setBorder(isSelected ? BorderFactory.createLineBorder(Color.YELLOW, 1) : null);
|
||||
|
||||
panel.add(getAvatarPortrait(), "w 70!, h 70!");
|
||||
panel.add(getNamePanel(), "w 100%");
|
||||
panel.add(getDefaultDuelSettingsPanel(), "w 100%");
|
||||
panel.add(getMiniStatsPanel());
|
||||
|
||||
panel.setToolTipText(profile.getAiType().toString());
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel getDefaultDuelSettingsPanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("debug, insets 0 20 0 0, flowy"));
|
||||
panel.setOpaque(false);
|
||||
panel.add(getLabel("AI: " + profile.getAiType().name()), "w 100%");
|
||||
panel.add(getLabel("Level: " + profile.getAiLevel() + " / 8"), "w 100%");
|
||||
panel.add(getLabel("Extra Life: " + profile.getExtraLife()), "w 100%");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JLabel getLabel(final String caption) {
|
||||
final JLabel lbl = new JLabel(caption);
|
||||
lbl.setForeground(foreColor);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getAvatarPortrait() {
|
||||
return new JLabel(profile.getAvatar().getIcon(2));
|
||||
}
|
||||
|
||||
private JPanel getMiniStatsPanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 0, wrap 4", "[][30!]"));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.add(new JLabel());
|
||||
panel.add(getStatsLabel("P", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("W", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("L", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("Duels", foreColor), "w 60!");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsPlayed), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsPlayed - profile.getStats().duelsWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("Games", foreColor), "w 60!");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesPlayed), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesPlayed - profile.getStats().gamesWon), foreColor), "w 100%");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel getNamePanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 0, flowy"));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.add(getPlayerNameLabel(), "gapbottom 4");
|
||||
// panel.add(getAiTypeLabel());
|
||||
panel.add(getTimestampLabel());
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JLabel getTimestampLabel() {
|
||||
final JLabel lbl = new JLabel("Last played: Never");
|
||||
lbl.setForeground(foreColor);
|
||||
// lbl.setBorder(BorderFactory.createDashedBorder(null));
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getPlayerNameLabel() {
|
||||
final JLabel lbl = new JLabel(profile.getPlayerName());
|
||||
lbl.setFont(FontsAndBorders.FONT2);
|
||||
lbl.setForeground(foreColor);
|
||||
lbl.setVerticalAlignment(SwingConstants.TOP);
|
||||
// lbl.setBorder(BorderFactory.createDashedBorder(null));
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getStatsLabel(final String text, final Color foreColor) {
|
||||
final JLabel lbl = new JLabel(text);
|
||||
lbl.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
lbl.setBorder(BorderFactory.createDashedBorder(null));
|
||||
lbl.setFont(FontsAndBorders.FONT0);
|
||||
lbl.setForeground(foreColor);
|
||||
return lbl;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DeckComboPanel extends TexturedPanel {
|
||||
|
||||
private final DecksComboBox decksComboBox;
|
||||
|
||||
public DeckComboPanel(final String deckGenerator) {
|
||||
|
||||
this.decksComboBox = new DecksComboBox(deckGenerator);
|
||||
|
||||
setBorder(FontsAndBorders.BLACK_BORDER);
|
||||
setBackground(FontsAndBorders.MAGSCREEN_BAR_COLOR);
|
||||
|
||||
setLayout(new MigLayout("center, center"));
|
||||
setOpaque(false);
|
||||
add(getDeckLabel());
|
||||
add(decksComboBox , "w 140!");
|
||||
|
||||
}
|
||||
|
||||
private JLabel getDeckLabel() {
|
||||
final JLabel lbl = new JLabel("Random Deck:");
|
||||
lbl.setFont(new Font("dialog", Font.PLAIN, 16));
|
||||
lbl.setForeground(Color.WHITE);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public String getDeckGenerator() {
|
||||
return decksComboBox.getSelectedItem();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.GridLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Vector;
|
||||
|
||||
import javax.swing.DefaultComboBoxModel;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
|
||||
import magic.data.DeckGenerators;
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicColor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DecksComboBox extends JComboBox<String> implements ListCellRenderer<String> {
|
||||
|
||||
private static final String SEPARATOR = "----";
|
||||
|
||||
private String lastSelected;
|
||||
|
||||
public DecksComboBox(final String colors) {
|
||||
|
||||
setRenderer(this);
|
||||
|
||||
final Vector<String> items = new Vector<String>();
|
||||
items.add("bug");
|
||||
items.add("bur");
|
||||
items.add("buw");
|
||||
items.add("bgr");
|
||||
items.add("bgw");
|
||||
items.add("brw");
|
||||
items.add("ugw");
|
||||
items.add("ugr");
|
||||
items.add("urw");
|
||||
items.add("grw");
|
||||
items.add("***");
|
||||
items.add("bu");
|
||||
items.add("bg");
|
||||
items.add("br");
|
||||
items.add("bw");
|
||||
items.add("ug");
|
||||
items.add("ur");
|
||||
items.add("uw");
|
||||
items.add("gr");
|
||||
items.add("gw");
|
||||
items.add("rw");
|
||||
items.add("**");
|
||||
items.add("b");
|
||||
items.add("u");
|
||||
items.add("g");
|
||||
items.add("r");
|
||||
items.add("w");
|
||||
items.add("*");
|
||||
items.add("@");
|
||||
|
||||
if (DeckGenerators.getInstance().getNrGenerators() > 0) {
|
||||
items.add(SEPARATOR);
|
||||
for(final String generatorName : DeckGenerators.getInstance().getGeneratorNames()) {
|
||||
items.add(generatorName);
|
||||
}
|
||||
}
|
||||
|
||||
setModel(new DefaultComboBoxModel<String>(items));
|
||||
setSelectedItem(colors);
|
||||
lastSelected = colors;
|
||||
this.setFocusable(false);
|
||||
addActionListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSelectedItem() {
|
||||
return getItemAt(getSelectedIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
final JList<? extends String> list,
|
||||
final String selectedVal,
|
||||
final int index,
|
||||
final boolean isSelected,
|
||||
final boolean cellHasFocus) {
|
||||
if(selectedVal.equals(SEPARATOR)) {
|
||||
return new javax.swing.JSeparator(javax.swing.JSeparator.HORIZONTAL);
|
||||
} else if(DeckGenerators.getInstance().getGeneratorNames().contains(selectedVal)) {
|
||||
final JPanel panel=new JPanel(new GridLayout(1,1));
|
||||
panel.setBorder(FontsAndBorders.EMPTY_BORDER);
|
||||
if (isSelected) {
|
||||
panel.setBackground(Color.LIGHT_GRAY);
|
||||
}
|
||||
|
||||
final JLabel label = new JLabel(selectedVal, JLabel.CENTER);
|
||||
label.setFont(FontsAndBorders.FONT1);
|
||||
panel.add(label);
|
||||
|
||||
return panel;
|
||||
} else {
|
||||
final JPanel panel=new JPanel(new GridLayout(1,3));
|
||||
for (int i=0;i<selectedVal.length();i++) {
|
||||
|
||||
final char ch = selectedVal.charAt(i);
|
||||
final ImageIcon icon;
|
||||
switch (ch) {
|
||||
case '*': icon=IconImages.ANY; break;
|
||||
case '@': icon=IconImages.FOLDER; break;
|
||||
default: icon=MagicColor.getColor(ch).getIcon(); break;
|
||||
}
|
||||
panel.add(new JLabel(icon));
|
||||
}
|
||||
panel.setBorder(FontsAndBorders.EMPTY_BORDER);
|
||||
if (isSelected) {
|
||||
panel.setBackground(Color.LIGHT_GRAY);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final String tempItem = getSelectedItem();
|
||||
|
||||
if (SEPARATOR.equals(tempItem)) {
|
||||
// don't select separator
|
||||
setSelectedItem(lastSelected);
|
||||
} else {
|
||||
lastSelected = tempItem;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import magic.MagicUtility;
|
||||
import magic.data.DuelConfig;
|
||||
import magic.model.player.HumanPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import magic.ui.MagicFrame;
|
||||
import magic.ui.screen.interfaces.IPlayerProfileConsumer;
|
||||
import magic.ui.widget.TexturedPanel;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class DuelPlayerPanel
|
||||
extends TexturedPanel
|
||||
implements IPlayerProfileConsumer {
|
||||
|
||||
private final MagicFrame frame;
|
||||
private PlayerProfilePanel playerProfilePanel;
|
||||
private PlayerProfile playerProfile;
|
||||
|
||||
// CTR
|
||||
public DuelPlayerPanel(final MagicFrame frame, final PlayerProfile playerProfile) {
|
||||
this.frame = frame;
|
||||
this.playerProfile = playerProfile;
|
||||
this.playerProfilePanel = getPlayerProfilePanel();
|
||||
setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
|
||||
setBackground(FontsAndBorders.MAGSCREEN_BAR_COLOR);
|
||||
doMigLayout();
|
||||
addMouseListener(getMouseAdapter());
|
||||
}
|
||||
|
||||
private MouseAdapter getMouseAdapter() {
|
||||
return new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
MagicUtility.setBusyMouseCursor(true);
|
||||
selectNewProfile();
|
||||
mouseExited(e);
|
||||
MagicUtility.setBusyMouseCursor(false);
|
||||
}
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
|
||||
setBorder(BorderFactory.createLineBorder(Color.YELLOW, 2));
|
||||
setBackground(FontsAndBorders.MENUPANEL_COLOR);
|
||||
}
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
||||
setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
|
||||
setBackground(FontsAndBorders.MAGSCREEN_BAR_COLOR);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void doMigLayout() {
|
||||
removeAll();
|
||||
setLayout(new MigLayout("flowy, gapy 10"));
|
||||
add(playerProfilePanel, "w 100%, h 70!");
|
||||
add(getStatisticsPanel(), "w 100%, h 100%");
|
||||
}
|
||||
|
||||
private JPanel getStatisticsPanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0 6 0 0"));
|
||||
panel.setOpaque(false);
|
||||
final JTextArea textArea = new JTextArea(playerProfile.getStats().toString());
|
||||
textArea.setEditable(false);
|
||||
textArea.setFocusable(false);
|
||||
textArea.setTabSize(16);
|
||||
textArea.setBackground(new Color(0,0,0,1));
|
||||
textArea.setBorder(null);
|
||||
textArea.setForeground(Color.LIGHT_GRAY);
|
||||
textArea.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
});
|
||||
panel.add(textArea, "w 100%, h 100%");
|
||||
// MagicUtility.setDebugBorder(panel);
|
||||
return panel;
|
||||
}
|
||||
|
||||
public PlayerProfile getPlayerProfile() {
|
||||
return playerProfile;
|
||||
}
|
||||
|
||||
public void selectNewProfile() {
|
||||
if (playerProfile instanceof HumanPlayer) {
|
||||
frame.showSelectHumanPlayerScreen(this, playerProfile);
|
||||
} else {
|
||||
frame.showSelectAiProfileScreen(this, playerProfile);
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see magic.ui.screen.duel.IPlayerProfileConsumer#setPlayerProfile(magic.model.player.PlayerProfile)
|
||||
*/
|
||||
@Override
|
||||
public void setPlayerProfile(PlayerProfile selectedPlayerProfile) {
|
||||
if (selectedPlayerProfile != null) {
|
||||
playerProfile = selectedPlayerProfile;
|
||||
if (selectedPlayerProfile instanceof HumanPlayer) {
|
||||
DuelConfig.getInstance().setPlayerOneProfile(selectedPlayerProfile);
|
||||
} else {
|
||||
DuelConfig.getInstance().setPlayerTwoProfile(selectedPlayerProfile);
|
||||
}
|
||||
DuelConfig.getInstance().save();
|
||||
}
|
||||
playerProfilePanel = new PlayerProfilePanel(playerProfile);
|
||||
doMigLayout();
|
||||
}
|
||||
|
||||
private PlayerProfilePanel getPlayerProfilePanel() {
|
||||
final PlayerProfilePanel panel = new PlayerProfilePanel(playerProfile);
|
||||
panel.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) { DuelPlayerPanel.this.dispatchEvent(e); }
|
||||
});
|
||||
return panel;
|
||||
}
|
||||
|
||||
private class PlayerProfilePanel extends JPanel {
|
||||
|
||||
private PlayerProfile profile;
|
||||
|
||||
public PlayerProfilePanel(final PlayerProfile profile) {
|
||||
this.profile = profile;
|
||||
setPreferredSize(new Dimension(0, 70));
|
||||
setOpaque(false);
|
||||
doMigLayout();
|
||||
}
|
||||
|
||||
private void doMigLayout() {
|
||||
removeAll();
|
||||
setLayout(new MigLayout("insets 0 0 0 6, gap 0"));
|
||||
add(new JLabel(profile.getAvatar().getIcon(2)), "w 70!, h 70!");
|
||||
add(new PlayerDetailsPanel(profile), "w 100%");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import magic.model.player.HumanPlayer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class HumanPlayerJList
|
||||
extends JList<HumanPlayer> {
|
||||
|
||||
public HumanPlayerJList() {
|
||||
setOpaque(false);
|
||||
setCellRenderer(new HumanPlayerListRenderer());
|
||||
}
|
||||
|
||||
private class HumanPlayerListRenderer extends JPanel implements ListCellRenderer<HumanPlayer> {
|
||||
|
||||
private Color foreColor;
|
||||
private HumanPlayer profile;
|
||||
|
||||
public HumanPlayerListRenderer() {
|
||||
setOpaque(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends HumanPlayer> list,
|
||||
HumanPlayer profile,
|
||||
int index,
|
||||
boolean isSelected,
|
||||
boolean cellHasFocus) {
|
||||
|
||||
this.profile = profile;
|
||||
foreColor = isSelected ? Color.YELLOW : Color.WHITE;
|
||||
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0 0 0 6, gap 0"));
|
||||
panel.setPreferredSize(new Dimension(0, 70));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.setBorder(isSelected ? BorderFactory.createLineBorder(Color.YELLOW, 1) : null);
|
||||
|
||||
panel.add(getAvatarPortrait(), "w 70!, h 70!");
|
||||
panel.add(getNamePanel(), "w 100%");
|
||||
// panel.add(getDefaultDuelSettingsPanel(), "w 100%");
|
||||
panel.add(getMiniStatsPanel());
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
// private JPanel getDefaultDuelSettingsPanel() {
|
||||
// final JPanel panel = new JPanel(new MigLayout("debug, insets 0 20 0 0, flowy"));
|
||||
// panel.setOpaque(false);
|
||||
// panel.add(getLabel("Life: " + profile.getPlayerLife()), "w 100%");
|
||||
// panel.add(getLabel("Hand: " + profile.getHandSize()), "w 100%");
|
||||
// panel.add(getLabel("Win: " + profile.getGamesToWin()), "w 100%");
|
||||
// return panel;
|
||||
// }
|
||||
|
||||
// private JLabel getLabel(final String caption) {
|
||||
// final JLabel lbl = new JLabel(caption);
|
||||
// lbl.setForeground(foreColor);
|
||||
// return lbl;
|
||||
// }
|
||||
|
||||
private JLabel getAvatarPortrait() {
|
||||
return new JLabel(profile.getAvatar().getIcon(2));
|
||||
}
|
||||
|
||||
private JPanel getMiniStatsPanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 0, wrap 4", "[][30!]"));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.add(new JLabel());
|
||||
panel.add(getStatsLabel("P", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("W", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("L", foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("Duels", foreColor), "w 60!");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsPlayed), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().duelsPlayed - profile.getStats().duelsWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel("Games", foreColor), "w 60!");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesPlayed), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesWon), foreColor), "w 100%");
|
||||
panel.add(getStatsLabel(Integer.toString(profile.getStats().gamesPlayed - profile.getStats().gamesWon), foreColor), "w 100%");
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JPanel getNamePanel() {
|
||||
final JPanel panel = new JPanel(new MigLayout("insets 0, gap 0, flowy"));
|
||||
panel.setOpaque(false);
|
||||
panel.setForeground(foreColor);
|
||||
panel.add(getPlayerNameLabel(), "w 100%, gapbottom 4");
|
||||
panel.add(getTimestampLabel());
|
||||
return panel;
|
||||
}
|
||||
|
||||
private JLabel getTimestampLabel() {
|
||||
final JLabel lbl = new JLabel("Last played: " + profile.getStats().getLastPlayed());
|
||||
lbl.setForeground(foreColor);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getPlayerNameLabel() {
|
||||
final JLabel lbl = new JLabel(profile.getPlayerName());
|
||||
lbl.setFont(FontsAndBorders.FONT2);
|
||||
lbl.setForeground(foreColor);
|
||||
lbl.setVerticalAlignment(SwingConstants.TOP);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getStatsLabel(final String text, final Color foreColor) {
|
||||
final JLabel lbl = new JLabel(text);
|
||||
lbl.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
lbl.setBorder(BorderFactory.createDashedBorder(null));
|
||||
lbl.setFont(FontsAndBorders.FONT0);
|
||||
lbl.setForeground(foreColor);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2,8 +2,6 @@ package magic.ui.widget;
|
|||
|
||||
import magic.data.IconImages;
|
||||
import magic.model.MagicMessage;
|
||||
import magic.ui.theme.Theme;
|
||||
import magic.ui.theme.ThemeFactory;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
@ -100,8 +98,6 @@ public class MessagePanel extends JPanel {
|
|||
}
|
||||
|
||||
private JLabel getPlayerAvatar() {
|
||||
final Theme theme = ThemeFactory.getInstance().getCurrentTheme();
|
||||
final int face = message.getPlayer().getPlayerDefinition().getFace();
|
||||
return new JLabel(theme.getAvatarIcon(face,1));
|
||||
return new JLabel(message.getPlayer().getPlayerDefinition().getAvatar().getIcon(1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import magic.ui.theme.Theme;
|
|||
import magic.ui.theme.ThemeFactory;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.border.Border;
|
||||
import java.awt.BorderLayout;
|
||||
|
@ -77,15 +76,14 @@ public class PlayerAvatarPanel extends TexturedPanel {
|
|||
|
||||
private void update() {
|
||||
if (playerDefinition != null) {
|
||||
final Theme theme=ThemeFactory.getInstance().getCurrentTheme();
|
||||
final ImageIcon faceIcon=theme.getAvatarIcon(playerDefinition.getFace(),small?2:3);
|
||||
faceLabel.setIcon(faceIcon);
|
||||
|
||||
faceLabel.setIcon(playerDefinition.getAvatar().getIcon(small?2:3));
|
||||
|
||||
titleBar.setText(playerDefinition.getName());
|
||||
if (small) {
|
||||
titleBar.setVisible(false);
|
||||
setPreferredSize(new Dimension(72,80));
|
||||
} else {
|
||||
new JLabel(faceIcon);
|
||||
titleBar.setVisible(true);
|
||||
setPreferredSize(new Dimension(132,150));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package magic.ui.widget;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import magic.model.player.AiPlayer;
|
||||
import magic.model.player.PlayerProfile;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PlayerDetailsPanel extends JPanel {
|
||||
|
||||
private final Color foreColor;
|
||||
|
||||
private final PlayerProfile profile;
|
||||
|
||||
// CTR
|
||||
public PlayerDetailsPanel(final PlayerProfile profile, final Color foreColor) {
|
||||
this.profile = profile;
|
||||
this.foreColor = foreColor;
|
||||
setOpaque(false);
|
||||
setForeground(foreColor);
|
||||
setLayout(new MigLayout("insets 0, gap 0, flowy"));
|
||||
layoutComponents();
|
||||
}
|
||||
public PlayerDetailsPanel(final PlayerProfile profile) {
|
||||
this(profile, Color.WHITE);
|
||||
}
|
||||
|
||||
private void layoutComponents() {
|
||||
add(getPlayerTypeLabel(), "w 100%");
|
||||
add(getPlayerNameLabel(), "w 100%");
|
||||
add(getPlayerPropertiesLabel(), "w 100%");
|
||||
}
|
||||
|
||||
private JLabel getPlayerTypeLabel() {
|
||||
final JLabel lbl = new JLabel();
|
||||
lbl.setFont(FontsAndBorders.FONT0);
|
||||
lbl.setForeground(foreColor);
|
||||
if (profile instanceof AiPlayer) {
|
||||
final AiPlayer player = (AiPlayer)profile;
|
||||
lbl.setText("AI : " + player.getAiType());
|
||||
}
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getPlayerNameLabel() {
|
||||
final JLabel lbl = new JLabel(profile.getPlayerName());
|
||||
lbl.setFont(FontsAndBorders.FONT3);
|
||||
lbl.setForeground(foreColor);
|
||||
lbl.setVerticalAlignment(SwingConstants.TOP);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getPlayerPropertiesLabel() {
|
||||
JLabel lbl = new JLabel();
|
||||
if (profile instanceof AiPlayer) {
|
||||
lbl = getAiPlayerProperties();
|
||||
}
|
||||
return lbl;
|
||||
}
|
||||
|
||||
private JLabel getAiPlayerProperties() {
|
||||
final AiPlayer player = (AiPlayer)profile;
|
||||
final JLabel lbl = new JLabel("Level: " + player.getAiLevel() + " Extra Life: " + player.getExtraLife());
|
||||
lbl.setFont(FontsAndBorders.FONT0);
|
||||
lbl.setForeground(foreColor);
|
||||
return lbl;
|
||||
}
|
||||
|
||||
}
|