GUI, table: improved save/load table config to support player types, AI skill level and deck files (closes #12981)

This commit is contained in:
Oleg Agafonov 2024-10-11 17:09:15 +04:00
parent f652665f87
commit 3475249c99
4 changed files with 100 additions and 32 deletions

View file

@ -20,11 +20,13 @@ import mage.view.TableView;
import org.apache.log4j.Logger;
import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* App GUI: create new GAME
@ -35,13 +37,22 @@ public class NewTableDialog extends MageDialog {
private static final Logger logger = Logger.getLogger(NewTableDialog.class);
private static final int DEFAULT_COMPUTER_PLAYER_SKILL_LEVEL = 2;
private static final String PLAYER_DATA_DELIMETER_OLD = ","; // need for compatibility with old version
private static final String PLAYER_DATA_DELIMETER_NEW = "@@@";
private final CustomOptionsDialog customOptions;
private TableView table;
private UUID playerId;
private UUID roomId;
private String lastSessionId;
private final List<TablePlayerPanel> players = new ArrayList<>();
// temp settings on loading players list
private final List<PlayerType> prefPlayerTypes = new ArrayList<>();
private final List<Integer> prefPlayerSkills = new ArrayList<>();
private final List<String> prefPlayerDecks = new ArrayList<>();
private static final String LIMITED = "Limited";
@ -756,27 +767,56 @@ public class NewTableDialog extends MageDialog {
}
private void createPlayers(int numPlayers) {
// add missing player panels
// add miss panels
if (numPlayers > players.size()) {
while (players.size() != numPlayers) {
TablePlayerPanel playerPanel = new TablePlayerPanel();
PlayerType playerType = PlayerType.HUMAN;
if (prefPlayerTypes.size() >= players.size() && !players.isEmpty()) {
playerType = prefPlayerTypes.get(players.size() - 1);
}
playerPanel.init(players.size() + 2, playerType);
players.add(playerPanel);
playerPanel.addPlayerTypeEventListener(
(Listener<Event>) event -> drawPlayers()
);
}
} // remove player panels no longer needed
else if (numPlayers < players.size()) {
}
// remove un-used panels
if (numPlayers < players.size()) {
while (players.size() != numPlayers) {
players.remove(players.size() - 1);
}
}
// load player data
String prevGoodPlayerDeck = "";
for (int i = 0; i < players.size(); i++) {
TablePlayerPanel playerPanel = players.get(i);
// find player type
PlayerType playerType = PlayerType.HUMAN;
if (i < prefPlayerTypes.size()) {
playerType = prefPlayerTypes.get(i);
}
// find skill level
int playerSkill = DEFAULT_COMPUTER_PLAYER_SKILL_LEVEL;
if (i < prefPlayerSkills.size()) {
playerSkill = prefPlayerSkills.get(i);
}
// find deck file
String playerDeck = "";
if (i < prefPlayerDecks.size()) {
playerDeck = prefPlayerDecks.get(i);
// use prev deck if loaded not found
if (playerDeck.isEmpty() || !(new File(playerDeck).exists())) {
playerDeck = prevGoodPlayerDeck;
} else {
prevGoodPlayerDeck = playerDeck;
}
}
playerPanel.init(i + 1, playerType, playerSkill, playerDeck);
}
drawPlayers();
}
@ -808,11 +848,6 @@ public class NewTableDialog extends MageDialog {
cbRange.setModel(new DefaultComboBoxModel(RangeOfInfluence.values()));
cbAttackOption.setModel(new DefaultComboBoxModel(MultiplayerAttackOption.values()));
cbSkillLevel.setModel(new DefaultComboBoxModel(SkillLevel.values()));
// Update the existing player panels (neccessary if server was changes = new session)
int i = 2;
for (TablePlayerPanel tablePlayerPanel : players) {
tablePlayerPanel.init(i++, tablePlayerPanel.getPlayerType());
}
this.setModal(true);
setGameOptions();
this.setLocation(150, 100);
@ -863,11 +898,24 @@ public class NewTableDialog extends MageDialog {
txtName.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NAME + versionStr, "Game"));
txtPassword.setText(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PASSWORD + versionStr, ""));
String playerTypes = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_TYPES + versionStr, "Human");
// load player data
// player type
String playerData = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_TYPES + versionStr, "Human");
prefPlayerTypes.clear();
for (String pType : playerTypes.split(",")) {
prefPlayerTypes.add(PlayerType.getByDescription(pType));
for (String playerTypeStr : playerData.split(PLAYER_DATA_DELIMETER_OLD)) {
prefPlayerTypes.add(PlayerType.getByDescription(playerTypeStr));
}
// player skill
playerData = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_SKILLS + versionStr, String.valueOf(DEFAULT_COMPUTER_PLAYER_SKILL_LEVEL));
prefPlayerSkills.clear();
for (String playerSkillStr : playerData.split(PLAYER_DATA_DELIMETER_NEW)) {
prefPlayerSkills.add(Integer.parseInt(playerSkillStr));
}
// player deck
playerData = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_DECKS + versionStr, "Human");
prefPlayerDecks.clear();
prefPlayerDecks.addAll(Arrays.asList(playerData.split(PLAYER_DATA_DELIMETER_NEW)));
this.spnNumPlayers.setValue(Integer.parseInt(PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_NUMBER_PLAYERS + versionStr, "2")));
String gameTypeName = PreferencesDialog.getCachedValue(PreferencesDialog.KEY_NEW_TABLE_GAME_TYPE + versionStr, "Two Player Duel");
@ -968,15 +1016,22 @@ public class NewTableDialog extends MageDialog {
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_MINIMUM_RATING + versionStr, Integer.toString(options.getMinimumRating()));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_EDH_POWER_LEVEL + versionStr, Integer.toString(options.getEdhPowerLevel()));
StringBuilder playerTypesString = new StringBuilder();
for (Object player : players) {
if (playerTypesString.length() > 0) {
playerTypesString.append(',');
}
TablePlayerPanel tpp = (TablePlayerPanel) player;
playerTypesString.append(tpp.getPlayerType());
}
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_TYPES + versionStr, playerTypesString.toString());
// save player data
// player type
String playerData = players.stream()
.map(panel -> panel.getPlayerType().toString())
.collect(Collectors.joining(PLAYER_DATA_DELIMETER_OLD));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_TYPES + versionStr, playerData);
// player skill
playerData = players.stream()
.map(panel -> String.valueOf(panel.getPlayerSkill()))
.collect(Collectors.joining(PLAYER_DATA_DELIMETER_NEW));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_SKILLS + versionStr, playerData);
// player deck
playerData = players.stream()
.map(panel -> String.valueOf(panel.getPlayerDeck()))
.collect(Collectors.joining(PLAYER_DATA_DELIMETER_NEW));
PreferencesDialog.saveValue(PreferencesDialog.KEY_NEW_TABLE_PLAYER_DECKS + versionStr, playerData);
customOptions.onSaveSettings(version, options);
}

View file

@ -217,6 +217,8 @@ public class PreferencesDialog extends javax.swing.JDialog {
public static final String KEY_NEW_TABLE_SKILL_LEVEL = "newTableSkillLevel";
public static final String KEY_NEW_TABLE_NUMBER_PLAYERS = "newTableNumberPlayers";
public static final String KEY_NEW_TABLE_PLAYER_TYPES = "newTablePlayerTypes";
public static final String KEY_NEW_TABLE_PLAYER_SKILLS = "newTablePlayerSkills";
public static final String KEY_NEW_TABLE_PLAYER_DECKS = "newTablePlayerDecks";
public static final String KEY_NEW_TABLE_QUIT_RATIO = "newTableQuitRatio";
public static final String KEY_NEW_TABLE_MINIMUM_RATING = "newTableMinimumRating";
public static final String KEY_NEW_TABLE_RATED = "newTableRated";

View file

@ -77,7 +77,11 @@ public class NewPlayerPanel extends javax.swing.JPanel {
this.txtPlayerDeck.setText(deckFile);
}
public int getLevel() {
public void setSkillLevel(int level) {
this.spnLevel.setValue(level);
}
public int getSkillLevel() {
return (Integer) spnLevel.getValue();
}

View file

@ -18,16 +18,12 @@ public class TablePlayerPanel extends javax.swing.JPanel {
protected final PlayerTypeEventSource playerTypeEventSource = new PlayerTypeEventSource();
/**
* Creates new form TablePlayerPanel
*/
public TablePlayerPanel() {
initComponents();
this.newPlayerPanel.setVisible(false);
}
public void init(int playerNum, PlayerType playerType) {
public void init(int playerNum, PlayerType playerType, int playerSkill, String playerDeck) {
cbPlayerType.setModel(new DefaultComboBoxModel(SessionHandler.getPlayerTypes()));
this.lblPlayerNum.setText("Player " + playerNum);
if (ClientDefaultSettings.otherPlayerIndex != null) {
@ -41,11 +37,14 @@ public class TablePlayerPanel extends javax.swing.JPanel {
if (playerType != null) {
this.cbPlayerType.setSelectedItem(playerType);
}
this.newPlayerPanel.setDeckFile(playerDeck);
this.newPlayerPanel.setSkillLevel(playerSkill);
}
public boolean joinTable(UUID roomId, UUID tableId) throws IOException, ClassNotFoundException {
if (this.cbPlayerType.getSelectedItem() != PlayerType.HUMAN) {
return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (PlayerType) this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getLevel(), DeckImporter.importDeckFromFile(this.newPlayerPanel.getDeckFile(), true), "");
return SessionHandler.joinTable(roomId, tableId, this.newPlayerPanel.getPlayerName(), (PlayerType) this.cbPlayerType.getSelectedItem(), this.newPlayerPanel.getSkillLevel(), DeckImporter.importDeckFromFile(this.newPlayerPanel.getDeckFile(), true), "");
}
return true;
}
@ -54,6 +53,14 @@ public class TablePlayerPanel extends javax.swing.JPanel {
return PlayerType.getByDescription(this.cbPlayerType.getSelectedItem().toString());
}
public int getPlayerSkill() {
return newPlayerPanel.getSkillLevel();
}
public String getPlayerDeck() {
return newPlayerPanel.getDeckFile();
}
public void addPlayerTypeEventListener(Listener<Event> listener) {
playerTypeEventSource.addListener(listener);
}