From b8c4ecf4c85010acae151c6fe69da8b9e4c659a1 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 29 Mar 2024 15:52:09 -0700 Subject: [PATCH 01/76] Allow user to set date in vanilla scenarios --- .../gui/dialog/CustomizeScenarioDialog.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index b29dfd6f1e..0dfd8bcdf6 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -174,20 +174,18 @@ public Component getListCellRendererComponent(final JList list, final Object panMain.add(choiceStatus, gridBagConstraints); } - if (!scenario.getStatus().isCurrent() || (campaign.getCampaignOptions().isUseAtB() && (scenario instanceof AtBScenario))) { - btnDate = new JButton(); - btnDate.setText(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); - btnDate.addActionListener(evt -> changeDate()); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 0.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panMain.add(btnDate, gridBagConstraints); - } + btnDate = new JButton(); + btnDate.setText(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); + btnDate.addActionListener(evt -> changeDate()); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + panMain.add(btnDate, gridBagConstraints); if (scenario.getStatus().isCurrent()) { initLootPanel(); @@ -318,9 +316,8 @@ private void btnOKActionPerformed(ActionEvent evt) { if (choiceStatus.getSelectedItem() != null) { scenario.setStatus((ScenarioStatus) choiceStatus.getSelectedItem()); } - - scenario.setDate(date); } + scenario.setDate(date); scenario.resetLoot(); for (Loot loot : lootModel.getAllLoot()) { scenario.addLoot(loot); From f43adc9ceb4dd2373af95d996e1787bd87797b09 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 29 Mar 2024 16:10:51 -0700 Subject: [PATCH 02/76] Allow user to edit planetary conditions in CustomizeScenarioDialog --- MekHQ/src/mekhq/GameThread.java | 17 +------ .../src/mekhq/campaign/mission/Scenario.java | 45 +++++++++++++++++++ .../gui/dialog/CustomizeScenarioDialog.java | 27 +++++++++++ 3 files changed, 73 insertions(+), 16 deletions(-) diff --git a/MekHQ/src/mekhq/GameThread.java b/MekHQ/src/mekhq/GameThread.java index b527d10f52..90f2a6c697 100644 --- a/MekHQ/src/mekhq/GameThread.java +++ b/MekHQ/src/mekhq/GameThread.java @@ -173,22 +173,7 @@ public void run() { client.sendMapSettings(mapSettings); Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay()); - PlanetaryConditions planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setLight(scenario.getLight()); - planetaryConditions.setWeather(scenario.getWeather()); - planetaryConditions.setWind(scenario.getWind()); - planetaryConditions.setFog(scenario.getFog()); - planetaryConditions.setAtmosphere(scenario.getAtmosphere()); - planetaryConditions.setTemperature(scenario.getModifiedTemperature()); - planetaryConditions.setGravity(scenario.getGravity()); - planetaryConditions.setEMI(scenario.getEMI()); - planetaryConditions.setBlowingSand(scenario.getBlowingSand()); - planetaryConditions.setShiftingWindDirection(scenario.canWindShiftDirection()); - planetaryConditions.setShiftingWindStrength(scenario.canWindShiftStrength()); - planetaryConditions.setWindMax(scenario.getMaxWindStrength()); - planetaryConditions.setWindMin(scenario.getMinWindStrength()); - - client.sendPlanetaryConditions(planetaryConditions); + client.sendPlanetaryConditions(scenario.createPlanetaryConditions()); Thread.sleep(MekHQ.getMHQOptions().getStartGameDelay()); client.getLocalPlayer().setStartingPos(scenario.getStart()); diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index d58b892269..ad272c489d 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -380,6 +380,50 @@ public BlowingSand getBlowingSand() { public void setMinWindStrength(Wind strength) { this.minWindStrength = strength; } + /** + * Create a PlanetaryConditions object from variables + * @return PlanetaryConditions object + */ + public PlanetaryConditions createPlanetaryConditions() { + PlanetaryConditions planetaryConditions = new PlanetaryConditions(); + planetaryConditions.setLight(getLight()); + planetaryConditions.setWeather(getWeather()); + planetaryConditions.setWind(getWind()); + planetaryConditions.setFog(getFog()); + planetaryConditions.setAtmosphere(getAtmosphere()); + planetaryConditions.setTemperature(getModifiedTemperature()); + planetaryConditions.setGravity(getGravity()); + planetaryConditions.setEMI(getEMI()); + planetaryConditions.setBlowingSand(getBlowingSand()); + planetaryConditions.setShiftingWindDirection(canWindShiftDirection()); + planetaryConditions.setShiftingWindStrength(canWindShiftStrength()); + planetaryConditions.setWindMax(getMaxWindStrength()); + planetaryConditions.setWindMin(getMinWindStrength()); + + return planetaryConditions; + } + + /** + * Read the values from a PlanetaryConditions object into the Scenario variables for planetary conditions. + * This is necessary because MekHQ has XML and MegaMek doesn't. + * @param planetaryConditions A PlanetaryConditions object + */ + public void readPlanetaryConditions(PlanetaryConditions planetaryConditions) { + this.setLight(planetaryConditions.getLight()); + this.setWeather(planetaryConditions.getWeather()); + this.setWind(planetaryConditions.getWind()); + this.setFog(planetaryConditions.getFog()); + this.setAtmosphere(planetaryConditions.getAtmosphere()); + this.setTemperature(planetaryConditions.getTemperature()); + this.setGravity(planetaryConditions.getGravity()); + this.setEMI(planetaryConditions.getEMI()); + this.setBlowingSand(planetaryConditions.getBlowingSand()); + this.setShiftWindDirection(planetaryConditions.shiftingWindDirection()); + this.setShiftWindStrength(planetaryConditions.shiftingWindStrength()); + this.setMaxWindStrength(planetaryConditions.getWindMax()); + this.setMinWindStrength(planetaryConditions.getWindMin()); + } + public ScenarioDeploymentLimit getDeploymentLimit() { return deploymentLimit; } @@ -1029,4 +1073,5 @@ public boolean getHasTrack() { public void setHasTrack(boolean b) { hasTrack = b; } + } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 0dfd8bcdf6..c8e02ac1e2 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -22,6 +22,8 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; +import megamek.client.ui.swing.PlanetaryConditionsDialog; +import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.mission.*; @@ -53,6 +55,7 @@ public class CustomizeScenarioDialog extends JDialog { private Campaign campaign; private boolean newScenario; private LocalDate date; + private PlanetaryConditions planetaryConditions; private LootTableModel lootModel; @@ -76,6 +79,7 @@ public class CustomizeScenarioDialog extends JDialog { private JComboBox choiceStatus; private JLabel lblStatus; private JButton btnDate; + private JButton btnPlanetaryConditions; public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission m, Campaign c) { super(parent, modal); @@ -94,6 +98,8 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission } date = scenario.getDate(); + planetaryConditions = scenario.createPlanetaryConditions(); + loots = new ArrayList<>(); for (Loot loot : scenario.getLoot()) { loots.add((Loot) loot.clone()); @@ -187,6 +193,19 @@ public Component getListCellRendererComponent(final JList list, final Object gridBagConstraints.insets = new Insets(5, 5, 0, 0); panMain.add(btnDate, gridBagConstraints); + btnPlanetaryConditions = new JButton(); + btnPlanetaryConditions.setText("Planetary Conditions"); + btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 0.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + panMain.add(btnPlanetaryConditions, gridBagConstraints); + if (scenario.getStatus().isCurrent()) { initLootPanel(); gridBagConstraints.gridx = 0; @@ -317,6 +336,7 @@ private void btnOKActionPerformed(ActionEvent evt) { scenario.setStatus((ScenarioStatus) choiceStatus.getSelectedItem()); } } + scenario.readPlanetaryConditions(planetaryConditions); scenario.setDate(date); scenario.resetLoot(); for (Loot loot : lootModel.getAllLoot()) { @@ -382,6 +402,13 @@ private void changeDate() { } } + private void changePlanetaryConditions() { + PlanetaryConditionsDialog pc = new PlanetaryConditionsDialog(frame, planetaryConditions); + if(pc.showDialog()) { + planetaryConditions = pc.getConditions(); + } + } + private void initLootPanel() { panLoot = new JPanel(new BorderLayout()); From 25f8ca4dd5a3f437f1f61a0675a79e8e7857d35f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 1 Apr 2024 19:51:19 -0700 Subject: [PATCH 03/76] Reorganize layout of CustomizeScenarioDialog --- .../CustomizeScenarioDialog.properties | 10 +- .../gui/dialog/CustomizeScenarioDialog.java | 271 +++++++++--------- 2 files changed, 147 insertions(+), 134 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 488c4ad211..7a062d1122 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -1,6 +1,10 @@ btnCancel.text=Cancel btnOkay.text=OK -lblName.text=Scenario Name -lblStatus.text=Status +lblName.text=Scenario Name: +lblDate.text=Scenario Date: +lblStatus.text=Status: title=Customize Scenario -title.new=New Scenario \ No newline at end of file +title.new=New Scenario +btnAddLoot.text=Add Loot +btnEditLoot.text=Edit Loot +btnDeleteLoot.text=Delete Loot \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index c8e02ac1e2..54fc450cd7 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -50,6 +50,7 @@ */ public class CustomizeScenarioDialog extends JDialog { private JFrame frame; + private Scenario scenario; private Mission mission; private Campaign campaign; @@ -57,29 +58,49 @@ public class CustomizeScenarioDialog extends JDialog { private LocalDate date; private PlanetaryConditions planetaryConditions; - private LootTableModel lootModel; - - private JButton btnAdd; - private JButton btnEdit; - private JButton btnDelete; + // begin: loot private ArrayList loots; private JTable lootTable; - private JPanel panLoot; - - private JComboBox modifierBox; + private LootTableModel lootModel; + // end: loot + // begin: panels private JPanel panMain; + private JPanel panLeft; + private JPanel panRight; + private JPanel panLoot; private JPanel panBtn; - private JButton btnClose; - private JButton btnOK; + // end: panels + + // begin: labels private JLabel lblName; + private JLabel lblDate; + private JLabel lblStatus; + // end: labels + + // begin: textfields private JTextField txtName; - private MarkdownEditorPanel txtDesc; - private MarkdownEditorPanel txtReport; + // end: textfields + + // begin: comboboxes + private JComboBox modifierBox; private JComboBox choiceStatus; - private JLabel lblStatus; + //end: comboboxes + + // begin: buttons private JButton btnDate; private JButton btnPlanetaryConditions; + private JButton btnAddLoot; + private JButton btnEditLoot; + private JButton btnDeleteLoot; + private JButton btnClose; + private JButton btnOK; + // end: buttons + + // begin: markdown editors + private MarkdownEditorPanel txtDesc; + private MarkdownEditorPanel txtReport; + // end: markdown editors public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission m, Campaign c) { super(parent, modal); @@ -112,58 +133,51 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission } private void initComponents() { - txtName = new JTextField(); - lblName = new JLabel(); - btnOK = new JButton(); - btnClose = new JButton(); - lblStatus = new JLabel(); - panMain = new JPanel(); - panBtn = new JPanel(); - choiceStatus = new JComboBox<>(); - + getContentPane().setLayout(new BorderLayout()); final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.CustomizeScenarioDialog", MekHQ.getMHQOptions().getLocale()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setName("Form"); setTitle(resourceMap.getString("title.new")); - getContentPane().setLayout(new BorderLayout()); - panMain.setLayout(new GridBagLayout()); - panBtn.setLayout(new GridLayout(0,2)); + // set up panels + panMain = new JPanel(new GridLayout(0, 2)); + panLeft = new JPanel(new GridBagLayout()); + panRight = new JPanel(new GridBagLayout()); + panBtn = new JPanel(new GridLayout(0,2)); + + getContentPane().add(panMain, BorderLayout.CENTER); + getContentPane().add(panBtn, BorderLayout.PAGE_END); + panMain.add(panLeft); + panMain.add(panRight); - lblName.setText(resourceMap.getString("lblName.text")); - lblName.setName("lblName"); + // set up left panel + lblName = new JLabel(resourceMap.getString("lblName.text")); GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 1; gridBagConstraints.anchor = GridBagConstraints.WEST; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panMain.add(lblName, gridBagConstraints); + panLeft.add(lblName, gridBagConstraints); + txtName = new JTextField(); txtName.setText(scenario.getName()); - txtName.setName("txtName"); - gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 1; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 1; gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; - gridBagConstraints.anchor = GridBagConstraints.WEST; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panMain.add(txtName, gridBagConstraints); + panLeft.add(txtName, gridBagConstraints); - if (!scenario.getStatus().isCurrent()) { - lblStatus.setText(resourceMap.getString("lblStatus.text")); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panMain.add(lblStatus, gridBagConstraints); + lblStatus = new JLabel(resourceMap.getString("lblStatus.text")); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.fill = GridBagConstraints.NONE; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + panLeft.add(lblStatus, gridBagConstraints); - choiceStatus.setModel(new DefaultComboBoxModel<>(ScenarioStatus.values())); - choiceStatus.setName("choiceStatus"); - choiceStatus.setSelectedItem(scenario.getStatus()); - choiceStatus.setRenderer(new DefaultListCellRenderer() { + choiceStatus = new JComboBox<>(new DefaultComboBoxModel<>(ScenarioStatus.values())); + choiceStatus.setSelectedItem(scenario.getStatus()); + choiceStatus.setRenderer(new DefaultListCellRenderer() { @Override public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, @@ -174,66 +188,25 @@ public Component getListCellRendererComponent(final JList list, final Object } return this; } - }); - gridBagConstraints.gridx = 1; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panMain.add(choiceStatus, gridBagConstraints); - } - - btnDate = new JButton(); - btnDate.setText(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); - btnDate.addActionListener(evt -> changeDate()); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 0.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panMain.add(btnDate, gridBagConstraints); - - btnPlanetaryConditions = new JButton(); - btnPlanetaryConditions.setText("Planetary Conditions"); - btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 0.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + }); + gridBagConstraints.gridx = 1; gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panMain.add(btnPlanetaryConditions, gridBagConstraints); + choiceStatus.setEnabled(!scenario.getStatus().isCurrent()); + panLeft.add(choiceStatus, gridBagConstraints); - if (scenario.getStatus().isCurrent()) { - initLootPanel(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.anchor = GridBagConstraints.WEST; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLoot.setPreferredSize(new Dimension(400,150)); - panLoot.setMinimumSize(new Dimension(400,150)); - panLoot.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Scenario Costs & Payouts"), - BorderFactory.createEmptyBorder(5,5,5,5))); - panMain.add(panLoot, gridBagConstraints); - } - - txtDesc = new MarkdownEditorPanel("Description"); - txtDesc.setText(scenario.getDescription()); - txtDesc.setMinimumSize(new Dimension(400, 100)); - txtDesc.setPreferredSize(new Dimension(400, 250)); + lblDate = new JLabel(resourceMap.getString("lblDate.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.gridwidth = 1; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panMain.add(txtDesc, gridBagConstraints); + panLeft.add(lblDate, gridBagConstraints); + + btnDate = new JButton(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); + btnDate.addActionListener(evt -> changeDate()); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridwidth = 1; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + panLeft.add(btnDate, gridBagConstraints); if (scenario.getStatus().isCurrent() && (scenario instanceof AtBDynamicScenario)) { gridBagConstraints.gridx = 0; @@ -249,14 +222,55 @@ public Component getListCellRendererComponent(final JList list, final Object modifierBox.addItem(modifierKey); } } - panMain.add(modifierBox, gridBagConstraints); + panLeft.add(modifierBox, gridBagConstraints); JButton addEventButton = new JButton("Apply Modifier"); addEventButton.addActionListener(this::btnAddModifierActionPerformed); gridBagConstraints.gridx = 1; - panMain.add(addEventButton, gridBagConstraints); + panLeft.add(addEventButton, gridBagConstraints); } + btnPlanetaryConditions = new JButton(); + btnPlanetaryConditions.setText("Planetary Conditions"); + btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); + btnPlanetaryConditions.setEnabled(scenario.getStatus().isCurrent()); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.fill = GridBagConstraints.NONE; + gridBagConstraints.insets = new Insets(5, 5, 0, 0); + panLeft.add(btnPlanetaryConditions, gridBagConstraints); + + initLootPanel(resourceMap); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.insets = new Insets(5, 5, 5, 5); + panLoot.setPreferredSize(new Dimension(400,150)); + panLoot.setMinimumSize(new Dimension(400,150)); + panLoot.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder("Scenario Costs & Payouts"), + BorderFactory.createEmptyBorder(5,5,5,5))); + panLeft.add(panLoot, gridBagConstraints); + + //set up right panel + txtDesc = new MarkdownEditorPanel("Description"); + txtDesc.setText(scenario.getDescription()); + txtDesc.setMinimumSize(new Dimension(400, 100)); + txtDesc.setPreferredSize(new Dimension(400, 250)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy++; + gridBagConstraints.gridwidth = 1; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.insets = new Insets(5, 5, 5, 5); + panRight.add(txtDesc, gridBagConstraints); + if (!scenario.getStatus().isCurrent()) { txtReport = new MarkdownEditorPanel("After-Action Report"); txtReport.setText(scenario.getReport()); @@ -264,15 +278,16 @@ public Component getListCellRendererComponent(final JList list, final Object txtReport.setPreferredSize(new Dimension(400, 250)); gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; + gridBagConstraints.gridwidth = 1; gridBagConstraints.weightx = 1.0; gridBagConstraints.weighty = 1.0; gridBagConstraints.fill = GridBagConstraints.BOTH; gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panMain.add(txtReport, gridBagConstraints); + panRight.add(txtReport, gridBagConstraints); } + // set up buttons if (newScenario && (mission instanceof AtBContract)) { JButton btnLoad = new JButton("Generate From Template"); btnLoad.addActionListener(this::btnLoadActionPerformed); @@ -292,23 +307,14 @@ public Component getListCellRendererComponent(final JList list, final Object panBtn.add(btnFinalize); } - btnOK.setText(resourceMap.getString("btnOkay.text")); - btnOK.setName("btnOK"); + btnOK = new JButton(resourceMap.getString("btnOkay.text")); btnOK.addActionListener(this::btnOKActionPerformed); panBtn.add(btnOK); - btnClose.setText(resourceMap.getString("btnCancel.text")); - btnClose.setName("btnClose"); + btnClose = new JButton(resourceMap.getString("btnCancel.text")); btnClose.addActionListener(this::btnCloseActionPerformed); - gridBagConstraints.gridx = GridBagConstraints.RELATIVE; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.anchor = GridBagConstraints.CENTER; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); panBtn.add(btnClose); - getContentPane().add(panMain, BorderLayout.CENTER); - getContentPane().add(panBtn, BorderLayout.PAGE_END); - pack(); } @@ -409,23 +415,26 @@ private void changePlanetaryConditions() { } } - private void initLootPanel() { + private void initLootPanel(ResourceBundle resourceMap) { panLoot = new JPanel(new BorderLayout()); JPanel panBtns = new JPanel(new GridLayout(1,0)); - btnAdd = new JButton("Add Loot"); - btnAdd.addActionListener(evt -> addLoot()); - panBtns.add(btnAdd); - - btnEdit = new JButton("Edit Loot"); - btnEdit.setEnabled(false); - btnEdit.addActionListener(evt -> editLoot()); - panBtns.add(btnEdit); - - btnDelete = new JButton("Delete Loot"); - btnDelete.setEnabled(false); - btnDelete.addActionListener(evt -> deleteLoot()); - panBtns.add(btnDelete); + btnAddLoot = new JButton(resourceMap.getString("btnAddLoot.text")); + btnAddLoot.addActionListener(evt -> addLoot()); + btnAddLoot.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnAddLoot); + + btnEditLoot = new JButton(resourceMap.getString("btnEditLoot.text")); + btnEditLoot.setEnabled(false); + btnEditLoot.addActionListener(evt -> editLoot()); + btnEditLoot.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnEditLoot); + + btnDeleteLoot = new JButton(resourceMap.getString("btnDeleteLoot.text")); + btnDeleteLoot.setEnabled(false); + btnDeleteLoot.addActionListener(evt -> deleteLoot()); + btnDeleteLoot.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnDeleteLoot); panLoot.add(panBtns, BorderLayout.PAGE_START); lootTable = new JTable(lootModel); @@ -445,8 +454,8 @@ private void initLootPanel() { private void lootTableValueChanged(ListSelectionEvent evt) { int row = lootTable.getSelectedRow(); - btnDelete.setEnabled(row != -1); - btnEdit.setEnabled(row != -1); + btnDeleteLoot.setEnabled(row != -1); + btnEditLoot.setEnabled(row != -1); } private void addLoot() { From aca003075970cb56500458851b0ac286dc74c4fb Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 1 Apr 2024 20:48:05 -0700 Subject: [PATCH 04/76] Add planetary conditions panel to CustomizeScenarioDialog --- .../CustomizeScenarioDialog.properties | 16 +- .../gui/dialog/CustomizeScenarioDialog.java | 169 +++++++++++++++++- 2 files changed, 177 insertions(+), 8 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 7a062d1122..ea654f3f37 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -7,4 +7,18 @@ title=Customize Scenario title.new=New Scenario btnAddLoot.text=Add Loot btnEditLoot.text=Edit Loot -btnDeleteLoot.text=Delete Loot \ No newline at end of file +btnDeleteLoot.text=Delete Loot +btnPlanetaryConditions.text=Edit Planetary Conditions... +panPlanetaryConditions.title=Planetary Conditions +lblLight.text=Light: +lblWeather.text=Weather: +lblWind.text=Wind: +lblFog.text=Fog: +lblBlowingSand.text=Blowing Sand: +lblEMI.text=EMI: +lblAtmosphere.text=Atmosphere: +lblGravity.text=Gravity: +lblTemperature.text=Temperature: +lblOtherConditions.text=Other: +emi.text=Electromagnetic interference +sand.text=Blowing sand diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 54fc450cd7..ecec82097f 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -23,6 +23,7 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; import megamek.client.ui.swing.PlanetaryConditionsDialog; +import megamek.common.planetaryconditions.Atmosphere; import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; import mekhq.campaign.Campaign; @@ -41,6 +42,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; +import java.text.DecimalFormat; import java.time.LocalDate; import java.util.ArrayList; import java.util.ResourceBundle; @@ -69,6 +71,7 @@ public class CustomizeScenarioDialog extends JDialog { private JPanel panLeft; private JPanel panRight; private JPanel panLoot; + private JPanel panPlanetaryConditions; private JPanel panBtn; // end: panels @@ -76,6 +79,16 @@ public class CustomizeScenarioDialog extends JDialog { private JLabel lblName; private JLabel lblDate; private JLabel lblStatus; + private JLabel lblLightDesc; + private JLabel lblWindDesc; + private JLabel lblAtmosphereDesc; + private JLabel lblWeatherDesc; + private JLabel lblFogDesc; + private JLabel lblBlowingSandDesc; + private JLabel lblEMIDesc; + private JLabel lblTemperatureDesc; + private JLabel lblGravityDesc; + private JLabel lblOtherConditionsDesc; // end: labels // begin: textfields @@ -230,15 +243,13 @@ public Component getListCellRendererComponent(final JList list, final Object panLeft.add(addEventButton, gridBagConstraints); } - btnPlanetaryConditions = new JButton(); - btnPlanetaryConditions.setText("Planetary Conditions"); - btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); - btnPlanetaryConditions.setEnabled(scenario.getStatus().isCurrent()); + initPlanetaryConditionsPanel(resourceMap); gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; - gridBagConstraints.fill = GridBagConstraints.NONE; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panLeft.add(btnPlanetaryConditions, gridBagConstraints); + gridBagConstraints.gridwidth = 2; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + panLeft.add(panPlanetaryConditions, gridBagConstraints); initLootPanel(resourceMap); gridBagConstraints.gridx = 0; @@ -285,6 +296,7 @@ public Component getListCellRendererComponent(final JList list, final Object gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; gridBagConstraints.insets = new Insets(5, 5, 5, 5); panRight.add(txtReport, gridBagConstraints); + txtReport.setEnabled(!scenario.getStatus().isCurrent()); } // set up buttons @@ -408,11 +420,154 @@ private void changeDate() { } } + private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { + panPlanetaryConditions = new JPanel(new GridBagLayout()); + panPlanetaryConditions.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 0, 10, 0), + BorderFactory.createTitledBorder(resourceMap.getString("panPlanetaryConditions.title")))); + + btnPlanetaryConditions = new JButton(resourceMap.getString("btnPlanetaryConditions.text")); + btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); + btnPlanetaryConditions.setEnabled(scenario.getStatus().isCurrent()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 4; + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 0, 0, 0); + panPlanetaryConditions.add(btnPlanetaryConditions, gbc); + + GridBagConstraints leftGbc = new GridBagConstraints(); + leftGbc.gridx = 0; + leftGbc.gridy = 0; + leftGbc.gridwidth = 1; + leftGbc.weightx = 0.0; + leftGbc.weighty = 0.0; + leftGbc.insets = new Insets(0, 0, 5, 10); + leftGbc.fill = GridBagConstraints.NONE; + leftGbc.anchor = GridBagConstraints.NORTHWEST; + + GridBagConstraints rightGbc = new GridBagConstraints(); + rightGbc.gridx = 1; + rightGbc.gridy = 0; + rightGbc.gridwidth = 1; + rightGbc.weightx = 0.5; + rightGbc.weighty = 0.0; + rightGbc.insets = new Insets(0, 10, 5, 0); + rightGbc.fill = GridBagConstraints.NONE; + rightGbc.anchor = GridBagConstraints.NORTHWEST; + + JLabel lblLight = new JLabel(resourceMap.getString("lblLight.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblLight, leftGbc); + + lblLightDesc = new JLabel(scenario.getLight().toString()); + rightGbc.gridy++; + panPlanetaryConditions.add(lblLightDesc, rightGbc); + + JLabel lblWeather = new JLabel(resourceMap.getString("lblWeather.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblWeather, leftGbc); + + lblWeatherDesc = new JLabel(scenario.getWeather().toString()); + rightGbc.gridy++; + panPlanetaryConditions.add(lblWeatherDesc, rightGbc); + + JLabel lblWind = new JLabel(resourceMap.getString("lblWind.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblWind, leftGbc); + + lblWindDesc = new JLabel(scenario.getWind().toString()); + rightGbc.gridy++; + panPlanetaryConditions.add(lblWindDesc, rightGbc); + + JLabel lblFog = new JLabel(resourceMap.getString("lblFog.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblFog, leftGbc); + + lblFogDesc = new JLabel(scenario.getFog().toString()); + rightGbc.gridy++; + panPlanetaryConditions.add(lblFogDesc, rightGbc); + + JLabel lblOtherConditions = new JLabel(resourceMap.getString("lblOtherConditions.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblOtherConditions, leftGbc); + + ArrayList otherConditions = new ArrayList<>(); + if (scenario.getEMI().isEMI()) { + otherConditions.add(resourceMap.getString("emi.text")); + } + if (scenario.getBlowingSand().isBlowingSand()) { + otherConditions.add(resourceMap.getString("sand.text")); + } + + lblOtherConditionsDesc = new JLabel(String.join(", ", otherConditions)); + if (otherConditions.isEmpty()) { + lblOtherConditionsDesc.setText("None"); + } + rightGbc.gridy++; + rightGbc.gridwidth = 3; + panPlanetaryConditions.add(lblOtherConditionsDesc, rightGbc); + + JLabel lblTemperature = new JLabel(resourceMap.getString("lblTemperature.text")); + leftGbc.gridx = 2; + leftGbc.gridy = 1; + panPlanetaryConditions.add(lblTemperature, leftGbc); + + lblTemperatureDesc = new JLabel(PlanetaryConditions.getTemperatureDisplayableName(scenario.getModifiedTemperature())); + rightGbc.gridx = 3; + rightGbc.gridy = 1; + rightGbc.gridwidth = 1; + panPlanetaryConditions.add(lblTemperatureDesc, rightGbc); + + JLabel lblGravity = new JLabel(resourceMap.getString("lblGravity.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblGravity, leftGbc); + + lblGravityDesc = new JLabel(DecimalFormat.getInstance().format(scenario.getGravity())); + rightGbc.gridy++; + panPlanetaryConditions.add(lblGravityDesc, rightGbc); + + JLabel lblAtmosphere = new JLabel(resourceMap.getString("lblAtmosphere.text")); + leftGbc.gridy++; + panPlanetaryConditions.add(lblAtmosphere, leftGbc); + + lblAtmosphereDesc = new JLabel(scenario.getAtmosphere().toString()); + rightGbc.gridy++; + panPlanetaryConditions.add(lblAtmosphereDesc, rightGbc); + + + } + + private void refreshPlanetaryConditions() { + lblLightDesc.setText(planetaryConditions.getLight().toString()); + lblAtmosphereDesc.setText(planetaryConditions.getAtmosphere().toString()); + lblWeatherDesc.setText(planetaryConditions.getWeather().toString()); + lblFogDesc.setText(planetaryConditions.getFog().toString()); + lblWindDesc.setText(planetaryConditions.getWind().toString()); + lblGravityDesc.setText(DecimalFormat.getInstance().format(planetaryConditions.getGravity())); + lblTemperatureDesc.setText(PlanetaryConditions.getTemperatureDisplayableName(planetaryConditions.getTemperature())); + ArrayList otherConditions = new ArrayList<>(); + if (planetaryConditions.getEMI().isEMI()) { + otherConditions.add("Electromagnetic interference"); + } + if (planetaryConditions.getBlowingSand().isBlowingSand()) { + otherConditions.add("Blowing sand"); + } + if (otherConditions.isEmpty()) { + lblOtherConditionsDesc.setText("None"); + } else { + lblOtherConditionsDesc.setText(String.join(", ", otherConditions)); + } + } + private void changePlanetaryConditions() { PlanetaryConditionsDialog pc = new PlanetaryConditionsDialog(frame, planetaryConditions); if(pc.showDialog()) { planetaryConditions = pc.getConditions(); } + refreshPlanetaryConditions(); } private void initLootPanel(ResourceBundle resourceMap) { From 59bb9dde2478c21153e3c253bbab48a2a2dc8a13 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 5 Apr 2024 16:49:51 -0700 Subject: [PATCH 05/76] Remove Jlabel definitions where not needed --- .../gui/dialog/CustomizeScenarioDialog.java | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index c2ed238cb0..90fac1ea6d 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -76,9 +76,6 @@ public class CustomizeScenarioDialog extends JDialog { // end: panels // begin: labels - private JLabel lblName; - private JLabel lblDate; - private JLabel lblStatus; private JLabel lblLightDesc; private JLabel lblWindDesc; private JLabel lblAtmosphereDesc; @@ -166,14 +163,13 @@ private void initComponents() { panMain.add(panRight); // set up left panel - lblName = new JLabel(resourceMap.getString("lblName.text")); GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; gridBagConstraints.gridwidth = 1; gridBagConstraints.anchor = GridBagConstraints.WEST; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLeft.add(lblName, gridBagConstraints); + panLeft.add(new JLabel(resourceMap.getString("lblName.text")), gridBagConstraints); txtName = new JTextField(); txtName.setText(scenario.getName()); @@ -182,12 +178,11 @@ private void initComponents() { gridBagConstraints.insets = new Insets(5, 5, 5, 5); panLeft.add(txtName, gridBagConstraints); - lblStatus = new JLabel(resourceMap.getString("lblStatus.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; gridBagConstraints.fill = GridBagConstraints.NONE; gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panLeft.add(lblStatus, gridBagConstraints); + panLeft.add(new JLabel(resourceMap.getString("lblStatus.text")), gridBagConstraints); choiceStatus = new JComboBox<>(new DefaultComboBoxModel<>(ScenarioStatus.values())); choiceStatus.setSelectedItem(scenario.getStatus()); @@ -208,12 +203,11 @@ public Component getListCellRendererComponent(final JList list, final Object choiceStatus.setEnabled(!scenario.getStatus().isCurrent()); panLeft.add(choiceStatus, gridBagConstraints); - lblDate = new JLabel(resourceMap.getString("lblDate.text")); gridBagConstraints.gridx = 0; gridBagConstraints.gridy++; gridBagConstraints.gridwidth = 1; gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLeft.add(lblDate, gridBagConstraints); + panLeft.add(new JLabel(resourceMap.getString("lblDate.text")), gridBagConstraints); btnDate = new JButton(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); btnDate.addActionListener(evt -> changeDate()); @@ -459,41 +453,36 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { rightGbc.fill = GridBagConstraints.NONE; rightGbc.anchor = GridBagConstraints.NORTHWEST; - JLabel lblLight = new JLabel(resourceMap.getString("lblLight.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblLight, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblLight.text")), leftGbc); lblLightDesc = new JLabel(scenario.getLight().toString()); rightGbc.gridy++; panPlanetaryConditions.add(lblLightDesc, rightGbc); - JLabel lblWeather = new JLabel(resourceMap.getString("lblWeather.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblWeather, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblWeather.text")), leftGbc); lblWeatherDesc = new JLabel(scenario.getWeather().toString()); rightGbc.gridy++; panPlanetaryConditions.add(lblWeatherDesc, rightGbc); - JLabel lblWind = new JLabel(resourceMap.getString("lblWind.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblWind, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblWind.text")), leftGbc); lblWindDesc = new JLabel(scenario.getWind().toString()); rightGbc.gridy++; panPlanetaryConditions.add(lblWindDesc, rightGbc); - JLabel lblFog = new JLabel(resourceMap.getString("lblFog.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblFog, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblFog.text")), leftGbc); lblFogDesc = new JLabel(scenario.getFog().toString()); rightGbc.gridy++; panPlanetaryConditions.add(lblFogDesc, rightGbc); - JLabel lblOtherConditions = new JLabel(resourceMap.getString("lblOtherConditions.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblOtherConditions, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblOtherConditions.text")), leftGbc); ArrayList otherConditions = new ArrayList<>(); if (scenario.getEMI().isEMI()) { @@ -511,10 +500,9 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { rightGbc.gridwidth = 3; panPlanetaryConditions.add(lblOtherConditionsDesc, rightGbc); - JLabel lblTemperature = new JLabel(resourceMap.getString("lblTemperature.text")); leftGbc.gridx = 2; leftGbc.gridy = 1; - panPlanetaryConditions.add(lblTemperature, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblTemperature.text")), leftGbc); lblTemperatureDesc = new JLabel(PlanetaryConditions.getTemperatureDisplayableName(scenario.getModifiedTemperature())); rightGbc.gridx = 3; @@ -522,17 +510,15 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { rightGbc.gridwidth = 1; panPlanetaryConditions.add(lblTemperatureDesc, rightGbc); - JLabel lblGravity = new JLabel(resourceMap.getString("lblGravity.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblGravity, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblGravity.text")), leftGbc); lblGravityDesc = new JLabel(DecimalFormat.getInstance().format(scenario.getGravity())); rightGbc.gridy++; panPlanetaryConditions.add(lblGravityDesc, rightGbc); - JLabel lblAtmosphere = new JLabel(resourceMap.getString("lblAtmosphere.text")); leftGbc.gridy++; - panPlanetaryConditions.add(lblAtmosphere, leftGbc); + panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblAtmosphere.text")), leftGbc); lblAtmosphereDesc = new JLabel(scenario.getAtmosphere().toString()); rightGbc.gridy++; From ef1662d64a43aa912949667ac5cad4f705cd2ad5 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 10 Apr 2024 14:14:43 -0700 Subject: [PATCH 06/76] Add BotForce Table to scenario dialog --- .../CustomizeScenarioDialog.properties | 4 + .../gui/dialog/CustomizeScenarioDialog.java | 157 ++++++++++++--- .../mekhq/gui/model/BotForceTableModel.java | 185 ++++++++++++++++++ 3 files changed, 323 insertions(+), 23 deletions(-) create mode 100644 MekHQ/src/mekhq/gui/model/BotForceTableModel.java diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index ea654f3f37..d9bdbeaece 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -22,3 +22,7 @@ lblTemperature.text=Temperature: lblOtherConditions.text=Other: emi.text=Electromagnetic interference sand.text=Blowing sand +panOtherForces.title=Other Forces +btnAddForce.text=Add Force +btnEditForce.text=Edit Force +btnDeleteForce.text=Delete Force diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 90fac1ea6d..3242bbdf59 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -32,6 +32,7 @@ import mekhq.campaign.mission.atb.AtBScenarioModifier.EventTiming; import mekhq.campaign.mission.enums.ScenarioStatus; import mekhq.gui.FileDialogs; +import mekhq.gui.model.BotForceTableModel; import mekhq.gui.model.LootTableModel; import mekhq.gui.utilities.MarkdownEditorPanel; import org.apache.logging.log4j.LogManager; @@ -39,43 +40,53 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.table.TableColumn; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; import java.text.DecimalFormat; import java.time.LocalDate; import java.util.ArrayList; +import java.util.List; import java.util.ResourceBundle; /** * @author Taharqa */ public class CustomizeScenarioDialog extends JDialog { - private JFrame frame; + // region Variable declarations + private JFrame frame; private Scenario scenario; private Mission mission; private Campaign campaign; private boolean newScenario; private LocalDate date; private PlanetaryConditions planetaryConditions; + private List botForces; - // begin: loot + // loot private ArrayList loots; private JTable lootTable; private LootTableModel lootModel; - // end: loot - // begin: panels + // other forces + private JTable forcesTable; + private BotForceTableModel forcesModel; + + // panels private JPanel panMain; private JPanel panLeft; + private JPanel panCenter; private JPanel panRight; private JPanel panLoot; + private JPanel panOtherForces; private JPanel panPlanetaryConditions; private JPanel panBtn; - // end: panels - // begin: labels + // labels private JLabel lblLightDesc; private JLabel lblWindDesc; private JLabel lblAtmosphereDesc; @@ -88,30 +99,29 @@ public class CustomizeScenarioDialog extends JDialog { private JLabel lblOtherConditionsDesc; // end: labels - // begin: textfields + // textfields private JTextField txtName; - // end: textfields - // begin: comboboxes + // comboboxes private JComboBox modifierBox; private JComboBox choiceStatus; - //end: comboboxes - // begin: buttons + // buttons private JButton btnDate; private JButton btnPlanetaryConditions; private JButton btnAddLoot; private JButton btnEditLoot; private JButton btnDeleteLoot; + private JButton btnAddForce; + private JButton btnEditForce; + private JButton btnDeleteForce; private JButton btnClose; private JButton btnOK; - // end: buttons - // begin: markdown editors + // markdown editors private MarkdownEditorPanel txtDesc; private MarkdownEditorPanel txtReport; - // end: markdown editors - + //endregion Variable declarations public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission m, Campaign c) { super(parent, modal); @@ -132,6 +142,9 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission planetaryConditions = scenario.createPlanetaryConditions(); + botForces = scenario.getBotForces(); + forcesModel = new BotForceTableModel(botForces, campaign); + loots = new ArrayList<>(); for (Loot loot : scenario.getLoot()) { loots.add((Loot) loot.clone()); @@ -152,17 +165,19 @@ private void initComponents() { setTitle(resourceMap.getString("title.new")); // set up panels - panMain = new JPanel(new GridLayout(0, 2)); + panMain = new JPanel(new GridLayout(0, 3)); panLeft = new JPanel(new GridBagLayout()); + panCenter = new JPanel(new GridBagLayout()); panRight = new JPanel(new GridBagLayout()); panBtn = new JPanel(new GridLayout(0,2)); getContentPane().add(panMain, BorderLayout.CENTER); getContentPane().add(panBtn, BorderLayout.PAGE_END); panMain.add(panLeft); + panMain.add(panCenter); panMain.add(panRight); - // set up left panel + // region Set up left panel GridBagConstraints gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; @@ -260,8 +275,27 @@ public Component getListCellRendererComponent(final JList list, final Object BorderFactory.createTitledBorder("Scenario Costs & Payouts"), BorderFactory.createEmptyBorder(5,5,5,5))); panLeft.add(panLoot, gridBagConstraints); + // endregion Set up left panel - //set up right panel + // region Set up center panel + initOtherForcesPanel(resourceMap); + panOtherForces.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 0, 10, 0), + BorderFactory.createTitledBorder(resourceMap.getString("panOtherForces.title")))); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.gridwidth = 1; + gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.weighty = 1.0; + gridBagConstraints.fill = GridBagConstraints.BOTH; + gridBagConstraints.insets = new Insets(5, 5, 5, 5); + panCenter.add(panOtherForces, gridBagConstraints); + + // endregion Set up center panel + + // region Set up right panel txtDesc = new MarkdownEditorPanel("Description"); txtDesc.setText(scenario.getDescription()); txtDesc.setMinimumSize(new Dimension(400, 100)); @@ -293,8 +327,9 @@ public Component getListCellRendererComponent(final JList list, final Object panRight.add(txtReport, gridBagConstraints); txtReport.setEnabled(!scenario.getStatus().isCurrent()); } + // endregion Set up right panel - // set up buttons + // region Set up buttons if (newScenario && (mission instanceof AtBContract)) { JButton btnLoad = new JButton("Generate From Template"); btnLoad.addActionListener(this::btnLoadActionPerformed); @@ -321,6 +356,7 @@ public Component getListCellRendererComponent(final JList list, final Object btnClose = new JButton(resourceMap.getString("btnCancel.text")); btnClose.addActionListener(this::btnCloseActionPerformed); panBtn.add(btnClose); + //endregion Set up buttons pack(); } @@ -606,7 +642,7 @@ private void addLoot() { if (null != ekld.getLoot()) { lootModel.addLoot(ekld.getLoot()); } - refreshTable(); + refreshLootTable(); } private void editLoot() { @@ -614,7 +650,7 @@ private void editLoot() { if (null != loot) { LootDialog ekld = new LootDialog(frame, true, loot, campaign); ekld.setVisible(true); - refreshTable(); + refreshLootTable(); } } @@ -623,10 +659,10 @@ private void deleteLoot() { if (-1 != row) { loots.remove(row); } - refreshTable(); + refreshLootTable(); } - private void refreshTable() { + private void refreshLootTable() { int selectedRow = lootTable.getSelectedRow(); lootModel.setData(loots); if (selectedRow != -1) { @@ -640,6 +676,81 @@ private void refreshTable() { } } + private void initOtherForcesPanel(ResourceBundle resourceMap) { + panOtherForces = new JPanel(new BorderLayout()); + + JPanel panBtns = new JPanel(new GridLayout(1,0)); + btnAddForce = new JButton(resourceMap.getString("btnAddForce.text")); + btnAddForce.addActionListener(evt -> addForce()); + btnAddForce.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnAddForce); + + btnEditForce = new JButton(resourceMap.getString("btnEditForce.text")); + btnEditForce.setEnabled(false); + btnEditForce.addActionListener(evt -> editForce()); + btnEditForce.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnEditForce); + + btnDeleteForce = new JButton(resourceMap.getString("btnDeleteForce.text")); + btnDeleteForce.setEnabled(false); + btnDeleteForce.addActionListener(evt -> deleteForce()); + btnDeleteForce.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnDeleteForce); + panOtherForces.add(panBtns, BorderLayout.PAGE_START); + + forcesTable = new JTable(forcesModel); + TableColumn column; + for (int i = 0; i < BotForceTableModel.N_COL; i++) { + column = forcesTable.getColumnModel().getColumn(i); + column.setPreferredWidth(forcesModel.getColumnWidth(i)); + column.setCellRenderer(forcesModel.getRenderer()); + } + forcesTable.setIntercellSpacing(new Dimension(0, 0)); + forcesTable.setShowGrid(false); + forcesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + forcesTable.getSelectionModel().addListSelectionListener(this::forcesTableValueChanged); + + panOtherForces.add(new JScrollPane(forcesTable), BorderLayout.CENTER); + } + + private void forcesTableValueChanged(ListSelectionEvent evt) { + int row = forcesTable.getSelectedRow(); + btnDeleteForce.setEnabled(row != -1); + btnEditForce.setEnabled(row != -1); + } + + private void addForce() { + // TODO: BotForceEditorDialog + refreshForcesTable(); + } + + private void editForce() { + // TODO: BotForceEditorDialog + refreshForcesTable(); + } + + private void deleteForce() { + int row = forcesTable.getSelectedRow(); + if (-1 != row) { + botForces.remove(row); + } + refreshForcesTable(); + } + + private void refreshForcesTable() { + int selectedRow = forcesTable.getSelectedRow(); + forcesModel.setData(botForces); + if (selectedRow != -1) { + if (forcesTable.getRowCount() > 0) { + if (forcesTable.getRowCount() == selectedRow) { + forcesTable.setRowSelectionInterval(selectedRow-1, selectedRow-1); + } else { + forcesTable.setRowSelectionInterval(selectedRow, selectedRow); + } + } + } + } + /** * Event handler for the 'add modifier' button. * @param event diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java new file mode 100644 index 0000000000..42fb7942f6 --- /dev/null +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -0,0 +1,185 @@ +/* + * BotForceTableModel.java + * + * Copyright (c) 2009 Jay Lawson (jaylawson39 at yahoo.com). All rights reserved. + * Copyright (c) 2020 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.gui.model; + + +import megamek.common.IStartingPositions; +import mekhq.campaign.Campaign; +import mekhq.campaign.mission.BotForce; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; +import java.util.List; +import java.util.stream.Collectors; + +public class BotForceTableModel extends AbstractTableModel { + + //region Variable Declarations + protected String[] columnNames; + protected List data; + private Campaign campaign; + + public final static int COL_NAME = 0; + public final static int COL_RELATION = 1; + public final static int COL_FIXED = 2; + public final static int COL_RANDOM = 3; + public final static int COL_DEPLOYMENT = 4; + public final static int N_COL = 5; + //endregion Variable Declarations + + public BotForceTableModel(List entries, Campaign c) { + data = entries; + this.campaign = c; + } + + @Override + public int getRowCount() { + return data.size(); + } + + @Override + public int getColumnCount() { + return N_COL; + } + + @Override + public String getColumnName(int column) { + switch (column) { + case COL_NAME: + return "Name"; + case COL_RELATION: + return "Relation"; + case COL_FIXED: + return "Fixed"; + case COL_RANDOM: + return "Random"; + case COL_DEPLOYMENT: + return "Deployment"; + default: + return "?"; + } + } + + @Override + public Object getValueAt(int row, int col) { + BotForce botForce; + if (data.isEmpty()) { + return ""; + } else { + botForce = getBotForceAt(row); + } + + switch (col) { + case COL_NAME: + return botForce.getName(); + case COL_RELATION: + return (botForce.getTeam() == 1) ? "Allied" : "Enemy"; + case COL_FIXED: + return botForce.getTotalBV(campaign); + case COL_RANDOM: + return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer().getDescription()); + case COL_DEPLOYMENT: + return IStartingPositions.START_LOCATION_NAMES[botForce.getStart()]; + default: + return "?"; + } + } + + @Override + public boolean isCellEditable(int row, int col) { + return false; + } + + @Override + public Class getColumnClass(int c) { + return getValueAt(0, c).getClass(); + } + + public BotForce getBotForceAt(int row) { + return data.get(row); + } + + public void addForce(BotForce botForce) { + data.add(botForce); + fireTableDataChanged(); + } + + public List getAllBotForces() { + return data; + } + + public int getColumnWidth(int col) { + switch (col) { + case COL_NAME: + return 100; + default: + return 20; + } + } + + public int getAlignment(int col) { + switch (col) { + case COL_NAME: + case COL_RELATION: + return SwingConstants.LEFT; + case COL_DEPLOYMENT: + return SwingConstants.CENTER; + default: + return SwingConstants.RIGHT; + } + } + + public String getTooltip(int row, int col) { + switch (col) { + default: + return null; + } + } + + //fill table with values + public void setData(List botForce) { + data = botForce; + fireTableDataChanged(); + } + + public BotForceTableModel.Renderer getRenderer() { + return new BotForceTableModel.Renderer(); + } + + public class Renderer extends DefaultTableCellRenderer { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setOpaque(true); + int actualCol = table.convertColumnIndexToModel(column); + int actualRow = table.convertRowIndexToModel(row); + setHorizontalAlignment(getAlignment(actualCol)); + setToolTipText(getTooltip(actualRow, actualCol)); + + return this; + } + } +} From b225170cd67f99ac60fc2ce82ccf1d2dd89bdd3a Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 12:53:42 -0700 Subject: [PATCH 07/76] Add CustomizeBotForceDialog beginning --- .../CustomizeBotForceDialog.properties | 7 + .../gui/dialog/CustomizeBotForceDialog.java | 134 ++++++++++++++++++ .../gui/dialog/CustomizeScenarioDialog.java | 14 +- .../mekhq/gui/model/BotForceTableModel.java | 2 +- 4 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties create mode 100644 MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties new file mode 100644 index 0000000000..5877af08a9 --- /dev/null +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -0,0 +1,7 @@ +title=Customize BotForce +lblName.text=Name: +lblTeam.text=Team: +choiceTeam.text=Team +choiceAllied.text=Allied +btnOK.text=OK +btnClose.text=Cancel \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java new file mode 100644 index 0000000000..e6f0950758 --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.gui.dialog; + +import mekhq.MekHQ; +import mekhq.campaign.Campaign; +import mekhq.campaign.mission.BotForce; +import mekhq.campaign.mission.Mission; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.util.ResourceBundle; + +public class CustomizeBotForceDialog extends JDialog { + + private BotForce botForce; + private Campaign campaign; + + //gui components + private JTextField txtName; + private JComboBox choiceTeam; + private JButton btnClose; + private JButton btnOK; + + public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { + super(parent, modal); + if (null == bf) { + botForce = new BotForce(); + botForce.setName("New Bot Force"); + // assume enemy by default + botForce.setTeam(2); + } else { + botForce = bf; + } + campaign = c; + initComponents(); + setLocationRelativeTo(parent); + pack(); + } + + private void initComponents() { + + final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.CustomizeBotForceDialog", + MekHQ.getMHQOptions().getLocale()); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + setTitle(resourceMap.getString("title")); + + getContentPane().setLayout(new BorderLayout()); + JPanel panMain = new JPanel(new GridLayout(0, 2)); + JPanel panLeft = new JPanel(new GridBagLayout()); + JPanel panRight = new JPanel(new GridBagLayout()); + panMain.add(panLeft); + panMain.add(panRight); + getContentPane().add(panMain, BorderLayout.CENTER); + + JPanel panButtons = new JPanel(new GridLayout(0, 2)); + btnOK = new JButton(resourceMap.getString("btnOK.text")); + btnOK.addActionListener(this::done); + btnClose = new JButton(resourceMap.getString("btnClose.text")); + btnClose.addActionListener(this::cancel); + panButtons.add(btnOK); + panButtons.add(btnClose); + getContentPane().add(panButtons, BorderLayout.PAGE_END); + + GridBagConstraints gbc; + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.gridwidth = 1; + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(5, 5, 5, 5); + panLeft.add(new JLabel(resourceMap.getString("lblName.text")), gbc); + + txtName = new JTextField(botForce.getName()); + gbc.gridx = 1; + gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + panLeft.add(txtName, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + gbc.weightx = 0.0; + gbc.fill = GridBagConstraints.NONE; + panLeft.add(new JLabel(resourceMap.getString("lblTeam.text")), gbc); + + choiceTeam = new JComboBox(); + for (int i = 1; i < 6; i++) { + String choice = resourceMap.getString("choiceTeam.text") + " " + i; + if (i ==1) { + choice = choice + " (" + resourceMap.getString("choiceAllied.text") + ")"; + } + choiceTeam.addItem(choice); + } + choiceTeam.setSelectedIndex(botForce.getTeam() - 1); + gbc.gridx = 1; + gbc.weightx = 1.0; + panLeft.add(choiceTeam, gbc); + + } + + public BotForce getBotForce() { + return botForce; + } + + private void done(ActionEvent evt) { + botForce.setName(txtName.getText()); + botForce.setTeam(choiceTeam.getSelectedIndex()+1); + this.setVisible(false); + } + private void cancel(ActionEvent evt) { + botForce = null; + this.setVisible(false); + } + +} diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 3242bbdf59..4ff4d893f8 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -720,13 +720,21 @@ private void forcesTableValueChanged(ListSelectionEvent evt) { } private void addForce() { - // TODO: BotForceEditorDialog + CustomizeBotForceDialog cbfd = new CustomizeBotForceDialog(frame, true, null, campaign); + cbfd.setVisible(true); + if (null != cbfd.getBotForce()) { + forcesModel.addForce(cbfd.getBotForce()); + } refreshForcesTable(); } private void editForce() { - // TODO: BotForceEditorDialog - refreshForcesTable(); + BotForce bf = forcesModel.getBotForceAt(forcesTable.getSelectedRow()); + if (null != bf) { + CustomizeBotForceDialog cbfd = new CustomizeBotForceDialog(frame, true, bf, campaign); + cbfd.setVisible(true); + refreshForcesTable(); + } } private void deleteForce() { diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java index 42fb7942f6..7d7a11fe4f 100644 --- a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -94,7 +94,7 @@ public Object getValueAt(int row, int col) { case COL_NAME: return botForce.getName(); case COL_RELATION: - return (botForce.getTeam() == 1) ? "Allied" : "Enemy"; + return (botForce.getTeam() == 1) ? "Allied" : "Enemy (Team " + botForce.getTeam() + ")"; case COL_FIXED: return botForce.getTotalBV(campaign); case COL_RANDOM: From 4cd36b2c789057a9219ff58240c58ae74b745e97 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 15:53:06 -0700 Subject: [PATCH 08/76] Add behavior settings to CustomizeBotForceDialog --- .../CustomizeBotForceDialog.properties | 11 +- .../gui/dialog/CustomizeBotForceDialog.java | 129 +++++++++++++++++- 2 files changed, 135 insertions(+), 5 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index 5877af08a9..bf1c704e44 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -1,7 +1,16 @@ title=Customize BotForce lblName.text=Name: lblTeam.text=Team: +panBehavior.title=Behavior choiceTeam.text=Team choiceAllied.text=Allied +lblCowardice.text=Cowardice: +lblSelfPreservation.text=Self-Preservation: +lblAggression.text=Aggression: +lblHerdMentality.text=Herd Mentality: +lblPilotingRisk.text=Piloting Risk: +lblForcedWithdrawal.text=Forced Withdrawal: +lblAutoFlee.text=Auto Flee: btnOK.text=OK -btnClose.text=Cancel \ No newline at end of file +btnClose.text=Cancel +btnBehavior.text=Edit Behavior Settings \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index e6f0950758..f8dcdecf01 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -18,6 +18,9 @@ */ package mekhq.gui.dialog; +import megamek.client.bot.princess.BehaviorSettings; +import megamek.client.bot.princess.CardinalEdge; +import megamek.client.ui.dialogs.BotConfigDialog; import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; @@ -30,17 +33,25 @@ public class CustomizeBotForceDialog extends JDialog { + private JFrame frame; private BotForce botForce; private Campaign campaign; //gui components private JTextField txtName; private JComboBox choiceTeam; - private JButton btnClose; - private JButton btnOK; + private JPanel panBehavior; + private JLabel lblCowardice; + private JLabel lblSelfPreservation; + private JLabel lblAggression; + private JLabel lblHerdMentality; + private JLabel lblPilotingRisk; + private JLabel lblForcedWithdrawal; + private JLabel lblAutoFlee; public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { super(parent, modal); + this.frame = parent; if (null == bf) { botForce = new BotForce(); botForce.setName("New Bot Force"); @@ -71,9 +82,9 @@ private void initComponents() { getContentPane().add(panMain, BorderLayout.CENTER); JPanel panButtons = new JPanel(new GridLayout(0, 2)); - btnOK = new JButton(resourceMap.getString("btnOK.text")); + JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); btnOK.addActionListener(this::done); - btnClose = new JButton(resourceMap.getString("btnClose.text")); + JButton btnClose = new JButton(resourceMap.getString("btnClose.text")); btnClose.addActionListener(this::cancel); panButtons.add(btnOK); panButtons.add(btnClose); @@ -115,12 +126,122 @@ private void initComponents() { gbc.weightx = 1.0; panLeft.add(choiceTeam, gbc); + intBehaviorPanel(resourceMap); + gbc.gridx = 0; + gbc.gridy = 2; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.gridwidth = 2; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.NONE; + panLeft.add(panBehavior, gbc); + + + } + + private void intBehaviorPanel(ResourceBundle resourceMap) { + panBehavior = new JPanel(new GridBagLayout()); + panBehavior.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder(resourceMap.getString("panBehavior.title")), + BorderFactory.createEmptyBorder(5,5,5,5))); + + BehaviorSettings behavior = botForce.getBehaviorSettings(); + + GridBagConstraints gbcLeft = new GridBagConstraints(); + gbcLeft.gridx = 0; + gbcLeft.gridy = 0; + gbcLeft.weightx = 0.0; + gbcLeft.weighty = 0.0; + gbcLeft.fill = GridBagConstraints.NONE; + gbcLeft.anchor = GridBagConstraints.WEST; + gbcLeft.insets = new Insets(0, 0, 0, 5); + + GridBagConstraints gbcRight = new GridBagConstraints(); + gbcRight.gridx = 1; + gbcRight.gridy = 0; + gbcRight.weightx = 1.0; + gbcRight.weighty = 0.0; + gbcRight.fill = GridBagConstraints.NONE; + gbcRight.anchor = GridBagConstraints.CENTER; + gbcRight.insets = new Insets(0, 5, 0, 0); + + lblCowardice = new JLabel(Integer.toString(behavior.getBraveryIndex())); + lblSelfPreservation = new JLabel(Integer.toString(behavior.getSelfPreservationIndex())); + lblAggression = new JLabel(Integer.toString(behavior.getHyperAggressionIndex())); + lblHerdMentality = new JLabel(Integer.toString(behavior.getHerdMentalityIndex())); + lblPilotingRisk = new JLabel(Integer.toString(behavior.getFallShameIndex())); + lblForcedWithdrawal = new JLabel(getForcedWithdrawalDescription(behavior)); + lblAutoFlee = new JLabel(getAutoFleeDescription(behavior)); + + + panBehavior.add(new JLabel(resourceMap.getString("lblCowardice.text")), gbcLeft); + panBehavior.add(lblCowardice, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblSelfPreservation.text")), gbcLeft); + panBehavior.add(lblSelfPreservation, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblAggression.text")), gbcLeft); + panBehavior.add(lblAggression, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblHerdMentality.text")), gbcLeft); + panBehavior.add(lblHerdMentality, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblPilotingRisk.text")), gbcLeft); + panBehavior.add(lblPilotingRisk, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblForcedWithdrawal.text")), gbcLeft); + panBehavior.add(lblForcedWithdrawal, gbcRight); + gbcLeft.gridy++; + gbcRight.gridy++; + panBehavior.add(new JLabel(resourceMap.getString("lblAutoFlee.text")), gbcLeft); + panBehavior.add(lblAutoFlee, gbcRight); + + JButton btnBehavior = new JButton(resourceMap.getString("btnBehavior.text")); + btnBehavior.addActionListener(this::editBehavior); + gbcLeft.gridy++; + gbcLeft.gridwidth = 2; + panBehavior.add(btnBehavior, gbcLeft); } public BotForce getBotForce() { return botForce; } + private void editBehavior(ActionEvent evt) { + BotConfigDialog bcd = new BotConfigDialog(frame, botForce.getName(), botForce.getBehaviorSettings(), null); + bcd.setVisible(true); + if(!bcd.getResult().isCancelled()) { + botForce.setBehaviorSettings(bcd.getBehaviorSettings()); + lblCowardice.setText(Integer.toString(botForce.getBehaviorSettings().getBraveryIndex())); + lblSelfPreservation.setText(Integer.toString(botForce.getBehaviorSettings().getSelfPreservationIndex())); + lblAggression.setText(Integer.toString(botForce.getBehaviorSettings().getHyperAggressionIndex())); + lblHerdMentality.setText(Integer.toString(botForce.getBehaviorSettings().getHerdMentalityIndex())); + lblPilotingRisk.setText(Integer.toString(botForce.getBehaviorSettings().getFallShameIndex())); + lblForcedWithdrawal.setText(getForcedWithdrawalDescription(botForce.getBehaviorSettings())); + lblAutoFlee.setText(getAutoFleeDescription(botForce.getBehaviorSettings())); + } + } + + private String getForcedWithdrawalDescription(BehaviorSettings behavior) { + if(!behavior.isForcedWithdrawal()) { + return "NONE"; + } else { + return behavior.getRetreatEdge().toString(); + } + } + private String getAutoFleeDescription(BehaviorSettings behavior) { + if(!behavior.shouldAutoFlee()) { + return "NO"; + } else { + return behavior.getDestinationEdge().toString(); + } + } + private void done(ActionEvent evt) { botForce.setName(txtName.getText()); botForce.setTeam(choiceTeam.getSelectedIndex()+1); From b7322bd57ba6cc73d291ecbfd5e95966a1c41f7a Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 16:06:06 -0700 Subject: [PATCH 09/76] Add camo selector to CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index f8dcdecf01..cd279c401a 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -21,6 +21,7 @@ import megamek.client.bot.princess.BehaviorSettings; import megamek.client.bot.princess.CardinalEdge; import megamek.client.ui.dialogs.BotConfigDialog; +import megamek.client.ui.dialogs.CamoChooserDialog; import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; @@ -40,6 +41,7 @@ public class CustomizeBotForceDialog extends JDialog { //gui components private JTextField txtName; private JComboBox choiceTeam; + private JButton btnCamo; private JPanel panBehavior; private JLabel lblCowardice; private JLabel lblSelfPreservation; @@ -126,14 +128,25 @@ private void initComponents() { gbc.weightx = 1.0; panLeft.add(choiceTeam, gbc); - intBehaviorPanel(resourceMap); + btnCamo = new JButton(); + btnCamo.setIcon(botForce.getCamouflage().getImageIcon()); + btnCamo.setMinimumSize(new Dimension(84, 72)); + btnCamo.setPreferredSize(new Dimension(84, 72)); + btnCamo.setMaximumSize(new Dimension(84, 72)); + btnCamo.addActionListener(this::editCamo); gbc.gridx = 0; gbc.gridy = 2; - gbc.weightx = 1.0; - gbc.weighty = 1.0; gbc.gridwidth = 2; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.NONE; + panLeft.add(btnCamo, gbc); + + + intBehaviorPanel(resourceMap); + gbc.gridx = 0; + gbc.gridy = 3; + gbc.weightx = 1.0; + gbc.weighty = 1.0; panLeft.add(panBehavior, gbc); @@ -227,6 +240,14 @@ private void editBehavior(ActionEvent evt) { } } + private void editCamo(ActionEvent evt) { + CamoChooserDialog ccd = new CamoChooserDialog(frame, botForce.getCamouflage()); + if (ccd.showDialog().isConfirmed()) { + botForce.setCamouflage(ccd.getSelectedItem()); + btnCamo.setIcon(botForce.getCamouflage().getImageIcon()); + } + } + private String getForcedWithdrawalDescription(BehaviorSettings behavior) { if(!behavior.isForcedWithdrawal()) { return "NONE"; From a18edb64a611eeca04b0d33d300df88fb455cc9d Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 16:21:34 -0700 Subject: [PATCH 10/76] Refactor scenario.generateBotStubs and scenario.getEntityStubs --- MekHQ/src/mekhq/Utilities.java | 16 ++++++++++ .../mekhq/campaign/mission/AtBScenario.java | 3 +- .../src/mekhq/campaign/mission/BotForce.java | 18 ++++++++---- .../src/mekhq/campaign/mission/Scenario.java | 29 +------------------ .../gui/dialog/CustomizeBotForceDialog.java | 1 + .../mekhq/gui/view/AtBScenarioViewPanel.java | 5 ++-- .../src/mekhq/gui/view/ScenarioViewPanel.java | 2 +- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/MekHQ/src/mekhq/Utilities.java b/MekHQ/src/mekhq/Utilities.java index fd0eb58ffe..c66ec110cf 100644 --- a/MekHQ/src/mekhq/Utilities.java +++ b/MekHQ/src/mekhq/Utilities.java @@ -1285,4 +1285,20 @@ public static MechSummary retrieveOriginalUnit(Entity newE) throws EntityLoading return summary; } + + public static List generateEntityStub(List entities) { + List stub = new ArrayList<>(); + for (Entity en : entities) { + if (null == en) { + stub.add("No random assignment table found for faction"); + } else { + stub.add("" + en.getCrew().getName() + " (" + + en.getCrew().getGunnery() + "/" + + en.getCrew().getPiloting() + "), " + + "" + en.getShortName() + "" + + ""); + } + } + return stub; + } } diff --git a/MekHQ/src/mekhq/campaign/mission/AtBScenario.java b/MekHQ/src/mekhq/campaign/mission/AtBScenario.java index ae90729ff6..2935371b9a 100644 --- a/MekHQ/src/mekhq/campaign/mission/AtBScenario.java +++ b/MekHQ/src/mekhq/campaign/mission/AtBScenario.java @@ -33,6 +33,7 @@ import megamek.common.planetaryconditions.Atmosphere; import mekhq.MHQConstants; import mekhq.MekHQ; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.againstTheBot.AtBConfiguration; import mekhq.campaign.againstTheBot.AtBStaticWeightGenerator; @@ -1478,7 +1479,7 @@ protected BotForce getEnemyBotForce(AtBContract c, int start, int home, List stubs = Utilities.generateEntityStub(getFullEntityList(c)); + return new BotForceStub("" + + getName() + " " + + ((getTeam() == 1) ? "Allied" : "Enemy") + "" + + " Start: " + IStartingPositions.START_LOCATION_NAMES[getStart()] + + " Fixed BV: " + getTotalBV(c) + + ((null == getBotForceRandomizer()) ? "" : "
Random: " + getBotForceRandomizer().getDescription()) + + "", stubs); + } + public void writeToXML(final PrintWriter pw, int indent) { MHQXMLUtility.writeSimpleXMLOpenTag(pw, indent++, "botForce"); MHQXMLUtility.writeSimpleXMLTag(pw, indent, "name", name); diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index ad272c489d..97f0603425 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -548,7 +548,7 @@ public void convertToStub(final Campaign campaign, final ScenarioStatus status) public void generateStub(Campaign c) { stub = new ForceStub(getForces(c), c); for (BotForce bf : botForces) { - botForcesStubs.add(generateBotStub(bf, c)); + botForcesStubs.add(bf.generateStub(c)); } botForces.clear(); } @@ -557,33 +557,6 @@ public ForceStub getForceStub() { return stub; } - public BotForceStub generateBotStub(BotForce bf, Campaign c) { - List stubs = generateEntityStub(bf.getFullEntityList(c)); - return new BotForceStub("" + - bf.getName() + " " + - ((bf.getTeam() == 1) ? "Allied" : "Enemy") + "" + - " Start: " + IStartingPositions.START_LOCATION_NAMES[bf.getStart()] + - " Fixed BV: " + bf.getTotalBV(c) + - ((null == bf.getBotForceRandomizer()) ? "" : "
Random: " + bf.getBotForceRandomizer().getDescription()) + - "", stubs); - } - - public List generateEntityStub(List entities) { - List stub = new ArrayList<>(); - for (Entity en : entities) { - if (null == en) { - stub.add("No random assignment table found for faction"); - } else { - stub.add("" + en.getCrew().getName() + " (" + - en.getCrew().getGunnery() + "/" + - en.getCrew().getPiloting() + "), " + - "" + en.getShortName() + "" + - ""); - } - } - return stub; - } - public boolean isAssigned(Unit unit, Campaign campaign) { for (UUID uid : getForces(campaign).getAllUnits(true)) { if (uid.equals(unit.getId())) { diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index cd279c401a..c1bb6acebb 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -25,6 +25,7 @@ import mekhq.MekHQ; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; +import mekhq.campaign.mission.BotForceStub; import mekhq.campaign.mission.Mission; import javax.swing.*; diff --git a/MekHQ/src/mekhq/gui/view/AtBScenarioViewPanel.java b/MekHQ/src/mekhq/gui/view/AtBScenarioViewPanel.java index fc0498b440..71f4cb1587 100644 --- a/MekHQ/src/mekhq/gui/view/AtBScenarioViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/AtBScenarioViewPanel.java @@ -28,6 +28,7 @@ import megamek.common.planetaryconditions.Atmosphere; import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.force.ForceStub; import mekhq.campaign.force.UnitStub; @@ -123,9 +124,9 @@ public AtBScenarioViewPanel(AtBScenario s, Campaign c, JFrame frame) { if (s.getStatus().isCurrent()) { s.refresh(c); this.playerForces = new ForceStub(s.getForces(campaign), campaign); - attachedAllyStub = s.generateEntityStub(s.getAlliesPlayer()); + attachedAllyStub = Utilities.generateEntityStub(s.getAlliesPlayer()); for (int i = 0; i < s.getNumBots(); i++) { - botStubs.add(s.generateBotStub(s.getBotForce(i), campaign)); + botStubs.add(s.getBotForce(i).generateStub(campaign)); } } else { this.playerForces = s.getForceStub(); diff --git a/MekHQ/src/mekhq/gui/view/ScenarioViewPanel.java b/MekHQ/src/mekhq/gui/view/ScenarioViewPanel.java index ed00252f36..7d169e91f4 100644 --- a/MekHQ/src/mekhq/gui/view/ScenarioViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/ScenarioViewPanel.java @@ -80,7 +80,7 @@ public ScenarioViewPanel(JFrame f, Campaign c, Scenario s) { botStubs = new ArrayList<>(); if (s.getStatus().isCurrent()) { for (int i = 0; i < s.getNumBots(); i++) { - botStubs.add(s.generateBotStub(s.getBotForce(i), campaign)); + botStubs.add(s.getBotForce(i).generateStub(campaign)); } } else { botStubs = s.getBotForcesStubs(); From 52fdaaf0c319dca813c6e6110d523806422eb8e9 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 20:22:03 -0700 Subject: [PATCH 11/76] Add editing of fixed entity bot forces by mul in CustomizeBotForceDialog --- .../CustomizeBotForceDialog.properties | 8 +- MekHQ/src/mekhq/gui/FileDialogs.java | 17 +++ .../gui/dialog/CustomizeBotForceDialog.java | 124 ++++++++++++++++-- 3 files changed, 137 insertions(+), 12 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index bf1c704e44..fafa894abc 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -13,4 +13,10 @@ lblForcedWithdrawal.text=Forced Withdrawal: lblAutoFlee.text=Auto Flee: btnOK.text=OK btnClose.text=Cancel -btnBehavior.text=Edit Behavior Settings \ No newline at end of file +btnBehavior.text=Edit Behavior Settings +btnLoadUnits.text=Load Units +btnLoadUnits.tooltip=Load units from a .mul file,
overwriting existing units +btnSaveUnits.text=Save Units +btnSaveUnits.tooltip=Save units to a .mul file +btnDeleteUnits.text=Delete Units +btnDeleteUnits.tooltip=Delete all units \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/FileDialogs.java b/MekHQ/src/mekhq/gui/FileDialogs.java index 32c8ba4538..873f9f325e 100644 --- a/MekHQ/src/mekhq/gui/FileDialogs.java +++ b/MekHQ/src/mekhq/gui/FileDialogs.java @@ -225,6 +225,23 @@ public static Optional saveDeployUnits(JFrame frame, Scenario scenario, St return value; } + /** + * Displays a dialog window from which the user can select a .mul file to save to. + * + * @return the file selected, if any + */ + public static Optional saveUnits(JFrame frame, String name) { + Optional value = GUI.fileDialogSave( + frame, + "Save Units", + FileType.MUL, + MekHQ.getUnitsDirectory().getValue(), + name + ".mul"); + + value.ifPresent(x -> MekHQ.getUnitsDirectory().setValue(x.getParent())); + return value; + } + /** * Displays a dialog window from which the user can select a campaign file to open. * diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index c1bb6acebb..cfc9419646 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -19,18 +19,26 @@ package mekhq.gui.dialog; import megamek.client.bot.princess.BehaviorSettings; -import megamek.client.bot.princess.CardinalEdge; import megamek.client.ui.dialogs.BotConfigDialog; import megamek.client.ui.dialogs.CamoChooserDialog; +import megamek.common.Entity; +import megamek.common.EntityListFile; +import megamek.common.MULParser; import mekhq.MekHQ; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; -import mekhq.campaign.mission.BotForceStub; -import mekhq.campaign.mission.Mission; +import mekhq.gui.FileDialogs; +import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; +import org.apache.logging.log4j.LogManager; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; import java.util.ResourceBundle; public class CustomizeBotForceDialog extends JDialog { @@ -44,6 +52,10 @@ public class CustomizeBotForceDialog extends JDialog { private JComboBox choiceTeam; private JButton btnCamo; private JPanel panBehavior; + private DefaultMHQScrollablePanel panFixedEntity; + private JButton btnLoadUnits; + private JButton btnSaveUnits; + private JButton btnDeleteUnits; private JLabel lblCowardice; private JLabel lblSelfPreservation; private JLabel lblAggression; @@ -77,12 +89,16 @@ private void initComponents() { setTitle(resourceMap.getString("title")); getContentPane().setLayout(new BorderLayout()); - JPanel panMain = new JPanel(new GridLayout(0, 2)); + JPanel panName = new JPanel(new GridBagLayout()); JPanel panLeft = new JPanel(new GridBagLayout()); - JPanel panRight = new JPanel(new GridBagLayout()); - panMain.add(panLeft); - panMain.add(panRight); - getContentPane().add(panMain, BorderLayout.CENTER); + JPanel panCenter = new JPanel(new GridBagLayout()); + + //panMain.add(panLeft); + //panMain.add(panRight); + //getContentPane().add(panMain, BorderLayout.CENTER); + getContentPane().add(panName, BorderLayout.NORTH); + getContentPane().add(panLeft, BorderLayout.WEST); + getContentPane().add(panCenter, BorderLayout.CENTER); JPanel panButtons = new JPanel(new GridLayout(0, 2)); JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); @@ -102,16 +118,15 @@ private void initComponents() { gbc.gridwidth = 1; gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(5, 5, 5, 5); - panLeft.add(new JLabel(resourceMap.getString("lblName.text")), gbc); + panName.add(new JLabel(resourceMap.getString("lblName.text")), gbc); txtName = new JTextField(botForce.getName()); gbc.gridx = 1; gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; - panLeft.add(txtName, gbc); + panName.add(txtName, gbc); gbc.gridx = 0; - gbc.gridy = 1; gbc.weightx = 0.0; gbc.fill = GridBagConstraints.NONE; panLeft.add(new JLabel(resourceMap.getString("lblTeam.text")), gbc); @@ -151,6 +166,42 @@ private void initComponents() { panLeft.add(panBehavior, gbc); + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.NONE; + btnLoadUnits = new JButton(resourceMap.getString("btnLoadUnits.text")); + btnLoadUnits.setToolTipText(resourceMap.getString("btnLoadUnits.tooltip")); + btnLoadUnits.addActionListener(this::loadUnits); + panCenter.add(btnLoadUnits); + gbc.gridx++; + btnSaveUnits = new JButton(resourceMap.getString("btnSaveUnits.text")); + btnSaveUnits.setToolTipText(resourceMap.getString("btnSaveUnits.tooltip")); + btnSaveUnits.addActionListener(this::saveUnits); + panCenter.add(btnSaveUnits); + gbc.gridx++; + gbc.weightx = 1.0; + btnDeleteUnits = new JButton(resourceMap.getString("btnDeleteUnits.text")); + btnDeleteUnits.setToolTipText(resourceMap.getString("btnDeleteUnits.tooltip")); + btnDeleteUnits.addActionListener(this::deleteUnits); + panCenter.add(btnDeleteUnits, gbc); + + panFixedEntity = new DefaultMHQScrollablePanel(frame, "panFixedEntity", new GridBagLayout()); + refreshFixedEntityPanel(); + JScrollPane scrollFixedEntity = new JScrollPane(panFixedEntity); + scrollFixedEntity.setMinimumSize(new Dimension(400, 200)); + scrollFixedEntity.setPreferredSize(new Dimension(400, 200)); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.gridwidth = 3; + gbc.fill = GridBagConstraints.BOTH; + panCenter.add(scrollFixedEntity, gbc); + } private void intBehaviorPanel(ResourceBundle resourceMap) { @@ -222,6 +273,24 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { panBehavior.add(btnBehavior, gbcLeft); } + private void refreshFixedEntityPanel() { + + panFixedEntity.removeAll(); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.anchor = GridBagConstraints.WEST; + gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(2, 5, 0, 0); + for(String en : Utilities.generateEntityStub(botForce.getFixedEntityList())) { + panFixedEntity.add(new JLabel(en), gbc); + gbc.gridy++; + } + panFixedEntity.revalidate(); + panFixedEntity.repaint(); + } + public BotForce getBotForce() { return botForce; } @@ -249,6 +318,39 @@ private void editCamo(ActionEvent evt) { } } + private void loadUnits(ActionEvent evt) { + Optional units = FileDialogs.openUnits(frame); + if (units.isPresent() && units.get() != null) { + final MULParser parser; + try { + parser = new MULParser(units.get(), campaign.getGameOptions()); + } catch (Exception ex) { + LogManager.getLogger().error("Could not parse BotForce entities", ex); + return; + } + botForce.setFixedEntityList(Collections.list(parser.getEntities().elements())); + refreshFixedEntityPanel(); + } + } + + private void saveUnits(ActionEvent evt) { + Optional saveUnits = FileDialogs.saveUnits(frame, + (botForce.getName().length() > 0) ? botForce.getName() : "BotForce"); + + if(saveUnits.isPresent() && saveUnits.get() != null) { + try { + EntityListFile.saveTo(saveUnits.get(), (ArrayList) botForce.getFixedEntityListDirect()); + } catch (Exception ex) { + LogManager.getLogger().error("Could not save BotForce to file", ex); + } + } + } + + private void deleteUnits(ActionEvent evt) { + botForce.setFixedEntityList(new ArrayList<>()); + refreshFixedEntityPanel(); + } + private String getForcedWithdrawalDescription(BehaviorSettings behavior) { if(!behavior.isForcedWithdrawal()) { return "NONE"; From a120e629878ece41cee60f49c1a357059c600712 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 21:02:24 -0700 Subject: [PATCH 12/76] Use copies of camo and behavior in CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index cfc9419646..b4d70b090e 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -19,11 +19,13 @@ package mekhq.gui.dialog; import megamek.client.bot.princess.BehaviorSettings; +import megamek.client.bot.princess.PrincessException; import megamek.client.ui.dialogs.BotConfigDialog; import megamek.client.ui.dialogs.CamoChooserDialog; import megamek.common.Entity; import megamek.common.EntityListFile; import megamek.common.MULParser; +import megamek.common.icons.Camouflage; import mekhq.MekHQ; import mekhq.Utilities; import mekhq.campaign.Campaign; @@ -46,6 +48,11 @@ public class CustomizeBotForceDialog extends JDialog { private JFrame frame; private BotForce botForce; private Campaign campaign; + private Camouflage camo; + private BehaviorSettings behavior; + + + private List fixedEntities; //gui components private JTextField txtName; @@ -76,6 +83,13 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai botForce = bf; } campaign = c; + camo = botForce.getCamouflage(); + behavior = new BehaviorSettings(); + try { + behavior = botForce.getBehaviorSettings().getCopy(); + } catch (PrincessException ex) { + LogManager.getLogger().error("Error copying princess behaviors", ex); + } initComponents(); setLocationRelativeTo(parent); pack(); @@ -145,7 +159,7 @@ private void initComponents() { panLeft.add(choiceTeam, gbc); btnCamo = new JButton(); - btnCamo.setIcon(botForce.getCamouflage().getImageIcon()); + btnCamo.setIcon(camo.getImageIcon()); btnCamo.setMinimumSize(new Dimension(84, 72)); btnCamo.setPreferredSize(new Dimension(84, 72)); btnCamo.setMaximumSize(new Dimension(84, 72)); @@ -210,8 +224,6 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { BorderFactory.createTitledBorder(resourceMap.getString("panBehavior.title")), BorderFactory.createEmptyBorder(5,5,5,5))); - BehaviorSettings behavior = botForce.getBehaviorSettings(); - GridBagConstraints gbcLeft = new GridBagConstraints(); gbcLeft.gridx = 0; gbcLeft.gridy = 0; @@ -299,22 +311,22 @@ private void editBehavior(ActionEvent evt) { BotConfigDialog bcd = new BotConfigDialog(frame, botForce.getName(), botForce.getBehaviorSettings(), null); bcd.setVisible(true); if(!bcd.getResult().isCancelled()) { - botForce.setBehaviorSettings(bcd.getBehaviorSettings()); - lblCowardice.setText(Integer.toString(botForce.getBehaviorSettings().getBraveryIndex())); - lblSelfPreservation.setText(Integer.toString(botForce.getBehaviorSettings().getSelfPreservationIndex())); - lblAggression.setText(Integer.toString(botForce.getBehaviorSettings().getHyperAggressionIndex())); - lblHerdMentality.setText(Integer.toString(botForce.getBehaviorSettings().getHerdMentalityIndex())); - lblPilotingRisk.setText(Integer.toString(botForce.getBehaviorSettings().getFallShameIndex())); - lblForcedWithdrawal.setText(getForcedWithdrawalDescription(botForce.getBehaviorSettings())); - lblAutoFlee.setText(getAutoFleeDescription(botForce.getBehaviorSettings())); + behavior = bcd.getBehaviorSettings(); + lblCowardice.setText(Integer.toString(behavior.getBraveryIndex())); + lblSelfPreservation.setText(Integer.toString(behavior.getSelfPreservationIndex())); + lblAggression.setText(Integer.toString(behavior.getHyperAggressionIndex())); + lblHerdMentality.setText(Integer.toString(behavior.getHerdMentalityIndex())); + lblPilotingRisk.setText(Integer.toString(behavior.getFallShameIndex())); + lblForcedWithdrawal.setText(getForcedWithdrawalDescription(behavior)); + lblAutoFlee.setText(getAutoFleeDescription(behavior)); } } private void editCamo(ActionEvent evt) { CamoChooserDialog ccd = new CamoChooserDialog(frame, botForce.getCamouflage()); if (ccd.showDialog().isConfirmed()) { - botForce.setCamouflage(ccd.getSelectedItem()); - btnCamo.setIcon(botForce.getCamouflage().getImageIcon()); + camo = ccd.getSelectedItem(); + btnCamo.setIcon(camo.getImageIcon()); } } @@ -369,6 +381,8 @@ private String getAutoFleeDescription(BehaviorSettings behavior) { private void done(ActionEvent evt) { botForce.setName(txtName.getText()); botForce.setTeam(choiceTeam.getSelectedIndex()+1); + botForce.setCamouflage(camo); + botForce.setBehaviorSettings(behavior); this.setVisible(false); } private void cancel(ActionEvent evt) { From 1ff975fef8d65940edd75298e1a7cece446f65e6 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 21:26:13 -0700 Subject: [PATCH 13/76] Work with a copy of fixed entity list in CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index b4d70b090e..fb8bfb81f6 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -40,8 +40,10 @@ import java.io.File; import java.util.ArrayList; import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.ResourceBundle; +import java.util.stream.Collectors; public class CustomizeBotForceDialog extends JDialog { @@ -50,9 +52,7 @@ public class CustomizeBotForceDialog extends JDialog { private Campaign campaign; private Camouflage camo; private BehaviorSettings behavior; - - - private List fixedEntities; + private List fixedEntities; //gui components private JTextField txtName; @@ -90,6 +90,7 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai } catch (PrincessException ex) { LogManager.getLogger().error("Error copying princess behaviors", ex); } + fixedEntities = botForce.getFixedEntityListDirect().stream().collect(Collectors.toList()); initComponents(); setLocationRelativeTo(parent); pack(); @@ -295,7 +296,7 @@ private void refreshFixedEntityPanel() { gbc.weightx = 1.0; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(2, 5, 0, 0); - for(String en : Utilities.generateEntityStub(botForce.getFixedEntityList())) { + for(String en : Utilities.generateEntityStub(fixedEntities)) { panFixedEntity.add(new JLabel(en), gbc); gbc.gridy++; } @@ -340,7 +341,7 @@ private void loadUnits(ActionEvent evt) { LogManager.getLogger().error("Could not parse BotForce entities", ex); return; } - botForce.setFixedEntityList(Collections.list(parser.getEntities().elements())); + fixedEntities = Collections.list(parser.getEntities().elements()); refreshFixedEntityPanel(); } } @@ -351,7 +352,7 @@ private void saveUnits(ActionEvent evt) { if(saveUnits.isPresent() && saveUnits.get() != null) { try { - EntityListFile.saveTo(saveUnits.get(), (ArrayList) botForce.getFixedEntityListDirect()); + EntityListFile.saveTo(saveUnits.get(), (ArrayList) fixedEntities); } catch (Exception ex) { LogManager.getLogger().error("Could not save BotForce to file", ex); } @@ -359,7 +360,7 @@ private void saveUnits(ActionEvent evt) { } private void deleteUnits(ActionEvent evt) { - botForce.setFixedEntityList(new ArrayList<>()); + fixedEntities = new ArrayList(); refreshFixedEntityPanel(); } @@ -383,6 +384,7 @@ private void done(ActionEvent evt) { botForce.setTeam(choiceTeam.getSelectedIndex()+1); botForce.setCamouflage(camo); botForce.setBehaviorSettings(behavior); + botForce.setFixedEntityList(fixedEntities); this.setVisible(false); } private void cancel(ActionEvent evt) { From 124704e8cb24b3fc39d42b90a9efce55162755ae Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 21:39:16 -0700 Subject: [PATCH 14/76] Work with a copy of BotForces in CustomizeScenarioDialog --- MekHQ/src/mekhq/campaign/mission/BotForce.java | 12 ++++++++++++ MekHQ/src/mekhq/campaign/mission/Scenario.java | 4 ++++ .../mekhq/gui/dialog/CustomizeScenarioDialog.java | 4 +++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 64f79e52a4..8965cdde43 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -98,6 +98,18 @@ public BotForce(String name, int team, int start, int home, List entityL behaviorSettings.setDestinationEdge(CardinalEdge.NONE); } + public BotForce getCopy() { + final BotForce copy = new BotForce(); + copy.setName(this.getName()); + copy.setTeam(this.getTeam()); + copy.setStart(this.getStart()); + copy.setCamouflage(this.getCamouflage()); + copy.setColour(this.getColour()); + //copy.setBehaviorSettings(getBehaviorSettings().getCopy()); + + return copy; + } + /* Convert from MM's Board to Princess's HomeEdge */ public CardinalEdge findCardinalEdge(int start) { switch (start) { diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index 97f0603425..aa4ba892ec 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -570,6 +570,10 @@ public List getBotForces() { return botForces; } + public void setBotForces(List bf) { + botForces = bf; + } + public void addBotForce(BotForce botForce, Campaign c) { botForces.add(botForce); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 4ff4d893f8..06f370b987 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -51,6 +51,7 @@ import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; +import java.util.stream.Collectors; /** * @author Taharqa @@ -142,7 +143,7 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission planetaryConditions = scenario.createPlanetaryConditions(); - botForces = scenario.getBotForces(); + botForces = scenario.getBotForces().stream().collect(Collectors.toList());; forcesModel = new BotForceTableModel(botForces, campaign); loots = new ArrayList<>(); @@ -387,6 +388,7 @@ private void btnOKActionPerformed(ActionEvent evt) { } scenario.readPlanetaryConditions(planetaryConditions); scenario.setDate(date); + scenario.setBotForces(botForces); scenario.resetLoot(); for (Loot loot : lootModel.getAllLoot()) { scenario.addLoot(loot); From a70d54b934ea53c59063c46770d836395084a2d6 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 22:01:10 -0700 Subject: [PATCH 15/76] Add getCopy method to BotForceRandomizer --- .../mekhq/campaign/mission/BotForceRandomizer.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index 80ec8fc9a9..aa5be903b9 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -126,6 +126,20 @@ public BotForceRandomizer() { } //endregion Constructors + public BotForceRandomizer getCopy() { + BotForceRandomizer copy = new BotForceRandomizer(); + copy.setFactionCode(this.getFactionCode()); + copy.skill = this.skill; + copy.unitType = this.unitType; + copy.forceMultiplier = this.forceMultiplier; + copy.percentConventional = this.percentConventional; + copy.baChance = this.baChance; + copy.balancingMethod = this.balancingMethod; + copy.lanceSize = this.lanceSize; + + return copy; + } + //region Getters/Setters public String getFactionCode() { return factionCode; From d5b8ae235e45c8ba30494bd30ecaccc4bab6e466 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 11 Apr 2024 23:14:45 -0700 Subject: [PATCH 16/76] Add botForceRandomizer setter/getters --- .../campaign/mission/BotForceRandomizer.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index aa5be903b9..08d92788ec 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -136,6 +136,7 @@ public BotForceRandomizer getCopy() { copy.baChance = this.baChance; copy.balancingMethod = this.balancingMethod; copy.lanceSize = this.lanceSize; + copy.quality = this.quality; return copy; } @@ -148,6 +149,70 @@ public String getFactionCode() { public void setFactionCode(final String factionCode) { this.factionCode = factionCode; } + + public SkillLevel getSkill() { + return skill; + } + + public void setSkill(SkillLevel s) { + skill = s; + } + + public int getUnitType() { + return unitType; + } + + public void setUnitType(int u) { + unitType = u; + } + + public int getQuality() { + return quality; + } + + public void setQuality(int q) { + quality = q; + } + + public BalancingMethod getBalancingMethod() { + return balancingMethod; + } + + public void setBalancingMethod(BalancingMethod bm) { + balancingMethod = bm; + } + + public double getForceMultiplier() { + return forceMultiplier; + } + + public void setForceMultiplier(double fm) { + forceMultiplier = fm; + } + + public int getPercentConventional() { + return percentConventional; + } + + public void setPercentConventional(int p) { + percentConventional = p; + } + + public int getBaChance() { + return baChance; + } + + public void setBaChance(int b) { + baChance = b; + } + + public int getLanceSize() { + return lanceSize; + } + + public void setLanceSize(int l) { + lanceSize = l; + } //endregion Getters/Setters /** From e1f964d66842f161b68f9429f9c13c59cdbde8ea Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 07:27:26 -0700 Subject: [PATCH 17/76] Add additional getter/setters for BotForceRandomizer --- .../mekhq/campaign/mission/BotForceRandomizer.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index 08d92788ec..f0eb2349e2 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -59,7 +59,7 @@ public class BotForceRandomizer { //region Variable declarations public static final int UNIT_WEIGHT_UNSPECIFIED = -1; - private enum BalancingMethod { + public enum BalancingMethod { BV, WEIGHT_ADJ; @@ -136,6 +136,7 @@ public BotForceRandomizer getCopy() { copy.baChance = this.baChance; copy.balancingMethod = this.balancingMethod; copy.lanceSize = this.lanceSize; + copy.focalWeightClass = this.focalWeightClass; copy.quality = this.quality; return copy; @@ -213,6 +214,14 @@ public int getLanceSize() { public void setLanceSize(int l) { lanceSize = l; } + + public double getFocalWeightClass() { + return focalWeightClass; + } + + public void setFocalWeightClass(double f) { + focalWeightClass = f; + } //endregion Getters/Setters /** From 0ed751ea2f9cb7c0b00dd8e7b8b02cc9c043a6d4 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 07:45:17 -0700 Subject: [PATCH 18/76] Remove campaign pointer from BotForceRandomizer --- .../src/mekhq/campaign/mission/BotForce.java | 4 +-- .../campaign/mission/BotForceRandomizer.java | 26 +++++++++---------- .../mekhq/gui/model/BotForceTableModel.java | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 8965cdde43..4b0838936f 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -273,7 +273,7 @@ public void generateRandomForces(List playerUnits, Campaign c) { List existingEntityList = new ArrayList<>(); existingEntityList.addAll(fixedEntityList); existingEntityList.addAll(getTraitorEntities(c)); - generatedEntityList = bfRandomizer.generateForce(playerUnits, existingEntityList); + generatedEntityList = bfRandomizer.generateForce(playerUnits, existingEntityList, c); } public List getTraitorPersons() { @@ -332,7 +332,7 @@ public BotForceStub generateStub(Campaign c) { ((getTeam() == 1) ? "Allied" : "Enemy") + "" + " Start: " + IStartingPositions.START_LOCATION_NAMES[getStart()] + " Fixed BV: " + getTotalBV(c) + - ((null == getBotForceRandomizer()) ? "" : "
Random: " + getBotForceRandomizer().getDescription()) + + ((null == getBotForceRandomizer()) ? "" : "
Random: " + getBotForceRandomizer().getDescription(c)) + "", stubs); } diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index f0eb2349e2..007ba97135 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -98,9 +98,6 @@ public String toString() { /** balancing method **/ private BalancingMethod balancingMethod; - /** convenience campaign pointer **/ - private Campaign campaign; - /** * what percent of mek and aero forces should actually be conventional? * (tanks and conventional aircraft respectively) @@ -231,9 +228,10 @@ public void setFocalWeightClass(double f) { * is used to determine the total points allowed for this force. * @param botFixedEntities A List of The fixed Entities that might have also been declared in BotForce already. * This is used to calculate the starting points already used when generating the force. + * @param Campaign A Campaign object which is necessary for various information * @return A List of Entities that will be added to the game by GameThread. */ - public List generateForce(List playerUnits, List botFixedEntities) { + public List generateForce(List playerUnits, List botFixedEntities, Campaign campaign) { ArrayList entityList = new ArrayList<>(); double maxPoints = calculateMaxPoints(playerUnits); @@ -266,7 +264,7 @@ public List generateForce(List playerUnits, List botFixedE uType = UnitType.CONV_FIGHTER; } - lanceList = generateLance(lanceSize, uType, weightClass); + lanceList = generateLance(lanceSize, uType, weightClass, campaign); for (Entity e : lanceList) { entityList.add(e); currentPoints += calculatePoints(e); @@ -285,13 +283,14 @@ public List generateForce(List playerUnits, List botFixedE * @param uType The UnitType of generated units * @param weightClass an int giving the weight class of generated units. The function applies some randomness * to this, so some entities within the lance may be heavier or lighter. + * @param campaign a Campaign object for campaign related information * @return A List of generated entities. */ - public List generateLance(int size, int uType, int weightClass) { + public List generateLance(int size, int uType, int weightClass, Campaign campaign) { ArrayList lanceList = new ArrayList<>(); for (int i = 0; i < size; i++) { - Entity e = getEntity(uType, weightClass); + Entity e = getEntity(uType, weightClass, campaign); if (null != e) { lanceList.add(e); } @@ -301,7 +300,7 @@ public List generateLance(int size, int uType, int weightClass) { if ((unitType == UnitType.MEK) && (baChance > 0) && (Compute.randomInt(100) <= baChance)) { for (int i = 0; i < size; i++) { - Entity e = getEntity(UnitType.BATTLE_ARMOR, UNIT_WEIGHT_UNSPECIFIED); + Entity e = getEntity(UnitType.BATTLE_ARMOR, UNIT_WEIGHT_UNSPECIFIED, campaign); if (null != e) { lanceList.add(e); } @@ -317,9 +316,10 @@ public List generateLance(int size, int uType, int weightClass) { * * @param uType The UnitTableData constant for the type of unit to generate. * @param weightClass The weight class of the unit to generate + * @param campaign A campaign object * @return A new Entity with crew. */ - public Entity getEntity(int uType, int weightClass) { + public Entity getEntity(int uType, int weightClass, Campaign campaign) { MechSummary ms; // allow some variation in actual weight class @@ -344,16 +344,17 @@ public Entity getEntity(int uType, int weightClass) { ms = campaign.getUnitGenerator().generate(params); - return createEntityWithCrew(ms); + return createEntityWithCrew(ms, campaign); } /** * This creates the entity with a crew. Borrows heavily from AtBDynamicScenarioFactory#createEntityWithCrew * * @param ms Which entity to generate + * @param campaign A campaign file * @return A crewed entity */ - public @Nullable Entity createEntityWithCrew(MechSummary ms) { + public @Nullable Entity createEntityWithCrew(MechSummary ms, Campaign campaign) { Entity en; try { en = new MechFileParser(ms.getSourceFile(), ms.getEntryName()).getEntity(); @@ -569,7 +570,7 @@ private double calculateMeanWeightClass(List playerUnits) { * ScenarioViewPanel * @return a String giving the description. */ - public String getDescription() { + public String getDescription(Campaign campaign) { StringBuilder sb = new StringBuilder(); sb.append(Factions.getInstance().getFaction(factionCode).getFullName(campaign.getGameYear())); sb.append(" "); @@ -607,7 +608,6 @@ public void writeToXML(final PrintWriter pw, int indent) { public static BotForceRandomizer generateInstanceFromXML(Node wn, Campaign c, Version version) { BotForceRandomizer retVal = new BotForceRandomizer(); - retVal.campaign = c; try { // Okay, now load Part-specific fields! NodeList nl = wn.getChildNodes(); diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java index 7d7a11fe4f..870d1f92a3 100644 --- a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -98,7 +98,7 @@ public Object getValueAt(int row, int col) { case COL_FIXED: return botForce.getTotalBV(campaign); case COL_RANDOM: - return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer().getDescription()); + return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer().getDescription(campaign)); case COL_DEPLOYMENT: return IStartingPositions.START_LOCATION_NAMES[botForce.getStart()]; default: From 5ef9a62d7540cd3b8b4cf305b8617d07b0280281 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 07:47:53 -0700 Subject: [PATCH 19/76] Add botForceRandomizer editor to CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 199 +++++++++++++++++- 1 file changed, 192 insertions(+), 7 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index fb8bfb81f6..4c82ae4b46 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -20,16 +20,18 @@ import megamek.client.bot.princess.BehaviorSettings; import megamek.client.bot.princess.PrincessException; +import megamek.client.ui.baseComponents.MMComboBox; import megamek.client.ui.dialogs.BotConfigDialog; import megamek.client.ui.dialogs.CamoChooserDialog; -import megamek.common.Entity; -import megamek.common.EntityListFile; -import megamek.common.MULParser; +import megamek.common.*; +import megamek.common.enums.SkillLevel; import megamek.common.icons.Camouflage; import mekhq.MekHQ; import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; +import mekhq.campaign.mission.BotForceRandomizer; +import mekhq.campaign.universe.Factions; import mekhq.gui.FileDialogs; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; import org.apache.logging.log4j.LogManager; @@ -52,6 +54,8 @@ public class CustomizeBotForceDialog extends JDialog { private Campaign campaign; private Camouflage camo; private BehaviorSettings behavior; + private BotForceRandomizer randomizer; + private boolean useRandomForces; private List fixedEntities; //gui components @@ -59,6 +63,7 @@ public class CustomizeBotForceDialog extends JDialog { private JComboBox choiceTeam; private JButton btnCamo; private JPanel panBehavior; + private JPanel panRandomForces; private DefaultMHQScrollablePanel panFixedEntity; private JButton btnLoadUnits; private JButton btnSaveUnits; @@ -70,6 +75,16 @@ public class CustomizeBotForceDialog extends JDialog { private JLabel lblPilotingRisk; private JLabel lblForcedWithdrawal; private JLabel lblAutoFlee; + private JCheckBox chkUseRandomForces; + private JSpinner spnForceMultiplier; + private JSpinner spnPercentConventional; + private JSpinner spnBaChance; + private JSpinner spnLanceSize; + private MMComboBox choiceBalancingMethod; + private MMComboBox choiceUnitType; + private MMComboBox choiceSkillLevel; + private MMComboBox choiceFocalWeightClass; + private MMComboBox choiceFaction; public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { super(parent, modal); @@ -90,6 +105,12 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai } catch (PrincessException ex) { LogManager.getLogger().error("Error copying princess behaviors", ex); } + useRandomForces = botForce.getBotForceRandomizer() != null; + if(useRandomForces) { + randomizer = botForce.getBotForceRandomizer().getCopy(); + } else { + randomizer = new BotForceRandomizer(); + } fixedEntities = botForce.getFixedEntityListDirect().stream().collect(Collectors.toList()); initComponents(); setLocationRelativeTo(parent); @@ -181,22 +202,29 @@ private void initComponents() { panLeft.add(panBehavior, gbc); + initRandomForcesPanel(resourceMap); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; - gbc.weightx = 0.0; + gbc.weightx = 1.0; gbc.weighty = 0.0; + gbc.gridwidth = 3; gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.BOTH; + panCenter.add(panRandomForces, gbc); + gbc.gridy++; + gbc.weightx = 0.0; + gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; btnLoadUnits = new JButton(resourceMap.getString("btnLoadUnits.text")); btnLoadUnits.setToolTipText(resourceMap.getString("btnLoadUnits.tooltip")); btnLoadUnits.addActionListener(this::loadUnits); - panCenter.add(btnLoadUnits); + panCenter.add(btnLoadUnits, gbc); gbc.gridx++; btnSaveUnits = new JButton(resourceMap.getString("btnSaveUnits.text")); btnSaveUnits.setToolTipText(resourceMap.getString("btnSaveUnits.tooltip")); btnSaveUnits.addActionListener(this::saveUnits); - panCenter.add(btnSaveUnits); + panCenter.add(btnSaveUnits, gbc); gbc.gridx++; gbc.weightx = 1.0; btnDeleteUnits = new JButton(resourceMap.getString("btnDeleteUnits.text")); @@ -210,7 +238,7 @@ private void initComponents() { scrollFixedEntity.setMinimumSize(new Dimension(400, 200)); scrollFixedEntity.setPreferredSize(new Dimension(400, 200)); gbc.gridx = 0; - gbc.gridy = 1; + gbc.gridy++; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.gridwidth = 3; @@ -286,6 +314,145 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { panBehavior.add(btnBehavior, gbcLeft); } + private void initRandomForcesPanel(ResourceBundle resourceMap) { + panRandomForces = new JPanel(new GridBagLayout()); + panRandomForces.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder("Random Forces"), + BorderFactory.createEmptyBorder(5,5,5,5))); + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.gridwidth = 4; + chkUseRandomForces = new JCheckBox("Use randomly generated forces"); + chkUseRandomForces.setSelected(useRandomForces); + chkUseRandomForces.addActionListener(evt -> { + spnForceMultiplier.setEnabled(chkUseRandomForces.isSelected()); + spnPercentConventional.setEnabled(chkUseRandomForces.isSelected()); + spnBaChance.setEnabled(chkUseRandomForces.isSelected()); + spnLanceSize.setEnabled(chkUseRandomForces.isSelected()); + choiceFaction.setEnabled(chkUseRandomForces.isSelected()); + choiceBalancingMethod.setEnabled(chkUseRandomForces.isSelected()); + choiceUnitType.setEnabled(chkUseRandomForces.isSelected()); + choiceFocalWeightClass.setEnabled(chkUseRandomForces.isSelected()); + choiceSkillLevel.setEnabled(chkUseRandomForces.isSelected()); + }); + panRandomForces.add(chkUseRandomForces, gbc); + + spnForceMultiplier = new JSpinner(new SpinnerNumberModel(randomizer.getForceMultiplier(), + 0.05, 5, 0.05)); + spnForceMultiplier.setEnabled(useRandomForces); + gbc.gridwidth = 1; + gbc.weightx = 0.0; + gbc.gridy++; + panRandomForces.add(new JLabel("Force Multiplier:"), gbc); + gbc.gridx = 1; + panRandomForces.add(spnForceMultiplier, gbc); + + spnPercentConventional = new JSpinner(new SpinnerNumberModel(randomizer.getPercentConventional(), + 0, 75, 5)); + spnPercentConventional.setEnabled(useRandomForces); + gbc.gridx = 0; + gbc.gridy++; + panRandomForces.add(new JLabel("Percent Conventional:"), gbc); + gbc.gridx = 1; + panRandomForces.add(spnPercentConventional, gbc); + + spnBaChance = new JSpinner(new SpinnerNumberModel(randomizer.getBaChance(), + 0, 100, 5)); + spnBaChance.setEnabled(useRandomForces); + gbc.gridx = 0; + gbc.gridy++; + panRandomForces.add(new JLabel("Integrated BA Chance:"), gbc); + gbc.gridx = 1; + panRandomForces.add(spnBaChance, gbc); + + spnLanceSize = new JSpinner(new SpinnerNumberModel(randomizer.getLanceSize(), + 0, 6, 1)); + spnLanceSize.setEnabled(useRandomForces); + gbc.gridx = 0; + gbc.gridy++; + panRandomForces.add(new JLabel("Lance Size:"), gbc); + gbc.gridx = 1; + panRandomForces.add(spnLanceSize, gbc); + + DefaultComboBoxModel balancingMethodModel = new DefaultComboBoxModel<>(); + balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.BV.name()); + balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.WEIGHT_ADJ.name()); + choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", balancingMethodModel); + choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().toString()); + choiceBalancingMethod.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy = 1; + panRandomForces.add(new JLabel("Balancing Method:"), gbc); + gbc.gridx = 3; + panRandomForces.add(choiceBalancingMethod, gbc); + + DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>(); + factionModel.addAll(Factions.getInstance().getFactionList()); + choiceFaction = new MMComboBox("choiceFaction", factionModel); + choiceFaction.setSelectedItem(randomizer.getFactionCode()); + choiceFaction.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Faction:"), gbc); + gbc.gridx = 3; + panRandomForces.add(choiceFaction, gbc); + + DefaultComboBoxModel unitTypeModel = new DefaultComboBoxModel<>(); + for(int i = 0; i < UnitType.SIZE; i++) { + unitTypeModel.addElement(UnitType.getTypeName(i)); + } + choiceUnitType = new MMComboBox("choiceUnitType", unitTypeModel); + choiceUnitType.setSelectedItem(UnitType.getTypeName(randomizer.getUnitType())); + choiceUnitType.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Unit Type:"), gbc); + gbc.gridx = 3; + panRandomForces.add(choiceUnitType, gbc); + + DefaultComboBoxModel skillLevelModel = new DefaultComboBoxModel<>(); + for(SkillLevel skill : SkillLevel.values()) { + if(skill.isNone()) { + continue; + } + skillLevelModel.addElement(skill.name()); + } + choiceSkillLevel = new MMComboBox("choiceSkillLevel", skillLevelModel); + choiceSkillLevel.setSelectedItem(randomizer.getSkill().name()); + choiceSkillLevel.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Skill Level:"), gbc); + gbc.gridx = 3; + panRandomForces.add(choiceSkillLevel, gbc); + + DefaultComboBoxModel weightClassModel = new DefaultComboBoxModel<>(); + weightClassModel.addElement("Not Specified"); + for(int i = EntityWeightClass.WEIGHT_LIGHT; i <= EntityWeightClass.WEIGHT_ASSAULT; i++) { + weightClassModel.addElement(EntityWeightClass.getClassName(i)); + } + choiceFocalWeightClass = new MMComboBox("choiceFocalWeightClass", weightClassModel); + if(randomizer.getFocalWeightClass() < EntityWeightClass.WEIGHT_LIGHT + || randomizer.getFocalWeightClass() > EntityWeightClass.WEIGHT_ASSAULT) { + choiceFocalWeightClass.setSelectedIndex(0); + } else { + choiceFocalWeightClass.setSelectedItem(EntityWeightClass + .getClassName((int) Math.round(randomizer.getFocalWeightClass()))); + } + choiceFocalWeightClass.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Focal Weight Class:"), gbc); + gbc.gridx = 3; + panRandomForces.add(choiceFocalWeightClass, gbc); + } + private void refreshFixedEntityPanel() { panFixedEntity.removeAll(); @@ -384,7 +551,25 @@ private void done(ActionEvent evt) { botForce.setTeam(choiceTeam.getSelectedIndex()+1); botForce.setCamouflage(camo); botForce.setBehaviorSettings(behavior); + botForce.setBotForceRandomizer(randomizer); botForce.setFixedEntityList(fixedEntities); + useRandomForces = chkUseRandomForces.isSelected(); + if(useRandomForces) { + randomizer.setFactionCode((String) choiceFaction.getSelectedItem()); + randomizer.setForceMultiplier((double) spnForceMultiplier.getValue()); + randomizer.setPercentConventional((int) spnPercentConventional.getValue()); + randomizer.setBaChance((int) spnBaChance.getValue()); + randomizer.setLanceSize((int) spnLanceSize.getValue()); + randomizer.setFocalWeightClass(choiceFocalWeightClass.getSelectedIndex()); + randomizer.setSkill(SkillLevel.valueOf((String) choiceSkillLevel.getSelectedItem())); + randomizer.setUnitType(choiceUnitType.getSelectedIndex()); + randomizer.setBalancingMethod(BotForceRandomizer.BalancingMethod + .valueOf((String) choiceBalancingMethod.getSelectedItem())); + botForce.setBotForceRandomizer(randomizer); + } else { + botForce.setBotForceRandomizer(null); + } + this.setVisible(false); } private void cancel(ActionEvent evt) { From f91f25be218d52fdd1067178fb0b3335eebc48b1 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 08:06:07 -0700 Subject: [PATCH 20/76] Rework botrandomizer panel layout for CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 108 ++++++++++-------- 1 file changed, 61 insertions(+), 47 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 4c82ae4b46..1c97af47a6 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -343,53 +343,21 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { }); panRandomForces.add(chkUseRandomForces, gbc); - spnForceMultiplier = new JSpinner(new SpinnerNumberModel(randomizer.getForceMultiplier(), - 0.05, 5, 0.05)); - spnForceMultiplier.setEnabled(useRandomForces); - gbc.gridwidth = 1; - gbc.weightx = 0.0; - gbc.gridy++; - panRandomForces.add(new JLabel("Force Multiplier:"), gbc); - gbc.gridx = 1; - panRandomForces.add(spnForceMultiplier, gbc); - - spnPercentConventional = new JSpinner(new SpinnerNumberModel(randomizer.getPercentConventional(), - 0, 75, 5)); - spnPercentConventional.setEnabled(useRandomForces); - gbc.gridx = 0; - gbc.gridy++; - panRandomForces.add(new JLabel("Percent Conventional:"), gbc); - gbc.gridx = 1; - panRandomForces.add(spnPercentConventional, gbc); - - spnBaChance = new JSpinner(new SpinnerNumberModel(randomizer.getBaChance(), - 0, 100, 5)); - spnBaChance.setEnabled(useRandomForces); - gbc.gridx = 0; - gbc.gridy++; - panRandomForces.add(new JLabel("Integrated BA Chance:"), gbc); - gbc.gridx = 1; - panRandomForces.add(spnBaChance, gbc); - - spnLanceSize = new JSpinner(new SpinnerNumberModel(randomizer.getLanceSize(), - 0, 6, 1)); - spnLanceSize.setEnabled(useRandomForces); - gbc.gridx = 0; - gbc.gridy++; - panRandomForces.add(new JLabel("Lance Size:"), gbc); - gbc.gridx = 1; - panRandomForces.add(spnLanceSize, gbc); - DefaultComboBoxModel balancingMethodModel = new DefaultComboBoxModel<>(); balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.BV.name()); balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.WEIGHT_ADJ.name()); choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", balancingMethodModel); choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().toString()); choiceBalancingMethod.setEnabled(useRandomForces); - gbc.gridx = 2; + gbc.gridx = 0; gbc.gridy = 1; + gbc.gridwidth = 1; + gbc.weightx = 0.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(1, 0, 0, 5); panRandomForces.add(new JLabel("Balancing Method:"), gbc); - gbc.gridx = 3; + gbc.gridx = 1; + gbc.weightx = 1.0; panRandomForces.add(choiceBalancingMethod, gbc); DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>(); @@ -397,10 +365,12 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { choiceFaction = new MMComboBox("choiceFaction", factionModel); choiceFaction.setSelectedItem(randomizer.getFactionCode()); choiceFaction.setEnabled(useRandomForces); - gbc.gridx = 2; + gbc.gridx = 0; gbc.gridy++; + gbc.weightx = 0.0; panRandomForces.add(new JLabel("Faction:"), gbc); - gbc.gridx = 3; + gbc.gridx = 1; + gbc.weightx = 1.0; panRandomForces.add(choiceFaction, gbc); DefaultComboBoxModel unitTypeModel = new DefaultComboBoxModel<>(); @@ -410,10 +380,12 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { choiceUnitType = new MMComboBox("choiceUnitType", unitTypeModel); choiceUnitType.setSelectedItem(UnitType.getTypeName(randomizer.getUnitType())); choiceUnitType.setEnabled(useRandomForces); - gbc.gridx = 2; + gbc.gridx = 0; gbc.gridy++; + gbc.weightx = 0.0; panRandomForces.add(new JLabel("Unit Type:"), gbc); - gbc.gridx = 3; + gbc.gridx = 1; + gbc.weightx = 1.0; panRandomForces.add(choiceUnitType, gbc); DefaultComboBoxModel skillLevelModel = new DefaultComboBoxModel<>(); @@ -426,10 +398,12 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { choiceSkillLevel = new MMComboBox("choiceSkillLevel", skillLevelModel); choiceSkillLevel.setSelectedItem(randomizer.getSkill().name()); choiceSkillLevel.setEnabled(useRandomForces); - gbc.gridx = 2; + gbc.gridx = 0; gbc.gridy++; + gbc.weightx = 0.0; panRandomForces.add(new JLabel("Skill Level:"), gbc); - gbc.gridx = 3; + gbc.gridx = 1; + gbc.weightx = 1.0; panRandomForces.add(choiceSkillLevel, gbc); DefaultComboBoxModel weightClassModel = new DefaultComboBoxModel<>(); @@ -446,11 +420,51 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { .getClassName((int) Math.round(randomizer.getFocalWeightClass()))); } choiceFocalWeightClass.setEnabled(useRandomForces); - gbc.gridx = 2; + gbc.gridx = 0; gbc.gridy++; + gbc.weightx = 0.0; panRandomForces.add(new JLabel("Focal Weight Class:"), gbc); - gbc.gridx = 3; + gbc.gridx = 1; + gbc.weightx = 1.0; panRandomForces.add(choiceFocalWeightClass, gbc); + + spnForceMultiplier = new JSpinner(new SpinnerNumberModel(randomizer.getForceMultiplier(), + 0.05, 5, 0.05)); + spnForceMultiplier.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy = 1; + gbc.gridwidth = 1; + gbc.weightx = 0.0; + panRandomForces.add(new JLabel("Force Multiplier:"), gbc); + gbc.gridx = 3; + panRandomForces.add(spnForceMultiplier, gbc); + + spnPercentConventional = new JSpinner(new SpinnerNumberModel(randomizer.getPercentConventional(), + 0, 75, 5)); + spnPercentConventional.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Percent Conventional:"), gbc); + gbc.gridx = 3; + panRandomForces.add(spnPercentConventional, gbc); + + spnBaChance = new JSpinner(new SpinnerNumberModel(randomizer.getBaChance(), + 0, 100, 5)); + spnBaChance.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Integrated BA Chance:"), gbc); + gbc.gridx = 3; + panRandomForces.add(spnBaChance, gbc); + + spnLanceSize = new JSpinner(new SpinnerNumberModel(randomizer.getLanceSize(), + 0, 6, 1)); + spnLanceSize.setEnabled(useRandomForces); + gbc.gridx = 2; + gbc.gridy++; + panRandomForces.add(new JLabel("Lance Size:"), gbc); + gbc.gridx = 3; + panRandomForces.add(spnLanceSize, gbc); } private void refreshFixedEntityPanel() { From 33257c1f05c68e9c79aadfc703ccdbb3fb56347b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 08:08:03 -0700 Subject: [PATCH 21/76] Use titled border for fixed units in CustomizeBotForceDialog --- MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 1c97af47a6..fabf15cb41 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -237,6 +237,9 @@ private void initComponents() { JScrollPane scrollFixedEntity = new JScrollPane(panFixedEntity); scrollFixedEntity.setMinimumSize(new Dimension(400, 200)); scrollFixedEntity.setPreferredSize(new Dimension(400, 200)); + scrollFixedEntity.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder("Fixed Units"), + BorderFactory.createEmptyBorder(5,5,5,5))); gbc.gridx = 0; gbc.gridy++; gbc.weightx = 1.0; @@ -317,7 +320,7 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { private void initRandomForcesPanel(ResourceBundle resourceMap) { panRandomForces = new JPanel(new GridBagLayout()); panRandomForces.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Random Forces"), + BorderFactory.createTitledBorder("Random Units"), BorderFactory.createEmptyBorder(5,5,5,5))); GridBagConstraints gbc = new GridBagConstraints(); From 1eb938e171ab6f729b4c7e1f09a884dd9d38ed44 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 08:23:56 -0700 Subject: [PATCH 22/76] use resourceMap for randomizer labels in CustomizeBotForceDialog --- .../CustomizeBotForceDialog.properties | 20 ++- .../gui/dialog/CustomizeBotForceDialog.java | 126 +++++++++--------- 2 files changed, 79 insertions(+), 67 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index fafa894abc..f82fa36076 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -2,6 +2,8 @@ title=Customize BotForce lblName.text=Name: lblTeam.text=Team: panBehavior.title=Behavior +panRandomUnits.title=Random Units +scrollFixedUnits.title=Fixed Units choiceTeam.text=Team choiceAllied.text=Allied lblCowardice.text=Cowardice: @@ -11,12 +13,22 @@ lblHerdMentality.text=Herd Mentality: lblPilotingRisk.text=Piloting Risk: lblForcedWithdrawal.text=Forced Withdrawal: lblAutoFlee.text=Auto Flee: +lblBalancingMethod.text=Balancing Method: +lblFaction.text=Faction: +lblUnitType.text=Unit Type: +lblSkillLevel.text=Skill Level: +lblFocalWeightClass.text=Focal Weight Class: +lblForceMultiplier.text=Force Multiplier: +lblPercentConventional.text=Percent Conventional: +lblBaChance.text=Integrated BA Chance: +lblLanceSize.text=Formation Size: btnOK.text=OK btnClose.text=Cancel btnBehavior.text=Edit Behavior Settings -btnLoadUnits.text=Load Units +btnLoadUnits.text=Load Fixed Units btnLoadUnits.tooltip=Load units from a .mul file,
overwriting existing units -btnSaveUnits.text=Save Units +btnSaveUnits.text=Save Fixed Units btnSaveUnits.tooltip=Save units to a .mul file -btnDeleteUnits.text=Delete Units -btnDeleteUnits.tooltip=Delete all units \ No newline at end of file +btnDeleteUnits.text=Delete Fixed Units +btnDeleteUnits.tooltip=Delete all units +chkUseRandomUnits.text=Use randomly generated units \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index fabf15cb41..e0a21538b7 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -55,7 +55,7 @@ public class CustomizeBotForceDialog extends JDialog { private Camouflage camo; private BehaviorSettings behavior; private BotForceRandomizer randomizer; - private boolean useRandomForces; + private boolean useRandomUnits; private List fixedEntities; //gui components @@ -63,8 +63,8 @@ public class CustomizeBotForceDialog extends JDialog { private JComboBox choiceTeam; private JButton btnCamo; private JPanel panBehavior; - private JPanel panRandomForces; - private DefaultMHQScrollablePanel panFixedEntity; + private JPanel panRandomUnits; + private DefaultMHQScrollablePanel panFixedUnits; private JButton btnLoadUnits; private JButton btnSaveUnits; private JButton btnDeleteUnits; @@ -75,7 +75,7 @@ public class CustomizeBotForceDialog extends JDialog { private JLabel lblPilotingRisk; private JLabel lblForcedWithdrawal; private JLabel lblAutoFlee; - private JCheckBox chkUseRandomForces; + private JCheckBox chkUseRandomUnits; private JSpinner spnForceMultiplier; private JSpinner spnPercentConventional; private JSpinner spnBaChance; @@ -105,8 +105,8 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai } catch (PrincessException ex) { LogManager.getLogger().error("Error copying princess behaviors", ex); } - useRandomForces = botForce.getBotForceRandomizer() != null; - if(useRandomForces) { + useRandomUnits = botForce.getBotForceRandomizer() != null; + if(useRandomUnits) { randomizer = botForce.getBotForceRandomizer().getCopy(); } else { randomizer = new BotForceRandomizer(); @@ -211,7 +211,7 @@ private void initComponents() { gbc.gridwidth = 3; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.BOTH; - panCenter.add(panRandomForces, gbc); + panCenter.add(panRandomUnits, gbc); gbc.gridy++; gbc.weightx = 0.0; gbc.gridwidth = 1; @@ -232,13 +232,13 @@ private void initComponents() { btnDeleteUnits.addActionListener(this::deleteUnits); panCenter.add(btnDeleteUnits, gbc); - panFixedEntity = new DefaultMHQScrollablePanel(frame, "panFixedEntity", new GridBagLayout()); + panFixedUnits = new DefaultMHQScrollablePanel(frame, "panFixedEntity", new GridBagLayout()); refreshFixedEntityPanel(); - JScrollPane scrollFixedEntity = new JScrollPane(panFixedEntity); - scrollFixedEntity.setMinimumSize(new Dimension(400, 200)); - scrollFixedEntity.setPreferredSize(new Dimension(400, 200)); - scrollFixedEntity.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Fixed Units"), + JScrollPane scrollFixedUnits = new JScrollPane(panFixedUnits); + scrollFixedUnits.setMinimumSize(new Dimension(400, 200)); + scrollFixedUnits.setPreferredSize(new Dimension(400, 200)); + scrollFixedUnits.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder(resourceMap.getString("scrollFixedUnits.title")), BorderFactory.createEmptyBorder(5,5,5,5))); gbc.gridx = 0; gbc.gridy++; @@ -246,7 +246,7 @@ private void initComponents() { gbc.weighty = 1.0; gbc.gridwidth = 3; gbc.fill = GridBagConstraints.BOTH; - panCenter.add(scrollFixedEntity, gbc); + panCenter.add(scrollFixedUnits, gbc); } @@ -318,9 +318,9 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { } private void initRandomForcesPanel(ResourceBundle resourceMap) { - panRandomForces = new JPanel(new GridBagLayout()); - panRandomForces.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Random Units"), + panRandomUnits = new JPanel(new GridBagLayout()); + panRandomUnits.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder(resourceMap.getString("panRandomUnits.title")), BorderFactory.createEmptyBorder(5,5,5,5))); GridBagConstraints gbc = new GridBagConstraints(); @@ -331,50 +331,50 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.gridwidth = 4; - chkUseRandomForces = new JCheckBox("Use randomly generated forces"); - chkUseRandomForces.setSelected(useRandomForces); - chkUseRandomForces.addActionListener(evt -> { - spnForceMultiplier.setEnabled(chkUseRandomForces.isSelected()); - spnPercentConventional.setEnabled(chkUseRandomForces.isSelected()); - spnBaChance.setEnabled(chkUseRandomForces.isSelected()); - spnLanceSize.setEnabled(chkUseRandomForces.isSelected()); - choiceFaction.setEnabled(chkUseRandomForces.isSelected()); - choiceBalancingMethod.setEnabled(chkUseRandomForces.isSelected()); - choiceUnitType.setEnabled(chkUseRandomForces.isSelected()); - choiceFocalWeightClass.setEnabled(chkUseRandomForces.isSelected()); - choiceSkillLevel.setEnabled(chkUseRandomForces.isSelected()); + chkUseRandomUnits = new JCheckBox(resourceMap.getString("chkUseRandomUnits.text")); + chkUseRandomUnits.setSelected(useRandomUnits); + chkUseRandomUnits.addActionListener(evt -> { + spnForceMultiplier.setEnabled(chkUseRandomUnits.isSelected()); + spnPercentConventional.setEnabled(chkUseRandomUnits.isSelected()); + spnBaChance.setEnabled(chkUseRandomUnits.isSelected()); + spnLanceSize.setEnabled(chkUseRandomUnits.isSelected()); + choiceFaction.setEnabled(chkUseRandomUnits.isSelected()); + choiceBalancingMethod.setEnabled(chkUseRandomUnits.isSelected()); + choiceUnitType.setEnabled(chkUseRandomUnits.isSelected()); + choiceFocalWeightClass.setEnabled(chkUseRandomUnits.isSelected()); + choiceSkillLevel.setEnabled(chkUseRandomUnits.isSelected()); }); - panRandomForces.add(chkUseRandomForces, gbc); + panRandomUnits.add(chkUseRandomUnits, gbc); DefaultComboBoxModel balancingMethodModel = new DefaultComboBoxModel<>(); balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.BV.name()); balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.WEIGHT_ADJ.name()); choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", balancingMethodModel); choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().toString()); - choiceBalancingMethod.setEnabled(useRandomForces); + choiceBalancingMethod.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 1; gbc.weightx = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(1, 0, 0, 5); - panRandomForces.add(new JLabel("Balancing Method:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblBalancingMethod.text")), gbc); gbc.gridx = 1; gbc.weightx = 1.0; - panRandomForces.add(choiceBalancingMethod, gbc); + panRandomUnits.add(choiceBalancingMethod, gbc); DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>(); factionModel.addAll(Factions.getInstance().getFactionList()); choiceFaction = new MMComboBox("choiceFaction", factionModel); choiceFaction.setSelectedItem(randomizer.getFactionCode()); - choiceFaction.setEnabled(useRandomForces); + choiceFaction.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomForces.add(new JLabel("Faction:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblFaction.text")), gbc); gbc.gridx = 1; gbc.weightx = 1.0; - panRandomForces.add(choiceFaction, gbc); + panRandomUnits.add(choiceFaction, gbc); DefaultComboBoxModel unitTypeModel = new DefaultComboBoxModel<>(); for(int i = 0; i < UnitType.SIZE; i++) { @@ -382,14 +382,14 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { } choiceUnitType = new MMComboBox("choiceUnitType", unitTypeModel); choiceUnitType.setSelectedItem(UnitType.getTypeName(randomizer.getUnitType())); - choiceUnitType.setEnabled(useRandomForces); + choiceUnitType.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomForces.add(new JLabel("Unit Type:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblUnitType.text")), gbc); gbc.gridx = 1; gbc.weightx = 1.0; - panRandomForces.add(choiceUnitType, gbc); + panRandomUnits.add(choiceUnitType, gbc); DefaultComboBoxModel skillLevelModel = new DefaultComboBoxModel<>(); for(SkillLevel skill : SkillLevel.values()) { @@ -400,14 +400,14 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { } choiceSkillLevel = new MMComboBox("choiceSkillLevel", skillLevelModel); choiceSkillLevel.setSelectedItem(randomizer.getSkill().name()); - choiceSkillLevel.setEnabled(useRandomForces); + choiceSkillLevel.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomForces.add(new JLabel("Skill Level:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblSkillLevel.text")), gbc); gbc.gridx = 1; gbc.weightx = 1.0; - panRandomForces.add(choiceSkillLevel, gbc); + panRandomUnits.add(choiceSkillLevel, gbc); DefaultComboBoxModel weightClassModel = new DefaultComboBoxModel<>(); weightClassModel.addElement("Not Specified"); @@ -422,57 +422,57 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { choiceFocalWeightClass.setSelectedItem(EntityWeightClass .getClassName((int) Math.round(randomizer.getFocalWeightClass()))); } - choiceFocalWeightClass.setEnabled(useRandomForces); + choiceFocalWeightClass.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomForces.add(new JLabel("Focal Weight Class:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblFocalWeightClass.text")), gbc); gbc.gridx = 1; gbc.weightx = 1.0; - panRandomForces.add(choiceFocalWeightClass, gbc); + panRandomUnits.add(choiceFocalWeightClass, gbc); spnForceMultiplier = new JSpinner(new SpinnerNumberModel(randomizer.getForceMultiplier(), 0.05, 5, 0.05)); - spnForceMultiplier.setEnabled(useRandomForces); + spnForceMultiplier.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy = 1; gbc.gridwidth = 1; gbc.weightx = 0.0; - panRandomForces.add(new JLabel("Force Multiplier:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblForceMultiplier.text")), gbc); gbc.gridx = 3; - panRandomForces.add(spnForceMultiplier, gbc); + panRandomUnits.add(spnForceMultiplier, gbc); spnPercentConventional = new JSpinner(new SpinnerNumberModel(randomizer.getPercentConventional(), 0, 75, 5)); - spnPercentConventional.setEnabled(useRandomForces); + spnPercentConventional.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomForces.add(new JLabel("Percent Conventional:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblPercentConventional.text")), gbc); gbc.gridx = 3; - panRandomForces.add(spnPercentConventional, gbc); + panRandomUnits.add(spnPercentConventional, gbc); spnBaChance = new JSpinner(new SpinnerNumberModel(randomizer.getBaChance(), 0, 100, 5)); - spnBaChance.setEnabled(useRandomForces); + spnBaChance.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomForces.add(new JLabel("Integrated BA Chance:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblBaChance.text")), gbc); gbc.gridx = 3; - panRandomForces.add(spnBaChance, gbc); + panRandomUnits.add(spnBaChance, gbc); spnLanceSize = new JSpinner(new SpinnerNumberModel(randomizer.getLanceSize(), 0, 6, 1)); - spnLanceSize.setEnabled(useRandomForces); + spnLanceSize.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomForces.add(new JLabel("Lance Size:"), gbc); + panRandomUnits.add(new JLabel(resourceMap.getString("lblLanceSize.text")), gbc); gbc.gridx = 3; - panRandomForces.add(spnLanceSize, gbc); + panRandomUnits.add(spnLanceSize, gbc); } private void refreshFixedEntityPanel() { - panFixedEntity.removeAll(); + panFixedUnits.removeAll(); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; @@ -481,11 +481,11 @@ private void refreshFixedEntityPanel() { gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(2, 5, 0, 0); for(String en : Utilities.generateEntityStub(fixedEntities)) { - panFixedEntity.add(new JLabel(en), gbc); + panFixedUnits.add(new JLabel(en), gbc); gbc.gridy++; } - panFixedEntity.revalidate(); - panFixedEntity.repaint(); + panFixedUnits.revalidate(); + panFixedUnits.repaint(); } public BotForce getBotForce() { @@ -570,8 +570,8 @@ private void done(ActionEvent evt) { botForce.setBehaviorSettings(behavior); botForce.setBotForceRandomizer(randomizer); botForce.setFixedEntityList(fixedEntities); - useRandomForces = chkUseRandomForces.isSelected(); - if(useRandomForces) { + useRandomUnits = chkUseRandomUnits.isSelected(); + if(useRandomUnits) { randomizer.setFactionCode((String) choiceFaction.getSelectedItem()); randomizer.setForceMultiplier((double) spnForceMultiplier.getValue()); randomizer.setPercentConventional((int) spnPercentConventional.getValue()); From c017c75c4f103986ddfbc1f50f6e542fe66c8579 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 09:34:01 -0700 Subject: [PATCH 23/76] Set botForceRandomizer default quality to C --- MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index 007ba97135..ed8eaa3a2c 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -29,6 +29,7 @@ import megamek.common.annotations.Nullable; import megamek.common.enums.Gender; import megamek.common.enums.SkillLevel; +import mekhq.campaign.rating.IUnitRating; import mekhq.utilities.MHQXMLUtility; import mekhq.campaign.Campaign; import mekhq.campaign.personnel.Bloodname; @@ -115,6 +116,7 @@ public BotForceRandomizer() { factionCode = "MERC"; skill = SkillLevel.REGULAR; unitType = UnitType.MEK; + quality = IUnitRating.DRAGOON_C; forceMultiplier = 1.0; percentConventional = 0; baChance = 0; From 52ff9240644b891fb672e63559076dd8d38a1244 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 09:34:32 -0700 Subject: [PATCH 24/76] Add quality chooser to CustomizeBotForceDialog randomizer options --- .../CustomizeBotForceDialog.properties | 1 + .../gui/dialog/CustomizeBotForceDialog.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index f82fa36076..1d6516055b 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -17,6 +17,7 @@ lblBalancingMethod.text=Balancing Method: lblFaction.text=Faction: lblUnitType.text=Unit Type: lblSkillLevel.text=Skill Level: +lblQuality.text=Rating: lblFocalWeightClass.text=Focal Weight Class: lblForceMultiplier.text=Force Multiplier: lblPercentConventional.text=Percent Conventional: diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index e0a21538b7..9b17e5f810 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -85,6 +85,7 @@ public class CustomizeBotForceDialog extends JDialog { private MMComboBox choiceSkillLevel; private MMComboBox choiceFocalWeightClass; private MMComboBox choiceFaction; + private MMComboBox choiceQuality; public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { super(parent, modal); @@ -343,6 +344,7 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { choiceUnitType.setEnabled(chkUseRandomUnits.isSelected()); choiceFocalWeightClass.setEnabled(chkUseRandomUnits.isSelected()); choiceSkillLevel.setEnabled(chkUseRandomUnits.isSelected()); + choiceQuality.setEnabled(chkUseRandomUnits.isSelected()); }); panRandomUnits.add(chkUseRandomUnits, gbc); @@ -409,6 +411,23 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.weightx = 1.0; panRandomUnits.add(choiceSkillLevel, gbc); + DefaultComboBoxModel qualityModel = new DefaultComboBoxModel<>(); + qualityModel.addElement("F"); + qualityModel.addElement("D"); + qualityModel.addElement("C"); + qualityModel.addElement("B"); + qualityModel.addElement("A"); + choiceQuality = new MMComboBox("choiceQuality", qualityModel); + choiceQuality.setSelectedIndex(randomizer.getQuality()); + choiceQuality.setEnabled(useRandomUnits); + gbc.gridx = 0; + gbc.gridy++; + gbc.weightx = 0.0; + panRandomUnits.add(new JLabel(resourceMap.getString("lblQuality.text")), gbc); + gbc.gridx = 1; + gbc.weightx = 1.0; + panRandomUnits.add(choiceQuality, gbc); + DefaultComboBoxModel weightClassModel = new DefaultComboBoxModel<>(); weightClassModel.addElement("Not Specified"); for(int i = EntityWeightClass.WEIGHT_LIGHT; i <= EntityWeightClass.WEIGHT_ASSAULT; i++) { @@ -579,6 +598,7 @@ private void done(ActionEvent evt) { randomizer.setLanceSize((int) spnLanceSize.getValue()); randomizer.setFocalWeightClass(choiceFocalWeightClass.getSelectedIndex()); randomizer.setSkill(SkillLevel.valueOf((String) choiceSkillLevel.getSelectedItem())); + randomizer.setQuality(choiceQuality.getSelectedIndex()); randomizer.setUnitType(choiceUnitType.getSelectedIndex()); randomizer.setBalancingMethod(BotForceRandomizer.BalancingMethod .valueOf((String) choiceBalancingMethod.getSelectedItem())); From ce533b109faab09f88f37e2fd23f324dd430a252 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 10:19:42 -0700 Subject: [PATCH 25/76] Add tooltips to randomizer elements in CustomizeBotForceDialog --- .../CustomizeBotForceDialog.properties | 16 +++++-- .../gui/dialog/CustomizeBotForceDialog.java | 42 ++++++++++++++----- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index 1d6516055b..79cc0db477 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -14,22 +14,32 @@ lblPilotingRisk.text=Piloting Risk: lblForcedWithdrawal.text=Forced Withdrawal: lblAutoFlee.text=Auto Flee: lblBalancingMethod.text=Balancing Method: +lblBalancingMethod.tooltip=What characteristic to balance force multiplier on
(e.g. BV, weight) lblFaction.text=Faction: +lblFaction.tooltip=Faction code for selecting units lblUnitType.text=Unit Type: +lblUnitType.tooltip=Which unit type to generate. For mixed unit types
use different forces on the same team or use percent
conventional and/or integrated BA chance. lblSkillLevel.text=Skill Level: +lblSkillLevel.tooltip=Base skill level for random skill generation of the units. lblQuality.text=Rating: +lblQuality.tooltip=Determines the tech quality of generated units. lblFocalWeightClass.text=Focal Weight Class: +lblFocalWeightClass.tooltip=The targeted weight class of the generated units. If not specified,
the targeted weight class will be chosen to match the player's force. lblForceMultiplier.text=Force Multiplier: +lblForceMultiplier.tooltip=How big/tough is this force relative to the player's force?
The final calculation will include fixed units as well. lblPercentConventional.text=Percent Conventional: +lblPercentConventional.tooltip=Replace a certain percent of a Mek or Aero force
with vehicles or conventional fighters, respectively. lblBaChance.text=Integrated BA Chance: +lblBaChance.tooltip=Probability that this force includes
integrated Battle Armor units. lblLanceSize.text=Formation Size: +lblLanceSize.tooltip=The minimum group size that units should be added in.
Larger values can lead to more approximate
results with force multiplier matching. btnOK.text=OK btnClose.text=Cancel btnBehavior.text=Edit Behavior Settings btnLoadUnits.text=Load Fixed Units -btnLoadUnits.tooltip=Load units from a .mul file,
overwriting existing units +btnLoadUnits.tooltip=Load fixed units from a .mul file,
overwriting existing units btnSaveUnits.text=Save Fixed Units -btnSaveUnits.tooltip=Save units to a .mul file +btnSaveUnits.tooltip=Save fixed units to a .mul file btnDeleteUnits.text=Delete Fixed Units -btnDeleteUnits.tooltip=Delete all units +btnDeleteUnits.tooltip=Delete all fixed units chkUseRandomUnits.text=Use randomly generated units \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 9b17e5f810..b64abb7f35 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -352,7 +352,7 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.BV.name()); balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.WEIGHT_ADJ.name()); choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", balancingMethodModel); - choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().toString()); + choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().name()); choiceBalancingMethod.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy = 1; @@ -360,7 +360,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.weightx = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets = new Insets(1, 0, 0, 5); - panRandomUnits.add(new JLabel(resourceMap.getString("lblBalancingMethod.text")), gbc); + JLabel lblBalancingMethod = new JLabel(resourceMap.getString("lblBalancingMethod.text")); + lblBalancingMethod.setToolTipText(resourceMap.getString("lblBalancingMethod.tooltip")); + panRandomUnits.add(lblBalancingMethod, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceBalancingMethod, gbc); @@ -373,7 +375,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblFaction.text")), gbc); + JLabel lblFaction = new JLabel(resourceMap.getString("lblFaction.text")); + lblFaction.setToolTipText(resourceMap.getString("lblFaction.tooltip")); + panRandomUnits.add(lblFaction, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceFaction, gbc); @@ -388,7 +392,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblUnitType.text")), gbc); + JLabel lblUnitType = new JLabel(resourceMap.getString("lblUnitType.text")); + lblUnitType.setToolTipText(resourceMap.getString("lblUnitType.tooltip")); + panRandomUnits.add(lblUnitType, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceUnitType, gbc); @@ -406,7 +412,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblSkillLevel.text")), gbc); + JLabel lblSkillLevel = new JLabel(resourceMap.getString("lblSkillLevel.text")); + lblSkillLevel.setToolTipText(resourceMap.getString("lblSkillLevel.tooltip")); + panRandomUnits.add(lblSkillLevel, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceSkillLevel, gbc); @@ -423,7 +431,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblQuality.text")), gbc); + JLabel lblQuality = new JLabel(resourceMap.getString("lblQuality.text")); + lblQuality.setToolTipText(resourceMap.getString("lblQuality.tooltip")); + panRandomUnits.add(lblQuality, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceQuality, gbc); @@ -445,7 +455,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblFocalWeightClass.text")), gbc); + JLabel lblFocalWeightClass = new JLabel(resourceMap.getString("lblFocalWeightClass.text")); + lblFocalWeightClass.setToolTipText(resourceMap.getString("lblFocalWeightClass.tooltip")); + panRandomUnits.add(lblFocalWeightClass, gbc); gbc.gridx = 1; gbc.weightx = 1.0; panRandomUnits.add(choiceFocalWeightClass, gbc); @@ -457,7 +469,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.gridy = 1; gbc.gridwidth = 1; gbc.weightx = 0.0; - panRandomUnits.add(new JLabel(resourceMap.getString("lblForceMultiplier.text")), gbc); + JLabel lblForceMultiplier = new JLabel(resourceMap.getString("lblForceMultiplier.text")); + lblForceMultiplier.setToolTipText(resourceMap.getString("lblForceMultiplier.tooltip")); + panRandomUnits.add(lblForceMultiplier, gbc); gbc.gridx = 3; panRandomUnits.add(spnForceMultiplier, gbc); @@ -466,7 +480,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { spnPercentConventional.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomUnits.add(new JLabel(resourceMap.getString("lblPercentConventional.text")), gbc); + JLabel lblPercentConventional = new JLabel(resourceMap.getString("lblPercentConventional.text")); + lblPercentConventional.setToolTipText(resourceMap.getString("lblPercentConventional.tooltip")); + panRandomUnits.add(lblPercentConventional, gbc); gbc.gridx = 3; panRandomUnits.add(spnPercentConventional, gbc); @@ -475,7 +491,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { spnBaChance.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomUnits.add(new JLabel(resourceMap.getString("lblBaChance.text")), gbc); + JLabel lblBaChance = new JLabel(resourceMap.getString("lblBaChance.text")); + lblBaChance.setToolTipText(resourceMap.getString("lblBaChance.tooltip")); + panRandomUnits.add(lblBaChance, gbc); gbc.gridx = 3; panRandomUnits.add(spnBaChance, gbc); @@ -484,7 +502,9 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { spnLanceSize.setEnabled(useRandomUnits); gbc.gridx = 2; gbc.gridy++; - panRandomUnits.add(new JLabel(resourceMap.getString("lblLanceSize.text")), gbc); + JLabel lblLanceSize = new JLabel(resourceMap.getString("lblLanceSize.text")); + lblLanceSize.setToolTipText(resourceMap.getString("lblLanceSize.tooltip")); + panRandomUnits.add(lblLanceSize, gbc); gbc.gridx = 3; panRandomUnits.add(spnLanceSize, gbc); } From 8d61ab6e6e5f7bd24f13470a8e702b3cd8cfaad3 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 10:36:55 -0700 Subject: [PATCH 26/76] Improve display of faction choices in CustomizeBotForceDialog --- .../resources/CustomizeBotForceDialog.properties | 2 +- .../mekhq/gui/dialog/CustomizeBotForceDialog.java | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index 79cc0db477..80f53d1783 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -16,7 +16,7 @@ lblAutoFlee.text=Auto Flee: lblBalancingMethod.text=Balancing Method: lblBalancingMethod.tooltip=What characteristic to balance force multiplier on
(e.g. BV, weight) lblFaction.text=Faction: -lblFaction.tooltip=Faction code for selecting units +lblFaction.tooltip=Faction for selecting units lblUnitType.text=Unit Type: lblUnitType.tooltip=Which unit type to generate. For mixed unit types
use different forces on the same team or use percent
conventional and/or integrated BA chance. lblSkillLevel.text=Skill Level: diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index b64abb7f35..34d5b4d44d 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -34,6 +34,7 @@ import mekhq.campaign.universe.Factions; import mekhq.gui.FileDialogs; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; +import mekhq.gui.displayWrappers.FactionDisplay; import org.apache.logging.log4j.LogManager; import javax.swing.*; @@ -84,7 +85,7 @@ public class CustomizeBotForceDialog extends JDialog { private MMComboBox choiceUnitType; private MMComboBox choiceSkillLevel; private MMComboBox choiceFocalWeightClass; - private MMComboBox choiceFaction; + private MMComboBox choiceFaction; private MMComboBox choiceQuality; public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { @@ -367,10 +368,12 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.weightx = 1.0; panRandomUnits.add(choiceBalancingMethod, gbc); - DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>(); - factionModel.addAll(Factions.getInstance().getFactionList()); - choiceFaction = new MMComboBox("choiceFaction", factionModel); - choiceFaction.setSelectedItem(randomizer.getFactionCode()); + DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>(); + factionModel.addAll(FactionDisplay.getSortedValidFactionDisplays(Factions.getInstance().getFactions(), + campaign.getLocalDate())); + choiceFaction = new MMComboBox<>("choiceFaction", factionModel); + choiceFaction.setSelectedItem(new FactionDisplay(Factions.getInstance().getFaction(randomizer.getFactionCode()), + campaign.getLocalDate())); choiceFaction.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; @@ -611,7 +614,7 @@ private void done(ActionEvent evt) { botForce.setFixedEntityList(fixedEntities); useRandomUnits = chkUseRandomUnits.isSelected(); if(useRandomUnits) { - randomizer.setFactionCode((String) choiceFaction.getSelectedItem()); + randomizer.setFactionCode(choiceFaction.getSelectedItem().getFaction().getShortName()); randomizer.setForceMultiplier((double) spnForceMultiplier.getValue()); randomizer.setPercentConventional((int) spnPercentConventional.getValue()); randomizer.setBaChance((int) spnBaChance.getValue()); From 76cd5bfd09e4c7e72c28bc5bdc7be5672b9f9e4b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 10:56:29 -0700 Subject: [PATCH 27/76] Improve processing of comboboxes with enumes in CustomizeBotForceDialog --- .../gui/dialog/CustomizeBotForceDialog.java | 35 +++++++------------ 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 34d5b4d44d..3afacef871 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -41,11 +41,8 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; -import java.util.ArrayList; -import java.util.Collections; +import java.util.*; import java.util.List; -import java.util.Optional; -import java.util.ResourceBundle; import java.util.stream.Collectors; public class CustomizeBotForceDialog extends JDialog { @@ -81,9 +78,9 @@ public class CustomizeBotForceDialog extends JDialog { private JSpinner spnPercentConventional; private JSpinner spnBaChance; private JSpinner spnLanceSize; - private MMComboBox choiceBalancingMethod; + private MMComboBox choiceBalancingMethod; private MMComboBox choiceUnitType; - private MMComboBox choiceSkillLevel; + private MMComboBox choiceSkillLevel; private MMComboBox choiceFocalWeightClass; private MMComboBox choiceFaction; private MMComboBox choiceQuality; @@ -349,11 +346,8 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { }); panRandomUnits.add(chkUseRandomUnits, gbc); - DefaultComboBoxModel balancingMethodModel = new DefaultComboBoxModel<>(); - balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.BV.name()); - balancingMethodModel.addElement(BotForceRandomizer.BalancingMethod.WEIGHT_ADJ.name()); - choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", balancingMethodModel); - choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod().name()); + choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", BotForceRandomizer.BalancingMethod.values()); + choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod()); choiceBalancingMethod.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy = 1; @@ -402,15 +396,11 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { gbc.weightx = 1.0; panRandomUnits.add(choiceUnitType, gbc); - DefaultComboBoxModel skillLevelModel = new DefaultComboBoxModel<>(); - for(SkillLevel skill : SkillLevel.values()) { - if(skill.isNone()) { - continue; - } - skillLevelModel.addElement(skill.name()); - } - choiceSkillLevel = new MMComboBox("choiceSkillLevel", skillLevelModel); - choiceSkillLevel.setSelectedItem(randomizer.getSkill().name()); + //leave out none as a skill option + ArrayList skills = Arrays.stream(SkillLevel.values()). + filter(skill -> !skill.isNone()).collect(Collectors.toCollection(() -> new ArrayList())); + choiceSkillLevel = new MMComboBox("choiceSkillLevel", skills.toArray()); + choiceSkillLevel.setSelectedItem(randomizer.getSkill()); choiceSkillLevel.setEnabled(useRandomUnits); gbc.gridx = 0; gbc.gridy++; @@ -620,11 +610,10 @@ private void done(ActionEvent evt) { randomizer.setBaChance((int) spnBaChance.getValue()); randomizer.setLanceSize((int) spnLanceSize.getValue()); randomizer.setFocalWeightClass(choiceFocalWeightClass.getSelectedIndex()); - randomizer.setSkill(SkillLevel.valueOf((String) choiceSkillLevel.getSelectedItem())); + randomizer.setSkill(choiceSkillLevel.getSelectedItem()); randomizer.setQuality(choiceQuality.getSelectedIndex()); randomizer.setUnitType(choiceUnitType.getSelectedIndex()); - randomizer.setBalancingMethod(BotForceRandomizer.BalancingMethod - .valueOf((String) choiceBalancingMethod.getSelectedItem())); + randomizer.setBalancingMethod(choiceBalancingMethod.getSelectedItem()); botForce.setBotForceRandomizer(randomizer); } else { botForce.setBotForceRandomizer(null); From 7b339f79cbe23953c2e3acf3a36020398c50915d Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 10:58:46 -0700 Subject: [PATCH 28/76] Align planetary condition values to the right in CustomizeBotForceDialog --- MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 3afacef871..201d99c10a 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -270,7 +270,7 @@ private void intBehaviorPanel(ResourceBundle resourceMap) { gbcRight.weightx = 1.0; gbcRight.weighty = 0.0; gbcRight.fill = GridBagConstraints.NONE; - gbcRight.anchor = GridBagConstraints.CENTER; + gbcRight.anchor = GridBagConstraints.EAST; gbcRight.insets = new Insets(0, 5, 0, 0); lblCowardice = new JLabel(Integer.toString(behavior.getBraveryIndex())); From 55534b430cfb10987e8a61f179bccdc458c8101e Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 14:13:45 -0700 Subject: [PATCH 29/76] Rework layout of CustomizeScenarioDialog --- .../src/mekhq/campaign/mission/BotForce.java | 13 ++ .../campaign/mission/BotForceRandomizer.java | 9 + .../gui/dialog/CustomizeScenarioDialog.java | 199 +++++++++--------- .../mekhq/gui/model/BotForceTableModel.java | 33 ++- 4 files changed, 140 insertions(+), 114 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 4b0838936f..b500ab866d 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -243,6 +243,19 @@ public int getTotalBV(Campaign c) { return bv; } + public int getFixedBV() { + int bv = 0; + + for (Entity entity : getFixedEntityList()) { + if (entity == null) { + LogManager.getLogger().error("Null entity when calculating the BV a bot force, we should never find a null here. Please investigate"); + } else { + bv += entity.calculateBattleValue(true, false); + } + } + return bv; + } + public BehaviorSettings getBehaviorSettings() { return behaviorSettings; } diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index ed8eaa3a2c..0608843530 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -567,6 +567,15 @@ private double calculateMeanWeightClass(List playerUnits) { return sumWeightClass / ((double) nUnits); } + public String getShortDescription(Campaign campaign) { + StringBuilder sb = new StringBuilder(); + sb.append(forceMultiplier); + sb.append(" ("); + sb.append(balancingMethod.toString()); + sb.append(")"); + return sb.toString(); + } + /** * This method returns a description of the random parameters of this object that will be shown in the * ScenarioViewPanel diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 06f370b987..03dff41fe6 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -78,14 +78,9 @@ public class CustomizeScenarioDialog extends JDialog { private BotForceTableModel forcesModel; // panels - private JPanel panMain; - private JPanel panLeft; - private JPanel panCenter; - private JPanel panRight; private JPanel panLoot; private JPanel panOtherForces; private JPanel panPlanetaryConditions; - private JPanel panBtn; // labels private JLabel lblLightDesc; @@ -165,40 +160,32 @@ private void initComponents() { setName("Form"); setTitle(resourceMap.getString("title.new")); - // set up panels - panMain = new JPanel(new GridLayout(0, 3)); - panLeft = new JPanel(new GridBagLayout()); - panCenter = new JPanel(new GridBagLayout()); - panRight = new JPanel(new GridBagLayout()); - panBtn = new JPanel(new GridLayout(0,2)); + JPanel panMain = new JPanel(new GridBagLayout()); + JPanel panInfo = new JPanel(new GridBagLayout()); + JPanel panWrite = new JPanel(new GridBagLayout()); + JPanel panBtn = new JPanel(new GridLayout(0,2)); - getContentPane().add(panMain, BorderLayout.CENTER); - getContentPane().add(panBtn, BorderLayout.PAGE_END); - panMain.add(panLeft); - panMain.add(panCenter); - panMain.add(panRight); - - // region Set up left panel - GridBagConstraints gridBagConstraints = new GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.anchor = GridBagConstraints.WEST; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLeft.add(new JLabel(resourceMap.getString("lblName.text")), gridBagConstraints); + // region Set up info panel + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 1; + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(5, 5, 5, 5); + panInfo.add(new JLabel(resourceMap.getString("lblName.text")), gbc); txtName = new JTextField(); txtName.setText(scenario.getName()); - gridBagConstraints.gridx = 1; - gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLeft.add(txtName, gridBagConstraints); + gbc.gridx = 1; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.insets = new Insets(5, 5, 5, 5); + panInfo.add(txtName, gbc); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.fill = GridBagConstraints.NONE; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panLeft.add(new JLabel(resourceMap.getString("lblStatus.text")), gridBagConstraints); + gbc.gridx = 0; + gbc.gridy++; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 5, 0, 0); + panInfo.add(new JLabel(resourceMap.getString("lblStatus.text")), gbc); choiceStatus = new JComboBox<>(new DefaultComboBoxModel<>(ScenarioStatus.values())); choiceStatus.setSelectedItem(scenario.getStatus()); @@ -214,28 +201,28 @@ public Component getListCellRendererComponent(final JList list, final Object return this; } }); - gridBagConstraints.gridx = 1; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); + gbc.gridx = 1; + gbc.insets = new Insets(5, 5, 0, 0); choiceStatus.setEnabled(!scenario.getStatus().isCurrent()); - panLeft.add(choiceStatus, gridBagConstraints); + panInfo.add(choiceStatus, gbc); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLeft.add(new JLabel(resourceMap.getString("lblDate.text")), gridBagConstraints); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.insets = new Insets(5, 5, 5, 5); + panInfo.add(new JLabel(resourceMap.getString("lblDate.text")), gbc); btnDate = new JButton(MekHQ.getMHQOptions().getDisplayFormattedDate(date)); btnDate.addActionListener(evt -> changeDate()); - gridBagConstraints.gridx = 1; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.insets = new Insets(5, 5, 0, 0); - panLeft.add(btnDate, gridBagConstraints); + gbc.gridx = 1; + gbc.gridwidth = 1; + gbc.insets = new Insets(5, 5, 0, 0); + panInfo.add(btnDate, gbc); if (scenario.getStatus().isCurrent() && (scenario instanceof AtBDynamicScenario)) { - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 1; + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; modifierBox = new JComboBox<>(); EventTiming scenarioState = ((AtBDynamicScenario) scenario).getNumBots() > 0 ? @@ -246,89 +233,70 @@ public Component getListCellRendererComponent(final JList list, final Object modifierBox.addItem(modifierKey); } } - panLeft.add(modifierBox, gridBagConstraints); + panInfo.add(modifierBox, gbc); JButton addEventButton = new JButton("Apply Modifier"); addEventButton.addActionListener(this::btnAddModifierActionPerformed); - gridBagConstraints.gridx = 1; - panLeft.add(addEventButton, gridBagConstraints); + gbc.gridx = 1; + panInfo.add(addEventButton, gbc); } initPlanetaryConditionsPanel(resourceMap); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - panLeft.add(panPlanetaryConditions, gridBagConstraints); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 2; + gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.BOTH; + panInfo.add(panPlanetaryConditions, gbc); + // endregion Set up info panel initLootPanel(resourceMap); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 2; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panLoot.setPreferredSize(new Dimension(400,150)); - panLoot.setMinimumSize(new Dimension(400,150)); + panLoot.setPreferredSize(new Dimension(300,150)); + panLoot.setMinimumSize(new Dimension(300,150)); panLoot.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Scenario Costs & Payouts"), BorderFactory.createEmptyBorder(5,5,5,5))); - panLeft.add(panLoot, gridBagConstraints); - // endregion Set up left panel - // region Set up center panel initOtherForcesPanel(resourceMap); panOtherForces.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(0, 0, 10, 0), BorderFactory.createTitledBorder(resourceMap.getString("panOtherForces.title")))); - gridBagConstraints = new GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy = 0; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panCenter.add(panOtherForces, gridBagConstraints); - - // endregion Set up center panel - - // region Set up right panel + panOtherForces.setPreferredSize(new Dimension(600,150)); + panOtherForces.setMinimumSize(new Dimension(600,150)); + + // region Set up writing panel txtDesc = new MarkdownEditorPanel("Description"); txtDesc.setText(scenario.getDescription()); txtDesc.setMinimumSize(new Dimension(400, 100)); txtDesc.setPreferredSize(new Dimension(400, 250)); - gridBagConstraints = new GridBagConstraints(); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panRight.add(txtDesc, gridBagConstraints); + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.insets = new Insets(5, 5, 5, 5); + panWrite.add(txtDesc, gbc); if (!scenario.getStatus().isCurrent()) { txtReport = new MarkdownEditorPanel("After-Action Report"); txtReport.setText(scenario.getReport()); txtReport.setMinimumSize(new Dimension(400, 100)); txtReport.setPreferredSize(new Dimension(400, 250)); - gridBagConstraints.gridx = 0; - gridBagConstraints.gridy++; - gridBagConstraints.gridwidth = 1; - gridBagConstraints.weightx = 1.0; - gridBagConstraints.weighty = 1.0; - gridBagConstraints.fill = GridBagConstraints.BOTH; - gridBagConstraints.anchor = GridBagConstraints.NORTHWEST; - gridBagConstraints.insets = new Insets(5, 5, 5, 5); - panRight.add(txtReport, gridBagConstraints); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.insets = new Insets(5, 5, 5, 5); + panWrite.add(txtReport, gbc); txtReport.setEnabled(!scenario.getStatus().isCurrent()); } - // endregion Set up right panel + // endregion Set up writing panel // region Set up buttons if (newScenario && (mission instanceof AtBContract)) { @@ -359,6 +327,29 @@ public Component getListCellRendererComponent(final JList list, final Object panBtn.add(btnClose); //endregion Set up buttons + // layout main panel + getContentPane().add(panMain, BorderLayout.CENTER); + getContentPane().add(panBtn, BorderLayout.PAGE_END); + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.BOTH; + panMain.add(panInfo, gbc); + gbc.gridx = 1; + panMain.add(panLoot, gbc); + gbc.gridx = 2; + gbc.gridheight = 2; + gbc.weighty = 1.0; + panMain.add(panWrite, gbc); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.gridwidth = 2; + gbc.gridheight = 1; + panMain.add(panOtherForces, gbc); + pack(); } diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java index 870d1f92a3..b90163d011 100644 --- a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -25,13 +25,13 @@ import megamek.common.IStartingPositions; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; +import mekhq.campaign.universe.Factions; import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import java.awt.*; import java.util.List; -import java.util.stream.Collectors; public class BotForceTableModel extends AbstractTableModel { @@ -41,7 +41,7 @@ public class BotForceTableModel extends AbstractTableModel { private Campaign campaign; public final static int COL_NAME = 0; - public final static int COL_RELATION = 1; + public final static int COL_IFF = 1; public final static int COL_FIXED = 2; public final static int COL_RANDOM = 3; public final static int COL_DEPLOYMENT = 4; @@ -68,8 +68,8 @@ public String getColumnName(int column) { switch (column) { case COL_NAME: return "Name"; - case COL_RELATION: - return "Relation"; + case COL_IFF: + return "IFF"; case COL_FIXED: return "Fixed"; case COL_RANDOM: @@ -93,12 +93,13 @@ public Object getValueAt(int row, int col) { switch (col) { case COL_NAME: return botForce.getName(); - case COL_RELATION: + case COL_IFF: return (botForce.getTeam() == 1) ? "Allied" : "Enemy (Team " + botForce.getTeam() + ")"; case COL_FIXED: - return botForce.getTotalBV(campaign); + return botForce.getFixedEntityList().size() + " Units, BV: " + botForce.getFixedBV(); case COL_RANDOM: - return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer().getDescription(campaign)); + return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer(). + getShortDescription(campaign)); case COL_DEPLOYMENT: return IStartingPositions.START_LOCATION_NAMES[botForce.getStart()]; default: @@ -132,16 +133,18 @@ public List getAllBotForces() { public int getColumnWidth(int col) { switch (col) { case COL_NAME: - return 100; - default: + return 80; + case COL_DEPLOYMENT: return 20; + default: + return 30; } } public int getAlignment(int col) { switch (col) { case COL_NAME: - case COL_RELATION: + case COL_IFF: return SwingConstants.LEFT; case COL_DEPLOYMENT: return SwingConstants.CENTER; @@ -151,7 +154,17 @@ public int getAlignment(int col) { } public String getTooltip(int row, int col) { + BotForce botForce; + if (data.isEmpty()) { + return ""; + } else { + botForce = getBotForceAt(row); + } + switch (col) { + case COL_RANDOM: + return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer(). + getDescription(campaign)); default: return null; } From f83f05172cd480803e8f480d4033e04bd770fdf2 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 14:25:25 -0700 Subject: [PATCH 30/76] Disable edit/delete buttons for loot and forces in initialization --- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 03dff41fe6..4256e622d3 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -598,13 +598,11 @@ private void initLootPanel(ResourceBundle resourceMap) { btnEditLoot = new JButton(resourceMap.getString("btnEditLoot.text")); btnEditLoot.setEnabled(false); btnEditLoot.addActionListener(evt -> editLoot()); - btnEditLoot.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnEditLoot); btnDeleteLoot = new JButton(resourceMap.getString("btnDeleteLoot.text")); btnDeleteLoot.setEnabled(false); btnDeleteLoot.addActionListener(evt -> deleteLoot()); - btnDeleteLoot.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnDeleteLoot); panLoot.add(panBtns, BorderLayout.PAGE_START); @@ -681,13 +679,13 @@ private void initOtherForcesPanel(ResourceBundle resourceMap) { btnEditForce = new JButton(resourceMap.getString("btnEditForce.text")); btnEditForce.setEnabled(false); btnEditForce.addActionListener(evt -> editForce()); - btnEditForce.setEnabled(scenario.getStatus().isCurrent()); + btnEditForce.setEnabled(false); panBtns.add(btnEditForce); btnDeleteForce = new JButton(resourceMap.getString("btnDeleteForce.text")); btnDeleteForce.setEnabled(false); btnDeleteForce.addActionListener(evt -> deleteForce()); - btnDeleteForce.setEnabled(scenario.getStatus().isCurrent()); + btnDeleteForce.setEnabled(false); panBtns.add(btnDeleteForce); panOtherForces.add(panBtns, BorderLayout.PAGE_START); From 2d3654cf164ad812e1fb78ed9613f8a2bc95fe62 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 12 Apr 2024 14:38:00 -0700 Subject: [PATCH 31/76] Adjust insets of planetary conditions labels in CustomizeScenarioDialog --- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 4256e622d3..c2b7741d04 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -468,7 +468,7 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { leftGbc.gridwidth = 1; leftGbc.weightx = 0.0; leftGbc.weighty = 0.0; - leftGbc.insets = new Insets(0, 0, 5, 10); + leftGbc.insets = new Insets(0, 5, 5, 5); leftGbc.fill = GridBagConstraints.NONE; leftGbc.anchor = GridBagConstraints.NORTHWEST; @@ -476,9 +476,9 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { rightGbc.gridx = 1; rightGbc.gridy = 0; rightGbc.gridwidth = 1; - rightGbc.weightx = 0.5; + rightGbc.weightx = 0.0; rightGbc.weighty = 0.0; - rightGbc.insets = new Insets(0, 10, 5, 0); + rightGbc.insets = new Insets(0, 5, 5, 0); rightGbc.fill = GridBagConstraints.NONE; rightGbc.anchor = GridBagConstraints.NORTHWEST; @@ -508,6 +508,7 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { lblFogDesc = new JLabel(scenario.getFog().toString()); rightGbc.gridy++; + rightGbc.weightx = 1.0; panPlanetaryConditions.add(lblFogDesc, rightGbc); leftGbc.gridy++; From 490bcfc57eaed57c9a49bf6aa5b24e2078506145 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 13 Apr 2024 08:06:54 -0700 Subject: [PATCH 32/76] Start EditScenarioDeploymentLimitDialog --- .../CustomizeScenarioDialog.properties | 5 + .../src/mekhq/campaign/mission/Scenario.java | 4 + .../mission/ScenarioDeploymentLimit.java | 41 +++++- .../gui/dialog/CustomizeScenarioDialog.java | 127 +++++++++++++++- .../EditScenarioDeploymentLimitDialog.java | 137 ++++++++++++++++++ 5 files changed, 305 insertions(+), 9 deletions(-) create mode 100644 MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index d9bdbeaece..348d326bcd 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -10,6 +10,11 @@ btnEditLoot.text=Edit Loot btnDeleteLoot.text=Delete Loot btnPlanetaryConditions.text=Edit Planetary Conditions... panPlanetaryConditions.title=Planetary Conditions +panDeploymentLimits.title=Deployment Limits +lblAllowedUnits.text=Allowed Unit Types: +lblQuantityLimit.text=Quantity Limit: +lblRequiredPersonnel.text=Required Personnel: +lblRequiredUnits.text=Required Units: lblLight.text=Light: lblWeather.text=Weather: lblWind.text=Wind: diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index aa4ba892ec..c8dd61f30a 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -428,6 +428,10 @@ public ScenarioDeploymentLimit getDeploymentLimit() { return deploymentLimit; } + public void setDeploymentLimit(ScenarioDeploymentLimit limit) { + this.deploymentLimit = limit; + } + public Map> getPlayerTransportLinkages() { return playerTransportLinkages; } diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java index deabbc15ba..7c5c01acf0 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.UUID; import java.util.Vector; +import java.util.stream.Collectors; /** * This class is optionally used by Scenario to determine any limits on the type and quantity of units that the player @@ -50,7 +51,7 @@ public class ScenarioDeploymentLimit { /** * The QuantityType enum tells this class how to interpret the meaning quantityLimit variable */ - private enum QuantityType { + public enum QuantityType { /** * the PERCENT QuantityType will treat the quantityLimit variable as a percent of the player's valid forces */ @@ -64,7 +65,7 @@ private enum QuantityType { /** * The CountType enum tells this class what the units of the quantity limits should be */ - private enum CountType { + public enum CountType { /** * The BV CountType will limit deployed forces by BV */ @@ -118,6 +119,42 @@ public ScenarioDeploymentLimit() { } //endregion Constructors + public ScenarioDeploymentLimit getCopy() { + ScenarioDeploymentLimit copy = new ScenarioDeploymentLimit(); + copy.quantityLimit = this.quantityLimit; + copy.quantityType = this.quantityType; + copy.countType = this.countType; + copy.requiredPersonnel = this.requiredPersonnel.stream().collect(Collectors.toList()); + copy.requiredPersonnel = this.requiredUnits.stream().collect(Collectors.toList()); + copy.allowedUnitTypes = this.allowedUnitTypes.stream().collect(Collectors.toList()); + + return copy; + } + + public int getQuantityLimit() { + return quantityLimit; + } + + public void setQuantityLimit(int quantityLimit) { + this.quantityLimit = quantityLimit; + } + + public CountType getCountType() { + return countType; + } + + public void setCountType(CountType countType) { + this.countType = countType; + } + + public QuantityType getQuantityType() { + return quantityType; + } + + public void setQuantityType(QuantityType quantityType) { + this.quantityType = quantityType; + } + //region Unit type methods /** * Add a UnitType integer to the allowed unit types list diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index c2b7741d04..70c8ee7823 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -23,7 +23,6 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; import megamek.client.ui.swing.PlanetaryConditionsDialog; -import megamek.common.planetaryconditions.Atmosphere; import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; import mekhq.campaign.Campaign; @@ -40,9 +39,6 @@ import javax.swing.*; import javax.swing.event.ListSelectionEvent; import javax.swing.table.TableColumn; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.TreePath; -import javax.swing.tree.TreeSelectionModel; import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; @@ -65,6 +61,7 @@ public class CustomizeScenarioDialog extends JDialog { private Campaign campaign; private boolean newScenario; private LocalDate date; + private ScenarioDeploymentLimit deploymentLimits; private PlanetaryConditions planetaryConditions; private List botForces; @@ -78,11 +75,16 @@ public class CustomizeScenarioDialog extends JDialog { private BotForceTableModel forcesModel; // panels + private JPanel panDeploymentLimits; private JPanel panLoot; private JPanel panOtherForces; private JPanel panPlanetaryConditions; // labels + private JLabel lblAllowedUnitsDesc; + private JLabel lblQuantityLimitDesc; + private JLabel lblRequiredPersonnelDesc; + private JLabel lblRequiredUnitsDesc; private JLabel lblLightDesc; private JLabel lblWindDesc; private JLabel lblAtmosphereDesc; @@ -114,7 +116,7 @@ public class CustomizeScenarioDialog extends JDialog { private JButton btnClose; private JButton btnOK; - // markdown editors + //region markdown editors private MarkdownEditorPanel txtDesc; private MarkdownEditorPanel txtReport; //endregion Variable declarations @@ -136,9 +138,13 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission } date = scenario.getDate(); + if(scenario.getDeploymentLimit() != null) { + deploymentLimits = scenario.getDeploymentLimit().getCopy(); + } + planetaryConditions = scenario.createPlanetaryConditions(); - botForces = scenario.getBotForces().stream().collect(Collectors.toList());; + botForces = scenario.getBotForces().stream().collect(Collectors.toList()); forcesModel = new BotForceTableModel(botForces, campaign); loots = new ArrayList<>(); @@ -241,11 +247,16 @@ public Component getListCellRendererComponent(final JList list, final Object panInfo.add(addEventButton, gbc); } - initPlanetaryConditionsPanel(resourceMap); + initDeployLimitPanel(resourceMap); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 2; gbc.weightx = 1.0; + gbc.fill = GridBagConstraints.HORIZONTAL; + panInfo.add(panDeploymentLimits, gbc); + + initPlanetaryConditionsPanel(resourceMap); + gbc.gridy++; gbc.fill = GridBagConstraints.BOTH; panInfo.add(panPlanetaryConditions, gbc); // endregion Set up info panel @@ -377,6 +388,7 @@ private void btnOKActionPerformed(ActionEvent evt) { scenario.setStatus((ScenarioStatus) choiceStatus.getSelectedItem()); } } + scenario.setDeploymentLimit(deploymentLimits); scenario.readPlanetaryConditions(planetaryConditions); scenario.setDate(date); scenario.setBotForces(botForces); @@ -444,6 +456,107 @@ private void changeDate() { } } + private void initDeployLimitPanel(ResourceBundle resourceMap) { + + panDeploymentLimits = new JPanel(new GridBagLayout()); + panDeploymentLimits.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 0, 10, 0), + BorderFactory.createTitledBorder(resourceMap.getString("panDeploymentLimits.title")))); + + JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JButton btnEditLimits = new JButton("Edit Limits"); + btnEditLimits.addActionListener(this::editLimits); + panButtons.add(btnEditLimits); + JButton btnRemoveLimits = new JButton("Remove Limits"); + btnRemoveLimits.addActionListener(this::removeLimits); + panButtons.add(btnRemoveLimits); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.NORTHWEST; + panDeploymentLimits.add(panButtons, gbc); + + GridBagConstraints leftGbc = new GridBagConstraints(); + leftGbc.gridx = 0; + leftGbc.gridy = 1; + leftGbc.gridwidth = 1; + leftGbc.weightx = 0.0; + leftGbc.weighty = 0.0; + leftGbc.insets = new Insets(0, 0, 5, 10); + leftGbc.fill = GridBagConstraints.NONE; + leftGbc.anchor = GridBagConstraints.NORTHWEST; + + GridBagConstraints rightGbc = new GridBagConstraints(); + rightGbc.gridx = 1; + rightGbc.gridy = 1; + rightGbc.gridwidth = 1; + rightGbc.weightx = 1.0; + rightGbc.weighty = 0.0; + rightGbc.insets = new Insets(0, 10, 5, 0); + rightGbc.fill = GridBagConstraints.HORIZONTAL; + rightGbc.anchor = GridBagConstraints.NORTHWEST; + + leftGbc.gridy++; + panDeploymentLimits.add(new JLabel(resourceMap.getString("lblAllowedUnits.text")), leftGbc); + + lblAllowedUnitsDesc = new JLabel(); + rightGbc.gridy++; + panDeploymentLimits.add(lblAllowedUnitsDesc, rightGbc); + + leftGbc.gridy++; + panDeploymentLimits.add(new JLabel(resourceMap.getString("lblQuantityLimit.text")), leftGbc); + + lblQuantityLimitDesc = new JLabel(); + rightGbc.gridy++; + panDeploymentLimits.add(lblQuantityLimitDesc, rightGbc); + + leftGbc.gridy++; + panDeploymentLimits.add(new JLabel(resourceMap.getString("lblRequiredPersonnel.text")), leftGbc); + + lblRequiredPersonnelDesc = new JLabel(); + rightGbc.gridy++; + panDeploymentLimits.add(lblRequiredPersonnelDesc, rightGbc); + + leftGbc.gridy++; + panDeploymentLimits.add(new JLabel(resourceMap.getString("lblRequiredUnits.text")), leftGbc); + + lblRequiredUnitsDesc = new JLabel(); + rightGbc.gridy++; + panDeploymentLimits.add(lblRequiredUnitsDesc, rightGbc); + + refreshDeploymentLimits(); + } + + private void refreshDeploymentLimits() { + if(deploymentLimits != null) { + lblAllowedUnitsDesc.setText(deploymentLimits.getAllowedUnitTypeDesc()); + lblQuantityLimitDesc.setText(deploymentLimits.getQuantityLimitDesc(scenario, campaign)); + lblRequiredPersonnelDesc.setText(deploymentLimits.getRequiredPersonnelDesc(campaign)); + lblRequiredUnitsDesc.setText(deploymentLimits.getRequiredUnitDesc(campaign)); + } else { + lblAllowedUnitsDesc.setText("All"); + lblQuantityLimitDesc.setText("No Limits"); + lblRequiredPersonnelDesc.setText("None"); + lblRequiredUnitsDesc.setText("None"); + } + } + + private void editLimits(ActionEvent evt) { + EditScenarioDeploymentLimitDialog esdld = new EditScenarioDeploymentLimitDialog(frame, true, deploymentLimits); + esdld.setVisible(true); + deploymentLimits = esdld.getDeploymentLimit(); + refreshDeploymentLimits(); + } + + private void removeLimits(ActionEvent evt) { + deploymentLimits = null; + refreshDeploymentLimits(); + } + private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { panPlanetaryConditions = new JPanel(new GridBagLayout()); panPlanetaryConditions.setBorder(BorderFactory.createCompoundBorder( diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java new file mode 100644 index 0000000000..16f9654b37 --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.gui.dialog; + +import megamek.client.ui.baseComponents.MMComboBox; +import mekhq.campaign.mission.BotForceRandomizer; +import mekhq.campaign.mission.ScenarioDeploymentLimit; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; + +public class EditScenarioDeploymentLimitDialog extends JDialog { + + private JFrame frame; + private ScenarioDeploymentLimit deploymentLimit; + private boolean newLimit; + + private JSpinner spnQuantity; + private MMComboBox choiceQuantityType; + private MMComboBox choiceCountType; + + public EditScenarioDeploymentLimitDialog(JFrame parent, boolean modal, ScenarioDeploymentLimit limit) { + super(parent, modal); + this.frame = parent; + if(limit == null) { + deploymentLimit = new ScenarioDeploymentLimit(); + newLimit = true; + } else { + deploymentLimit = limit; + newLimit = false; + } + initComponents(); + setLocationRelativeTo(parent); + pack(); + } + + private void initComponents() { + //final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.EditScenarioDeploymentLimitsDialog", + // MekHQ.getMHQOptions().getLocale()); + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + setName("Form"); + setTitle("Edit Scenario Deployment Limits"); + + getContentPane().setLayout(new BorderLayout()); + JPanel panMain = new JPanel(new GridBagLayout()); + JPanel panButtons = new JPanel(new GridLayout(0, 2)); + + GridBagConstraints leftGbc = new GridBagConstraints(); + leftGbc.gridx = 0; + leftGbc.gridy = 1; + leftGbc.gridwidth = 1; + leftGbc.weightx = 0.0; + leftGbc.weighty = 0.0; + leftGbc.insets = new Insets(0, 0, 5, 10); + leftGbc.fill = GridBagConstraints.NONE; + leftGbc.anchor = GridBagConstraints.NORTHWEST; + + GridBagConstraints rightGbc = new GridBagConstraints(); + rightGbc.gridx = 1; + rightGbc.gridy = 1; + rightGbc.gridwidth = 1; + rightGbc.weightx = 1.0; + rightGbc.weighty = 0.0; + rightGbc.insets = new Insets(0, 10, 5, 0); + rightGbc.fill = GridBagConstraints.HORIZONTAL; + rightGbc.anchor = GridBagConstraints.NORTHWEST; + + JLabel lblQuantityType = new JLabel("Quantity Type:"); + panMain.add(lblQuantityType, leftGbc); + choiceQuantityType = new MMComboBox("choiceQuantityType", ScenarioDeploymentLimit.QuantityType.values()); + choiceQuantityType.setSelectedItem(deploymentLimit.getQuantityType()); + panMain.add(choiceQuantityType, rightGbc); + + + JLabel lblCountType = new JLabel("Maximum Type:"); + leftGbc.gridy++; + panMain.add(lblCountType, leftGbc); + choiceCountType = new MMComboBox("choiceCountType", ScenarioDeploymentLimit.CountType.values()); + choiceCountType.setSelectedItem(deploymentLimit.getCountType()); + rightGbc.gridy++; + panMain.add(choiceCountType, rightGbc); + + + JLabel lblQuantity = new JLabel("Maximum Quantity:"); + leftGbc.gridy++; + panMain.add(lblQuantity, leftGbc); + spnQuantity = new JSpinner(new SpinnerNumberModel(deploymentLimit.getQuantityLimit(), + 1, 100, 1)); + rightGbc.gridy++; + panMain.add(spnQuantity, rightGbc); + + JButton btnOk = new JButton("OK"); + btnOk.addActionListener(this::complete); + JButton btnClose = new JButton("Cancel"); + btnClose.addActionListener(this::cancel); + panButtons.add(btnOk); + panButtons.add(btnClose); + + getContentPane().add(panMain, BorderLayout.CENTER); + getContentPane().add(panButtons, BorderLayout.PAGE_END); + } + + private void complete(ActionEvent evt) { + deploymentLimit.setQuantityLimit((int) spnQuantity.getValue()); + deploymentLimit.setQuantityType(choiceQuantityType.getSelectedItem()); + deploymentLimit.setCountType(choiceCountType.getSelectedItem()); + this.setVisible(false); + } + + private void cancel(ActionEvent evt) { + if(newLimit) { + deploymentLimit = null; + } + this.setVisible(false); + } + + public ScenarioDeploymentLimit getDeploymentLimit() { + return deploymentLimit; + } +} From 8c75c8faec66eb024b7839d96356df2a6f52be60 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 13 Apr 2024 08:22:59 -0700 Subject: [PATCH 33/76] Change SpinnerModel dynamically in EditScenarioDeploymentLimitDialog --- .../EditScenarioDeploymentLimitDialog.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 16f9654b37..851e313a7c 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -86,6 +86,7 @@ private void initComponents() { panMain.add(lblQuantityType, leftGbc); choiceQuantityType = new MMComboBox("choiceQuantityType", ScenarioDeploymentLimit.QuantityType.values()); choiceQuantityType.setSelectedItem(deploymentLimit.getQuantityType()); + choiceQuantityType.addActionListener(this::setQuantityModel); panMain.add(choiceQuantityType, rightGbc); @@ -94,6 +95,7 @@ private void initComponents() { panMain.add(lblCountType, leftGbc); choiceCountType = new MMComboBox("choiceCountType", ScenarioDeploymentLimit.CountType.values()); choiceCountType.setSelectedItem(deploymentLimit.getCountType()); + choiceCountType.addActionListener(this::setQuantityModel); rightGbc.gridy++; panMain.add(choiceCountType, rightGbc); @@ -101,8 +103,9 @@ private void initComponents() { JLabel lblQuantity = new JLabel("Maximum Quantity:"); leftGbc.gridy++; panMain.add(lblQuantity, leftGbc); - spnQuantity = new JSpinner(new SpinnerNumberModel(deploymentLimit.getQuantityLimit(), - 1, 100, 1)); + spnQuantity = new JSpinner(); + spnQuantity.setValue(deploymentLimit.getQuantityLimit()); + setQuantityModel(null); rightGbc.gridy++; panMain.add(spnQuantity, rightGbc); @@ -117,6 +120,27 @@ private void initComponents() { getContentPane().add(panButtons, BorderLayout.PAGE_END); } + private void setQuantityModel(ActionEvent evt) { + int currentQuantity = (int) spnQuantity.getValue(); + if(currentQuantity < 1) { + currentQuantity = 1; + } + ScenarioDeploymentLimit.CountType currentCountType = choiceCountType.getSelectedItem(); + ScenarioDeploymentLimit.QuantityType currentQuantityType = choiceQuantityType.getSelectedItem(); + if(currentQuantityType == ScenarioDeploymentLimit.QuantityType.PERCENT) { + if(currentQuantity > 100) { + currentQuantity = 100; + } + spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, 100, 5)); + } else { + if(currentCountType == ScenarioDeploymentLimit.CountType.UNIT) { + spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, null, 1)); + } else { + spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, null, 500)); + } + } + } + private void complete(ActionEvent evt) { deploymentLimit.setQuantityLimit((int) spnQuantity.getValue()); deploymentLimit.setQuantityType(choiceQuantityType.getSelectedItem()); From 20e00dbae184ceddbf5e45d0bbc6565387ef07a8 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 13 Apr 2024 15:26:39 -0700 Subject: [PATCH 34/76] Add EditScenarioDeploymentLimitDialog --- .../mission/ScenarioDeploymentLimit.java | 8 +++ .../EditScenarioDeploymentLimitDialog.java | 56 ++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java index 7c5c01acf0..cf35715acb 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java @@ -155,6 +155,14 @@ public void setQuantityType(QuantityType quantityType) { this.quantityType = quantityType; } + public List getAllowedUnitTypes() { + return allowedUnitTypes; + } + + public void setAllowedUnitTypes(List allowedUnitTypes) { + this.allowedUnitTypes = allowedUnitTypes; + } + //region Unit type methods /** * Add a UnitType integer to the allowed unit types list diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 851e313a7c..7a1e501a55 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -19,12 +19,13 @@ package mekhq.gui.dialog; import megamek.client.ui.baseComponents.MMComboBox; -import mekhq.campaign.mission.BotForceRandomizer; +import megamek.common.UnitType; import mekhq.campaign.mission.ScenarioDeploymentLimit; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; +import java.util.ArrayList; public class EditScenarioDeploymentLimitDialog extends JDialog { @@ -35,6 +36,8 @@ public class EditScenarioDeploymentLimitDialog extends JDialog { private JSpinner spnQuantity; private MMComboBox choiceQuantityType; private MMComboBox choiceCountType; + private JCheckBox checkAllUnits; + private JCheckBox[] checkAllowedUnits; public EditScenarioDeploymentLimitDialog(JFrame parent, boolean modal, ScenarioDeploymentLimit limit) { super(parent, modal); @@ -64,7 +67,7 @@ private void initComponents() { GridBagConstraints leftGbc = new GridBagConstraints(); leftGbc.gridx = 0; - leftGbc.gridy = 1; + leftGbc.gridy = 0; leftGbc.gridwidth = 1; leftGbc.weightx = 0.0; leftGbc.weighty = 0.0; @@ -74,7 +77,7 @@ private void initComponents() { GridBagConstraints rightGbc = new GridBagConstraints(); rightGbc.gridx = 1; - rightGbc.gridy = 1; + rightGbc.gridy = 0; rightGbc.gridwidth = 1; rightGbc.weightx = 1.0; rightGbc.weighty = 0.0; @@ -109,6 +112,33 @@ private void initComponents() { rightGbc.gridy++; panMain.add(spnQuantity, rightGbc); + JPanel panAllowedUnits = new JPanel(new GridLayout(UnitType.SIZE+1, 1)); + panAllowedUnits.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 0, 10, 0), + BorderFactory.createTitledBorder("Allowed Units"))); + checkAllUnits = new JCheckBox("Allow all units"); + checkAllUnits.setSelected(deploymentLimit.getAllowedUnitTypes().isEmpty()); + checkAllUnits.addActionListener(this::checkAllUnits); + panAllowedUnits.add(checkAllUnits); + checkAllowedUnits = new JCheckBox [UnitType.SIZE]; + for(int i = UnitType.MEK; i < UnitType.SIZE; i++) { + JCheckBox check = new JCheckBox(UnitType.getTypeName(i)); + check.setSelected(deploymentLimit.getAllowedUnitTypes().contains(i)); + check.setEnabled(!checkAllUnits.isSelected()); + checkAllowedUnits[i] = check; + panAllowedUnits.add(check); + } + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 2; + gbc.gridy = 0; + gbc.weightx = 0.0; + gbc.weighty = 1.0; + gbc.fill = GridBagConstraints.BOTH; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.gridheight = 3; + panMain.add(panAllowedUnits, gbc); + JButton btnOk = new JButton("OK"); btnOk.addActionListener(this::complete); JButton btnClose = new JButton("Cancel"); @@ -120,6 +150,17 @@ private void initComponents() { getContentPane().add(panButtons, BorderLayout.PAGE_END); } + private void checkAllUnits(ActionEvent evt) { + for(JCheckBox box : checkAllowedUnits) { + if(checkAllUnits.isSelected()) { + box.setSelected(false); + box.setEnabled(false); + } else { + box.setEnabled(true); + } + } + } + private void setQuantityModel(ActionEvent evt) { int currentQuantity = (int) spnQuantity.getValue(); if(currentQuantity < 1) { @@ -145,6 +186,15 @@ private void complete(ActionEvent evt) { deploymentLimit.setQuantityLimit((int) spnQuantity.getValue()); deploymentLimit.setQuantityType(choiceQuantityType.getSelectedItem()); deploymentLimit.setCountType(choiceCountType.getSelectedItem()); + ArrayList allowed = new ArrayList(); + if(!checkAllUnits.isSelected()) { + for(int i = UnitType.MEK; i < UnitType.SIZE; i++) { + if(checkAllowedUnits[i].isSelected()) { + allowed.add(i); + } + } + } + deploymentLimit.setAllowedUnitTypes(allowed); this.setVisible(false); } From 47b49334fc0763b84ca5f49042169c5911988396 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 17 Apr 2024 10:17:20 -0700 Subject: [PATCH 35/76] Add IPlayerSettings interface to track player settings --- .../src/mekhq/campaign/mission/BotForce.java | 16 ++++++- .../campaign/mission/IPlayerSettings.java | 46 +++++++++++++++++++ .../src/mekhq/campaign/mission/Scenario.java | 21 +++++++-- 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 7a8bcc3514..bce42b60df 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -41,7 +41,7 @@ import java.io.PrintWriter; import java.util.*; -public class BotForce { +public class BotForce implements IPlayerSettings { private transient final UnitNameTracker nameTracker = new UnitNameTracker(); private String name; private List fixedEntityList; @@ -206,36 +206,50 @@ public void setTeam(int team) { this.team = team; } + @Override public int getStartingPos() { return startingPos; } + @Override public void setStartingPos(int start) { this.startingPos = start; } + @Override public int getStartOffset() { return startOffset; } + @Override public void setStartOffset(int startOffset) { this.startOffset = startOffset; } + @Override public int getStartWidth() { return startWidth; } + @Override public void setStartWidth(int startWidth) { this.startWidth = startWidth; } + @Override public int getStartingAnyNWx() { return startingAnyNWx; } + @Override public void setStartingAnyNWx(int startingAnyNWx) { this.startingAnyNWx = startingAnyNWx; } + @Override public int getStartingAnyNWy() { return startingAnyNWy; } + @Override public void setStartingAnyNWy(int startingAnyNWy) { this.startingAnyNWy = startingAnyNWy; } + @Override public int getStartingAnySEx() { return startingAnySEx; } + @Override public void setStartingAnySEx(int startingAnySEx) { this.startingAnySEx = startingAnySEx; } + @Override public int getStartingAnySEy() { return startingAnySEy; } + @Override public void setStartingAnySEy(int startingAnySEy) { this.startingAnySEy = startingAnySEy; } public int getDeployRound() { return deployRound; } diff --git a/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java b/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java new file mode 100644 index 0000000000..6e1bbbd84a --- /dev/null +++ b/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java @@ -0,0 +1,46 @@ +/* + * IPlayerSettings.java + * + * Copyright (c) 2024 - MegaMek Team. All rights reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.campaign.mission; + +/** + * This interface allows to identify classes that track player information like deployment, initiative bonuses, + * minefields, etc, so we can identify getter and setter methods across these types. Currently, that applies to + * Scenario and BotForce. + */ +public interface IPlayerSettings { + + // deployment information + public int getStartingPos(); + public void setStartingPos(int i); + public int getStartWidth(); + public void setStartWidth(int i); + public int getStartOffset(); + public void setStartOffset(int i); + public int getStartingAnyNWx(); + public void setStartingAnyNWx(int i); + public int getStartingAnyNWy(); + public void setStartingAnyNWy(int i); + public int getStartingAnySEx(); + public void setStartingAnySEx(int i); + public int getStartingAnySEy(); + public void setStartingAnySEy(int i); + +} diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index 598edd38d9..7a02aef075 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -23,10 +23,7 @@ import megamek.Version; import megamek.client.ui.swing.lobby.LobbyUtility; -import megamek.common.Board; -import megamek.common.Entity; -import megamek.common.IStartingPositions; -import megamek.common.MapSettings; +import megamek.common.*; import megamek.common.annotations.Nullable; import megamek.common.planetaryconditions.*; import mekhq.MekHQ; @@ -52,7 +49,7 @@ /** * @author Jay Lawson (jaylawson39 at yahoo.com) */ -public class Scenario { +public class Scenario implements IPlayerSettings { //region Variable Declarations public static final int S_DEFAULT_ID = -1; @@ -239,58 +236,72 @@ public String getTerrainType() { return terrainType; } + @Override public int getStartingPos() { return startingPos; } + @Override public void setStartingPos(int start) { this.startingPos = start; } + @Override public int getStartOffset() { return startOffset; } + @Override public void setStartOffset(int startOffset) { this.startOffset = startOffset; } + @Override public int getStartWidth() { return startWidth; } + @Override public void setStartWidth(int startWidth) { this.startWidth = startWidth; } + @Override public int getStartingAnyNWx() { return startingAnyNWx; } + @Override public void setStartingAnyNWx(int startingAnyNWx) { this.startingAnyNWx = startingAnyNWx; } + @Override public int getStartingAnyNWy() { return startingAnyNWy; } + @Override public void setStartingAnyNWy(int startingAnyNWy) { this.startingAnyNWy = startingAnyNWy; } + @Override public int getStartingAnySEx() { return startingAnySEx; } + @Override public void setStartingAnySEx(int startingAnySEx) { this.startingAnySEx = startingAnySEx; } + @Override public int getStartingAnySEy() { return startingAnySEy; } + @Override public void setStartingAnySEy(int startingAnySEy) { this.startingAnySEy = startingAnySEy; } From 6694e66bb5dd4a1e60ac1f37810907caa89602c6 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 17 Apr 2024 12:04:54 -0700 Subject: [PATCH 36/76] Add EditDeploymentDialog and apply to scenario --- .../CustomizeScenarioDialog.properties | 1 + .../resources/EditDeploymentDialog.properties | 8 + MekHQ/src/mekhq/Utilities.java | 68 ++++++ .../gui/dialog/CustomizeScenarioDialog.java | 27 +++ .../gui/dialog/EditDeploymentDialog.java | 220 ++++++++++++++++++ 5 files changed, 324 insertions(+) create mode 100644 MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties create mode 100644 MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 348d326bcd..2ae2d4426d 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -2,6 +2,7 @@ btnCancel.text=Cancel btnOkay.text=OK lblName.text=Scenario Name: lblDate.text=Scenario Date: +lblDeployment.text=Deployment: lblStatus.text=Status: title=Customize Scenario title.new=New Scenario diff --git a/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties b/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties new file mode 100644 index 0000000000..eb742ab82e --- /dev/null +++ b/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties @@ -0,0 +1,8 @@ +labDeploymentOffset.text=Deployment Zone Offset +labDeploymentOffset.tip=Deployment Zone Offset, in hexes from corresponding map edge +labDeploymentWidth.text=Deployment Zone Width +labDeploymentWidth.tip=Deployment Zone width, in hexes +labDeploymentAnyNW.text=Deployment Zone NW corner +labDeploymentAnySE.text=Deployment Zone SE corner +btnOK.text=OK +btnCancel.text=Cancel \ No newline at end of file diff --git a/MekHQ/src/mekhq/Utilities.java b/MekHQ/src/mekhq/Utilities.java index c66ec110cf..6a1bab3a49 100644 --- a/MekHQ/src/mekhq/Utilities.java +++ b/MekHQ/src/mekhq/Utilities.java @@ -21,6 +21,7 @@ import megamek.client.Client; import megamek.client.generator.RandomNameGenerator; +import megamek.client.ui.swing.util.UIUtil; import megamek.codeUtilities.ObjectUtility; import megamek.codeUtilities.StringUtility; import megamek.common.*; @@ -32,6 +33,7 @@ import mekhq.campaign.Campaign; import mekhq.campaign.CampaignOptions; import mekhq.campaign.finances.Money; +import mekhq.campaign.mission.IPlayerSettings; import mekhq.campaign.personnel.Person; import mekhq.campaign.personnel.SkillType; import mekhq.campaign.personnel.enums.PersonnelRole; @@ -1301,4 +1303,70 @@ public static List generateEntityStub(List entities) { } return stub; } + + /** + * Display a descriptive character string for the deployment parameters in an object that implements IPlayerSettings + * @param settings object that implements IPlayerSettings + * @return A character string + */ + public static String getDeploymentString(Player settings) { + StringBuilder result = new StringBuilder(""); + + if(settings.getStartingPos() >=0 + && settings.getStartingPos() <= IStartingPositions.START_LOCATION_NAMES.length) { + result.append(IStartingPositions.START_LOCATION_NAMES[settings.getStartingPos()]); + } + + if (settings.getStartingPos() == 0) { + int NWx = settings.getStartingAnyNWx() + 1; + int NWy = settings.getStartingAnyNWy() + 1; + int SEx = settings.getStartingAnySEx() + 1; + int SEy = settings.getStartingAnySEy() + 1; + if ((NWx + NWy + SEx + SEy) > 0) { + result.append(" (" + NWx + ", " + NWy + ")-(" + SEx + ", " + SEy + ")"); + } + } + int so = settings.getStartOffset(); + int sw = settings.getStartWidth(); + if ((so != 0) || (sw != 3)) { + result.append(", " + so); + result.append(", " + sw); + } + + return result.toString(); + } + + /** + * Create a Player object from IPlayerSettings parameters. Useful for tracking these variables in dialogs. + * @param settings an object that implements IPlayerSettings + * @return A Player object + */ + public static Player createPlayer(IPlayerSettings settings) { + Player p = new Player(1, "fake"); + p.setStartingPos(settings.getStartingPos()); + p.setStartWidth(settings.getStartWidth()); + p.setStartOffset(settings.getStartOffset()); + p.setStartingAnyNWx(settings.getStartingAnyNWx()); + p.setStartingAnyNWy(settings.getStartingAnyNWy()); + p.setStartingAnySEx(settings.getStartingAnySEx()); + p.setStartingAnySEy(settings.getStartingAnySEy()); + + return p; + } + + /** + * pdate values of an object that implements IPlayerSettings from a player object + * @param settings An object that implements IPlayerSettings + * @param player A Player object from which to read values + */ + public static void updatePlayerSettings(IPlayerSettings settings, Player player) { + settings.setStartingPos(player.getStartingPos()); + settings.setStartWidth(player.getStartWidth()); + settings.setStartOffset(player.getStartOffset()); + settings.setStartingAnyNWx(player.getStartingAnyNWx()); + settings.setStartingAnyNWy(player.getStartingAnyNWy()); + settings.setStartingAnySEx(player.getStartingAnySEx()); + settings.setStartingAnySEy(player.getStartingAnySEy()); + + } } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 70c8ee7823..a06099854c 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -23,8 +23,11 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; import megamek.client.ui.swing.PlanetaryConditionsDialog; +import megamek.client.ui.swing.lobby.PlayerSettingsDialog; +import megamek.common.Player; import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.mission.*; import mekhq.campaign.mission.atb.AtBScenarioModifier; @@ -63,6 +66,7 @@ public class CustomizeScenarioDialog extends JDialog { private LocalDate date; private ScenarioDeploymentLimit deploymentLimits; private PlanetaryConditions planetaryConditions; + private Player player; private List botForces; // loot @@ -106,6 +110,7 @@ public class CustomizeScenarioDialog extends JDialog { // buttons private JButton btnDate; + private JButton btnDeployment; private JButton btnPlanetaryConditions; private JButton btnAddLoot; private JButton btnEditLoot; @@ -142,6 +147,8 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission deploymentLimits = scenario.getDeploymentLimit().getCopy(); } + player = Utilities.createPlayer(scenario); + planetaryConditions = scenario.createPlanetaryConditions(); botForces = scenario.getBotForces().stream().collect(Collectors.toList()); @@ -225,6 +232,19 @@ public Component getListCellRendererComponent(final JList list, final Object gbc.insets = new Insets(5, 5, 0, 0); panInfo.add(btnDate, gbc); + gbc.gridx = 0; + gbc.gridy++; + gbc.gridwidth = 1; + gbc.insets = new Insets(5, 5, 5, 5); + panInfo.add(new JLabel(resourceMap.getString("lblDeployment.text")), gbc); + + btnDeployment = new JButton(Utilities.getDeploymentString(player)); + btnDeployment.addActionListener(evt -> changeDeployment()); + gbc.gridx = 1; + gbc.gridwidth = 1; + gbc.insets = new Insets(5, 5, 0, 0); + panInfo.add(btnDeployment, gbc); + if (scenario.getStatus().isCurrent() && (scenario instanceof AtBDynamicScenario)) { gbc.gridx = 0; gbc.gridy++; @@ -389,6 +409,7 @@ private void btnOKActionPerformed(ActionEvent evt) { } } scenario.setDeploymentLimit(deploymentLimits); + Utilities.updatePlayerSettings(scenario, player); scenario.readPlanetaryConditions(planetaryConditions); scenario.setDate(date); scenario.setBotForces(botForces); @@ -456,6 +477,12 @@ private void changeDate() { } } + private void changeDeployment() { + EditDeploymentDialog edd = new EditDeploymentDialog(frame, true, player); + edd.setVisible(true); + btnDeployment.setText(Utilities.getDeploymentString(player)); + } + private void initDeployLimitPanel(ResourceBundle resourceMap) { panDeploymentLimits = new JPanel(new GridBagLayout()); diff --git a/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java new file mode 100644 index 0000000000..cee9ce47f0 --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.gui.dialog; + +import megamek.client.bot.princess.BehaviorSettings; +import megamek.client.bot.princess.Princess; +import megamek.client.ui.GBC; +import megamek.client.ui.Messages; +import megamek.client.ui.dialogs.BotConfigDialog; +import megamek.client.ui.enums.DialogResult; +import megamek.client.ui.swing.GUIPreferences; +import megamek.client.ui.swing.util.UIUtil; +import megamek.common.IStartingPositions; +import megamek.common.Player; +import mekhq.MekHQ; +import mekhq.campaign.Campaign; +import mekhq.campaign.mission.BotForce; +import mekhq.campaign.mission.IPlayerSettings; + +import javax.swing.*; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.NumberFormatter; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.NumberFormat; +import java.util.ResourceBundle; + +import static megamek.client.ui.swing.util.UIUtil.*; +import static megamek.client.ui.swing.util.UIUtil.guiScaledFontHTML; + +public class EditDeploymentDialog extends JDialog { + + private JFrame frame; + + Player player; + + private int currentStartPos; + + private final JPanel panStartButtons = new JPanel(); + private final UIUtil.TipButton[] butStartPos = new UIUtil.TipButton[11]; + private final NumberFormatter numFormatter = new NumberFormatter(NumberFormat.getIntegerInstance()); + private final DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory(numFormatter); + private final JFormattedTextField txtOffset = new JFormattedTextField(formatterFactory, 0); + private final JFormattedTextField txtWidth = new JFormattedTextField(formatterFactory, 3); + private JSpinner spinStartingAnyNWx; + private JSpinner spinStartingAnyNWy; + private JSpinner spinStartingAnySEx; + private JSpinner spinStartingAnySEy; + + public EditDeploymentDialog(JFrame parent, boolean modal, Player player) { + super(parent, modal); + this.player = player; + currentStartPos = player.getStartingPos(); + initComponents(); + setLocationRelativeTo(parent); + pack(); + } + + private void initComponents() { + + final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.EditDeploymentDialog", + MekHQ.getMHQOptions().getLocale()); + + panStartButtons.setAlignmentX(Component.LEFT_ALIGNMENT); + for (int i = 0; i < 11; i++) { + butStartPos[i] = new UIUtil.TipButton(""); + butStartPos[i].addActionListener(startListener); + } + panStartButtons.setLayout(new GridLayout(4, 3)); + panStartButtons.add(butStartPos[1]); + panStartButtons.add(butStartPos[2]); + panStartButtons.add(butStartPos[3]); + panStartButtons.add(butStartPos[8]); + panStartButtons.add(butStartPos[10]); + panStartButtons.add(butStartPos[4]); + panStartButtons.add(butStartPos[7]); + panStartButtons.add(butStartPos[6]); + panStartButtons.add(butStartPos[5]); + panStartButtons.add(butStartPos[0]); + panStartButtons.add(butStartPos[9]); + updateStartGrid(); + + SpinnerNumberModel mStartingAnyNWx = new SpinnerNumberModel(player.getStartingAnyNWx()+1, 0, + null, 1); + spinStartingAnyNWx = new JSpinner(mStartingAnyNWx); + SpinnerNumberModel mStartingAnyNWy = new SpinnerNumberModel(player.getStartingAnyNWy()+1, 0, + null, 1); + spinStartingAnyNWy = new JSpinner(mStartingAnyNWy); + SpinnerNumberModel mStartingAnySEx = new SpinnerNumberModel(player.getStartingAnySEx()+1, 0, + null, 1); + spinStartingAnySEx = new JSpinner(mStartingAnySEx); + SpinnerNumberModel mStartingAnySEy = new SpinnerNumberModel(player.getStartingAnySEy()+1, 0, + null, 1); + spinStartingAnySEy = new JSpinner(mStartingAnySEy); + + GridBagLayout gbl = new GridBagLayout(); + JPanel main = new JPanel(gbl); + + JLabel lblOffset = new JLabel(resourceMap.getString("labDeploymentOffset.text")); + lblOffset.setToolTipText(resourceMap.getString("labDeploymentOffset.tip")); + JLabel lblWidth = new JLabel(resourceMap.getString("labDeploymentWidth.text")); + lblWidth.setToolTipText(resourceMap.getString("labDeploymentWidth.tip")); + + txtOffset.setColumns(4); + txtWidth.setColumns(4); + txtWidth.setText(Integer.toString(player.getStartWidth())); + txtOffset.setText(Integer.toString(player.getStartOffset())); + + main.add(lblOffset, GBC.std()); + main.add(txtOffset, GBC.eol()); + main.add(lblWidth, GBC.std()); + main.add(txtWidth, GBC.eol()); + + main.add(new JLabel(resourceMap.getString("labDeploymentAnyNW.text")), GBC.std()); + main.add(spinStartingAnyNWx, GBC.std()); + main.add(spinStartingAnyNWy, GBC.eol()); + main.add(new JLabel(resourceMap.getString("labDeploymentAnySE.text")), GBC.std()); + main.add(spinStartingAnySEx, GBC.std()); + main.add(spinStartingAnySEy, GBC.eol()); + + getContentPane().setLayout(new BorderLayout()); + getContentPane().add(main, BorderLayout.CENTER); + getContentPane().add(panStartButtons, BorderLayout.PAGE_START); + + JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); + btnOK.addActionListener(this::done); + JButton btnCancel = new JButton(resourceMap.getString("btnCancel.text")); + btnCancel.addActionListener(this::cancel); + panButtons.add(btnOK); + panButtons.add(btnCancel); + getContentPane().add(panButtons, BorderLayout.PAGE_END); + + } + + private void updateStartGrid() { + StringBuilder[] butText = new StringBuilder[11]; + StringBuilder[] butTT = new StringBuilder[11]; + boolean[] hasPlayer = new boolean[11]; + + for (int i = 0; i < 11; i++) { + butText[i] = new StringBuilder(); + butTT[i] = new StringBuilder(); + } + + for (int i = 0; i < 11; i++) { + butText[i].append("

"); + //butTT[i].append(Messages.getString("PlayerSettingsDialog.invalidStartPosTT")); + butText[i].append(IStartingPositions.START_LOCATION_NAMES[i]).append("
"); + } + + butText[currentStartPos].append(guiScaledFontHTML(uiGreen())); + butText[currentStartPos].append("\u2B24"); + + for (int i = 0; i < 11; i++) { + butStartPos[i].setText(butText[i].toString()); + if (butTT[i].length() > 0) { + butStartPos[i].setToolTipText(butTT[i].toString()); + } + } + } + + ActionListener startListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Deployment buttons + for (int i = 0; i < 11; i++) { + if (butStartPos[i].equals(e.getSource())) { + currentStartPos = i; + updateStartGrid(); + } + } + } + }; + + private void done(ActionEvent evt) { + player.setStartingPos(currentStartPos); + player.setStartWidth(parseField(txtWidth)); + player.setStartOffset(parseField(txtOffset)); + player.setStartingAnyNWx(Math.min((Integer) spinStartingAnyNWx.getValue(), (Integer) spinStartingAnySEx.getValue()) - 1); + player.setStartingAnyNWy(Math.min((Integer) spinStartingAnyNWy.getValue(), (Integer) spinStartingAnySEy.getValue()) - 1); + player.setStartingAnySEx(Math.max((Integer) spinStartingAnyNWx.getValue(), (Integer) spinStartingAnySEx.getValue()) - 1); + player.setStartingAnySEy(Math.max((Integer) spinStartingAnyNWy.getValue(), (Integer) spinStartingAnySEy.getValue()) - 1); + this.setVisible(false); + } + + private void cancel(ActionEvent evt) { + this.setVisible(false); + } + + /** + * Parse the given field and return the integer it contains or 0, if + * the field cannot be parsed. + */ + private int parseField(JTextField field) { + try { + return Integer.parseInt(field.getText()); + } catch (NumberFormatException ex) { + return 0; + } + } + +} From 9f110f0931c25be492bcf983eb72add8bd5fd9ff Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 17 Apr 2024 12:49:37 -0700 Subject: [PATCH 37/76] Allow deployment variable editing in CustomizeBotForceDialog --- MekHQ/src/mekhq/Utilities.java | 28 +++++++++++-------- .../src/mekhq/campaign/mission/BotForce.java | 2 +- .../gui/dialog/CustomizeBotForceDialog.java | 22 +++++++++++++++ .../mekhq/gui/model/BotForceTableModel.java | 3 +- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/MekHQ/src/mekhq/Utilities.java b/MekHQ/src/mekhq/Utilities.java index 6a1bab3a49..396ee08a3c 100644 --- a/MekHQ/src/mekhq/Utilities.java +++ b/MekHQ/src/mekhq/Utilities.java @@ -1306,28 +1306,28 @@ public static List generateEntityStub(List entities) { /** * Display a descriptive character string for the deployment parameters in an object that implements IPlayerSettings - * @param settings object that implements IPlayerSettings + * @param player object that implements IPlayerSettings * @return A character string */ - public static String getDeploymentString(Player settings) { + public static String getDeploymentString(Player player) { StringBuilder result = new StringBuilder(""); - if(settings.getStartingPos() >=0 - && settings.getStartingPos() <= IStartingPositions.START_LOCATION_NAMES.length) { - result.append(IStartingPositions.START_LOCATION_NAMES[settings.getStartingPos()]); + if(player.getStartingPos() >=0 + && player.getStartingPos() <= IStartingPositions.START_LOCATION_NAMES.length) { + result.append(IStartingPositions.START_LOCATION_NAMES[player.getStartingPos()]); } - if (settings.getStartingPos() == 0) { - int NWx = settings.getStartingAnyNWx() + 1; - int NWy = settings.getStartingAnyNWy() + 1; - int SEx = settings.getStartingAnySEx() + 1; - int SEy = settings.getStartingAnySEy() + 1; + if (player.getStartingPos() == 0) { + int NWx = player.getStartingAnyNWx() + 1; + int NWy = player.getStartingAnyNWy() + 1; + int SEx = player.getStartingAnySEx() + 1; + int SEy = player.getStartingAnySEy() + 1; if ((NWx + NWy + SEx + SEy) > 0) { result.append(" (" + NWx + ", " + NWy + ")-(" + SEx + ", " + SEy + ")"); } } - int so = settings.getStartOffset(); - int sw = settings.getStartWidth(); + int so = player.getStartOffset(); + int sw = player.getStartWidth(); if ((so != 0) || (sw != 3)) { result.append(", " + so); result.append(", " + sw); @@ -1336,6 +1336,10 @@ public static String getDeploymentString(Player settings) { return result.toString(); } + public static String getDeploymentString(IPlayerSettings settings) { + return getDeploymentString(createPlayer(settings)); + } + /** * Create a Player object from IPlayerSettings parameters. Useful for tracking these variables in dialogs. * @param settings an object that implements IPlayerSettings diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index bce42b60df..9db0581f1c 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -120,7 +120,7 @@ public BotForce getCopy() { copy.setDeployRound(this.getDeployRound()); copy.setCamouflage(this.getCamouflage()); copy.setColour(this.getColour()); - //copy.setBehaviorSettings(getBehaviorSettings().getCopy()); + //copy.setBehaviorSettings(getBehaviorSettings().clone()); return copy; } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 201d99c10a..0796106a49 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -51,6 +51,7 @@ public class CustomizeBotForceDialog extends JDialog { private BotForce botForce; private Campaign campaign; private Camouflage camo; + private Player player; private BehaviorSettings behavior; private BotForceRandomizer randomizer; private boolean useRandomUnits; @@ -59,6 +60,7 @@ public class CustomizeBotForceDialog extends JDialog { //gui components private JTextField txtName; private JComboBox choiceTeam; + private JButton btnDeployment; private JButton btnCamo; private JPanel panBehavior; private JPanel panRandomUnits; @@ -97,6 +99,7 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai botForce = bf; } campaign = c; + player = Utilities.createPlayer(bf); camo = botForce.getCamouflage(); behavior = new BehaviorSettings(); try { @@ -179,6 +182,18 @@ private void initComponents() { gbc.weightx = 1.0; panLeft.add(choiceTeam, gbc); + gbc.gridx = 0; + gbc.gridy = 1; + gbc.weightx = 0.0; + gbc.fill = GridBagConstraints.NONE; + panLeft.add(new JLabel("Deployment:"), gbc); + + btnDeployment = new JButton(Utilities.getDeploymentString(player)); + btnDeployment.addActionListener(evt -> changeDeployment()); + gbc.gridx = 1; + gbc.weightx = 1.0; + panLeft.add(btnDeployment, gbc); + btnCamo = new JButton(); btnCamo.setIcon(camo.getImageIcon()); btnCamo.setMinimumSize(new Dimension(84, 72)); @@ -547,6 +562,12 @@ private void editCamo(ActionEvent evt) { } } + private void changeDeployment() { + EditDeploymentDialog edd = new EditDeploymentDialog(frame, true, player); + edd.setVisible(true); + btnDeployment.setText(Utilities.getDeploymentString(player)); + } + private void loadUnits(ActionEvent evt) { Optional units = FileDialogs.openUnits(frame); if (units.isPresent() && units.get() != null) { @@ -598,6 +619,7 @@ private String getAutoFleeDescription(BehaviorSettings behavior) { private void done(ActionEvent evt) { botForce.setName(txtName.getText()); botForce.setTeam(choiceTeam.getSelectedIndex()+1); + Utilities.updatePlayerSettings(botForce, player); botForce.setCamouflage(camo); botForce.setBehaviorSettings(behavior); botForce.setBotForceRandomizer(randomizer); diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java index ac635b1c48..ca5116d0d2 100644 --- a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -23,6 +23,7 @@ import megamek.common.IStartingPositions; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; import mekhq.campaign.universe.Factions; @@ -101,7 +102,7 @@ public Object getValueAt(int row, int col) { return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer(). getShortDescription(campaign)); case COL_DEPLOYMENT: - return IStartingPositions.START_LOCATION_NAMES[botForce.getStartingPos()]; + return Utilities.getDeploymentString(botForce); default: return "?"; } From b15ecddc5fbba35acf400e40901e742197dc43dd Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 17 Apr 2024 14:58:51 -0700 Subject: [PATCH 38/76] Clone botforces to properly cancel out of CustomizeScenarioDialog --- .../src/mekhq/campaign/mission/BotForce.java | 25 ++++++++++++++++--- .../campaign/mission/BotForceRandomizer.java | 3 ++- .../gui/dialog/CustomizeBotForceDialog.java | 2 +- .../gui/dialog/CustomizeScenarioDialog.java | 5 +++- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 9db0581f1c..8996cbf402 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -40,6 +40,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.*; +import java.util.stream.Collectors; public class BotForce implements IPlayerSettings { private transient final UnitNameTracker nameTracker = new UnitNameTracker(); @@ -106,7 +107,8 @@ public BotForce(String name, int team, int start, int home, List entityL behaviorSettings.setDestinationEdge(CardinalEdge.NONE); } - public BotForce getCopy() { + @Override + public BotForce clone() { final BotForce copy = new BotForce(); copy.setName(this.getName()); copy.setTeam(this.getTeam()); @@ -118,9 +120,26 @@ public BotForce getCopy() { copy.setStartingAnySEx(this.getStartingAnySEx()); copy.setStartingAnySEy(this.getStartingAnySEy()); copy.setDeployRound(this.getDeployRound()); - copy.setCamouflage(this.getCamouflage()); + copy.setCamouflage(this.getCamouflage().clone()); copy.setColour(this.getColour()); - //copy.setBehaviorSettings(getBehaviorSettings().clone()); + copy.setTemplateName(this.getTemplateName()); + if(this.getBotForceRandomizer() != null) { + copy.setBotForceRandomizer(this.getBotForceRandomizer().clone()); + } + // UUID is immutable so this should work + copy.traitors = traitors.stream().collect(Collectors.toList()); + copy.setBehaviorSettings(new BehaviorSettings()); + copy.getBehaviorSettings().setAutoFlee(this.getBehaviorSettings().shouldAutoFlee()); + copy.getBehaviorSettings().setForcedWithdrawal(this.getBehaviorSettings().isForcedWithdrawal()); + copy.getBehaviorSettings().setDestinationEdge(this.getBehaviorSettings().getDestinationEdge()); + copy.getBehaviorSettings().setRetreatEdge(this.getBehaviorSettings().getRetreatEdge()); + copy.getBehaviorSettings().setBraveryIndex(this.getBehaviorSettings().getBraveryIndex()); + copy.getBehaviorSettings().setFallShameIndex(this.getBehaviorSettings().getFallShameIndex()); + copy.getBehaviorSettings().setHyperAggressionIndex(this.getBehaviorSettings().getHyperAggressionIndex()); + copy.getBehaviorSettings().setSelfPreservationIndex(this.getBehaviorSettings().getSelfPreservationIndex()); + copy.getBehaviorSettings().setHerdMentalityIndex(this.getBehaviorSettings().getHerdMentalityIndex()); + // this bit of trickery seems to work to make a proper copy of the entity list + copy.fixedEntityList = this.getFixedEntityListDirect().stream().collect(Collectors.toList()); return copy; } diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index 0608843530..b3d6eb3c93 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -125,7 +125,8 @@ public BotForceRandomizer() { } //endregion Constructors - public BotForceRandomizer getCopy() { + @Override + public BotForceRandomizer clone() { BotForceRandomizer copy = new BotForceRandomizer(); copy.setFactionCode(this.getFactionCode()); copy.skill = this.skill; diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 0796106a49..4854ce1e97 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -109,7 +109,7 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai } useRandomUnits = botForce.getBotForceRandomizer() != null; if(useRandomUnits) { - randomizer = botForce.getBotForceRandomizer().getCopy(); + randomizer = botForce.getBotForceRandomizer().clone(); } else { randomizer = new BotForceRandomizer(); } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index a06099854c..7d79cd8fc7 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -151,7 +151,10 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission planetaryConditions = scenario.createPlanetaryConditions(); - botForces = scenario.getBotForces().stream().collect(Collectors.toList()); + botForces = new ArrayList<>(); + for(BotForce bf : scenario.getBotForces()) { + botForces.add(bf.clone()); + } forcesModel = new BotForceTableModel(botForces, campaign); loots = new ArrayList<>(); From 6cc45df1c3aacfe5968035f0574c5e9285c11885 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Wed, 17 Apr 2024 22:18:46 -0700 Subject: [PATCH 39/76] Fix bug using wrong variable --- MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 4854ce1e97..5cd19740c5 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -99,7 +99,7 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai botForce = bf; } campaign = c; - player = Utilities.createPlayer(bf); + player = Utilities.createPlayer(botForce); camo = botForce.getCamouflage(); behavior = new BehaviorSettings(); try { From 60ee1ff21fe58e2c5d0d6b54a728b8e12c4a255e Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 11:47:20 -0700 Subject: [PATCH 40/76] Make display of deploymentLimit labels better on edits --- .../CustomizeScenarioDialog.properties | 18 +++++++++--------- .../mission/ScenarioDeploymentLimit.java | 6 ++++++ .../gui/dialog/CustomizeScenarioDialog.java | 8 ++++---- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 2ae2d4426d..197767522c 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -1,9 +1,9 @@ btnCancel.text=Cancel btnOkay.text=OK -lblName.text=Scenario Name: -lblDate.text=Scenario Date: -lblDeployment.text=Deployment: -lblStatus.text=Status: +lblName.text=Scenario Name: +lblDate.text=Scenario Date: +lblDeployment.text=Deployment: +lblStatus.text=Status: title=Customize Scenario title.new=New Scenario btnAddLoot.text=Add Loot @@ -12,15 +12,15 @@ btnDeleteLoot.text=Delete Loot btnPlanetaryConditions.text=Edit Planetary Conditions... panPlanetaryConditions.title=Planetary Conditions panDeploymentLimits.title=Deployment Limits -lblAllowedUnits.text=Allowed Unit Types: -lblQuantityLimit.text=Quantity Limit: -lblRequiredPersonnel.text=Required Personnel: -lblRequiredUnits.text=Required Units: +lblAllowedUnits.text=Allowed Unit Types: +lblQuantityLimit.text=Quantity Limit: +lblRequiredPersonnel.text=Required Personnel: +lblRequiredUnits.text=Required Units: lblLight.text=Light: lblWeather.text=Weather: lblWind.text=Wind: lblFog.text=Fog: -lblBlowingSand.text=Blowing Sand: +lblBlowingSand.text=Blowing Sand: lblEMI.text=EMI: lblAtmosphere.text=Atmosphere: lblGravity.text=Gravity: diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java index cf35715acb..6762aa1173 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java @@ -355,6 +355,9 @@ public String getRequiredPersonnelDesc(Campaign c) { personNames.add(p.getFullName()); } } + if(personNames.isEmpty()) { + return "None"; + } return String.join(", ", personNames); } //endregion Required personnel methods @@ -416,6 +419,9 @@ public String getRequiredUnitDesc(Campaign c) { unitNames.add(u.getName()); } } + if(unitNames.isEmpty()) { + return "None"; + } return String.join(", ", unitNames); } //endregion Required unit methods diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 7d79cd8fc7..e08b3aeb30 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -563,10 +563,10 @@ private void initDeployLimitPanel(ResourceBundle resourceMap) { private void refreshDeploymentLimits() { if(deploymentLimits != null) { - lblAllowedUnitsDesc.setText(deploymentLimits.getAllowedUnitTypeDesc()); - lblQuantityLimitDesc.setText(deploymentLimits.getQuantityLimitDesc(scenario, campaign)); - lblRequiredPersonnelDesc.setText(deploymentLimits.getRequiredPersonnelDesc(campaign)); - lblRequiredUnitsDesc.setText(deploymentLimits.getRequiredUnitDesc(campaign)); + lblAllowedUnitsDesc.setText("" + deploymentLimits.getAllowedUnitTypeDesc() + ""); + lblQuantityLimitDesc.setText("" +deploymentLimits.getQuantityLimitDesc(scenario, campaign) + ""); + lblRequiredPersonnelDesc.setText("" + deploymentLimits.getRequiredPersonnelDesc(campaign) + ""); + lblRequiredUnitsDesc.setText("" + deploymentLimits.getRequiredUnitDesc(campaign) + ""); } else { lblAllowedUnitsDesc.setText("All"); lblQuantityLimitDesc.setText("No Limits"); From 311ec338d4c41c8cc783b8e1928cbc9c36b87a66 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 12:32:17 -0700 Subject: [PATCH 41/76] Add setup for scenario objectives table in CustomizeScenarioDialog --- .../CustomizeScenarioDialog.properties | 3 + .../gui/dialog/CustomizeScenarioDialog.java | 80 ++++++++++++- .../mekhq/gui/model/ObjectiveTableModel.java | 109 ++++++++++++++++++ 3 files changed, 188 insertions(+), 4 deletions(-) create mode 100644 MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 197767522c..03ed0fab50 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -9,6 +9,9 @@ title.new=New Scenario btnAddLoot.text=Add Loot btnEditLoot.text=Edit Loot btnDeleteLoot.text=Delete Loot +btnAddObjective.text=Add Objective +btnEditObjective.text=Edit Objective +btnDeleteObjective.text=Delete Objective btnPlanetaryConditions.text=Edit Planetary Conditions... panPlanetaryConditions.title=Planetary Conditions panDeploymentLimits.title=Deployment Limits diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index e08b3aeb30..9d879901aa 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -36,6 +36,7 @@ import mekhq.gui.FileDialogs; import mekhq.gui.model.BotForceTableModel; import mekhq.gui.model.LootTableModel; +import mekhq.gui.model.ObjectiveTableModel; import mekhq.gui.utilities.MarkdownEditorPanel; import org.apache.logging.log4j.LogManager; @@ -69,6 +70,11 @@ public class CustomizeScenarioDialog extends JDialog { private Player player; private List botForces; + // objectives + private List objectives; + private JTable objectiveTable; + private ObjectiveTableModel objectiveModel; + // loot private ArrayList loots; private JTable lootTable; @@ -81,6 +87,7 @@ public class CustomizeScenarioDialog extends JDialog { // panels private JPanel panDeploymentLimits; private JPanel panLoot; + private JPanel panObjectives; private JPanel panOtherForces; private JPanel panPlanetaryConditions; @@ -115,6 +122,10 @@ public class CustomizeScenarioDialog extends JDialog { private JButton btnAddLoot; private JButton btnEditLoot; private JButton btnDeleteLoot; + + private JButton btnAddObjective; + private JButton btnEditObjective; + private JButton btnDeleteObjective; private JButton btnAddForce; private JButton btnEditForce; private JButton btnDeleteForce; @@ -162,6 +173,11 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission loots.add((Loot) loot.clone()); } lootModel = new LootTableModel(loots); + + // FIXME: clone this so we don't change on a cancel + objectives = scenario.getScenarioObjectives(); + objectiveModel = new ObjectiveTableModel(objectives); + initComponents(); setLocationRelativeTo(parent); setUserPreferences(); @@ -284,9 +300,16 @@ public Component getListCellRendererComponent(final JList list, final Object panInfo.add(panPlanetaryConditions, gbc); // endregion Set up info panel + initObjectivesPanel(resourceMap); + //panObjectives.setPreferredSize(new Dimension(300,150)); + //panObjectives.setMinimumSize(new Dimension(300,150)); + panObjectives.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder("Scenario Objectives"), + BorderFactory.createEmptyBorder(5,5,5,5))); + initLootPanel(resourceMap); - panLoot.setPreferredSize(new Dimension(300,150)); - panLoot.setMinimumSize(new Dimension(300,150)); + //panLoot.setPreferredSize(new Dimension(300,150)); + //panLoot.setMinimumSize(new Dimension(300,150)); panLoot.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Scenario Costs & Payouts"), BorderFactory.createEmptyBorder(5,5,5,5))); @@ -369,17 +392,24 @@ public Component getListCellRendererComponent(final JList list, final Object gbc.gridy = 0; gbc.weightx = 1.0; gbc.weighty = 0.0; + gbc.gridheight = 2; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.BOTH; panMain.add(panInfo, gbc); gbc.gridx = 1; + gbc.gridy = 0; + gbc.weighty = 0.5; + gbc.gridheight = 1; + panMain.add(panObjectives, gbc); + gbc.gridy = 1; panMain.add(panLoot, gbc); gbc.gridx = 2; - gbc.gridheight = 2; + gbc.gridy = 0; + gbc.gridheight = 3; gbc.weighty = 1.0; panMain.add(panWrite, gbc); gbc.gridx = 0; - gbc.gridy = 1; + gbc.gridy = 2; gbc.gridwidth = 2; gbc.gridheight = 1; panMain.add(panOtherForces, gbc); @@ -730,6 +760,48 @@ private void changePlanetaryConditions() { refreshPlanetaryConditions(); } + private void initObjectivesPanel(ResourceBundle resourceMap) { + panObjectives = new JPanel(new BorderLayout()); + + JPanel panBtns = new JPanel(new GridLayout(1,0)); + btnAddObjective = new JButton(resourceMap.getString("btnAddObjective.text")); + //btnAddObjective.addActionListener(evt -> addObjective()); + btnAddObjective.setEnabled(scenario.getStatus().isCurrent()); + panBtns.add(btnAddObjective); + + btnEditObjective = new JButton(resourceMap.getString("btnEditObjective.text")); + btnEditObjective.setEnabled(false); + //btnEditObjective.addActionListener(evt -> editObjective()); + panBtns.add(btnEditObjective); + + btnDeleteObjective = new JButton(resourceMap.getString("btnDeleteObjective.text")); + btnDeleteObjective.setEnabled(false); + //btnDeleteObjective.addActionListener(evt -> deleteObjective()); + panBtns.add(btnDeleteObjective); + panObjectives.add(panBtns, BorderLayout.PAGE_START); + + objectiveTable = new JTable(objectiveModel); + TableColumn column; + for (int i = 0; i < ObjectiveTableModel.N_COL; i++) { + column = objectiveTable.getColumnModel().getColumn(i); + column.setPreferredWidth(objectiveModel.getColumnWidth(i)); + column.setCellRenderer(objectiveModel.getRenderer()); + } + objectiveTable.setIntercellSpacing(new Dimension(0, 0)); + objectiveTable.setShowGrid(false); + objectiveTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + objectiveTable.getSelectionModel().addListSelectionListener(this::objectiveTableValueChanged); + + panObjectives.add(new JScrollPane(objectiveTable), BorderLayout.CENTER); + + } + + private void objectiveTableValueChanged(ListSelectionEvent evt) { + int row = objectiveTable.getSelectedRow(); + btnDeleteObjective.setEnabled(row != -1); + btnEditObjective.setEnabled(row != -1); + } + private void initLootPanel(ResourceBundle resourceMap) { panLoot = new JPanel(new BorderLayout()); diff --git a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java new file mode 100644 index 0000000000..7faed20de7 --- /dev/null +++ b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java @@ -0,0 +1,109 @@ +package mekhq.gui.model; + +import megamek.common.Entity; +import mekhq.campaign.mission.Loot; +import mekhq.campaign.mission.ScenarioObjective; +import mekhq.campaign.parts.Part; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.*; +import java.util.List; +import java.util.stream.Collectors; + +public class ObjectiveTableModel extends AbstractTableModel { + //region Variable Declarations + protected String[] columnNames; + protected List data; + + public final static int COL_DESC = 0; + + public final static int N_COL = 1; + //endregion Variable Declarations + + public ObjectiveTableModel(List entries) { + data = entries; + } + + @Override + public int getRowCount() { + return data.size(); + } + + @Override + public int getColumnCount() { + return N_COL; + } + + @Override + public String getColumnName(int column) { + switch (column) { + case COL_DESC: + return "Description"; + default: + return "?"; + } + } + + @Override + public Object getValueAt(int row, int col) { + ScenarioObjective objective; + if (data.isEmpty()) { + return ""; + } else { + objective = getObjectiveAt(row); + } + + switch (col) { + case COL_DESC: + return objective.getDescription(); + default: + return "?"; + } + } + + public ScenarioObjective getObjectiveAt(int row) { + return data.get(row); + } + + public int getColumnWidth(int c) { + switch (c) { + case COL_DESC: + return 100; + default: + return 20; + } + } + + public int getAlignment(int col) { + return SwingConstants.LEFT; + } + + public String getTooltip(int row, int col) { + switch (col) { + default: + return null; + } + } + + public ObjectiveTableModel.Renderer getRenderer() { + return new ObjectiveTableModel.Renderer(); + } + + public class Renderer extends DefaultTableCellRenderer { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setOpaque(true); + int actualCol = table.convertColumnIndexToModel(column); + int actualRow = table.convertRowIndexToModel(row); + setHorizontalAlignment(getAlignment(actualCol)); + setToolTipText(getTooltip(actualRow, actualCol)); + + return this; + } + } +} From b090fcf13e19d77aede70ce25e2aec1105f5979f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 14:32:01 -0700 Subject: [PATCH 42/76] Add very bad CustomizeScenarioObjectiveDialog (WIP) --- .../campaign/mission/ScenarioObjective.java | 5 +- .../gui/dialog/CustomizeScenarioDialog.java | 46 +- .../CustomizeScenarioObjectiveDialog.java | 607 ++++++++++++++++++ .../mekhq/gui/model/ObjectiveTableModel.java | 11 + 4 files changed, 665 insertions(+), 4 deletions(-) create mode 100644 MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java index 9e2d2b4267..f018acb6b3 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java @@ -140,7 +140,10 @@ public enum ObjectiveAmountType { } public ScenarioObjective() { - + description = ""; + objectiveCriterion = ObjectiveCriterion.Destroy; + destinationEdge = OffBoardDirection.NONE; + percentage = 100; } /** diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 9d879901aa..9f307e471c 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -765,18 +765,18 @@ private void initObjectivesPanel(ResourceBundle resourceMap) { JPanel panBtns = new JPanel(new GridLayout(1,0)); btnAddObjective = new JButton(resourceMap.getString("btnAddObjective.text")); - //btnAddObjective.addActionListener(evt -> addObjective()); + btnAddObjective.addActionListener(evt -> addObjective()); btnAddObjective.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnAddObjective); btnEditObjective = new JButton(resourceMap.getString("btnEditObjective.text")); btnEditObjective.setEnabled(false); - //btnEditObjective.addActionListener(evt -> editObjective()); + btnEditObjective.addActionListener(evt -> editObjective()); panBtns.add(btnEditObjective); btnDeleteObjective = new JButton(resourceMap.getString("btnDeleteObjective.text")); btnDeleteObjective.setEnabled(false); - //btnDeleteObjective.addActionListener(evt -> deleteObjective()); + btnDeleteObjective.addActionListener(evt -> deleteObjective()); panBtns.add(btnDeleteObjective); panObjectives.add(panBtns, BorderLayout.PAGE_START); @@ -802,6 +802,46 @@ private void objectiveTableValueChanged(ListSelectionEvent evt) { btnEditObjective.setEnabled(row != -1); } + private void addObjective() { + CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, new ScenarioObjective(), scenario.getBotForces()); + csod.setVisible(true); + if (null != csod.getObjective()) { + objectiveModel.addObjective(csod.getObjective()); + } + refreshObjectiveTable(); + } + + private void editObjective() { + ScenarioObjective objective = objectiveModel.getObjectiveAt(objectiveTable.getSelectedRow()); + if (null != objective) { + CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, objective, scenario.getBotForces()); + csod.setVisible(true); + refreshObjectiveTable(); + } + } + + private void deleteObjective() { + int row = objectiveTable.getSelectedRow(); + if (-1 != row) { + objectives.remove(row); + } + refreshObjectiveTable(); + } + + private void refreshObjectiveTable() { + int selectedRow = objectiveTable.getSelectedRow(); + objectiveModel.setData(objectives); + if (selectedRow != -1) { + if (objectiveTable.getRowCount() > 0) { + if (objectiveTable.getRowCount() == selectedRow) { + objectiveTable.setRowSelectionInterval(selectedRow-1, selectedRow-1); + } else { + objectiveTable.setRowSelectionInterval(selectedRow, selectedRow); + } + } + } + } + private void initLootPanel(ResourceBundle resourceMap) { panLoot = new JPanel(new BorderLayout()); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java new file mode 100644 index 0000000000..3d3b1d150a --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -0,0 +1,607 @@ +package mekhq.gui.dialog; + +import megamek.common.OffBoardDirection; +import mekhq.MHQConstants; +import mekhq.campaign.Campaign; +import mekhq.campaign.mission.*; + +import javax.swing.*; +import javax.swing.border.LineBorder; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +public class CustomizeScenarioObjectiveDialog extends JDialog { + + private ScenarioObjective objective; + private List botForces; + private JFrame frame; + private JLabel lblShortDescription; + private JTextArea txtShortDescription; + private JLabel lblObjectiveType; + private JComboBox cboObjectiveType; + private JComboBox cboDirection; + private JTextField txtPercentage; + private JComboBox cboCountType; + private JComboBox cboForceName; + + private JLabel lblMagnitude; + private JTextField txtAmount; + private JComboBox cboScalingType; + private JComboBox cboEffectType; + private JComboBox cboEffectCondition; + + private JList successEffects; + private JList failureEffects; + private JButton btnRemoveSuccess; + private JButton btnRemoveFailure; + + private JComboBox cboTimeLimitDirection; + private JComboBox cboTimeScaling; + private JTextField txtTimeLimit; + + private JList forceNames; + JButton btnRemove; + + private JList lstDetails; + + + public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForces) { + super(parent, modal); + this.frame = parent; + this.objective = objective; + this.botForces = botForces; + + initGUI(); + updateForceList(); + + txtShortDescription.setText(objective.getDescription()); + cboObjectiveType.setSelectedItem(objective.getObjectiveCriterion()); + cboCountType.setSelectedItem(objective.getAmountType()); + txtPercentage.setText(Integer.toString(objective.getAmount())); + setDirectionDropdownVisibility(); + + cboDirection.setSelectedIndex(objective.getDestinationEdge().ordinal()); + + cboTimeScaling.setSelectedItem(objective.getTimeLimitType()); + updateTimeLimitUI(); + cboTimeLimitDirection.setSelectedIndex(objective.isTimeLimitAtMost() ? 0 : 1); + if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { + txtTimeLimit.setText(objective.getTimeLimitScaleFactor().toString()); + } else { + if (objective.getTimeLimit() != null) { + txtTimeLimit.setText(objective.getTimeLimit().toString()); + } + } + + updateEffectList(successEffects, objective.getSuccessEffects()); + updateEffectList(failureEffects, objective.getFailureEffects()); + updateDetailList(); + + validate(); + setLocationRelativeTo(parent); + pack(); + } + + private void initGUI() { + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridwidth = 1; + gbc.gridheight = 1; + gbc.gridx = 0; + gbc.gridy = 0; + gbc.anchor = GridBagConstraints.WEST; + + getContentPane().setLayout(new GridBagLayout()); + + addDescriptionUI(gbc); + gbc.gridx = 0; + gbc.gridy++; + + addObjectiveTypeUI(gbc); + gbc.gridx = 0; + gbc.gridy++; + + addSubjectForce(gbc); + gbc.gridx = 0; + gbc.gridy++; + + addTimeLimitUI(gbc); + gbc.gridx = 0; + gbc.gridy++; + + addEffectUI(gbc); + gbc.gridx = 0; + gbc.gridy++; + + addObjectiveEffectUI(gbc); + + gbc.gridx = 0; + gbc.gridy++; + + addSaveCloseButtons(gbc); + } + + /** + * Handles the save/close buttons row. + */ + private void addSaveCloseButtons(GridBagConstraints gbc) { + JPanel saveClosePanel = new JPanel(); + saveClosePanel.setLayout(new GridBagLayout()); + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + + JButton btnCancel = new JButton("Cancel"); + btnCancel.addActionListener(e -> this.setVisible(false)); + JButton btnSaveAndClose = new JButton("Save and Close"); + btnSaveAndClose.addActionListener(e -> this.saveObjectiveAndClose()); + + saveClosePanel.add(btnCancel); + saveClosePanel.add(btnSaveAndClose); + + getContentPane().add(saveClosePanel, gbc); + } + + /** + * Handles the "description" row. + */ + private void addDescriptionUI(GridBagConstraints gbc) { + lblShortDescription = new JLabel("Short Description:"); + + JScrollPane txtScroll = new JScrollPane(); + txtShortDescription = new JTextArea(); + txtShortDescription.setColumns(40); + txtShortDescription.setRows(5); + txtShortDescription.setLineWrap(true); + txtShortDescription.setWrapStyleWord(true); + txtScroll.setViewportView(txtShortDescription); + + JTextField txtDetail = new JTextField(); + txtDetail.setColumns(40); + JLabel lblDetail = new JLabel("Details (shows up after force/unit list):"); + lstDetails = new JList<>(); + JButton btnAddDetail = new JButton("Add"); + JButton btnRemoveDetail = new JButton("Remove"); + + lstDetails.addListSelectionListener(e -> btnRemoveDetail.setEnabled(!lstDetails.getSelectedValuesList().isEmpty())); + lstDetails.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + btnRemoveDetail.addActionListener(e -> this.removeDetails()); + btnAddDetail.addActionListener(e -> this.addDetail(txtDetail)); + + JPanel descriptionPanel = new JPanel(); + descriptionPanel.setLayout(new GridBagLayout()); + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(5, 0, 5, 5); + + descriptionPanel.add(lblShortDescription, localGbc); + localGbc.gridx++; + descriptionPanel.add(txtScroll, localGbc); + localGbc.gridx = 0; + localGbc.gridy++; + descriptionPanel.add(lblDetail, localGbc); + localGbc.gridx++; + descriptionPanel.add(txtDetail, localGbc); + localGbc.gridx++; + descriptionPanel.add(btnAddDetail, localGbc); + localGbc.gridx++; + descriptionPanel.add(lstDetails, localGbc); + localGbc.gridx++; + descriptionPanel.add(btnRemoveDetail, localGbc); + + getContentPane().add(descriptionPanel, gbc); + } + + /** + * Handles the "objective type" row + */ + private void addObjectiveTypeUI(GridBagConstraints gbc) { + JPanel objectivePanel = new JPanel(); + + lblObjectiveType = new JLabel("Objective Type:"); + cboObjectiveType = new JComboBox<>(); + for (ScenarioObjective.ObjectiveCriterion objectiveType : ScenarioObjective.ObjectiveCriterion.values()) { + cboObjectiveType.addItem(objectiveType); + } + cboObjectiveType.addActionListener(e -> this.setDirectionDropdownVisibility()); + + txtPercentage = new JTextField(); + txtPercentage.setColumns(4); + + cboCountType = new JComboBox<>(); + cboCountType.addItem("Percent"); + cboCountType.addItem("Fixed Amount"); + + + cboDirection = new JComboBox<>(); + cboDirection.addItem("Force Destination Edge"); + for (int x = 1; x < OffBoardDirection.values().length; x++) { + cboDirection.addItem(OffBoardDirection.values()[x].toString()); + } + cboDirection.setVisible(false); + + objectivePanel.setLayout(new GridBagLayout()); + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + + + objectivePanel.add(lblObjectiveType, localGbc); + localGbc.gridx++; + objectivePanel.add(cboObjectiveType, localGbc); + localGbc.gridx++; + objectivePanel.add(cboDirection, localGbc); + localGbc.gridx++; + objectivePanel.add(txtPercentage, localGbc); + localGbc.gridx++; + objectivePanel.add(cboCountType, localGbc); + + getContentPane().add(objectivePanel, gbc); + } + + /** + * Handles the UI for adding objective effects + */ + private void addObjectiveEffectUI(GridBagConstraints gbc) { + JPanel effectPanel = new JPanel(); + + + JLabel lblSuccessEffects = new JLabel("Effects on completion:"); + JLabel lblFailureEffects = new JLabel("Effects on failure:"); + + successEffects = new JList<>(); + successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); + failureEffects = new JList<>(); + failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); + + btnRemoveSuccess = new JButton("Remove"); + btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess)); + btnRemoveSuccess.setEnabled(false); + + btnRemoveFailure = new JButton("Remove"); + btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure)); + btnRemoveFailure.setEnabled(false); + + GridBagConstraints localGbc = new GridBagConstraints(); + effectPanel.setLayout(new GridBagLayout()); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + + effectPanel.add(lblSuccessEffects, localGbc); + localGbc.gridx++; + effectPanel.add(successEffects, localGbc); + localGbc.gridx++; + effectPanel.add(btnRemoveSuccess, localGbc); + localGbc.gridx++; + effectPanel.add(lblFailureEffects, localGbc); + localGbc.gridx++; + effectPanel.add(failureEffects, localGbc); + localGbc.gridx++; + effectPanel.add(btnRemoveFailure, localGbc); + + getContentPane().add(effectPanel, gbc); + } + + /** + * Handles the UI for adding/removing forces relevant to this objective + */ + private void addSubjectForce(GridBagConstraints gbc) { + JPanel forcePanel = new JPanel(); + + JLabel forcesLabel = new JLabel("Force Names:"); + + cboForceName = new JComboBox<>(); + cboForceName.addItem(MHQConstants.EGO_OBJECTIVE_NAME); + for(BotForce force : botForces) { + cboForceName.addItem(force.getName()); + } + + forceNames = new JList<>(); + forceNames.setVisibleRowCount(5); + forceNames.addListSelectionListener(e -> btnRemove.setEnabled(!forceNames.getSelectedValuesList().isEmpty())); + + JButton btnAdd = new JButton("Add"); + btnAdd.addActionListener(e -> this.addForce()); + + btnRemove = new JButton("Remove"); + btnRemove.addActionListener(e -> this.removeForce()); + btnRemove.setEnabled(false); + + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + + forcePanel.add(forcesLabel, localGbc); + localGbc.gridx++; + forcePanel.add(cboForceName, localGbc); + localGbc.gridx++; + forcePanel.add(btnAdd, localGbc); + localGbc.gridx--; + localGbc.gridy++; + forcePanel.add(forceNames, localGbc); + localGbc.gridx++; + forcePanel.add(btnRemove, localGbc); + + + getContentPane().add(forcePanel, gbc); + } + + private void addTimeLimitUI(GridBagConstraints gbc) { + JPanel timeLimitPanel = new JPanel(); + + cboTimeLimitDirection = new JComboBox<>(); + cboTimeLimitDirection.addItem("at most"); + cboTimeLimitDirection.addItem("at least"); + + cboTimeScaling = new JComboBox<>(); + for (ScenarioObjective.TimeLimitType timeLimitType : ScenarioObjective.TimeLimitType.values()) { + cboTimeScaling.addItem(timeLimitType); + } + cboTimeScaling.addActionListener(e -> this.updateTimeLimitUI()); + + txtTimeLimit = new JTextField(); + txtTimeLimit.setColumns(5); + + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + + timeLimitPanel.add(cboTimeLimitDirection, localGbc); + localGbc.gridx++; + timeLimitPanel.add(cboTimeScaling, localGbc); + localGbc.gridx++; + timeLimitPanel.add(txtTimeLimit, localGbc); + + + getContentPane().add(timeLimitPanel, gbc); + } + + /** + * Handles the "add objective effect" row + */ + private void addEffectUI(GridBagConstraints gbc) { + JPanel effectPanel = new JPanel(); + + lblMagnitude = new JLabel("Amount:"); + txtAmount = new JTextField(); + txtAmount.setColumns(5); + + JLabel lblScaling = new JLabel("Effect Scaling:"); + cboScalingType = new JComboBox<>(); + for (ObjectiveEffect.EffectScalingType scalingType : ObjectiveEffect.EffectScalingType.values()) { + cboScalingType.addItem(scalingType); + } + + JLabel lblEffectType = new JLabel("Effect Type:"); + cboEffectType = new JComboBox<>(); + for (ObjectiveEffect.ObjectiveEffectType scalingType : ObjectiveEffect.ObjectiveEffectType.values()) { + cboEffectType.addItem(scalingType); + } + + JLabel lblEffectCondition = new JLabel("Effect Condition:"); + cboEffectCondition = new JComboBox<>(); + cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess); + cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure); + + JButton btnAdd = new JButton("Add"); + btnAdd.addActionListener(e -> this.addEffect()); + + GridBagConstraints localGbc = new GridBagConstraints(); + localGbc.gridx = 0; + localGbc.gridy = 0; + localGbc.insets = new Insets(0, 0, 0, 5); + effectPanel.setLayout(new GridBagLayout()); + + effectPanel.add(lblMagnitude, localGbc); + localGbc.gridx++; + effectPanel.add(txtAmount, localGbc); + localGbc.gridx++; + effectPanel.add(lblScaling, localGbc); + localGbc.gridx++; + effectPanel.add(cboScalingType, localGbc); + localGbc.gridx++; + effectPanel.add(lblEffectType, localGbc); + localGbc.gridx++; + effectPanel.add(cboEffectType, localGbc); + localGbc.gridx++; + effectPanel.add(lblEffectCondition, localGbc); + localGbc.gridx++; + effectPanel.add(cboEffectCondition, localGbc); + localGbc.gridx++; + effectPanel.add(btnAdd, localGbc); + + getContentPane().add(effectPanel, gbc); + } + + /** + * Event handler for the 'add' button for scenario effects + */ + private void addEffect() { + int amount = 0; + try { + amount = Integer.parseInt(txtAmount.getText()); + lblMagnitude.setForeground(UIManager.getColor("text")); + } catch (Exception e) { + lblMagnitude.setForeground(Color.red); + return; + } + + ObjectiveEffect effect = new ObjectiveEffect(); + effect.howMuch = amount; + effect.effectScaling = (ObjectiveEffect.EffectScalingType) cboScalingType.getSelectedItem(); + effect.effectType = (ObjectiveEffect.ObjectiveEffectType) cboEffectType.getSelectedItem(); + + if (cboEffectCondition.getSelectedItem() == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { + objective.addSuccessEffect(effect); + + updateEffectList(successEffects, objective.getSuccessEffects()); + } else { + objective.addFailureEffect(effect); + + updateEffectList(failureEffects, objective.getFailureEffects()); + } + + pack(); + } + + /** + * Worker function that updates an objective effects list with the given objective effects + */ + private void updateEffectList(JList listToUpdate, java.util.List objectiveEffects) { + DefaultListModel effectModel = new DefaultListModel<>(); + for (ObjectiveEffect currentEffect : objectiveEffects) { + effectModel.addElement(currentEffect); + } + + listToUpdate.setModel(effectModel); + } + + private void removeEffect(ObjectiveEffect.ObjectiveEffectConditionType conditionType) { + JList listToUpdate; + List objectiveEffects; + + if (conditionType == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { + listToUpdate = successEffects; + objectiveEffects = objective.getSuccessEffects(); + btnRemoveSuccess.setEnabled(false); + } else { + listToUpdate = failureEffects; + objectiveEffects = objective.getFailureEffects(); + btnRemoveFailure.setEnabled(false); + } + + for (ObjectiveEffect effectToRemove : listToUpdate.getSelectedValuesList()) { + objectiveEffects.remove(effectToRemove); + } + + updateEffectList(listToUpdate, objectiveEffects); + } + + private void addForce() { + objective.addForce(cboForceName.getSelectedItem().toString()); + + updateForceList(); + pack(); + } + + private void removeForce() { + for (String forceName : forceNames.getSelectedValuesList()) { + objective.removeForce(forceName); + } + + updateForceList(); + btnRemove.setEnabled(false); + pack(); + } + + private void addDetail(JTextField field) { + objective.addDetail(field.getText()); + updateDetailList(); + } + + private void removeDetails() { + for (int index : lstDetails.getSelectedIndices()) { + objective.getDetails().remove(index); + } + updateDetailList(); + } + + private void updateDetailList() { + DefaultListModel detailModel = new DefaultListModel<>(); + for (String detail : objective.getDetails()) { + detailModel.addElement(detail); + } + + lstDetails.setModel(detailModel); + } + + private void updateForceList() { + DefaultListModel forceModel = new DefaultListModel<>(); + for (String forceName : objective.getAssociatedForceNames()) { + forceModel.addElement(forceName); + } + + forceNames.setModel(forceModel); + } + + private void setDirectionDropdownVisibility() { + switch ((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()) { + case PreventReachMapEdge: + case ReachMapEdge: + cboDirection.setVisible(true); + break; + default: + cboDirection.setVisible(false); + break; + } + } + + private void updateTimeLimitUI() { + boolean enable = !cboTimeScaling.getSelectedItem().equals(ScenarioObjective.TimeLimitType.None); + + txtTimeLimit.setEnabled(enable); + cboTimeLimitDirection.setEnabled(enable); + } + + public ScenarioObjective getObjective() { + return objective; + } + + private void saveObjectiveAndClose() { + int number = 0; + int timeLimit = 0; + + try { + number = Integer.parseInt(txtPercentage.getText()); + txtPercentage.setBorder(null); + } catch (Exception e) { + txtPercentage.setBorder(new LineBorder(Color.red)); + return; + } + + try { + if (txtTimeLimit.isEnabled()) { + timeLimit = Integer.parseInt(txtTimeLimit.getText()); + txtTimeLimit.setBorder(null); + } + } catch (Exception e) { + txtTimeLimit.setBorder(new LineBorder(Color.red)); + return; + } + + objective.setObjectiveCriterion((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()); + objective.setDescription(txtShortDescription.getText()); + if (this.cboCountType.getSelectedIndex() == 0) { + objective.setPercentage(number); + } else { + objective.setFixedAmount(number); + } + + if (cboDirection.isVisible() && cboDirection.getSelectedIndex() > 0) { + objective.setDestinationEdge(OffBoardDirection.getDirection(cboDirection.getSelectedIndex() - 1)); + } else { + objective.setDestinationEdge(OffBoardDirection.NONE); + } + + objective.setTimeLimitType((ScenarioObjective.TimeLimitType) cboTimeScaling.getSelectedItem()); + if (txtTimeLimit.isEnabled()) { + if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { + objective.setTimeLimitScaleFactor(timeLimit); + } else { + objective.setTimeLimit(timeLimit); + } + } + + if (cboTimeLimitDirection.isEnabled()) { + objective.setTimeLimitAtMost(cboTimeLimitDirection.getSelectedIndex() == 0); + } + + setVisible(false); + } +} diff --git a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java index 7faed20de7..92897b3feb 100644 --- a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java +++ b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java @@ -46,6 +46,11 @@ public String getColumnName(int column) { } } + public void addObjective(ScenarioObjective objective) { + data.add(objective); + fireTableDataChanged(); + } + @Override public Object getValueAt(int row, int col) { ScenarioObjective objective; @@ -87,6 +92,12 @@ public String getTooltip(int row, int col) { } } + //fill table with values + public void setData(List objectives) { + data = objectives; + fireTableDataChanged(); + } + public ObjectiveTableModel.Renderer getRenderer() { return new ObjectiveTableModel.Renderer(); } From 9c7a2a865013ba08dd89f853580218ddd570706f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 14:48:43 -0700 Subject: [PATCH 43/76] Dont save changes to associated forces in CustomizeScenarioObjectiveDialog until save --- .../CustomizeScenarioObjectiveDialog.java | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 3d3b1d150a..7c2bc7e30f 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -45,6 +45,8 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JList lstDetails; + DefaultListModel forceModel = new DefaultListModel<>(); + public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForces) { super(parent, modal); @@ -53,7 +55,10 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb this.botForces = botForces; initGUI(); - updateForceList(); + + for(String forceName : objective.getAssociatedForceNames()) { + forceModel.addElement(forceName); + } txtShortDescription.setText(objective.getDescription()); cboObjectiveType.setSelectedItem(objective.getObjectiveCriterion()); @@ -303,6 +308,7 @@ private void addSubjectForce(GridBagConstraints gbc) { forceNames = new JList<>(); forceNames.setVisibleRowCount(5); forceNames.addListSelectionListener(e -> btnRemove.setEnabled(!forceNames.getSelectedValuesList().isEmpty())); + forceNames.setModel(forceModel); JButton btnAdd = new JButton("Add"); btnAdd.addActionListener(e -> this.addForce()); @@ -484,18 +490,15 @@ private void removeEffect(ObjectiveEffect.ObjectiveEffectConditionType condition } private void addForce() { - objective.addForce(cboForceName.getSelectedItem().toString()); - - updateForceList(); + forceModel.addElement(cboForceName.getSelectedItem().toString()); + //forceNames.revalidate(); pack(); } private void removeForce() { for (String forceName : forceNames.getSelectedValuesList()) { - objective.removeForce(forceName); + forceModel.removeElement(forceName); } - - updateForceList(); btnRemove.setEnabled(false); pack(); } @@ -521,15 +524,6 @@ private void updateDetailList() { lstDetails.setModel(detailModel); } - private void updateForceList() { - DefaultListModel forceModel = new DefaultListModel<>(); - for (String forceName : objective.getAssociatedForceNames()) { - forceModel.addElement(forceName); - } - - forceNames.setModel(forceModel); - } - private void setDirectionDropdownVisibility() { switch ((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()) { case PreventReachMapEdge: @@ -583,6 +577,11 @@ private void saveObjectiveAndClose() { objective.setFixedAmount(number); } + objective.clearForces(); + for (int i = 0; i< forceModel.getSize(); i++) { + objective.addForce(forceModel.getElementAt(i)); + } + if (cboDirection.isVisible() && cboDirection.getSelectedIndex() > 0) { objective.setDestinationEdge(OffBoardDirection.getDirection(cboDirection.getSelectedIndex() - 1)); } else { From 30a83615eea085e9d52576206e3adc435fa458e2 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 14:59:47 -0700 Subject: [PATCH 44/76] Work with copy of objectives in CustomizeScenarioDialog --- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 9f307e471c..422e089fd6 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -175,7 +175,10 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission lootModel = new LootTableModel(loots); // FIXME: clone this so we don't change on a cancel - objectives = scenario.getScenarioObjectives(); + objectives = new ArrayList<>(); + for(ScenarioObjective objective : scenario.getScenarioObjectives()) { + objectives.add(new ScenarioObjective(objective)); + } objectiveModel = new ObjectiveTableModel(objectives); initComponents(); @@ -446,6 +449,7 @@ private void btnOKActionPerformed(ActionEvent evt) { scenario.readPlanetaryConditions(planetaryConditions); scenario.setDate(date); scenario.setBotForces(botForces); + scenario.setScenarioObjectives(objectives); scenario.resetLoot(); for (Loot loot : lootModel.getAllLoot()) { scenario.addLoot(loot); @@ -806,7 +810,7 @@ private void addObjective() { CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, new ScenarioObjective(), scenario.getBotForces()); csod.setVisible(true); if (null != csod.getObjective()) { - objectiveModel.addObjective(csod.getObjective()); + objectives.add(csod.getObjective()); } refreshObjectiveTable(); } From a9b28bc60e5857e2ad9afa89ac4f77300c8d1a5b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 17:27:02 -0700 Subject: [PATCH 45/76] Don't save objective effects in CustomizeScenarioObjectiveDialog until dialog is closed --- .../CustomizeScenarioObjectiveDialog.java | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 7c2bc7e30f..6bdd9d1c0c 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -46,6 +46,9 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JList lstDetails; DefaultListModel forceModel = new DefaultListModel<>(); + DefaultListModel successEffectsModel = new DefaultListModel<>(); + DefaultListModel failureEffectsModel = new DefaultListModel<>(); + public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForces) { @@ -79,8 +82,12 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb } } - updateEffectList(successEffects, objective.getSuccessEffects()); - updateEffectList(failureEffects, objective.getFailureEffects()); + for (ObjectiveEffect currentEffect : objective.getSuccessEffects()) { + successEffectsModel.addElement(currentEffect); + } + for (ObjectiveEffect currentEffect : objective.getFailureEffects()) { + failureEffectsModel.addElement(currentEffect); + } updateDetailList(); validate(); @@ -258,8 +265,10 @@ private void addObjectiveEffectUI(GridBagConstraints gbc) { JLabel lblFailureEffects = new JLabel("Effects on failure:"); successEffects = new JList<>(); + successEffects.setModel(successEffectsModel); successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); failureEffects = new JList<>(); + failureEffects.setModel(failureEffectsModel); failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); btnRemoveSuccess = new JButton("Remove"); @@ -444,54 +453,36 @@ private void addEffect() { effect.effectType = (ObjectiveEffect.ObjectiveEffectType) cboEffectType.getSelectedItem(); if (cboEffectCondition.getSelectedItem() == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { - objective.addSuccessEffect(effect); - - updateEffectList(successEffects, objective.getSuccessEffects()); + successEffectsModel.addElement(effect); + successEffects.repaint(); } else { - objective.addFailureEffect(effect); - - updateEffectList(failureEffects, objective.getFailureEffects()); + failureEffectsModel.addElement(effect); } pack(); } - /** - * Worker function that updates an objective effects list with the given objective effects - */ - private void updateEffectList(JList listToUpdate, java.util.List objectiveEffects) { - DefaultListModel effectModel = new DefaultListModel<>(); - for (ObjectiveEffect currentEffect : objectiveEffects) { - effectModel.addElement(currentEffect); - } - - listToUpdate.setModel(effectModel); - } - private void removeEffect(ObjectiveEffect.ObjectiveEffectConditionType conditionType) { - JList listToUpdate; - List objectiveEffects; + JList targetList; + DefaultListModel modelToUpdate; if (conditionType == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { - listToUpdate = successEffects; - objectiveEffects = objective.getSuccessEffects(); + targetList = successEffects; + modelToUpdate = (DefaultListModel) successEffects.getModel(); btnRemoveSuccess.setEnabled(false); } else { - listToUpdate = failureEffects; - objectiveEffects = objective.getFailureEffects(); + targetList = failureEffects; + modelToUpdate = (DefaultListModel) failureEffects.getModel(); btnRemoveFailure.setEnabled(false); } - for (ObjectiveEffect effectToRemove : listToUpdate.getSelectedValuesList()) { - objectiveEffects.remove(effectToRemove); + for (ObjectiveEffect effectToRemove : targetList.getSelectedValuesList()) { + modelToUpdate.removeElement(effectToRemove); } - - updateEffectList(listToUpdate, objectiveEffects); } private void addForce() { forceModel.addElement(cboForceName.getSelectedItem().toString()); - //forceNames.revalidate(); pack(); } @@ -582,6 +573,15 @@ private void saveObjectiveAndClose() { objective.addForce(forceModel.getElementAt(i)); } + + for (int i = 0; i< successEffectsModel.getSize(); i++) { + objective.addSuccessEffect(successEffectsModel.getElementAt(i)); + } + + for (int i = 0; i< failureEffectsModel.getSize(); i++) { + objective.addSuccessEffect(failureEffectsModel.getElementAt(i)); + } + if (cboDirection.isVisible() && cboDirection.getSelectedIndex() > 0) { objective.setDestinationEdge(OffBoardDirection.getDirection(cboDirection.getSelectedIndex() - 1)); } else { From 073bf5f4339b191512b173343d59c60404468691 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 17:37:27 -0700 Subject: [PATCH 46/76] Add clear options for Detailsa nd ObjectiveEffects in ScenarioObjectives --- .../campaign/mission/ScenarioObjective.java | 16 +++++++ .../CustomizeScenarioObjectiveDialog.java | 43 +++++++++---------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java index f018acb6b3..aa67aeb249 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java @@ -194,6 +194,14 @@ public void clearForces() { associatedForceNames.clear(); } + public void clearDetails() { + additionalDetails.clear(); + } + + public List getAdditionalDetails() { + return additionalDetails; + } + public void addDetail(String detail) { additionalDetails.add(detail); } @@ -222,6 +230,10 @@ public void clearAssociatedUnits() { associatedUnitIDs.clear(); } + public void clearSuccessEffects() { + successEffects.clear(); + } + public void addSuccessEffect(ObjectiveEffect successEffect) { successEffects.add(successEffect); } @@ -230,6 +242,10 @@ public List getSuccessEffects() { return successEffects; } + public void clearFailureEffects() { + failureEffects.clear(); + } + public void addFailureEffect(ObjectiveEffect failureEffect) { failureEffects.add(failureEffect); } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 6bdd9d1c0c..628e2f7e18 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -49,6 +49,7 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { DefaultListModel successEffectsModel = new DefaultListModel<>(); DefaultListModel failureEffectsModel = new DefaultListModel<>(); + DefaultListModel detailModel = new DefaultListModel<>(); public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForces) { @@ -88,7 +89,10 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb for (ObjectiveEffect currentEffect : objective.getFailureEffects()) { failureEffectsModel.addElement(currentEffect); } - updateDetailList(); + + for (String detail : objective.getDetails()) { + detailModel.addElement(detail); + } validate(); setLocationRelativeTo(parent); @@ -172,7 +176,7 @@ private void addDescriptionUI(GridBagConstraints gbc) { JTextField txtDetail = new JTextField(); txtDetail.setColumns(40); JLabel lblDetail = new JLabel("Details (shows up after force/unit list):"); - lstDetails = new JList<>(); + lstDetails = new JList<>(detailModel); JButton btnAddDetail = new JButton("Add"); JButton btnRemoveDetail = new JButton("Remove"); @@ -264,11 +268,9 @@ private void addObjectiveEffectUI(GridBagConstraints gbc) { JLabel lblSuccessEffects = new JLabel("Effects on completion:"); JLabel lblFailureEffects = new JLabel("Effects on failure:"); - successEffects = new JList<>(); - successEffects.setModel(successEffectsModel); + successEffects = new JList<>(successEffectsModel); successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); - failureEffects = new JList<>(); - failureEffects.setModel(failureEffectsModel); + failureEffects = new JList<>(failureEffectsModel); failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); btnRemoveSuccess = new JButton("Remove"); @@ -314,10 +316,9 @@ private void addSubjectForce(GridBagConstraints gbc) { cboForceName.addItem(force.getName()); } - forceNames = new JList<>(); + forceNames = new JList<>(forceModel); forceNames.setVisibleRowCount(5); forceNames.addListSelectionListener(e -> btnRemove.setEnabled(!forceNames.getSelectedValuesList().isEmpty())); - forceNames.setModel(forceModel); JButton btnAdd = new JButton("Add"); btnAdd.addActionListener(e -> this.addForce()); @@ -495,24 +496,13 @@ private void removeForce() { } private void addDetail(JTextField field) { - objective.addDetail(field.getText()); - updateDetailList(); + detailModel.addElement(field.getText()); } private void removeDetails() { - for (int index : lstDetails.getSelectedIndices()) { - objective.getDetails().remove(index); - } - updateDetailList(); - } - - private void updateDetailList() { - DefaultListModel detailModel = new DefaultListModel<>(); - for (String detail : objective.getDetails()) { - detailModel.addElement(detail); + for (String detail : lstDetails.getSelectedValuesList()) { + detailModel.removeElement(detail); } - - lstDetails.setModel(detailModel); } private void setDirectionDropdownVisibility() { @@ -574,12 +564,19 @@ private void saveObjectiveAndClose() { } + objective.clearSuccessEffects(); for (int i = 0; i< successEffectsModel.getSize(); i++) { objective.addSuccessEffect(successEffectsModel.getElementAt(i)); } + objective.clearFailureEffects(); for (int i = 0; i< failureEffectsModel.getSize(); i++) { - objective.addSuccessEffect(failureEffectsModel.getElementAt(i)); + objective.addFailureEffect(failureEffectsModel.getElementAt(i)); + } + + objective.clearDetails(); + for (int i = 0; i< detailModel.getSize(); i++) { + objective.addDetail(detailModel.getElementAt(i)); } if (cboDirection.isVisible() && cboDirection.getSelectedIndex() > 0) { From 3c760d0a31e76b968ce461466f27e14ae4c11c5f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 29 Apr 2024 18:52:16 -0700 Subject: [PATCH 47/76] Record ScenarioObjective amoun type correctly in CustomizeScenarioObjectiveDialog --- .../gui/dialog/CustomizeScenarioObjectiveDialog.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 628e2f7e18..c45446f200 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -1,5 +1,6 @@ package mekhq.gui.dialog; +import megamek.client.ui.baseComponents.MMComboBox; import megamek.common.OffBoardDirection; import mekhq.MHQConstants; import mekhq.campaign.Campaign; @@ -22,7 +23,7 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JComboBox cboObjectiveType; private JComboBox cboDirection; private JTextField txtPercentage; - private JComboBox cboCountType; + private MMComboBox cboCountType; private JComboBox cboForceName; private JLabel lblMagnitude; @@ -226,9 +227,7 @@ private void addObjectiveTypeUI(GridBagConstraints gbc) { txtPercentage = new JTextField(); txtPercentage.setColumns(4); - cboCountType = new JComboBox<>(); - cboCountType.addItem("Percent"); - cboCountType.addItem("Fixed Amount"); + cboCountType = new MMComboBox("cboCountType", ScenarioObjective.ObjectiveAmountType.values()); cboDirection = new JComboBox<>(); @@ -552,8 +551,9 @@ private void saveObjectiveAndClose() { objective.setObjectiveCriterion((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()); objective.setDescription(txtShortDescription.getText()); - if (this.cboCountType.getSelectedIndex() == 0) { + if (cboCountType.getSelectedItem().equals(ScenarioObjective.ObjectiveAmountType.Percentage)) { objective.setPercentage(number); + objective.setFixedAmount(null); } else { objective.setFixedAmount(number); } From ea1f32847afc57aa5c59326b6ed4e96ecc563b39 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 2 May 2024 22:39:25 -0700 Subject: [PATCH 48/76] Complete layout redesign of CustomizeScenarioObjectiveDialog --- .../CustomizeScenarioObjectiveDialog.java | 451 ++++++++++-------- 1 file changed, 241 insertions(+), 210 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index c45446f200..54fcf94b8c 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -17,9 +17,13 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private ScenarioObjective objective; private List botForces; private JFrame frame; - private JLabel lblShortDescription; - private JTextArea txtShortDescription; - private JLabel lblObjectiveType; + + private JPanel panObjectiveType; + private JPanel panForce; + private JPanel panTimeLimits; + private JPanel panEffect; + private JPanel panObjectiveEffect; + private JTextField txtShortDescription; private JComboBox cboObjectiveType; private JComboBox cboDirection; private JTextField txtPercentage; @@ -59,7 +63,7 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb this.objective = objective; this.botForces = botForces; - initGUI(); + initialize(); for(String forceName : objective.getAssociatedForceNames()) { forceModel.addElement(forceName); @@ -100,124 +104,137 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb pack(); } - private void initGUI() { + private void initialize() { + setTitle("Customize Scenario Objective"); + getContentPane().setLayout(new BorderLayout()); + JPanel panMain = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); - gbc.gridwidth = 1; - gbc.gridheight = 1; gbc.gridx = 0; gbc.gridy = 0; gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 5, 5, 5); + panMain.add(new JLabel("Description:"), gbc); - getContentPane().setLayout(new GridBagLayout()); + txtShortDescription = new JTextField(); + gbc.gridx++; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1.0; + panMain.add(txtShortDescription, gbc); - addDescriptionUI(gbc); gbc.gridx = 0; gbc.gridy++; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + panMain.add(new JLabel("Details:"), gbc); - addObjectiveTypeUI(gbc); - gbc.gridx = 0; + JTextField txtDetail = new JTextField(); + txtDetail.setColumns(40); + gbc.gridx = 1; + gbc.fill = GridBagConstraints.BOTH; + gbc.weightx = 1.0; + panMain.add(txtDetail, gbc); + + JButton btnAddDetail = new JButton("Add"); + btnAddDetail.addActionListener(e -> this.addDetail(txtDetail)); + gbc.gridx++; + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + panMain.add(btnAddDetail, gbc); + + + lstDetails = new JList<>(detailModel); + JButton btnRemoveDetail = new JButton("Remove"); + btnRemoveDetail.addActionListener(e -> this.removeDetails()); + lstDetails.addListSelectionListener(e -> btnRemoveDetail.setEnabled(!lstDetails.getSelectedValuesList().isEmpty())); + lstDetails.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + JScrollPane scrDetails = new JScrollPane(lstDetails); + scrDetails.setMinimumSize(new Dimension(200, 100)); + scrDetails.setPreferredSize(new Dimension(200, 100)); + gbc.gridx = 1; gbc.gridy++; + gbc.fill = GridBagConstraints.BOTH; + gbc.weightx = 1.0; + panMain.add(scrDetails, gbc); + + gbc.gridx++; + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + gbc.anchor = GridBagConstraints.NORTHWEST; + panMain.add(btnRemoveDetail, gbc); - addSubjectForce(gbc); gbc.gridx = 0; gbc.gridy++; + gbc.anchor = GridBagConstraints.WEST; + panMain.add(new JLabel("Objective Type:"), gbc); + initObjectiveTypePanel(); + gbc.gridx++; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1.0; + panMain.add(panObjectiveType, gbc); - addTimeLimitUI(gbc); gbc.gridx = 0; gbc.gridy++; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + gbc.anchor = GridBagConstraints.NORTHWEST; + panMain.add(new JLabel("Force Names:"), gbc); + + initForcePanel(); + gbc.gridx++; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1.0; + panMain.add(panForce, gbc); - addEffectUI(gbc); gbc.gridx = 0; gbc.gridy++; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + gbc.weightx = 0.0; + gbc.anchor = GridBagConstraints.WEST; + panMain.add(new JLabel("Time Limit:"), gbc); - addObjectiveEffectUI(gbc); + initTimeLimitPanel(); + gbc.gridx++; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1.0; + panMain.add(panTimeLimits, gbc); + initObjectiveEffectPanel(); gbc.gridx = 0; gbc.gridy++; + gbc.gridwidth = 3; + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + panMain.add(panObjectiveEffect, gbc); - addSaveCloseButtons(gbc); - } - - /** - * Handles the save/close buttons row. - */ - private void addSaveCloseButtons(GridBagConstraints gbc) { - JPanel saveClosePanel = new JPanel(); - saveClosePanel.setLayout(new GridBagLayout()); - GridBagConstraints localGbc = new GridBagConstraints(); - localGbc.gridx = 0; - localGbc.gridy = 0; - localGbc.insets = new Insets(0, 0, 0, 5); + getContentPane().add(panMain, BorderLayout.CENTER); + JPanel panButtons = new JPanel(new GridLayout(0, 2)); JButton btnCancel = new JButton("Cancel"); btnCancel.addActionListener(e -> this.setVisible(false)); - JButton btnSaveAndClose = new JButton("Save and Close"); - btnSaveAndClose.addActionListener(e -> this.saveObjectiveAndClose()); - - saveClosePanel.add(btnCancel); - saveClosePanel.add(btnSaveAndClose); + JButton btnOK = new JButton("OK"); + btnOK.addActionListener(e -> this.saveObjectiveAndClose()); + panButtons.add(btnOK); + panButtons.add(btnCancel); + getContentPane().add(panButtons, BorderLayout.PAGE_END); - getContentPane().add(saveClosePanel, gbc); - } - - /** - * Handles the "description" row. - */ - private void addDescriptionUI(GridBagConstraints gbc) { - lblShortDescription = new JLabel("Short Description:"); - - JScrollPane txtScroll = new JScrollPane(); - txtShortDescription = new JTextArea(); - txtShortDescription.setColumns(40); - txtShortDescription.setRows(5); - txtShortDescription.setLineWrap(true); - txtShortDescription.setWrapStyleWord(true); - txtScroll.setViewportView(txtShortDescription); - - JTextField txtDetail = new JTextField(); - txtDetail.setColumns(40); - JLabel lblDetail = new JLabel("Details (shows up after force/unit list):"); - lstDetails = new JList<>(detailModel); - JButton btnAddDetail = new JButton("Add"); - JButton btnRemoveDetail = new JButton("Remove"); - - lstDetails.addListSelectionListener(e -> btnRemoveDetail.setEnabled(!lstDetails.getSelectedValuesList().isEmpty())); - lstDetails.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - btnRemoveDetail.addActionListener(e -> this.removeDetails()); - btnAddDetail.addActionListener(e -> this.addDetail(txtDetail)); - - JPanel descriptionPanel = new JPanel(); - descriptionPanel.setLayout(new GridBagLayout()); - GridBagConstraints localGbc = new GridBagConstraints(); - localGbc.gridx = 0; - localGbc.gridy = 0; - localGbc.insets = new Insets(5, 0, 5, 5); - - descriptionPanel.add(lblShortDescription, localGbc); - localGbc.gridx++; - descriptionPanel.add(txtScroll, localGbc); - localGbc.gridx = 0; - localGbc.gridy++; - descriptionPanel.add(lblDetail, localGbc); - localGbc.gridx++; - descriptionPanel.add(txtDetail, localGbc); - localGbc.gridx++; - descriptionPanel.add(btnAddDetail, localGbc); - localGbc.gridx++; - descriptionPanel.add(lstDetails, localGbc); - localGbc.gridx++; - descriptionPanel.add(btnRemoveDetail, localGbc); - - getContentPane().add(descriptionPanel, gbc); } /** * Handles the "objective type" row */ - private void addObjectiveTypeUI(GridBagConstraints gbc) { - JPanel objectivePanel = new JPanel(); - - lblObjectiveType = new JLabel("Objective Type:"); + private void initObjectiveTypePanel() { + panObjectiveType = new JPanel(new GridBagLayout()); cboObjectiveType = new JComboBox<>(); for (ScenarioObjective.ObjectiveCriterion objectiveType : ScenarioObjective.ObjectiveCriterion.values()) { cboObjectiveType.addItem(objectiveType); @@ -237,77 +254,28 @@ private void addObjectiveTypeUI(GridBagConstraints gbc) { } cboDirection.setVisible(false); - objectivePanel.setLayout(new GridBagLayout()); - GridBagConstraints localGbc = new GridBagConstraints(); - localGbc.gridx = 0; - localGbc.gridy = 0; - localGbc.insets = new Insets(0, 0, 0, 5); - - - objectivePanel.add(lblObjectiveType, localGbc); - localGbc.gridx++; - objectivePanel.add(cboObjectiveType, localGbc); - localGbc.gridx++; - objectivePanel.add(cboDirection, localGbc); - localGbc.gridx++; - objectivePanel.add(txtPercentage, localGbc); - localGbc.gridx++; - objectivePanel.add(cboCountType, localGbc); - - getContentPane().add(objectivePanel, gbc); - } - - /** - * Handles the UI for adding objective effects - */ - private void addObjectiveEffectUI(GridBagConstraints gbc) { - JPanel effectPanel = new JPanel(); - - - JLabel lblSuccessEffects = new JLabel("Effects on completion:"); - JLabel lblFailureEffects = new JLabel("Effects on failure:"); - - successEffects = new JList<>(successEffectsModel); - successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); - failureEffects = new JList<>(failureEffectsModel); - failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); - - btnRemoveSuccess = new JButton("Remove"); - btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess)); - btnRemoveSuccess.setEnabled(false); - - btnRemoveFailure = new JButton("Remove"); - btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure)); - btnRemoveFailure.setEnabled(false); - GridBagConstraints localGbc = new GridBagConstraints(); - effectPanel.setLayout(new GridBagLayout()); localGbc.gridx = 0; localGbc.gridy = 0; + localGbc.anchor = GridBagConstraints.WEST; localGbc.insets = new Insets(0, 0, 0, 5); - effectPanel.add(lblSuccessEffects, localGbc); - localGbc.gridx++; - effectPanel.add(successEffects, localGbc); + panObjectiveType.add(cboObjectiveType, localGbc); localGbc.gridx++; - effectPanel.add(btnRemoveSuccess, localGbc); + panObjectiveType.add(cboDirection, localGbc); localGbc.gridx++; - effectPanel.add(lblFailureEffects, localGbc); + panObjectiveType.add(txtPercentage, localGbc); localGbc.gridx++; - effectPanel.add(failureEffects, localGbc); - localGbc.gridx++; - effectPanel.add(btnRemoveFailure, localGbc); + localGbc.weightx = 1.0; + panObjectiveType.add(cboCountType, localGbc); - getContentPane().add(effectPanel, gbc); } /** * Handles the UI for adding/removing forces relevant to this objective */ - private void addSubjectForce(GridBagConstraints gbc) { - JPanel forcePanel = new JPanel(); - - JLabel forcesLabel = new JLabel("Force Names:"); + private void initForcePanel() { + panForce = new JPanel(new GridBagLayout()); cboForceName = new JComboBox<>(); cboForceName.addItem(MHQConstants.EGO_OBJECTIVE_NAME); @@ -329,109 +297,172 @@ private void addSubjectForce(GridBagConstraints gbc) { GridBagConstraints localGbc = new GridBagConstraints(); localGbc.gridx = 0; localGbc.gridy = 0; + localGbc.anchor = GridBagConstraints.NORTHWEST; localGbc.insets = new Insets(0, 0, 0, 5); - forcePanel.add(forcesLabel, localGbc); - localGbc.gridx++; - forcePanel.add(cboForceName, localGbc); + panForce.add(cboForceName, localGbc); localGbc.gridx++; - forcePanel.add(btnAdd, localGbc); - localGbc.gridx--; - localGbc.gridy++; - forcePanel.add(forceNames, localGbc); - localGbc.gridx++; - forcePanel.add(btnRemove, localGbc); - - - getContentPane().add(forcePanel, gbc); - } - - private void addTimeLimitUI(GridBagConstraints gbc) { - JPanel timeLimitPanel = new JPanel(); - - cboTimeLimitDirection = new JComboBox<>(); - cboTimeLimitDirection.addItem("at most"); - cboTimeLimitDirection.addItem("at least"); - - cboTimeScaling = new JComboBox<>(); - for (ScenarioObjective.TimeLimitType timeLimitType : ScenarioObjective.TimeLimitType.values()) { - cboTimeScaling.addItem(timeLimitType); - } - cboTimeScaling.addActionListener(e -> this.updateTimeLimitUI()); - - txtTimeLimit = new JTextField(); - txtTimeLimit.setColumns(5); - - GridBagConstraints localGbc = new GridBagConstraints(); - localGbc.gridx = 0; - localGbc.gridy = 0; - localGbc.insets = new Insets(0, 0, 0, 5); - - timeLimitPanel.add(cboTimeLimitDirection, localGbc); + panForce.add(btnAdd, localGbc); localGbc.gridx++; - timeLimitPanel.add(cboTimeScaling, localGbc); + JScrollPane scrForceNames = new JScrollPane(forceNames); + scrForceNames.setMinimumSize(new Dimension(250, 100)); + scrForceNames.setPreferredSize(new Dimension(250, 100)); + panForce.add(scrForceNames, localGbc); localGbc.gridx++; - timeLimitPanel.add(txtTimeLimit, localGbc); - - - getContentPane().add(timeLimitPanel, gbc); + localGbc.weightx = 1.0; + panForce.add(btnRemove, localGbc); } /** - * Handles the "add objective effect" row + * Handles the UI for adding objective effects */ - private void addEffectUI(GridBagConstraints gbc) { - JPanel effectPanel = new JPanel(); + private void initObjectiveEffectPanel() { + panObjectiveEffect = new JPanel(new GridBagLayout()); + panObjectiveEffect.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createTitledBorder("Objective Effects"), + BorderFactory.createEmptyBorder(5,5,5,5))); + + GridBagConstraints gbcLeft = new GridBagConstraints(); + gbcLeft.gridx = 0; + gbcLeft.gridy = 0; + gbcLeft.anchor = GridBagConstraints.WEST; + gbcLeft.fill = GridBagConstraints.NONE; + gbcLeft.weightx = 0.0; + + GridBagConstraints gbcRight = new GridBagConstraints(); + gbcRight.gridx = 1; + gbcRight.gridy = 0; + gbcRight.anchor = GridBagConstraints.WEST; + gbcRight.fill = GridBagConstraints.NONE; + gbcRight.weightx = 1.0; lblMagnitude = new JLabel("Amount:"); + panObjectiveEffect.add(lblMagnitude, gbcLeft); txtAmount = new JTextField(); txtAmount.setColumns(5); + panObjectiveEffect.add(txtAmount, gbcRight); - JLabel lblScaling = new JLabel("Effect Scaling:"); + gbcLeft.gridy++; + gbcRight.gridy++; + panObjectiveEffect.add(new JLabel("Effect Scaling:"), gbcLeft); cboScalingType = new JComboBox<>(); for (ObjectiveEffect.EffectScalingType scalingType : ObjectiveEffect.EffectScalingType.values()) { cboScalingType.addItem(scalingType); } + panObjectiveEffect.add(cboScalingType, gbcRight); - JLabel lblEffectType = new JLabel("Effect Type:"); + gbcLeft.gridy++; + gbcRight.gridy++; + panObjectiveEffect.add(new JLabel("Effect Type:"), gbcLeft); cboEffectType = new JComboBox<>(); for (ObjectiveEffect.ObjectiveEffectType scalingType : ObjectiveEffect.ObjectiveEffectType.values()) { cboEffectType.addItem(scalingType); } + panObjectiveEffect.add(cboEffectType, gbcRight); - JLabel lblEffectCondition = new JLabel("Effect Condition:"); + gbcLeft.gridy++; + gbcRight.gridy++; + panObjectiveEffect.add(new JLabel("Effect Condition:"), gbcLeft); cboEffectCondition = new JComboBox<>(); cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess); cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure); + panObjectiveEffect.add(cboEffectCondition, gbcRight); JButton btnAdd = new JButton("Add"); btnAdd.addActionListener(e -> this.addEffect()); + gbcLeft.gridy++; + panObjectiveEffect.add(btnAdd, gbcLeft); + + JLabel lblSuccessEffects = new JLabel("Effects on Success"); + JLabel lblFailureEffects = new JLabel("Effects on Failure"); + + successEffects = new JList<>(successEffectsModel); + successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); + failureEffects = new JList<>(failureEffectsModel); + failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); + + btnRemoveSuccess = new JButton("Remove"); + btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess)); + btnRemoveSuccess.setEnabled(false); + + btnRemoveFailure = new JButton("Remove"); + btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure)); + btnRemoveFailure.setEnabled(false); + + JPanel panBottom = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(5,5,0,5); + panBottom.add(lblSuccessEffects, gbc); + gbc.gridx++; + gbc.gridx++; + panBottom.add(lblFailureEffects, gbc); + + gbc.gridx = 0; + gbc.gridy++; + gbc.anchor = GridBagConstraints.NORTHWEST; + JScrollPane scrSuccessEffects = new JScrollPane(successEffects); + scrSuccessEffects.setMinimumSize(new Dimension(300, 100)); + scrSuccessEffects.setPreferredSize(new Dimension(300, 100)); + panBottom.add(scrSuccessEffects, gbc); + gbc.gridx++; + panBottom.add(btnRemoveSuccess, gbc); + gbc.gridx++; + JScrollPane scrFailureEffects = new JScrollPane(failureEffects); + scrFailureEffects.setMinimumSize(new Dimension(300, 100)); + scrFailureEffects.setPreferredSize(new Dimension(300, 100)); + panBottom.add(scrFailureEffects, gbc); + gbc.gridx++; + panBottom.add(btnRemoveFailure, gbc); + + gbcLeft.gridy++; + gbcLeft.gridwidth = 3; + gbcLeft.anchor = GridBagConstraints.WEST; + gbcLeft.fill = GridBagConstraints.BOTH; + gbcLeft.weightx = 1.0; + gbcLeft.weighty = 1.0; + panObjectiveEffect.add(panBottom, gbcLeft); + + } + + private void initTimeLimitPanel() { + panTimeLimits = new JPanel(new GridBagLayout()); + + cboTimeLimitDirection = new JComboBox<>(); + cboTimeLimitDirection.addItem("at most"); + cboTimeLimitDirection.addItem("at least"); + + cboTimeScaling = new JComboBox<>(); + for (ScenarioObjective.TimeLimitType timeLimitType : ScenarioObjective.TimeLimitType.values()) { + cboTimeScaling.addItem(timeLimitType); + } + cboTimeScaling.addActionListener(e -> this.updateTimeLimitUI()); + + txtTimeLimit = new JTextField(); + txtTimeLimit.setColumns(5); GridBagConstraints localGbc = new GridBagConstraints(); localGbc.gridx = 0; localGbc.gridy = 0; + localGbc.anchor = GridBagConstraints.NORTHWEST; localGbc.insets = new Insets(0, 0, 0, 5); - effectPanel.setLayout(new GridBagLayout()); - effectPanel.add(lblMagnitude, localGbc); - localGbc.gridx++; - effectPanel.add(txtAmount, localGbc); - localGbc.gridx++; - effectPanel.add(lblScaling, localGbc); + panTimeLimits.add(cboTimeLimitDirection, localGbc); localGbc.gridx++; - effectPanel.add(cboScalingType, localGbc); + panTimeLimits.add(cboTimeScaling, localGbc); localGbc.gridx++; - effectPanel.add(lblEffectType, localGbc); - localGbc.gridx++; - effectPanel.add(cboEffectType, localGbc); - localGbc.gridx++; - effectPanel.add(lblEffectCondition, localGbc); - localGbc.gridx++; - effectPanel.add(cboEffectCondition, localGbc); - localGbc.gridx++; - effectPanel.add(btnAdd, localGbc); + localGbc.weightx = 1.0; + panTimeLimits.add(txtTimeLimit, localGbc); + } + + /** + * Handles the "add objective effect" row + */ + private void initEffectPanel() { + - getContentPane().add(effectPanel, gbc); } /** From 8735cb7a14e8233910e1f94061d7351a51bd75da Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 2 May 2024 22:40:36 -0700 Subject: [PATCH 49/76] Set Preserve as default objective --- MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java index aa67aeb249..113771a808 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioObjective.java @@ -141,7 +141,7 @@ public enum ObjectiveAmountType { public ScenarioObjective() { description = ""; - objectiveCriterion = ObjectiveCriterion.Destroy; + objectiveCriterion = ObjectiveCriterion.Preserve; destinationEdge = OffBoardDirection.NONE; percentage = 100; } From 1924ed959e7a4744e2aa3e2288572a8a747db864 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Thu, 2 May 2024 23:30:57 -0700 Subject: [PATCH 50/76] Add more detailed columns to ObjectiveTableModel --- .../mekhq/gui/model/ObjectiveTableModel.java | 69 ++++++++++++++++--- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java index 92897b3feb..dcefefb790 100644 --- a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java +++ b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java @@ -2,6 +2,7 @@ import megamek.common.Entity; import mekhq.campaign.mission.Loot; +import mekhq.campaign.mission.ObjectiveEffect; import mekhq.campaign.mission.ScenarioObjective; import mekhq.campaign.parts.Part; @@ -17,9 +18,12 @@ public class ObjectiveTableModel extends AbstractTableModel { protected String[] columnNames; protected List data; - public final static int COL_DESC = 0; - - public final static int N_COL = 1; + public final static int COL_CRITERION = 0; + public final static int COL_AMOUNT = 1; + public final static int COL_TIME = 2; + public final static int COL_SUCCESS_EFFECT = 3; + public final static int COL_FAILURE_EFFECT = 4; + public final static int N_COL = 5; //endregion Variable Declarations public ObjectiveTableModel(List entries) { @@ -39,8 +43,16 @@ public int getColumnCount() { @Override public String getColumnName(int column) { switch (column) { - case COL_DESC: - return "Description"; + case COL_CRITERION: + return "Type"; + case COL_AMOUNT: + return "Amount"; + case COL_TIME: + return "Time limits"; + case COL_SUCCESS_EFFECT: + return "On Success"; + case COL_FAILURE_EFFECT: + return "On Failure"; default: return "?"; } @@ -61,8 +73,23 @@ public Object getValueAt(int row, int col) { } switch (col) { - case COL_DESC: - return objective.getDescription(); + case COL_CRITERION: + return objective.getObjectiveCriterion().toString(); + case COL_AMOUNT: + return objective.getAmountType().equals(ScenarioObjective.ObjectiveAmountType.Percentage) ? + objective.getPercentage() + "%" : objective.getAmount() + " units"; + case COL_TIME: + if(objective.getTimeLimitType().equals(ScenarioObjective.TimeLimitType.None)) { + return "None"; + } + String timeDirection = objective.isTimeLimitAtMost() ? "At most " : "At least "; + return objective.getTimeLimitType().equals(ScenarioObjective.TimeLimitType.Fixed) ? + timeDirection + objective.getTimeLimit() + " turns" : + timeDirection + "(" + objective.getTimeLimitScaleFactor() + "x unit count) turns"; + case COL_SUCCESS_EFFECT: + return Integer.toString(objective.getSuccessEffects().size()) + " Effect(s)"; + case COL_FAILURE_EFFECT: + return Integer.toString(objective.getFailureEffects().size()) + " Effect(s)"; default: return "?"; } @@ -74,8 +101,6 @@ public ScenarioObjective getObjectiveAt(int row) { public int getColumnWidth(int c) { switch (c) { - case COL_DESC: - return 100; default: return 20; } @@ -86,7 +111,33 @@ public int getAlignment(int col) { } public String getTooltip(int row, int col) { + ScenarioObjective objective; + if (data.isEmpty()) { + return null; + } else { + objective = getObjectiveAt(row); + } + StringBuilder sb; + switch (col) { + case COL_CRITERION: + return "" + String.join("
", objective.getAssociatedForceNames()) +""; + case COL_SUCCESS_EFFECT: + sb = new StringBuilder(); + sb.append(""); + for(ObjectiveEffect effect : objective.getSuccessEffects()) { + sb.append(effect.toString()).append("
"); + } + sb.append(""); + return sb.toString(); + case COL_FAILURE_EFFECT: + sb = new StringBuilder(); + sb.append(""); + for(ObjectiveEffect effect : objective.getFailureEffects()) { + sb.append(effect.toString()).append("
"); + } + sb.append(""); + return sb.toString(); default: return null; } From 89a63956f8b874476b06b25792d7d181cd3a6621 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 3 May 2024 09:47:32 -0700 Subject: [PATCH 51/76] Replace textfields for numbers with spinner in CustomizeScenarioObjectiveDialog --- .../CustomizeScenarioObjectiveDialog.java | 80 ++++++++----------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 54fcf94b8c..fd9c6aea89 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -26,12 +26,14 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JTextField txtShortDescription; private JComboBox cboObjectiveType; private JComboBox cboDirection; - private JTextField txtPercentage; + private JSpinner spnPercentage; + private SpinnerNumberModel modelPercent; + private SpinnerNumberModel modelFixed; private MMComboBox cboCountType; private JComboBox cboForceName; private JLabel lblMagnitude; - private JTextField txtAmount; + private JSpinner spnAmount; private JComboBox cboScalingType; private JComboBox cboEffectType; private JComboBox cboEffectCondition; @@ -43,7 +45,7 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JComboBox cboTimeLimitDirection; private JComboBox cboTimeScaling; - private JTextField txtTimeLimit; + private JSpinner spnTimeLimit; private JList forceNames; JButton btnRemove; @@ -72,7 +74,7 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb txtShortDescription.setText(objective.getDescription()); cboObjectiveType.setSelectedItem(objective.getObjectiveCriterion()); cboCountType.setSelectedItem(objective.getAmountType()); - txtPercentage.setText(Integer.toString(objective.getAmount())); + spnPercentage.setValue(objective.getAmount()); setDirectionDropdownVisibility(); cboDirection.setSelectedIndex(objective.getDestinationEdge().ordinal()); @@ -81,10 +83,10 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb updateTimeLimitUI(); cboTimeLimitDirection.setSelectedIndex(objective.isTimeLimitAtMost() ? 0 : 1); if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { - txtTimeLimit.setText(objective.getTimeLimitScaleFactor().toString()); + spnTimeLimit.setValue(objective.getTimeLimitScaleFactor()); } else { if (objective.getTimeLimit() != null) { - txtTimeLimit.setText(objective.getTimeLimit().toString()); + spnTimeLimit.setValue(objective.getTimeLimit()); } } @@ -241,10 +243,12 @@ private void initObjectiveTypePanel() { } cboObjectiveType.addActionListener(e -> this.setDirectionDropdownVisibility()); - txtPercentage = new JTextField(); - txtPercentage.setColumns(4); + modelPercent = new SpinnerNumberModel(0, 0, 100, 5); + modelFixed = new SpinnerNumberModel(0, 0, null, 1); + spnPercentage = new JSpinner(modelPercent); cboCountType = new MMComboBox("cboCountType", ScenarioObjective.ObjectiveAmountType.values()); + cboCountType.addActionListener(etv -> switchNumberModel()); cboDirection = new JComboBox<>(); @@ -264,7 +268,7 @@ private void initObjectiveTypePanel() { localGbc.gridx++; panObjectiveType.add(cboDirection, localGbc); localGbc.gridx++; - panObjectiveType.add(txtPercentage, localGbc); + panObjectiveType.add(spnPercentage, localGbc); localGbc.gridx++; localGbc.weightx = 1.0; panObjectiveType.add(cboCountType, localGbc); @@ -338,9 +342,8 @@ private void initObjectiveEffectPanel() { lblMagnitude = new JLabel("Amount:"); panObjectiveEffect.add(lblMagnitude, gbcLeft); - txtAmount = new JTextField(); - txtAmount.setColumns(5); - panObjectiveEffect.add(txtAmount, gbcRight); + spnAmount = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); + panObjectiveEffect.add(spnAmount, gbcRight); gbcLeft.gridy++; gbcRight.gridy++; @@ -440,8 +443,7 @@ private void initTimeLimitPanel() { } cboTimeScaling.addActionListener(e -> this.updateTimeLimitUI()); - txtTimeLimit = new JTextField(); - txtTimeLimit.setColumns(5); + spnTimeLimit = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); GridBagConstraints localGbc = new GridBagConstraints(); localGbc.gridx = 0; @@ -454,15 +456,21 @@ private void initTimeLimitPanel() { panTimeLimits.add(cboTimeScaling, localGbc); localGbc.gridx++; localGbc.weightx = 1.0; - panTimeLimits.add(txtTimeLimit, localGbc); + panTimeLimits.add(spnTimeLimit, localGbc); } - /** - * Handles the "add objective effect" row - */ - private void initEffectPanel() { - - + private void switchNumberModel() { + int value = (int) spnPercentage.getValue(); + if(cboCountType.getSelectedItem() == ScenarioObjective.ObjectiveAmountType.Percentage) { + if(value > 100) { + value = 100; + } + modelPercent.setValue(value); + spnPercentage.setModel(modelPercent); + } else { + modelFixed.setValue(value); + spnPercentage.setModel(modelFixed); + } } /** @@ -471,7 +479,7 @@ private void initEffectPanel() { private void addEffect() { int amount = 0; try { - amount = Integer.parseInt(txtAmount.getText()); + amount = (int) spnAmount.getValue(); lblMagnitude.setForeground(UIManager.getColor("text")); } catch (Exception e) { lblMagnitude.setForeground(Color.red); @@ -550,7 +558,7 @@ private void setDirectionDropdownVisibility() { private void updateTimeLimitUI() { boolean enable = !cboTimeScaling.getSelectedItem().equals(ScenarioObjective.TimeLimitType.None); - txtTimeLimit.setEnabled(enable); + spnTimeLimit.setEnabled(enable); cboTimeLimitDirection.setEnabled(enable); } @@ -559,29 +567,9 @@ public ScenarioObjective getObjective() { } private void saveObjectiveAndClose() { - int number = 0; - int timeLimit = 0; - - try { - number = Integer.parseInt(txtPercentage.getText()); - txtPercentage.setBorder(null); - } catch (Exception e) { - txtPercentage.setBorder(new LineBorder(Color.red)); - return; - } - - try { - if (txtTimeLimit.isEnabled()) { - timeLimit = Integer.parseInt(txtTimeLimit.getText()); - txtTimeLimit.setBorder(null); - } - } catch (Exception e) { - txtTimeLimit.setBorder(new LineBorder(Color.red)); - return; - } - objective.setObjectiveCriterion((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()); objective.setDescription(txtShortDescription.getText()); + int number = (int) spnPercentage.getValue(); if (cboCountType.getSelectedItem().equals(ScenarioObjective.ObjectiveAmountType.Percentage)) { objective.setPercentage(number); objective.setFixedAmount(null); @@ -616,15 +604,15 @@ private void saveObjectiveAndClose() { objective.setDestinationEdge(OffBoardDirection.NONE); } + int timeLimit = (int) spnTimeLimit.getValue(); objective.setTimeLimitType((ScenarioObjective.TimeLimitType) cboTimeScaling.getSelectedItem()); - if (txtTimeLimit.isEnabled()) { + if (spnTimeLimit.isEnabled()) { if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { objective.setTimeLimitScaleFactor(timeLimit); } else { objective.setTimeLimit(timeLimit); } } - if (cboTimeLimitDirection.isEnabled()) { objective.setTimeLimitAtMost(cboTimeLimitDirection.getSelectedIndex() == 0); } From 93503fdd01c7dc6e38f00210b4ba0571b43e8061 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 3 May 2024 09:48:31 -0700 Subject: [PATCH 52/76] Refactor spinner names in CustomizeScenarioObjectiveDialog --- .../CustomizeScenarioObjectiveDialog.java | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index fd9c6aea89..8b57f75215 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -3,13 +3,10 @@ import megamek.client.ui.baseComponents.MMComboBox; import megamek.common.OffBoardDirection; import mekhq.MHQConstants; -import mekhq.campaign.Campaign; import mekhq.campaign.mission.*; import javax.swing.*; -import javax.swing.border.LineBorder; import java.awt.*; -import java.util.ArrayList; import java.util.List; public class CustomizeScenarioObjectiveDialog extends JDialog { @@ -26,14 +23,14 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JTextField txtShortDescription; private JComboBox cboObjectiveType; private JComboBox cboDirection; - private JSpinner spnPercentage; + private JSpinner spnAmount; private SpinnerNumberModel modelPercent; private SpinnerNumberModel modelFixed; private MMComboBox cboCountType; private JComboBox cboForceName; private JLabel lblMagnitude; - private JSpinner spnAmount; + private JSpinner spnScore; private JComboBox cboScalingType; private JComboBox cboEffectType; private JComboBox cboEffectCondition; @@ -74,7 +71,7 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb txtShortDescription.setText(objective.getDescription()); cboObjectiveType.setSelectedItem(objective.getObjectiveCriterion()); cboCountType.setSelectedItem(objective.getAmountType()); - spnPercentage.setValue(objective.getAmount()); + spnAmount.setValue(objective.getAmount()); setDirectionDropdownVisibility(); cboDirection.setSelectedIndex(objective.getDestinationEdge().ordinal()); @@ -245,7 +242,7 @@ private void initObjectiveTypePanel() { modelPercent = new SpinnerNumberModel(0, 0, 100, 5); modelFixed = new SpinnerNumberModel(0, 0, null, 1); - spnPercentage = new JSpinner(modelPercent); + spnAmount = new JSpinner(modelPercent); cboCountType = new MMComboBox("cboCountType", ScenarioObjective.ObjectiveAmountType.values()); cboCountType.addActionListener(etv -> switchNumberModel()); @@ -268,7 +265,7 @@ private void initObjectiveTypePanel() { localGbc.gridx++; panObjectiveType.add(cboDirection, localGbc); localGbc.gridx++; - panObjectiveType.add(spnPercentage, localGbc); + panObjectiveType.add(spnAmount, localGbc); localGbc.gridx++; localGbc.weightx = 1.0; panObjectiveType.add(cboCountType, localGbc); @@ -342,8 +339,8 @@ private void initObjectiveEffectPanel() { lblMagnitude = new JLabel("Amount:"); panObjectiveEffect.add(lblMagnitude, gbcLeft); - spnAmount = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); - panObjectiveEffect.add(spnAmount, gbcRight); + spnScore = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); + panObjectiveEffect.add(spnScore, gbcRight); gbcLeft.gridy++; gbcRight.gridy++; @@ -460,16 +457,16 @@ private void initTimeLimitPanel() { } private void switchNumberModel() { - int value = (int) spnPercentage.getValue(); + int value = (int) spnAmount.getValue(); if(cboCountType.getSelectedItem() == ScenarioObjective.ObjectiveAmountType.Percentage) { if(value > 100) { value = 100; } modelPercent.setValue(value); - spnPercentage.setModel(modelPercent); + spnAmount.setModel(modelPercent); } else { modelFixed.setValue(value); - spnPercentage.setModel(modelFixed); + spnAmount.setModel(modelFixed); } } @@ -479,7 +476,7 @@ private void switchNumberModel() { private void addEffect() { int amount = 0; try { - amount = (int) spnAmount.getValue(); + amount = (int) spnScore.getValue(); lblMagnitude.setForeground(UIManager.getColor("text")); } catch (Exception e) { lblMagnitude.setForeground(Color.red); @@ -569,7 +566,7 @@ public ScenarioObjective getObjective() { private void saveObjectiveAndClose() { objective.setObjectiveCriterion((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()); objective.setDescription(txtShortDescription.getText()); - int number = (int) spnPercentage.getValue(); + int number = (int) spnAmount.getValue(); if (cboCountType.getSelectedItem().equals(ScenarioObjective.ObjectiveAmountType.Percentage)) { objective.setPercentage(number); objective.setFixedAmount(null); From 11a622db33d8915a40660a93d66dcba2e33c23ed Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 3 May 2024 11:37:55 -0700 Subject: [PATCH 53/76] Localize text in CustomizeScenarioObjectiveDialog --- ...ustomizeScenarioObjectiveDialog.properties | 17 +++++ .../CustomizeScenarioObjectiveDialog.java | 62 ++++++++++--------- 2 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties new file mode 100644 index 0000000000..56486cc704 --- /dev/null +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties @@ -0,0 +1,17 @@ +dialog.title=Customize Scenario Objective +panObjectiveEffect.title=Objective Effects +lblDescription.text=Description: +lblDetails.text=Details: +lblObjectiveType.text=Objective Type: +lblForceNames.text=Force Names: +lblTimeLimit.text=Time Limit: +lblMagnitude.text=Amount: +lblEffectType.text=Effect Type: +lblEffectScaling.text=Effect Scaling: +lblEffectCondition.text=Effect Condition: +lblSuccessEffects.text=Effects on Success +lblFailureEffects.text=Effects on Failure +btnAdd.text=Add +btnRemove.text=Remove +btnCancel.text=Cancel +btnOK.text=OK \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 8b57f75215..dfe874709c 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -3,11 +3,13 @@ import megamek.client.ui.baseComponents.MMComboBox; import megamek.common.OffBoardDirection; import mekhq.MHQConstants; +import mekhq.MekHQ; import mekhq.campaign.mission.*; import javax.swing.*; import java.awt.*; import java.util.List; +import java.util.ResourceBundle; public class CustomizeScenarioObjectiveDialog extends JDialog { @@ -104,7 +106,11 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb } private void initialize() { - setTitle("Customize Scenario Objective"); + + final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.CustomizeScenarioObjectiveDialog", + MekHQ.getMHQOptions().getLocale()); + + setTitle(resourceMap.getString("dialog.title")); getContentPane().setLayout(new BorderLayout()); JPanel panMain = new JPanel(new GridBagLayout()); @@ -114,7 +120,7 @@ private void initialize() { gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(5, 5, 5, 5); - panMain.add(new JLabel("Description:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblDescription.text")), gbc); txtShortDescription = new JTextField(); gbc.gridx++; @@ -128,7 +134,7 @@ private void initialize() { gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; - panMain.add(new JLabel("Details:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblDetails.text")), gbc); JTextField txtDetail = new JTextField(); txtDetail.setColumns(40); @@ -137,7 +143,7 @@ private void initialize() { gbc.weightx = 1.0; panMain.add(txtDetail, gbc); - JButton btnAddDetail = new JButton("Add"); + JButton btnAddDetail = new JButton(resourceMap.getString("btnAdd.text")); btnAddDetail.addActionListener(e -> this.addDetail(txtDetail)); gbc.gridx++; gbc.fill = GridBagConstraints.NONE; @@ -146,7 +152,7 @@ private void initialize() { lstDetails = new JList<>(detailModel); - JButton btnRemoveDetail = new JButton("Remove"); + JButton btnRemoveDetail = new JButton(resourceMap.getString("btnRemove.text")); btnRemoveDetail.addActionListener(e -> this.removeDetails()); lstDetails.addListSelectionListener(e -> btnRemoveDetail.setEnabled(!lstDetails.getSelectedValuesList().isEmpty())); lstDetails.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); @@ -168,7 +174,7 @@ private void initialize() { gbc.gridx = 0; gbc.gridy++; gbc.anchor = GridBagConstraints.WEST; - panMain.add(new JLabel("Objective Type:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblObjectiveType.text")), gbc); initObjectiveTypePanel(); gbc.gridx++; gbc.gridwidth = 2; @@ -182,9 +188,9 @@ private void initialize() { gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.NORTHWEST; - panMain.add(new JLabel("Force Names:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblForceNames.text")), gbc); - initForcePanel(); + initForcePanel(resourceMap); gbc.gridx++; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.HORIZONTAL; @@ -197,7 +203,7 @@ private void initialize() { gbc.fill = GridBagConstraints.NONE; gbc.weightx = 0.0; gbc.anchor = GridBagConstraints.WEST; - panMain.add(new JLabel("Time Limit:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblTimeLimit.text")), gbc); initTimeLimitPanel(); gbc.gridx++; @@ -206,7 +212,7 @@ private void initialize() { gbc.weightx = 1.0; panMain.add(panTimeLimits, gbc); - initObjectiveEffectPanel(); + initObjectiveEffectPanel(resourceMap); gbc.gridx = 0; gbc.gridy++; gbc.gridwidth = 3; @@ -219,9 +225,9 @@ private void initialize() { getContentPane().add(panMain, BorderLayout.CENTER); JPanel panButtons = new JPanel(new GridLayout(0, 2)); - JButton btnCancel = new JButton("Cancel"); + JButton btnCancel = new JButton(resourceMap.getString("btnCancel.text")); btnCancel.addActionListener(e -> this.setVisible(false)); - JButton btnOK = new JButton("OK"); + JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); btnOK.addActionListener(e -> this.saveObjectiveAndClose()); panButtons.add(btnOK); panButtons.add(btnCancel); @@ -275,7 +281,7 @@ private void initObjectiveTypePanel() { /** * Handles the UI for adding/removing forces relevant to this objective */ - private void initForcePanel() { + private void initForcePanel(ResourceBundle resourceMap) { panForce = new JPanel(new GridBagLayout()); cboForceName = new JComboBox<>(); @@ -288,10 +294,10 @@ private void initForcePanel() { forceNames.setVisibleRowCount(5); forceNames.addListSelectionListener(e -> btnRemove.setEnabled(!forceNames.getSelectedValuesList().isEmpty())); - JButton btnAdd = new JButton("Add"); + JButton btnAdd = new JButton(resourceMap.getString("btnAdd.text")); btnAdd.addActionListener(e -> this.addForce()); - btnRemove = new JButton("Remove"); + btnRemove = new JButton(resourceMap.getString("btnRemove.text")); btnRemove.addActionListener(e -> this.removeForce()); btnRemove.setEnabled(false); @@ -317,10 +323,10 @@ private void initForcePanel() { /** * Handles the UI for adding objective effects */ - private void initObjectiveEffectPanel() { + private void initObjectiveEffectPanel(ResourceBundle resourceMap) { panObjectiveEffect = new JPanel(new GridBagLayout()); panObjectiveEffect.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Objective Effects"), + BorderFactory.createTitledBorder(resourceMap.getString("panObjectiveEffect.title")), BorderFactory.createEmptyBorder(5,5,5,5))); GridBagConstraints gbcLeft = new GridBagConstraints(); @@ -337,14 +343,14 @@ private void initObjectiveEffectPanel() { gbcRight.fill = GridBagConstraints.NONE; gbcRight.weightx = 1.0; - lblMagnitude = new JLabel("Amount:"); + lblMagnitude = new JLabel(resourceMap.getString("lblMagnitude.text")); panObjectiveEffect.add(lblMagnitude, gbcLeft); spnScore = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); panObjectiveEffect.add(spnScore, gbcRight); gbcLeft.gridy++; gbcRight.gridy++; - panObjectiveEffect.add(new JLabel("Effect Scaling:"), gbcLeft); + panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectScaling.text")), gbcLeft); cboScalingType = new JComboBox<>(); for (ObjectiveEffect.EffectScalingType scalingType : ObjectiveEffect.EffectScalingType.values()) { cboScalingType.addItem(scalingType); @@ -353,7 +359,7 @@ private void initObjectiveEffectPanel() { gbcLeft.gridy++; gbcRight.gridy++; - panObjectiveEffect.add(new JLabel("Effect Type:"), gbcLeft); + panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectType.text")), gbcLeft); cboEffectType = new JComboBox<>(); for (ObjectiveEffect.ObjectiveEffectType scalingType : ObjectiveEffect.ObjectiveEffectType.values()) { cboEffectType.addItem(scalingType); @@ -362,30 +368,30 @@ private void initObjectiveEffectPanel() { gbcLeft.gridy++; gbcRight.gridy++; - panObjectiveEffect.add(new JLabel("Effect Condition:"), gbcLeft); + panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectCondition.text")), gbcLeft); cboEffectCondition = new JComboBox<>(); cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess); cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure); panObjectiveEffect.add(cboEffectCondition, gbcRight); - JButton btnAdd = new JButton("Add"); + JButton btnAdd = new JButton(resourceMap.getString("btnAdd.text")); btnAdd.addActionListener(e -> this.addEffect()); gbcLeft.gridy++; panObjectiveEffect.add(btnAdd, gbcLeft); - JLabel lblSuccessEffects = new JLabel("Effects on Success"); - JLabel lblFailureEffects = new JLabel("Effects on Failure"); + JLabel lblSuccessEffects = new JLabel(resourceMap.getString("lblSuccessEffects.text")); + JLabel lblFailureEffects = new JLabel(resourceMap.getString("lblSuccessEffects.text")); successEffects = new JList<>(successEffectsModel); successEffects.addListSelectionListener(e -> btnRemoveSuccess.setEnabled(!successEffects.getSelectedValuesList().isEmpty())); failureEffects = new JList<>(failureEffectsModel); failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); - btnRemoveSuccess = new JButton("Remove"); + btnRemoveSuccess = new JButton(resourceMap.getString("btnRemove.text")); btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess)); btnRemoveSuccess.setEnabled(false); - btnRemoveFailure = new JButton("Remove"); + btnRemoveFailure = new JButton(resourceMap.getString("btnRemove.text")); btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure)); btnRemoveFailure.setEnabled(false); @@ -476,7 +482,7 @@ private void switchNumberModel() { private void addEffect() { int amount = 0; try { - amount = (int) spnScore.getValue(); + amount = lblMagnitude.setForeground(UIManager.getColor("text")); } catch (Exception e) { lblMagnitude.setForeground(Color.red); @@ -484,7 +490,7 @@ private void addEffect() { } ObjectiveEffect effect = new ObjectiveEffect(); - effect.howMuch = amount; + effect.howMuch = (int) spnScore.getValue();; effect.effectScaling = (ObjectiveEffect.EffectScalingType) cboScalingType.getSelectedItem(); effect.effectType = (ObjectiveEffect.ObjectiveEffectType) cboEffectType.getSelectedItem(); From 7906de554afe423ed98660de9b029ec68910eed7 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 3 May 2024 11:40:32 -0700 Subject: [PATCH 54/76] remove coloring of labels in CustomizeScenarioObjectiveDialog --- .../gui/dialog/CustomizeScenarioObjectiveDialog.java | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index dfe874709c..56d052cbd2 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -31,7 +31,6 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private MMComboBox cboCountType; private JComboBox cboForceName; - private JLabel lblMagnitude; private JSpinner spnScore; private JComboBox cboScalingType; private JComboBox cboEffectType; @@ -343,7 +342,7 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { gbcRight.fill = GridBagConstraints.NONE; gbcRight.weightx = 1.0; - lblMagnitude = new JLabel(resourceMap.getString("lblMagnitude.text")); + JLabel lblMagnitude = new JLabel(resourceMap.getString("lblMagnitude.text")); panObjectiveEffect.add(lblMagnitude, gbcLeft); spnScore = new JSpinner(new SpinnerNumberModel(1, 1, null, 1)); panObjectiveEffect.add(spnScore, gbcRight); @@ -480,14 +479,6 @@ private void switchNumberModel() { * Event handler for the 'add' button for scenario effects */ private void addEffect() { - int amount = 0; - try { - amount = - lblMagnitude.setForeground(UIManager.getColor("text")); - } catch (Exception e) { - lblMagnitude.setForeground(Color.red); - return; - } ObjectiveEffect effect = new ObjectiveEffect(); effect.howMuch = (int) spnScore.getValue();; From 8e658217396cd525eff38c1cc28d333ef1de2a44 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Fri, 3 May 2024 12:15:49 -0700 Subject: [PATCH 55/76] Check changes to forces for scenario objective changes in CustomizeScenarioDialog --- .../gui/dialog/CustomizeScenarioDialog.java | 42 ++++++++++++++++++- .../CustomizeScenarioObjectiveDialog.java | 10 ++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 422e089fd6..62bb21a0a9 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -806,8 +806,13 @@ private void objectiveTableValueChanged(ListSelectionEvent evt) { btnEditObjective.setEnabled(row != -1); } + private List getBotForceNames() { + return botForces.stream().map(BotForce::getName).collect(Collectors.toCollection(ArrayList::new)); + } + private void addObjective() { - CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, new ScenarioObjective(), scenario.getBotForces()); + CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, + new ScenarioObjective(), getBotForceNames()); csod.setVisible(true); if (null != csod.getObjective()) { objectives.add(csod.getObjective()); @@ -818,7 +823,8 @@ private void addObjective() { private void editObjective() { ScenarioObjective objective = objectiveModel.getObjectiveAt(objectiveTable.getSelectedRow()); if (null != objective) { - CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, objective, scenario.getBotForces()); + CustomizeScenarioObjectiveDialog csod = new CustomizeScenarioObjectiveDialog(frame, true, objective, + getBotForceNames()); csod.setVisible(true); refreshObjectiveTable(); } @@ -981,17 +987,26 @@ private void addForce() { private void editForce() { BotForce bf = forcesModel.getBotForceAt(forcesTable.getSelectedRow()); + String nameOld = bf.getName(); if (null != bf) { CustomizeBotForceDialog cbfd = new CustomizeBotForceDialog(frame, true, bf, campaign); cbfd.setVisible(true); refreshForcesTable(); + if(!bf.getName().equals(nameOld)) { + checkForceRename(nameOld, bf.getName()); + refreshObjectiveTable(); + } } } private void deleteForce() { + BotForce bf = forcesModel.getBotForceAt(forcesTable.getSelectedRow()); + String nameRemove = bf.getName(); int row = forcesTable.getSelectedRow(); if (-1 != row) { botForces.remove(row); + checkForceDelete(nameRemove); + refreshObjectiveTable(); } refreshForcesTable(); } @@ -1010,6 +1025,29 @@ private void refreshForcesTable() { } } + /** + * If a force was renamed, we need to change its name in any corresponding scenario objectives + */ + private void checkForceRename(String nameOld, String nameNew) { + for(ScenarioObjective objective : objectives) { + if(objective.getAssociatedForceNames().contains(nameOld)) { + objective.removeForce(nameOld); + objective.addForce(nameNew); + } + } + } + + /** + * If a force is deleted, check scenario objectives and remove it there as well + */ + private void checkForceDelete(String nameRemove) { + for(ScenarioObjective objective : objectives) { + if (objective.getAssociatedForceNames().contains(nameRemove)) { + objective.removeForce(nameRemove); + } + } + } + /** * Event handler for the 'add modifier' button. * @param event diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 56d052cbd2..9edffa57db 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -14,7 +14,7 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private ScenarioObjective objective; - private List botForces; + private List botForceNames; private JFrame frame; private JPanel panObjectiveType; @@ -57,11 +57,11 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { DefaultListModel detailModel = new DefaultListModel<>(); - public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForces) { + public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForceNames) { super(parent, modal); this.frame = parent; this.objective = objective; - this.botForces = botForces; + this.botForceNames = botForceNames; initialize(); @@ -285,8 +285,8 @@ private void initForcePanel(ResourceBundle resourceMap) { cboForceName = new JComboBox<>(); cboForceName.addItem(MHQConstants.EGO_OBJECTIVE_NAME); - for(BotForce force : botForces) { - cboForceName.addItem(force.getName()); + for(String name : botForceNames) { + cboForceName.addItem(name); } forceNames = new JList<>(forceModel); From 502daf5f06d2aa54e7e7be1492d1f6e756324145 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 09:30:22 -0700 Subject: [PATCH 56/76] Add map settings panel to CustomizeScenarioDialog --- .../CustomizeScenarioDialog.properties | 5 + .../src/mekhq/campaign/mission/Scenario.java | 4 + .../gui/dialog/CustomizeScenarioDialog.java | 114 +++++++++++++++++- 3 files changed, 119 insertions(+), 4 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index 03ed0fab50..e478f3314b 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -13,8 +13,10 @@ btnAddObjective.text=Add Objective btnEditObjective.text=Edit Objective btnDeleteObjective.text=Delete Objective btnPlanetaryConditions.text=Edit Planetary Conditions... +btnMapSettings.text=Edit Map Settings... panPlanetaryConditions.title=Planetary Conditions panDeploymentLimits.title=Deployment Limits +panMap.title=Map Settings lblAllowedUnits.text=Allowed Unit Types: lblQuantityLimit.text=Quantity Limit: lblRequiredPersonnel.text=Required Personnel: @@ -29,6 +31,9 @@ lblAtmosphere.text=Atmosphere: lblGravity.text=Gravity: lblTemperature.text=Temperature: lblOtherConditions.text=Other: +lblBoardType.text=Board Type: +lblMap.text=Map: +lblMapSize.text=Map Size: emi.text=Electromagnetic interference sand.text=Blowing sand panOtherForces.title=Other Forces diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index 7e4d35863f..b229d469ed 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -1177,4 +1177,8 @@ public void setHasTrack(boolean b) { hasTrack = b; } + public static String getBoardTypeName(int i) { + return typeNames[i]; + } + } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 62bb21a0a9..f5857963fd 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -70,6 +70,13 @@ public class CustomizeScenarioDialog extends JDialog { private Player player; private List botForces; + // map parameters + private int mapSizeX; + private int mapSizeY; + private String map; + private boolean usingFixedMap; + private int boardType; + // objectives private List objectives; private JTable objectiveTable; @@ -90,6 +97,7 @@ public class CustomizeScenarioDialog extends JDialog { private JPanel panObjectives; private JPanel panOtherForces; private JPanel panPlanetaryConditions; + private JPanel panMap; // labels private JLabel lblAllowedUnitsDesc; @@ -106,6 +114,9 @@ public class CustomizeScenarioDialog extends JDialog { private JLabel lblTemperatureDesc; private JLabel lblGravityDesc; private JLabel lblOtherConditionsDesc; + private JLabel lblMap; + private JLabel lblBoardType; + private JLabel lblMapSize; // end: labels // textfields @@ -119,6 +130,7 @@ public class CustomizeScenarioDialog extends JDialog { private JButton btnDate; private JButton btnDeployment; private JButton btnPlanetaryConditions; + private JButton btnMapSettings; private JButton btnAddLoot; private JButton btnEditLoot; private JButton btnDeleteLoot; @@ -174,13 +186,18 @@ public CustomizeScenarioDialog(JFrame parent, boolean modal, Scenario s, Mission } lootModel = new LootTableModel(loots); - // FIXME: clone this so we don't change on a cancel objectives = new ArrayList<>(); for(ScenarioObjective objective : scenario.getScenarioObjectives()) { objectives.add(new ScenarioObjective(objective)); } objectiveModel = new ObjectiveTableModel(objectives); + map = scenario.getMap(); + mapSizeX = scenario.getMapSizeX(); + mapSizeY = scenario.getMapSizeY(); + usingFixedMap = scenario.isUsingFixedMap(); + boardType = scenario.getBoardType(); + initComponents(); setLocationRelativeTo(parent); setUserPreferences(); @@ -299,8 +316,12 @@ public Component getListCellRendererComponent(final JList list, final Object initPlanetaryConditionsPanel(resourceMap); gbc.gridy++; - gbc.fill = GridBagConstraints.BOTH; panInfo.add(panPlanetaryConditions, gbc); + + initMapPanel(resourceMap); + gbc.gridy++; + panInfo.add(panMap, gbc); + // endregion Set up info panel initObjectivesPanel(resourceMap); @@ -457,6 +478,11 @@ private void btnOKActionPerformed(ActionEvent evt) { if (newScenario) { campaign.addScenario(scenario, mission); } + scenario.setMap(map); + scenario.setMapSizeX(mapSizeX); + scenario.setMapSizeY(mapSizeY); + scenario.setBoardType(boardType); + scenario.setUsingFixedMap(usingFixedMap); this.setVisible(false); } @@ -730,8 +756,6 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { lblAtmosphereDesc = new JLabel(scenario.getAtmosphere().toString()); rightGbc.gridy++; panPlanetaryConditions.add(lblAtmosphereDesc, rightGbc); - - } private void refreshPlanetaryConditions() { @@ -764,6 +788,88 @@ private void changePlanetaryConditions() { refreshPlanetaryConditions(); } + private void initMapPanel(ResourceBundle resourceMap) { + panMap = new JPanel(new GridBagLayout()); + panMap.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 0, 10, 0), + BorderFactory.createTitledBorder(resourceMap.getString("panMap.title")))); + + btnMapSettings = new JButton(resourceMap.getString("btnMapSettings.text")); + btnMapSettings.addActionListener(evt -> changeMapSettings()); + btnMapSettings.setEnabled(scenario.getStatus().isCurrent()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 0, 0, 0); + panMap.add(btnMapSettings, gbc); + + GridBagConstraints leftGbc = new GridBagConstraints(); + leftGbc.gridx = 0; + leftGbc.gridy = 1; + leftGbc.gridwidth = 1; + leftGbc.weightx = 0.0; + leftGbc.weighty = 0.0; + leftGbc.insets = new Insets(0, 5, 5, 5); + leftGbc.fill = GridBagConstraints.NONE; + leftGbc.anchor = GridBagConstraints.NORTHWEST; + + GridBagConstraints rightGbc = new GridBagConstraints(); + rightGbc.gridx = 1; + rightGbc.gridy = 1; + rightGbc.gridwidth = 1; + rightGbc.weightx = 1.0; + rightGbc.weighty = 0.0; + rightGbc.insets = new Insets(0, 5, 5, 0); + rightGbc.fill = GridBagConstraints.NONE; + rightGbc.anchor = GridBagConstraints.NORTHWEST; + + panMap.add(new JLabel(resourceMap.getString("lblBoardType.text")), leftGbc); + lblBoardType = new JLabel(Scenario.getBoardTypeName(scenario.getBoardType())); + panMap.add(lblBoardType, rightGbc); + + leftGbc.gridy++; + rightGbc.gridy++; + panMap.add(new JLabel(resourceMap.getString("lblMap.text")), leftGbc); + StringBuilder sb = new StringBuilder(); + if(map == null) { + sb.append("None"); + } else { + sb.append(map).append(usingFixedMap ? " (Fixed)" : " (Random)"); + } + lblMap = new JLabel(sb.toString()); + panMap.add(lblMap, rightGbc); + + leftGbc.gridy++; + rightGbc.gridy++; + panMap.add(new JLabel(resourceMap.getString("lblMapSize.text")), leftGbc); + sb = new StringBuilder(); + sb.append(mapSizeX).append(" x ").append(mapSizeY); + lblMapSize = new JLabel(sb.toString()); + panMap.add(lblMapSize, rightGbc); + } + + private void refreshMapSettings() { + lblBoardType.setText(Scenario.getBoardTypeName(scenario.getBoardType())); + StringBuilder sb = new StringBuilder(); + if(map == null) { + sb.append("None"); + } else { + sb.append(map).append(usingFixedMap ? " (Fixed)" : " (Random)"); + } + lblMap.setText(sb.toString()); + sb = new StringBuilder(); + sb.append(mapSizeX).append(" x ").append(mapSizeY); + lblMapSize.setText(sb.toString()); + } + + private void changeMapSettings() { + // TODO: Implement + refreshMapSettings(); + } + private void initObjectivesPanel(ResourceBundle resourceMap) { panObjectives = new JPanel(new BorderLayout()); From ffe11f096041eb61b1e1796535ce334ed60f11e5 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 09:58:23 -0700 Subject: [PATCH 57/76] Improve layout of CustomizeScenarioDialog --- .../gui/dialog/CustomizeScenarioDialog.java | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index f5857963fd..1cf30a308f 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -325,15 +325,15 @@ public Component getListCellRendererComponent(final JList list, final Object // endregion Set up info panel initObjectivesPanel(resourceMap); - //panObjectives.setPreferredSize(new Dimension(300,150)); - //panObjectives.setMinimumSize(new Dimension(300,150)); + panObjectives.setPreferredSize(new Dimension(400,150)); + panObjectives.setMinimumSize(new Dimension(400,150)); panObjectives.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Scenario Objectives"), BorderFactory.createEmptyBorder(5,5,5,5))); initLootPanel(resourceMap); - //panLoot.setPreferredSize(new Dimension(300,150)); - //panLoot.setMinimumSize(new Dimension(300,150)); + panLoot.setPreferredSize(new Dimension(400,150)); + panLoot.setMinimumSize(new Dimension(400,150)); panLoot.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Scenario Costs & Payouts"), BorderFactory.createEmptyBorder(5,5,5,5))); @@ -342,8 +342,8 @@ public Component getListCellRendererComponent(final JList list, final Object panOtherForces.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(0, 0, 10, 0), BorderFactory.createTitledBorder(resourceMap.getString("panOtherForces.title")))); - panOtherForces.setPreferredSize(new Dimension(600,150)); - panOtherForces.setMinimumSize(new Dimension(600,150)); + panOtherForces.setPreferredSize(new Dimension(600,250)); + panOtherForces.setMinimumSize(new Dimension(600,250)); // region Set up writing panel txtDesc = new MarkdownEditorPanel("Description"); @@ -411,30 +411,39 @@ public Component getListCellRendererComponent(final JList list, final Object // layout main panel getContentPane().add(panMain, BorderLayout.CENTER); getContentPane().add(panBtn, BorderLayout.PAGE_END); + + JPanel panNW = new JPanel(new GridBagLayout()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; - gbc.weightx = 1.0; - gbc.weighty = 0.0; gbc.gridheight = 2; gbc.anchor = GridBagConstraints.NORTHWEST; - gbc.fill = GridBagConstraints.BOTH; - panMain.add(panInfo, gbc); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + panNW.add(panInfo, gbc); gbc.gridx = 1; - gbc.gridy = 0; - gbc.weighty = 0.5; gbc.gridheight = 1; - panMain.add(panObjectives, gbc); + gbc.fill = GridBagConstraints.BOTH; + panNW.add(panObjectives, gbc); gbc.gridy = 1; - panMain.add(panLoot, gbc); - gbc.gridx = 2; + panNW.add(panLoot, gbc); + + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.NORTHWEST; + gbc.fill = GridBagConstraints.BOTH; + panMain.add(panNW, gbc); + gbc.gridx = 1; gbc.gridy = 0; - gbc.gridheight = 3; + gbc.gridheight = 2; gbc.weighty = 1.0; panMain.add(panWrite, gbc); gbc.gridx = 0; - gbc.gridy = 2; - gbc.gridwidth = 2; + gbc.gridy = 1; gbc.gridheight = 1; panMain.add(panOtherForces, gbc); From 8f3657f69bb5fe48eb334574b9807a3fa4fc4c01 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 14:08:55 -0700 Subject: [PATCH 58/76] Start EditMapSettingsDialog --- .../gui/dialog/CustomizeScenarioDialog.java | 13 ++- .../gui/dialog/EditMapSettingsDialog.java | 97 +++++++++++++++++++ 2 files changed, 107 insertions(+), 3 deletions(-) create mode 100644 MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 1cf30a308f..f55505c7ba 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -836,7 +836,7 @@ private void initMapPanel(ResourceBundle resourceMap) { rightGbc.anchor = GridBagConstraints.NORTHWEST; panMap.add(new JLabel(resourceMap.getString("lblBoardType.text")), leftGbc); - lblBoardType = new JLabel(Scenario.getBoardTypeName(scenario.getBoardType())); + lblBoardType = new JLabel(Scenario.getBoardTypeName(boardType)); panMap.add(lblBoardType, rightGbc); leftGbc.gridy++; @@ -861,7 +861,7 @@ private void initMapPanel(ResourceBundle resourceMap) { } private void refreshMapSettings() { - lblBoardType.setText(Scenario.getBoardTypeName(scenario.getBoardType())); + lblBoardType.setText(Scenario.getBoardTypeName(boardType)); StringBuilder sb = new StringBuilder(); if(map == null) { sb.append("None"); @@ -875,7 +875,14 @@ private void refreshMapSettings() { } private void changeMapSettings() { - // TODO: Implement + EditMapSettingsDialog emsd = new EditMapSettingsDialog(frame, true, boardType, usingFixedMap, + map, mapSizeX, mapSizeY); + emsd.setVisible(true); + boardType = emsd.getBoardType(); + usingFixedMap = emsd.getUsingFixedMap(); + map = emsd.getMap(); + mapSizeX = emsd.getMapSizeX(); + mapSizeY = emsd.getMapSizeY(); refreshMapSettings(); } diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java new file mode 100644 index 0000000000..bdcd5892af --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -0,0 +1,97 @@ +package mekhq.gui.dialog; + +import mekhq.campaign.mission.Scenario; + +import javax.swing.*; +import java.awt.*; + +public class EditMapSettingsDialog extends JDialog { + + private JFrame frame; + private boolean wasCancelled; + + private int mapSizeX; + private int mapSizeY; + private String map; + private boolean usingFixedMap; + private int boardType; + + private JCheckBox checkFixed; + private JComboBox comboBoardType; + + public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolean usingFixedMap, String map, + int mapSizeX, int mapSizeY) { + + super(parent, modal); + this.boardType = boardType; + this.usingFixedMap = usingFixedMap; + this.map = map; + this.mapSizeX = mapSizeX; + this.mapSizeY = mapSizeY; + wasCancelled = true; + + initComponents(); + setLocationRelativeTo(parent); + pack(); + } + + public int getBoardType() { + return boardType; + } + + public boolean getUsingFixedMap() { + return usingFixedMap; + } + + public String getMap() { + return map; + } + + public int getMapSizeX() { + return mapSizeX; + } + + public int getMapSizeY() { + return mapSizeY; + } + + private void initComponents() { + + getContentPane().setLayout(new BorderLayout()); + JPanel panMain = new JPanel(new GridLayout(2, 0)); + JPanel panButtons = new JPanel(new GridLayout(0, 2)); + + checkFixed = new JCheckBox("Use fixed map"); + checkFixed.setSelected(usingFixedMap); + + comboBoardType = new JComboBox(); + for (int i = Scenario.T_GROUND; i <= Scenario.T_SPACE; i++) { + comboBoardType.addItem(Scenario.getBoardTypeName(i)); + } + comboBoardType.setSelectedIndex(boardType); + + panMain.add(checkFixed); + panMain.add(comboBoardType); + + JButton btnOK = new JButton("Done"); + btnOK.addActionListener(evt -> done()); + JButton btnCancel = new JButton("Cancel"); + btnCancel.addActionListener(evt -> cancel()); + panButtons.add(btnOK); + panButtons.add(btnCancel); + + getContentPane().add(panMain, BorderLayout.CENTER); + getContentPane().add(panButtons, BorderLayout.PAGE_END); + } + + public void done() { + boardType = comboBoardType.getSelectedIndex(); + usingFixedMap = checkFixed.isSelected(); + setVisible(false); + } + + public void cancel() { + setVisible(false); + } + +} From c7d9d4a1c7eb951c65e55913217f72cd2c5af824 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 20:49:34 -0700 Subject: [PATCH 59/76] Add spinners for map size to EditMapSettingsDialog --- .../gui/dialog/EditMapSettingsDialog.java | 55 ++++++++++++++++++- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index bdcd5892af..055013b528 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -18,6 +18,10 @@ public class EditMapSettingsDialog extends JDialog { private JCheckBox checkFixed; private JComboBox comboBoardType; + private JSpinner spnMapX; + private JSpinner spnMapY; + + JPanel panSizeRandom; public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolean usingFixedMap, String map, int mapSizeX, int mapSizeY) { @@ -58,7 +62,8 @@ public int getMapSizeY() { private void initComponents() { getContentPane().setLayout(new BorderLayout()); - JPanel panMain = new JPanel(new GridLayout(2, 0)); + JPanel panMain = new JPanel(new GridBagLayout()); + panSizeRandom = new JPanel(new GridBagLayout()); JPanel panButtons = new JPanel(new GridLayout(0, 2)); checkFixed = new JCheckBox("Use fixed map"); @@ -70,8 +75,46 @@ private void initComponents() { } comboBoardType.setSelectedIndex(boardType); - panMain.add(checkFixed); - panMain.add(comboBoardType); + spnMapX = new JSpinner(new SpinnerNumberModel(mapSizeX, 0, null, 1)); + spnMapY = new JSpinner(new SpinnerNumberModel(mapSizeY, 0, null, 1)); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 5, 5, 5); + panSizeRandom.add(spnMapX, gbc); + gbc.gridx++; + panSizeRandom.add(new JLabel("x")); + gbc.gridx++; + gbc.weightx = 1.0; + panSizeRandom.add(spnMapY); + + gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 0.0; + gbc.weighty = 0.0; + gbc.anchor = GridBagConstraints.WEST; + gbc.fill = GridBagConstraints.NONE; + gbc.insets = new Insets(5, 5, 5, 5); + panMain.add(new JLabel("Board Type:")); + gbc.weightx = 1.0; + gbc.gridx++; + panMain.add(comboBoardType, gbc); + + gbc.gridx = 0; + gbc.gridy++; + panMain.add(new JLabel("Map Size:"), gbc); + gbc.gridx++; + panMain.add(panSizeRandom, gbc); + + gbc.gridwidth = 2; + gbc.gridx = 0; + gbc.gridy++; + panMain.add(checkFixed, gbc); JButton btnOK = new JButton("Done"); btnOK.addActionListener(evt -> done()); @@ -87,6 +130,12 @@ private void initComponents() { public void done() { boardType = comboBoardType.getSelectedIndex(); usingFixedMap = checkFixed.isSelected(); + if(usingFixedMap) { + + } else { + mapSizeX = (int) spnMapX.getValue(); + mapSizeY = (int) spnMapY.getValue(); + } setVisible(false); } From 8ede68ab222116b631b89c7719b1cf03978ad49c Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 21:17:42 -0700 Subject: [PATCH 60/76] Add list of mapgen options to EditMapSettingsDialog --- .../gui/dialog/EditMapSettingsDialog.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 055013b528..bfe3c511e1 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -4,6 +4,7 @@ import javax.swing.*; import java.awt.*; +import java.io.File; public class EditMapSettingsDialog extends JDialog { @@ -20,6 +21,9 @@ public class EditMapSettingsDialog extends JDialog { private JComboBox comboBoardType; private JSpinner spnMapX; private JSpinner spnMapY; + private JScrollPane scrChooseMap; + private JList listMapGenerators; + DefaultListModel generatorModel = new DefaultListModel<>(); JPanel panSizeRandom; @@ -66,6 +70,8 @@ private void initComponents() { panSizeRandom = new JPanel(new GridBagLayout()); JPanel panButtons = new JPanel(new GridLayout(0, 2)); + scrChooseMap = new JScrollPane(); + checkFixed = new JCheckBox("Use fixed map"); checkFixed.setSelected(usingFixedMap); @@ -92,7 +98,23 @@ private void initComponents() { gbc.weightx = 1.0; panSizeRandom.add(spnMapY); - gbc = new GridBagConstraints(); + listMapGenerators = new JList<>(generatorModel); + listMapGenerators.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + generatorModel.addElement("None"); + File dir = new File("data/mapgen/"); + File[] directoryListing = dir.listFiles(); + if (directoryListing != null) { + for (File child : directoryListing) { + if(child.isFile()) { + String s = child.getName().replace(".xml", ""); + generatorModel.addElement(s); + } + } + } + scrChooseMap.setViewportView(listMapGenerators); + listMapGenerators.setSelectedValue(map, true); + + gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.0; @@ -107,8 +129,10 @@ private void initComponents() { gbc.gridx = 0; gbc.gridy++; + gbc.weightx = 0.0; panMain.add(new JLabel("Map Size:"), gbc); gbc.gridx++; + gbc.weightx = 1.0; panMain.add(panSizeRandom, gbc); gbc.gridwidth = 2; @@ -116,6 +140,11 @@ private void initComponents() { gbc.gridy++; panMain.add(checkFixed, gbc); + gbc.gridy++; + gbc.fill = GridBagConstraints.BOTH; + gbc.weighty = 1.0; + panMain.add(scrChooseMap, gbc); + JButton btnOK = new JButton("Done"); btnOK.addActionListener(evt -> done()); JButton btnCancel = new JButton("Cancel"); @@ -133,6 +162,10 @@ public void done() { if(usingFixedMap) { } else { + map = listMapGenerators.getSelectedValue(); + if(listMapGenerators.getSelectedIndex() == 0) { + map = null; + } mapSizeX = (int) spnMapX.getValue(); mapSizeY = (int) spnMapY.getValue(); } From 5a79a7a0dbdedac1d1a36f0ac5292f61edbd5c6f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 21:20:49 -0700 Subject: [PATCH 61/76] remove old variable --- MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index bfe3c511e1..5a80687875 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -9,8 +9,6 @@ public class EditMapSettingsDialog extends JDialog { private JFrame frame; - private boolean wasCancelled; - private int mapSizeX; private int mapSizeY; private String map; @@ -36,7 +34,6 @@ public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolea this.map = map; this.mapSizeX = mapSizeX; this.mapSizeY = mapSizeY; - wasCancelled = true; initComponents(); setLocationRelativeTo(parent); From 1d13af2de5985e72ab4408129b3b9c6bafdf383b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sat, 4 May 2024 23:35:19 -0700 Subject: [PATCH 62/76] Add action listeners to EditMapSettingsDialog --- .../gui/dialog/EditMapSettingsDialog.java | 117 ++++++++++++++++-- 1 file changed, 110 insertions(+), 7 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 5a80687875..2d0500891c 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -1,10 +1,17 @@ package mekhq.gui.dialog; +import megamek.common.Board; +import megamek.common.BoardDimensions; +import megamek.common.Configuration; +import megamek.server.GameManager; import mekhq.campaign.mission.Scenario; +import org.apache.logging.log4j.LogManager; import javax.swing.*; import java.awt.*; import java.io.File; +import java.util.Set; +import java.util.TreeSet; public class EditMapSettingsDialog extends JDialog { @@ -17,6 +24,7 @@ public class EditMapSettingsDialog extends JDialog { private JCheckBox checkFixed; private JComboBox comboBoardType; + private JComboBox comboMapSize; private JSpinner spnMapX; private JSpinner spnMapY; private JScrollPane scrChooseMap; @@ -24,6 +32,7 @@ public class EditMapSettingsDialog extends JDialog { DefaultListModel generatorModel = new DefaultListModel<>(); JPanel panSizeRandom; + JPanel panSizeFixed; public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolean usingFixedMap, String map, int mapSizeX, int mapSizeY) { @@ -65,18 +74,14 @@ private void initComponents() { getContentPane().setLayout(new BorderLayout()); JPanel panMain = new JPanel(new GridBagLayout()); panSizeRandom = new JPanel(new GridBagLayout()); + panSizeFixed = new JPanel(new BorderLayout()); JPanel panButtons = new JPanel(new GridLayout(0, 2)); scrChooseMap = new JScrollPane(); checkFixed = new JCheckBox("Use fixed map"); checkFixed.setSelected(usingFixedMap); - - comboBoardType = new JComboBox(); - for (int i = Scenario.T_GROUND; i <= Scenario.T_SPACE; i++) { - comboBoardType.addItem(Scenario.getBoardTypeName(i)); - } - comboBoardType.setSelectedIndex(boardType); + checkFixed.addActionListener(evt -> changeMapType()); spnMapX = new JSpinner(new SpinnerNumberModel(mapSizeX, 0, null, 1)); spnMapY = new JSpinner(new SpinnerNumberModel(mapSizeY, 0, null, 1)); @@ -95,6 +100,13 @@ private void initComponents() { gbc.weightx = 1.0; panSizeRandom.add(spnMapY); + comboMapSize = new JComboBox<>(); + for (BoardDimensions size : getBoardSizes()) { + comboMapSize.addItem(size); + } + panSizeFixed.add(comboMapSize, BorderLayout.CENTER); + + listMapGenerators = new JList<>(generatorModel); listMapGenerators.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); generatorModel.addElement("None"); @@ -111,6 +123,13 @@ private void initComponents() { scrChooseMap.setViewportView(listMapGenerators); listMapGenerators.setSelectedValue(map, true); + comboBoardType = new JComboBox(); + for (int i = Scenario.T_GROUND; i <= Scenario.T_SPACE; i++) { + comboBoardType.addItem(Scenario.getBoardTypeName(i)); + } + comboBoardType.addActionListener(evt -> changeBoardType()); + comboBoardType.setSelectedIndex(boardType); + gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; @@ -119,7 +138,7 @@ private void initComponents() { gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(5, 5, 5, 5); - panMain.add(new JLabel("Board Type:")); + panMain.add(new JLabel("Board Type:"), gbc); gbc.weightx = 1.0; gbc.gridx++; panMain.add(comboBoardType, gbc); @@ -131,6 +150,12 @@ private void initComponents() { gbc.gridx++; gbc.weightx = 1.0; panMain.add(panSizeRandom, gbc); + panMain.add(panSizeFixed, gbc); + if(usingFixedMap) { + panSizeRandom.setVisible(false); + } else { + panSizeFixed.setVisible(false); + } gbc.gridwidth = 2; gbc.gridx = 0; @@ -153,6 +178,84 @@ private void initComponents() { getContentPane().add(panButtons, BorderLayout.PAGE_END); } + private void changeBoardType() { + if(comboBoardType.getSelectedIndex() == Scenario.T_SPACE) { + checkFixed.setSelected(false); + checkFixed.setEnabled(false); + panSizeRandom.setVisible(true); + panSizeFixed.setVisible(false); + listMapGenerators.setSelectedIndex(0); + listMapGenerators.setEnabled(false); + } else { + checkFixed.setEnabled(true); + listMapGenerators.setEnabled(true); + } + } + + private void changeMapType() { + if(checkFixed.isSelected()) { + panSizeRandom.setVisible(false); + panSizeFixed.setVisible(true); + } else { + panSizeRandom.setVisible(true); + panSizeFixed.setVisible(false); + } + } + + private Set getBoardSizes() { + TreeSet board_sizes = new TreeSet<>(); + + File boards_dir = Configuration.boardsDir(); + // Slightly overkill sanity check... + if (boards_dir.isDirectory()) { + getBoardSizesInDir(boards_dir, board_sizes); + } + + return board_sizes; + } + + /** + * Recursively scan the specified path to determine the board sizes + * available. + * + * @param searchDir The directory to search below this path (may be null for all + * in base path). + * @param sizes Where to store the discovered board sizes + */ + private void getBoardSizesInDir(final File searchDir, TreeSet sizes) { + if (searchDir == null) { + throw new IllegalArgumentException("must provide searchDir"); + } + + if (sizes == null) { + throw new IllegalArgumentException("must provide sizes"); + } + + String[] file_list = searchDir.list(); + + if (file_list != null) { + for (String filename : file_list) { + File query_file = new File(searchDir, filename); + + if (query_file.isDirectory()) { + getBoardSizesInDir(query_file, sizes); + } else { + try { + if (filename.endsWith(".board")) { + BoardDimensions size = Board.getSize(query_file); + if (size == null) { + throw new Exception(); + } + sizes.add(Board.getSize(query_file)); + } + } catch (Exception e) { + LogManager.getLogger().error("Error parsing board: " + query_file.getAbsolutePath(), e); + } + } + } + } + } + public void done() { boardType = comboBoardType.getSelectedIndex(); usingFixedMap = checkFixed.isSelected(); From e1a58cd5000dd7c20d778f09811411dfdb2ab9d5 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sun, 5 May 2024 11:32:35 -0700 Subject: [PATCH 63/76] Add fixed map selector to EditMapSettingsDialog --- .../gui/dialog/EditMapSettingsDialog.java | 100 +++++++++++++++++- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 2d0500891c..92db812d92 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -3,6 +3,8 @@ import megamek.common.Board; import megamek.common.BoardDimensions; import megamek.common.Configuration; +import megamek.common.MapSettings; +import megamek.common.util.fileUtils.MegaMekFile; import megamek.server.GameManager; import mekhq.campaign.mission.Scenario; import org.apache.logging.log4j.LogManager; @@ -10,8 +12,11 @@ import javax.swing.*; import java.awt.*; import java.io.File; +import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.TreeSet; +import java.util.stream.Collectors; public class EditMapSettingsDialog extends JDialog { @@ -24,12 +29,14 @@ public class EditMapSettingsDialog extends JDialog { private JCheckBox checkFixed; private JComboBox comboBoardType; - private JComboBox comboMapSize; + private JComboBox comboMapSize; private JSpinner spnMapX; private JSpinner spnMapY; private JScrollPane scrChooseMap; private JList listMapGenerators; + private JList listFixedMaps; DefaultListModel generatorModel = new DefaultListModel<>(); + DefaultListModel fixedMapModel = new DefaultListModel<>(); JPanel panSizeRandom; JPanel panSizeFixed; @@ -104,9 +111,15 @@ private void initComponents() { for (BoardDimensions size : getBoardSizes()) { comboMapSize.addItem(size); } + if(mapSizeX > 0 & mapSizeY > 0) { + comboMapSize.setSelectedItem(new BoardDimensions(mapSizeX, mapSizeY)); + } else { + // if no board size yet set, use the default + comboMapSize.setSelectedItem(new BoardDimensions(16, 17)); + } + comboMapSize.addActionListener(evt -> refreshBoardList()); panSizeFixed.add(comboMapSize, BorderLayout.CENTER); - listMapGenerators = new JList<>(generatorModel); listMapGenerators.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); generatorModel.addElement("None"); @@ -120,8 +133,18 @@ private void initComponents() { } } } - scrChooseMap.setViewportView(listMapGenerators); - listMapGenerators.setSelectedValue(map, true); + if(!usingFixedMap) { + listMapGenerators.setSelectedValue(map, true); + scrChooseMap.setViewportView(listMapGenerators); + } + + listFixedMaps = new JList<>(fixedMapModel); + listFixedMaps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + refreshBoardList(); + if(usingFixedMap) { + listFixedMaps.setSelectedValue(map, true); + scrChooseMap.setViewportView(listFixedMaps); + } comboBoardType = new JComboBox(); for (int i = Scenario.T_GROUND; i <= Scenario.T_SPACE; i++) { @@ -186,9 +209,11 @@ private void changeBoardType() { panSizeFixed.setVisible(false); listMapGenerators.setSelectedIndex(0); listMapGenerators.setEnabled(false); + listFixedMaps.setEnabled(false); } else { checkFixed.setEnabled(true); listMapGenerators.setEnabled(true); + listFixedMaps.setEnabled(true); } } @@ -196,12 +221,20 @@ private void changeMapType() { if(checkFixed.isSelected()) { panSizeRandom.setVisible(false); panSizeFixed.setVisible(true); + scrChooseMap.setViewportView(listFixedMaps); } else { panSizeRandom.setVisible(true); panSizeFixed.setVisible(false); + scrChooseMap.setViewportView(listMapGenerators); } } + private void refreshBoardList() { + List boards = scanForBoards(); + fixedMapModel.removeAllElements(); + fixedMapModel.addAll(boards); + } + private Set getBoardSizes() { TreeSet board_sizes = new TreeSet<>(); @@ -256,11 +289,68 @@ private void getBoardSizesInDir(final File searchDir, TreeSet s } } + /** + * Returns a list of path names of available boards of the size set in the given + * mapSettings. The path names are minus the '.board' extension and relative to + * the boards data directory. + */ + private List scanForBoards() { + BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); + java.util.List result = new ArrayList<>(); + + // Scan the Megamek boards directory + File boardDir = Configuration.boardsDir(); + scanForBoardsInDir(boardDir, "", boardSize, result); + + result.sort(String::compareTo); + return result.stream().map(this::backToForwardSlash).collect(Collectors.toList()); + } + + private String backToForwardSlash(String path) { + return path.replace("\\", "/"); + } + + /** + * Scans the given boardDir directory for map boards of the given size and + * returns them by adding them to the given boards list. Removes the .board extension. + */ + private void scanForBoardsInDir(final File boardDir, final String basePath, final BoardDimensions dimensions, + List boards) { + if (boardDir == null) { + throw new IllegalArgumentException("must provide searchDir"); + } else if (basePath == null) { + throw new IllegalArgumentException("must provide basePath"); + } else if (dimensions == null) { + throw new IllegalArgumentException("must provide dimensions"); + } else if (boards == null) { + throw new IllegalArgumentException("must provide boards"); + } + + String[] fileList = boardDir.list(); + if (fileList != null) { + for (String filename : fileList) { + File filePath = new MegaMekFile(boardDir, filename).getFile(); + if (filePath.isDirectory()) { + scanForBoardsInDir(filePath, basePath + File.separator + filename, dimensions, boards); + } else { + if (filename.endsWith(".board")) { + if (Board.boardIsSize(filePath, dimensions)) { + boards.add(basePath + File.separator + filename.substring(0, filename.lastIndexOf("."))); + } + } + } + } + } + } + public void done() { boardType = comboBoardType.getSelectedIndex(); usingFixedMap = checkFixed.isSelected(); if(usingFixedMap) { - + map = listFixedMaps.getSelectedValue(); + BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); + mapSizeX = boardSize.width(); + mapSizeY = boardSize.height(); } else { map = listMapGenerators.getSelectedValue(); if(listMapGenerators.getSelectedIndex() == 0) { From 169f99fb23c3236914e30d5cdd390e5cf43a7a9d Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Sun, 5 May 2024 11:39:27 -0700 Subject: [PATCH 64/76] Sort random map generators alphabetically in EditMapSettingsDialog --- .../mekhq/gui/dialog/EditMapSettingsDialog.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 92db812d92..f50448c6da 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -12,10 +12,8 @@ import javax.swing.*; import java.awt.*; import java.io.File; -import java.util.ArrayList; +import java.util.*; import java.util.List; -import java.util.Set; -import java.util.TreeSet; import java.util.stream.Collectors; public class EditMapSettingsDialog extends JDialog { @@ -125,25 +123,28 @@ private void initComponents() { generatorModel.addElement("None"); File dir = new File("data/mapgen/"); File[] directoryListing = dir.listFiles(); + ArrayList generators = new ArrayList<>(); if (directoryListing != null) { for (File child : directoryListing) { if(child.isFile()) { String s = child.getName().replace(".xml", ""); - generatorModel.addElement(s); + generators.add(s); } } } - if(!usingFixedMap) { - listMapGenerators.setSelectedValue(map, true); - scrChooseMap.setViewportView(listMapGenerators); - } + Collections.sort(generators); + generatorModel.addAll(generators); listFixedMaps = new JList<>(fixedMapModel); listFixedMaps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); refreshBoardList(); + if(usingFixedMap) { listFixedMaps.setSelectedValue(map, true); scrChooseMap.setViewportView(listFixedMaps); + } else { + listMapGenerators.setSelectedValue(map, true); + scrChooseMap.setViewportView(listMapGenerators); } comboBoardType = new JComboBox(); From 45d3e6799bec31fca369fa63eee9ee652227201f Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 11:00:04 -0700 Subject: [PATCH 65/76] Add map thumbnail to fixed map list selection --- .../gui/dialog/EditMapSettingsDialog.java | 233 ++++++++++++++++-- 1 file changed, 215 insertions(+), 18 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index f50448c6da..f05439cf56 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -1,5 +1,8 @@ package mekhq.gui.dialog; +import megamek.client.ui.swing.lobby.ChatLounge; +import megamek.client.ui.swing.lobby.LobbyUtility; +import megamek.client.ui.swing.minimap.Minimap; import megamek.common.Board; import megamek.common.BoardDimensions; import megamek.common.Configuration; @@ -11,11 +14,24 @@ import javax.swing.*; import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageProducer; import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.util.*; import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import static megamek.client.ui.swing.lobby.LobbyUtility.drawMinimapLabel; +import static megamek.client.ui.swing.util.UIUtil.scaleStringForGUI; + public class EditMapSettingsDialog extends JDialog { private JFrame frame; @@ -39,6 +55,12 @@ public class EditMapSettingsDialog extends JDialog { JPanel panSizeRandom; JPanel panSizeFixed; + private Map mapIcons = new HashMap<>(); + private Map baseImages = new HashMap<>(); + + private ImageLoader loader; + + public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolean usingFixedMap, String map, int mapSizeX, int mapSizeY) { @@ -48,6 +70,8 @@ public EditMapSettingsDialog(JFrame parent, boolean modal, int boardType, boolea this.map = map; this.mapSizeX = mapSizeX; this.mapSizeY = mapSizeY; + loader = new ImageLoader(); + loader.execute(); initComponents(); setLocationRelativeTo(parent); @@ -83,6 +107,9 @@ private void initComponents() { JPanel panButtons = new JPanel(new GridLayout(0, 2)); scrChooseMap = new JScrollPane(); + scrChooseMap.setMinimumSize(new Dimension(600, 800)); + scrChooseMap.setPreferredSize(new Dimension(600, 800)); + checkFixed = new JCheckBox("Use fixed map"); checkFixed.setSelected(usingFixedMap); @@ -136,6 +163,9 @@ private void initComponents() { generatorModel.addAll(generators); listFixedMaps = new JList<>(fixedMapModel); + listFixedMaps.setCellRenderer(new BoardNameRenderer()); + listFixedMaps.setLayoutOrientation(JList.HORIZONTAL_WRAP); + listFixedMaps.setVisibleRowCount(-1); listFixedMaps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); refreshBoardList(); @@ -231,9 +261,12 @@ private void changeMapType() { } private void refreshBoardList() { + listFixedMaps.setFixedCellHeight(-1); + listFixedMaps.setFixedCellWidth(-1); List boards = scanForBoards(); fixedMapModel.removeAllElements(); fixedMapModel.addAll(boards); + listFixedMaps.clearSelection(); } private Set getBoardSizes() { @@ -248,6 +281,30 @@ private Set getBoardSizes() { return board_sizes; } + public void done() { + boardType = comboBoardType.getSelectedIndex(); + usingFixedMap = checkFixed.isSelected(); + if(usingFixedMap) { + map = listFixedMaps.getSelectedValue(); + BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); + mapSizeX = boardSize.width(); + mapSizeY = boardSize.height(); + } else { + map = listMapGenerators.getSelectedValue(); + if(listMapGenerators.getSelectedIndex() == 0) { + map = null; + } + mapSizeX = (int) spnMapX.getValue(); + mapSizeY = (int) spnMapY.getValue(); + } + setVisible(false); + } + + public void cancel() { + setVisible(false); + } + + /** * Recursively scan the specified path to determine the board sizes * available. @@ -344,27 +401,167 @@ private void scanForBoardsInDir(final File boardDir, final String basePath, fina } } - public void done() { - boardType = comboBoardType.getSelectedIndex(); - usingFixedMap = checkFixed.isSelected(); - if(usingFixedMap) { - map = listFixedMaps.getSelectedValue(); - BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); - mapSizeX = boardSize.width(); - mapSizeY = boardSize.height(); - } else { - map = listMapGenerators.getSelectedValue(); - if(listMapGenerators.getSelectedIndex() == 0) { - map = null; + private class BoardNameRenderer extends DefaultListCellRenderer { + + private Image image; + private ImageIcon icon; + + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean isSelected, boolean cellHasFocus) { + + String board = (String) value; + // For generated boards, add the size to have different images for different sizes + //if (board.startsWith(MapSettings.BOARD_GENERATED)) { + // board += comboMapSize.getSelectedItem(); + //} + + // If an icon is present for the current board, use it + icon = mapIcons.get(board); + if (icon != null) { + setIcon(icon); + } else { + // The icon is not present, see if there's a base image + synchronized (baseImages) { + image = baseImages.get(board); + } + if (image == null) { + // There's no base image: trigger loading it and, for now, return the base list's panel + // The [GENERATED] entry will always land here as well + loader.add(board); + setToolTipText(null); + return super.getListCellRendererComponent(list, new File(board).getName(), index, isSelected, cellHasFocus); + } else { + // There is a base image: make it into an icon, store it and use it + //if (!listFixedMaps.isEnabled()) { + // ImageFilter filter = new GrayFilter(true, 50); + // ImageProducer producer = new FilteredImageSource(image.getSource(), filter); + // image = Toolkit.getDefaultToolkit().createImage(producer); + //} + icon = new ImageIcon(image); + + mapIcons.put(board, icon); + setIcon(icon); + } } - mapSizeX = (int) spnMapX.getValue(); - mapSizeY = (int) spnMapY.getValue(); + + // Found or created an icon; finish the panel + setText(""); + if (listFixedMaps.isEnabled()) { + //setToolTipText(scaleStringForGUI(createBoardTooltip(board))); + } else { + setToolTipText(null); + } + + if (isSelected) { + setForeground(list.getSelectionForeground()); + setBackground(list.getSelectionBackground()); + } else { + setForeground(list.getForeground()); + setBackground(list.getBackground()); + } + + return this; } - setVisible(false); } - public void cancel() { - setVisible(false); - } + private class ImageLoader extends SwingWorker { + + private BlockingQueue boards = new LinkedBlockingQueue<>(); + + private synchronized void add(String name) { + if (!boards.contains(name)) { + try { + boards.put(name); + } catch (Exception e) { + LogManager.getLogger().error("", e); + } + } + } + + private Image prepareImage(String boardName) { + MapSettings mapSettings = MapSettings.getInstance(); + BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); + mapSettings.setBoardSize(boardSize.width(), boardSize.height()); + File boardFile = new MegaMekFile(Configuration.boardsDir(), boardName + ".board").getFile(); + Board board; + StringBuffer errs = new StringBuffer(); + if (boardFile.exists()) { + board = new Board(); + try (InputStream is = new FileInputStream(boardFile)) { + board.load(is, errs, true); + } catch (IOException ex) { + board = Board.createEmptyBoard(mapSettings.getBoardWidth(), mapSettings.getBoardHeight()); + } + } else { + board = Board.createEmptyBoard(mapSettings.getBoardWidth(), mapSettings.getBoardHeight()); + } + // Determine a minimap zoom from the board size and gui scale. + // This is very magic numbers but currently the minimap has only fixed zoom states. + int largerEdge = Math.max(board.getWidth(), board.getHeight()); + int zoom = 3; + if (largerEdge < 17) { + zoom = 4; + } + if (largerEdge > 20) { + zoom = 2; + } + if (largerEdge > 30) { + zoom = 1; + } + if (largerEdge > 40) { + zoom = 0; + } + if (board.getWidth() < 25) { + zoom = Math.max(zoom, 3); + } + float scale = 1; + zoom = (int) (scale*zoom); + if (zoom > 6) { + zoom = 6; + } + if (zoom < 0) { + zoom = 0; + } + BufferedImage bufImage = Minimap.getMinimapImage(board, zoom); + + // Add the board name label and the server-side board label if necessary + String text = LobbyUtility.cleanBoardName(boardName, mapSettings); + Graphics g = bufImage.getGraphics(); + LobbyUtility.drawMinimapLabel(text, bufImage.getWidth(), bufImage.getHeight(), g, errs.length() != 0); + g.dispose(); + + synchronized(baseImages) { + baseImages.put(boardName, bufImage); + } + return bufImage; + } + + + @Override + protected Void doInBackground() throws Exception { + Image image; + while (!isCancelled()) { + // Create thumbnails for the MapSettings boards + String boardName = boards.poll(1, TimeUnit.SECONDS); + if (boardName != null && !baseImages.containsKey(boardName)) { + image = prepareImage(boardName); + redrawMapTable(image); + } + } + return null; + } + + private void redrawMapTable(Image image) { + if (image != null) { + if (listFixedMaps.getFixedCellHeight() != image.getHeight(null) + || listFixedMaps.getFixedCellWidth() != image.getWidth(null)) { + listFixedMaps.setFixedCellHeight(image.getHeight(null)); + listFixedMaps.setFixedCellWidth(image.getWidth(null)); + } + listFixedMaps.repaint(); + } + } + } } From 7db838d7fd2d8be7bf94efb8b6632959ab4c98be Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 11:09:44 -0700 Subject: [PATCH 66/76] Use static methods from MM to get available board sizes rather than new methods --- .../gui/dialog/EditMapSettingsDialog.java | 57 +------------------ 1 file changed, 1 insertion(+), 56 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index f05439cf56..84b9fae617 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -133,7 +133,7 @@ private void initComponents() { panSizeRandom.add(spnMapY); comboMapSize = new JComboBox<>(); - for (BoardDimensions size : getBoardSizes()) { + for (BoardDimensions size : GameManager.getBoardSizes()) { comboMapSize.addItem(size); } if(mapSizeX > 0 & mapSizeY > 0) { @@ -269,18 +269,6 @@ private void refreshBoardList() { listFixedMaps.clearSelection(); } - private Set getBoardSizes() { - TreeSet board_sizes = new TreeSet<>(); - - File boards_dir = Configuration.boardsDir(); - // Slightly overkill sanity check... - if (boards_dir.isDirectory()) { - getBoardSizesInDir(boards_dir, board_sizes); - } - - return board_sizes; - } - public void done() { boardType = comboBoardType.getSelectedIndex(); usingFixedMap = checkFixed.isSelected(); @@ -304,49 +292,6 @@ public void cancel() { setVisible(false); } - - /** - * Recursively scan the specified path to determine the board sizes - * available. - * - * @param searchDir The directory to search below this path (may be null for all - * in base path). - * @param sizes Where to store the discovered board sizes - */ - private void getBoardSizesInDir(final File searchDir, TreeSet sizes) { - if (searchDir == null) { - throw new IllegalArgumentException("must provide searchDir"); - } - - if (sizes == null) { - throw new IllegalArgumentException("must provide sizes"); - } - - String[] file_list = searchDir.list(); - - if (file_list != null) { - for (String filename : file_list) { - File query_file = new File(searchDir, filename); - - if (query_file.isDirectory()) { - getBoardSizesInDir(query_file, sizes); - } else { - try { - if (filename.endsWith(".board")) { - BoardDimensions size = Board.getSize(query_file); - if (size == null) { - throw new Exception(); - } - sizes.add(Board.getSize(query_file)); - } - } catch (Exception e) { - LogManager.getLogger().error("Error parsing board: " + query_file.getAbsolutePath(), e); - } - } - } - } - } - /** * Returns a list of path names of available boards of the size set in the given * mapSettings. The path names are minus the '.board' extension and relative to From 301ee2e5735b65c00899bf6231e81efb83d92fd9 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 11:17:41 -0700 Subject: [PATCH 67/76] Remove new methods for scanning boards, use MM methods instead --- .../gui/dialog/EditMapSettingsDialog.java | 59 ++----------------- 1 file changed, 6 insertions(+), 53 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 84b9fae617..1b5a18f685 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -9,6 +9,7 @@ import megamek.common.MapSettings; import megamek.common.util.fileUtils.MegaMekFile; import megamek.server.GameManager; +import megamek.server.ServerBoardHelper; import mekhq.campaign.mission.Scenario; import org.apache.logging.log4j.LogManager; @@ -263,7 +264,10 @@ private void changeMapType() { private void refreshBoardList() { listFixedMaps.setFixedCellHeight(-1); listFixedMaps.setFixedCellWidth(-1); - List boards = scanForBoards(); + MapSettings mapSettings = MapSettings.getInstance(); + BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); + mapSettings.setBoardSize(boardSize.width(), boardSize.height()); + List boards = ServerBoardHelper.scanForBoards(mapSettings); fixedMapModel.removeAllElements(); fixedMapModel.addAll(boards); listFixedMaps.clearSelection(); @@ -293,59 +297,8 @@ public void cancel() { } /** - * Returns a list of path names of available boards of the size set in the given - * mapSettings. The path names are minus the '.board' extension and relative to - * the boards data directory. - */ - private List scanForBoards() { - BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); - java.util.List result = new ArrayList<>(); - - // Scan the Megamek boards directory - File boardDir = Configuration.boardsDir(); - scanForBoardsInDir(boardDir, "", boardSize, result); - - result.sort(String::compareTo); - return result.stream().map(this::backToForwardSlash).collect(Collectors.toList()); - } - - private String backToForwardSlash(String path) { - return path.replace("\\", "/"); - } - - /** - * Scans the given boardDir directory for map boards of the given size and - * returns them by adding them to the given boards list. Removes the .board extension. + * A modified version of the thumbnail board rendered from Megamek.ChatLounge */ - private void scanForBoardsInDir(final File boardDir, final String basePath, final BoardDimensions dimensions, - List boards) { - if (boardDir == null) { - throw new IllegalArgumentException("must provide searchDir"); - } else if (basePath == null) { - throw new IllegalArgumentException("must provide basePath"); - } else if (dimensions == null) { - throw new IllegalArgumentException("must provide dimensions"); - } else if (boards == null) { - throw new IllegalArgumentException("must provide boards"); - } - - String[] fileList = boardDir.list(); - if (fileList != null) { - for (String filename : fileList) { - File filePath = new MegaMekFile(boardDir, filename).getFile(); - if (filePath.isDirectory()) { - scanForBoardsInDir(filePath, basePath + File.separator + filename, dimensions, boards); - } else { - if (filename.endsWith(".board")) { - if (Board.boardIsSize(filePath, dimensions)) { - boards.add(basePath + File.separator + filename.substring(0, filename.lastIndexOf("."))); - } - } - } - } - } - } - private class BoardNameRenderer extends DefaultListCellRenderer { private Image image; From e6b70547e66a6348f5766720f3b533d065a91485 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 11:35:51 -0700 Subject: [PATCH 68/76] Add missing copyright information --- .../CustomizeScenarioObjectiveDialog.java | 18 ++++++++++++++++++ .../gui/dialog/EditMapSettingsDialog.java | 18 ++++++++++++++++++ .../mekhq/gui/model/ObjectiveTableModel.java | 18 ++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 9edffa57db..76e6a62246 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ package mekhq.gui.dialog; import megamek.client.ui.baseComponents.MMComboBox; diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 1b5a18f685..99c210c52c 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ package mekhq.gui.dialog; import megamek.client.ui.swing.lobby.ChatLounge; diff --git a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java index dcefefb790..4cb352b3ae 100644 --- a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java +++ b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java @@ -1,3 +1,21 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ package mekhq.gui.model; import megamek.common.Entity; From 2ba23840ba0a52b385666866beba1e01aed2f9be Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 12:34:50 -0700 Subject: [PATCH 69/76] Make minor coding changes as requested by IDE --- MekHQ/src/mekhq/Utilities.java | 3 +- .../src/mekhq/campaign/mission/BotForce.java | 2 +- .../campaign/mission/BotForceRandomizer.java | 4 +- .../campaign/mission/IPlayerSettings.java | 30 ++++---- .../src/mekhq/campaign/mission/Scenario.java | 27 ------- .../mission/ScenarioDeploymentLimit.java | 4 +- .../gui/dialog/CustomizeBotForceDialog.java | 58 +++++++-------- .../gui/dialog/CustomizeScenarioDialog.java | 60 +++++---------- .../CustomizeScenarioObjectiveDialog.java | 73 ++++++++++--------- .../gui/dialog/EditDeploymentDialog.java | 17 +---- .../gui/dialog/EditMapSettingsDialog.java | 29 +++----- .../EditScenarioDeploymentLimitDialog.java | 42 +++++------ .../mekhq/gui/model/BotForceTableModel.java | 9 +-- .../mekhq/gui/model/ObjectiveTableModel.java | 30 ++++---- 14 files changed, 156 insertions(+), 232 deletions(-) diff --git a/MekHQ/src/mekhq/Utilities.java b/MekHQ/src/mekhq/Utilities.java index 396ee08a3c..866a797719 100644 --- a/MekHQ/src/mekhq/Utilities.java +++ b/MekHQ/src/mekhq/Utilities.java @@ -21,7 +21,6 @@ import megamek.client.Client; import megamek.client.generator.RandomNameGenerator; -import megamek.client.ui.swing.util.UIUtil; import megamek.codeUtilities.ObjectUtility; import megamek.codeUtilities.StringUtility; import megamek.common.*; @@ -1359,7 +1358,7 @@ public static Player createPlayer(IPlayerSettings settings) { } /** - * pdate values of an object that implements IPlayerSettings from a player object + * Update values of an object that implements IPlayerSettings from a player object * @param settings An object that implements IPlayerSettings * @param player A Player object from which to read values */ diff --git a/MekHQ/src/mekhq/campaign/mission/BotForce.java b/MekHQ/src/mekhq/campaign/mission/BotForce.java index 8996cbf402..f405689f01 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForce.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForce.java @@ -123,7 +123,7 @@ public BotForce clone() { copy.setCamouflage(this.getCamouflage().clone()); copy.setColour(this.getColour()); copy.setTemplateName(this.getTemplateName()); - if(this.getBotForceRandomizer() != null) { + if (this.getBotForceRandomizer() != null) { copy.setBotForceRandomizer(this.getBotForceRandomizer().clone()); } // UUID is immutable so this should work diff --git a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java index b3d6eb3c93..e01502f95b 100644 --- a/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java +++ b/MekHQ/src/mekhq/campaign/mission/BotForceRandomizer.java @@ -231,7 +231,7 @@ public void setFocalWeightClass(double f) { * is used to determine the total points allowed for this force. * @param botFixedEntities A List of The fixed Entities that might have also been declared in BotForce already. * This is used to calculate the starting points already used when generating the force. - * @param Campaign A Campaign object which is necessary for various information + * @param campaign A Campaign object which is necessary for various information * @return A List of Entities that will be added to the game by GameThread. */ public List generateForce(List playerUnits, List botFixedEntities, Campaign campaign) { @@ -568,7 +568,7 @@ private double calculateMeanWeightClass(List playerUnits) { return sumWeightClass / ((double) nUnits); } - public String getShortDescription(Campaign campaign) { + public String getShortDescription() { StringBuilder sb = new StringBuilder(); sb.append(forceMultiplier); sb.append(" ("); diff --git a/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java b/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java index 6e1bbbd84a..729c742817 100644 --- a/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java +++ b/MekHQ/src/mekhq/campaign/mission/IPlayerSettings.java @@ -22,25 +22,25 @@ /** * This interface allows to identify classes that track player information like deployment, initiative bonuses, - * minefields, etc, so we can identify getter and setter methods across these types. Currently, that applies to + * minefields, etc., so we can identify getter and setter methods across these types. Currently, that applies to * Scenario and BotForce. */ public interface IPlayerSettings { // deployment information - public int getStartingPos(); - public void setStartingPos(int i); - public int getStartWidth(); - public void setStartWidth(int i); - public int getStartOffset(); - public void setStartOffset(int i); - public int getStartingAnyNWx(); - public void setStartingAnyNWx(int i); - public int getStartingAnyNWy(); - public void setStartingAnyNWy(int i); - public int getStartingAnySEx(); - public void setStartingAnySEx(int i); - public int getStartingAnySEy(); - public void setStartingAnySEy(int i); + int getStartingPos(); + void setStartingPos(int i); + int getStartWidth(); + void setStartWidth(int i); + int getStartOffset(); + void setStartOffset(int i); + int getStartingAnyNWx(); + void setStartingAnyNWx(int i); + int getStartingAnyNWy(); + void setStartingAnyNWy(int i); + int getStartingAnySEx(); + void setStartingAnySEx(int i); + int getStartingAnySEy(); + void setStartingAnySEy(int i); } diff --git a/MekHQ/src/mekhq/campaign/mission/Scenario.java b/MekHQ/src/mekhq/campaign/mission/Scenario.java index b229d469ed..48c520a15e 100644 --- a/MekHQ/src/mekhq/campaign/mission/Scenario.java +++ b/MekHQ/src/mekhq/campaign/mission/Scenario.java @@ -636,33 +636,6 @@ public ForceStub getForceStub() { return stub; } - public BotForceStub generateBotStub(BotForce bf, Campaign c) { - List stubs = generateEntityStub(bf.getFullEntityList(c)); - return new BotForceStub("" + - bf.getName() + " " + - ((bf.getTeam() == 1) ? "Allied" : "Enemy") + "" + - " Start: " + IStartingPositions.START_LOCATION_NAMES[bf.getStartingPos()] + - " Fixed BV: " + bf.getTotalBV(c) + - ((null == bf.getBotForceRandomizer()) ? "" : "
Random: " + bf.getBotForceRandomizer().getDescription(c)) + - "", stubs); - } - - public List generateEntityStub(List entities) { - List stub = new ArrayList<>(); - for (Entity en : entities) { - if (null == en) { - stub.add("No random assignment table found for faction"); - } else { - stub.add("" + en.getCrew().getName() + " (" + - en.getCrew().getGunnery() + "/" + - en.getCrew().getPiloting() + "), " + - "" + en.getShortName() + "" + - ""); - } - } - return stub; - } - public boolean isAssigned(Unit unit, Campaign campaign) { for (UUID uid : getForces(campaign).getAllUnits(true)) { if (uid.equals(unit.getId())) { diff --git a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java index 6762aa1173..26cc3b3467 100644 --- a/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java +++ b/MekHQ/src/mekhq/campaign/mission/ScenarioDeploymentLimit.java @@ -355,7 +355,7 @@ public String getRequiredPersonnelDesc(Campaign c) { personNames.add(p.getFullName()); } } - if(personNames.isEmpty()) { + if (personNames.isEmpty()) { return "None"; } return String.join(", ", personNames); @@ -419,7 +419,7 @@ public String getRequiredUnitDesc(Campaign c) { unitNames.add(u.getName()); } } - if(unitNames.isEmpty()) { + if (unitNames.isEmpty()) { return "None"; } return String.join(", ", unitNames); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index 5cd19740c5..dd4ab31eee 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -31,6 +31,7 @@ import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; import mekhq.campaign.mission.BotForceRandomizer; +import mekhq.campaign.mission.BotForceRandomizer.BalancingMethod; import mekhq.campaign.universe.Factions; import mekhq.gui.FileDialogs; import mekhq.gui.baseComponents.DefaultMHQScrollablePanel; @@ -65,9 +66,6 @@ public class CustomizeBotForceDialog extends JDialog { private JPanel panBehavior; private JPanel panRandomUnits; private DefaultMHQScrollablePanel panFixedUnits; - private JButton btnLoadUnits; - private JButton btnSaveUnits; - private JButton btnDeleteUnits; private JLabel lblCowardice; private JLabel lblSelfPreservation; private JLabel lblAggression; @@ -80,12 +78,12 @@ public class CustomizeBotForceDialog extends JDialog { private JSpinner spnPercentConventional; private JSpinner spnBaChance; private JSpinner spnLanceSize; - private MMComboBox choiceBalancingMethod; - private MMComboBox choiceUnitType; + private MMComboBox choiceBalancingMethod; + private MMComboBox choiceUnitType; private MMComboBox choiceSkillLevel; - private MMComboBox choiceFocalWeightClass; + private MMComboBox choiceFocalWeightClass; private MMComboBox choiceFaction; - private MMComboBox choiceQuality; + private MMComboBox choiceQuality; public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campaign c) { super(parent, modal); @@ -108,7 +106,7 @@ public CustomizeBotForceDialog(JFrame parent, boolean modal, BotForce bf, Campai LogManager.getLogger().error("Error copying princess behaviors", ex); } useRandomUnits = botForce.getBotForceRandomizer() != null; - if(useRandomUnits) { + if (useRandomUnits) { randomizer = botForce.getBotForceRandomizer().clone(); } else { randomizer = new BotForceRandomizer(); @@ -131,9 +129,6 @@ private void initComponents() { JPanel panLeft = new JPanel(new GridBagLayout()); JPanel panCenter = new JPanel(new GridBagLayout()); - //panMain.add(panLeft); - //panMain.add(panRight); - //getContentPane().add(panMain, BorderLayout.CENTER); getContentPane().add(panName, BorderLayout.NORTH); getContentPane().add(panLeft, BorderLayout.WEST); getContentPane().add(panCenter, BorderLayout.CENTER); @@ -147,8 +142,7 @@ private void initComponents() { panButtons.add(btnClose); getContentPane().add(panButtons, BorderLayout.PAGE_END); - GridBagConstraints gbc; - gbc = new GridBagConstraints(); + GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.0; @@ -169,7 +163,7 @@ private void initComponents() { gbc.fill = GridBagConstraints.NONE; panLeft.add(new JLabel(resourceMap.getString("lblTeam.text")), gbc); - choiceTeam = new JComboBox(); + choiceTeam = new JComboBox<>(); for (int i = 1; i < 6; i++) { String choice = resourceMap.getString("choiceTeam.text") + " " + i; if (i ==1) { @@ -230,18 +224,18 @@ private void initComponents() { gbc.weightx = 0.0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; - btnLoadUnits = new JButton(resourceMap.getString("btnLoadUnits.text")); + JButton btnLoadUnits = new JButton(resourceMap.getString("btnLoadUnits.text")); btnLoadUnits.setToolTipText(resourceMap.getString("btnLoadUnits.tooltip")); btnLoadUnits.addActionListener(this::loadUnits); panCenter.add(btnLoadUnits, gbc); gbc.gridx++; - btnSaveUnits = new JButton(resourceMap.getString("btnSaveUnits.text")); + JButton btnSaveUnits = new JButton(resourceMap.getString("btnSaveUnits.text")); btnSaveUnits.setToolTipText(resourceMap.getString("btnSaveUnits.tooltip")); btnSaveUnits.addActionListener(this::saveUnits); panCenter.add(btnSaveUnits, gbc); gbc.gridx++; gbc.weightx = 1.0; - btnDeleteUnits = new JButton(resourceMap.getString("btnDeleteUnits.text")); + JButton btnDeleteUnits = new JButton(resourceMap.getString("btnDeleteUnits.text")); btnDeleteUnits.setToolTipText(resourceMap.getString("btnDeleteUnits.tooltip")); btnDeleteUnits.addActionListener(this::deleteUnits); panCenter.add(btnDeleteUnits, gbc); @@ -361,7 +355,7 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { }); panRandomUnits.add(chkUseRandomUnits, gbc); - choiceBalancingMethod = new MMComboBox("choiceBalancingMethod", BotForceRandomizer.BalancingMethod.values()); + choiceBalancingMethod = new MMComboBox<>("choiceBalancingMethod", BalancingMethod.values()); choiceBalancingMethod.setSelectedItem(randomizer.getBalancingMethod()); choiceBalancingMethod.setEnabled(useRandomUnits); gbc.gridx = 0; @@ -395,10 +389,10 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { panRandomUnits.add(choiceFaction, gbc); DefaultComboBoxModel unitTypeModel = new DefaultComboBoxModel<>(); - for(int i = 0; i < UnitType.SIZE; i++) { + for (int i = 0; i < UnitType.SIZE; i++) { unitTypeModel.addElement(UnitType.getTypeName(i)); } - choiceUnitType = new MMComboBox("choiceUnitType", unitTypeModel); + choiceUnitType = new MMComboBox<>("choiceUnitType", unitTypeModel); choiceUnitType.setSelectedItem(UnitType.getTypeName(randomizer.getUnitType())); choiceUnitType.setEnabled(useRandomUnits); gbc.gridx = 0; @@ -413,7 +407,7 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { //leave out none as a skill option ArrayList skills = Arrays.stream(SkillLevel.values()). - filter(skill -> !skill.isNone()).collect(Collectors.toCollection(() -> new ArrayList())); + filter(skill -> !skill.isNone()).collect(Collectors.toCollection(() -> new ArrayList<>())); choiceSkillLevel = new MMComboBox("choiceSkillLevel", skills.toArray()); choiceSkillLevel.setSelectedItem(randomizer.getSkill()); choiceSkillLevel.setEnabled(useRandomUnits); @@ -433,7 +427,7 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { qualityModel.addElement("C"); qualityModel.addElement("B"); qualityModel.addElement("A"); - choiceQuality = new MMComboBox("choiceQuality", qualityModel); + choiceQuality = new MMComboBox<>("choiceQuality", qualityModel); choiceQuality.setSelectedIndex(randomizer.getQuality()); choiceQuality.setEnabled(useRandomUnits); gbc.gridx = 0; @@ -448,11 +442,11 @@ private void initRandomForcesPanel(ResourceBundle resourceMap) { DefaultComboBoxModel weightClassModel = new DefaultComboBoxModel<>(); weightClassModel.addElement("Not Specified"); - for(int i = EntityWeightClass.WEIGHT_LIGHT; i <= EntityWeightClass.WEIGHT_ASSAULT; i++) { + for (int i = EntityWeightClass.WEIGHT_LIGHT; i <= EntityWeightClass.WEIGHT_ASSAULT; i++) { weightClassModel.addElement(EntityWeightClass.getClassName(i)); } choiceFocalWeightClass = new MMComboBox("choiceFocalWeightClass", weightClassModel); - if(randomizer.getFocalWeightClass() < EntityWeightClass.WEIGHT_LIGHT + if (randomizer.getFocalWeightClass() < EntityWeightClass.WEIGHT_LIGHT || randomizer.getFocalWeightClass() > EntityWeightClass.WEIGHT_ASSAULT) { choiceFocalWeightClass.setSelectedIndex(0); } else { @@ -527,7 +521,7 @@ private void refreshFixedEntityPanel() { gbc.weightx = 1.0; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(2, 5, 0, 0); - for(String en : Utilities.generateEntityStub(fixedEntities)) { + for (String en : Utilities.generateEntityStub(fixedEntities)) { panFixedUnits.add(new JLabel(en), gbc); gbc.gridy++; } @@ -542,7 +536,7 @@ public BotForce getBotForce() { private void editBehavior(ActionEvent evt) { BotConfigDialog bcd = new BotConfigDialog(frame, botForce.getName(), botForce.getBehaviorSettings(), null); bcd.setVisible(true); - if(!bcd.getResult().isCancelled()) { + if (!bcd.getResult().isCancelled()) { behavior = bcd.getBehaviorSettings(); lblCowardice.setText(Integer.toString(behavior.getBraveryIndex())); lblSelfPreservation.setText(Integer.toString(behavior.getSelfPreservationIndex())); @@ -570,7 +564,7 @@ private void changeDeployment() { private void loadUnits(ActionEvent evt) { Optional units = FileDialogs.openUnits(frame); - if (units.isPresent() && units.get() != null) { + if (units.isPresent()) { final MULParser parser; try { parser = new MULParser(units.get(), campaign.getGameOptions()); @@ -585,9 +579,9 @@ private void loadUnits(ActionEvent evt) { private void saveUnits(ActionEvent evt) { Optional saveUnits = FileDialogs.saveUnits(frame, - (botForce.getName().length() > 0) ? botForce.getName() : "BotForce"); + (!botForce.getName().isEmpty()) ? botForce.getName() : "BotForce"); - if(saveUnits.isPresent() && saveUnits.get() != null) { + if (saveUnits.isPresent()) { try { EntityListFile.saveTo(saveUnits.get(), (ArrayList) fixedEntities); } catch (Exception ex) { @@ -602,14 +596,14 @@ private void deleteUnits(ActionEvent evt) { } private String getForcedWithdrawalDescription(BehaviorSettings behavior) { - if(!behavior.isForcedWithdrawal()) { + if (!behavior.isForcedWithdrawal()) { return "NONE"; } else { return behavior.getRetreatEdge().toString(); } } private String getAutoFleeDescription(BehaviorSettings behavior) { - if(!behavior.shouldAutoFlee()) { + if (!behavior.shouldAutoFlee()) { return "NO"; } else { return behavior.getDestinationEdge().toString(); @@ -625,7 +619,7 @@ private void done(ActionEvent evt) { botForce.setBotForceRandomizer(randomizer); botForce.setFixedEntityList(fixedEntities); useRandomUnits = chkUseRandomUnits.isSelected(); - if(useRandomUnits) { + if (useRandomUnits) { randomizer.setFactionCode(choiceFaction.getSelectedItem().getFaction().getShortName()); randomizer.setForceMultiplier((double) spnForceMultiplier.getValue()); randomizer.setPercentConventional((int) spnPercentConventional.getValue()); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index f55505c7ba..1a680db308 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -23,7 +23,6 @@ import megamek.client.ui.preferences.JWindowPreference; import megamek.client.ui.preferences.PreferencesNode; import megamek.client.ui.swing.PlanetaryConditionsDialog; -import megamek.client.ui.swing.lobby.PlayerSettingsDialog; import megamek.common.Player; import megamek.common.planetaryconditions.PlanetaryConditions; import mekhq.MekHQ; @@ -109,8 +108,6 @@ public class CustomizeScenarioDialog extends JDialog { private JLabel lblAtmosphereDesc; private JLabel lblWeatherDesc; private JLabel lblFogDesc; - private JLabel lblBlowingSandDesc; - private JLabel lblEMIDesc; private JLabel lblTemperatureDesc; private JLabel lblGravityDesc; private JLabel lblOtherConditionsDesc; @@ -129,22 +126,15 @@ public class CustomizeScenarioDialog extends JDialog { // buttons private JButton btnDate; private JButton btnDeployment; - private JButton btnPlanetaryConditions; - private JButton btnMapSettings; - private JButton btnAddLoot; private JButton btnEditLoot; private JButton btnDeleteLoot; - private JButton btnAddObjective; private JButton btnEditObjective; private JButton btnDeleteObjective; - private JButton btnAddForce; private JButton btnEditForce; private JButton btnDeleteForce; - private JButton btnClose; - private JButton btnOK; - //region markdown editors + // markdown editors private MarkdownEditorPanel txtDesc; private MarkdownEditorPanel txtReport; //endregion Variable declarations @@ -217,7 +207,6 @@ private void initComponents() { JPanel panWrite = new JPanel(new GridBagLayout()); JPanel panBtn = new JPanel(new GridLayout(0,2)); - // region Set up info panel GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; @@ -290,7 +279,7 @@ public Component getListCellRendererComponent(final JList list, final Object gbc.gridwidth = 1; modifierBox = new JComboBox<>(); - EventTiming scenarioState = ((AtBDynamicScenario) scenario).getNumBots() > 0 ? + EventTiming scenarioState = scenario.getNumBots() > 0 ? EventTiming.PostForceGeneration : EventTiming.PreForceGeneration; for (String modifierKey : AtBScenarioModifier.getOrderedModifierKeys()) { @@ -322,8 +311,6 @@ public Component getListCellRendererComponent(final JList list, final Object gbc.gridy++; panInfo.add(panMap, gbc); - // endregion Set up info panel - initObjectivesPanel(resourceMap); panObjectives.setPreferredSize(new Dimension(400,150)); panObjectives.setMinimumSize(new Dimension(400,150)); @@ -345,7 +332,6 @@ public Component getListCellRendererComponent(final JList list, final Object panOtherForces.setPreferredSize(new Dimension(600,250)); panOtherForces.setMinimumSize(new Dimension(600,250)); - // region Set up writing panel txtDesc = new MarkdownEditorPanel("Description"); txtDesc.setText(scenario.getDescription()); txtDesc.setMinimumSize(new Dimension(400, 100)); @@ -377,9 +363,7 @@ public Component getListCellRendererComponent(final JList list, final Object panWrite.add(txtReport, gbc); txtReport.setEnabled(!scenario.getStatus().isCurrent()); } - // endregion Set up writing panel - // region Set up buttons if (newScenario && (mission instanceof AtBContract)) { JButton btnLoad = new JButton("Generate From Template"); btnLoad.addActionListener(this::btnLoadActionPerformed); @@ -389,7 +373,7 @@ public Component getListCellRendererComponent(final JList list, final Object (scenario.getStatus().isCurrent())) { JButton btnFinalize = new JButton(); - if (((AtBDynamicScenario) scenario).getNumBots() > 0) { + if (scenario.getNumBots() > 0) { btnFinalize.setText("Regenerate Bot Forces"); } else { btnFinalize.setText("Generate Bot Forces"); @@ -399,16 +383,14 @@ public Component getListCellRendererComponent(final JList list, final Object panBtn.add(btnFinalize); } - btnOK = new JButton(resourceMap.getString("btnOkay.text")); + JButton btnOK = new JButton(resourceMap.getString("btnOkay.text")); btnOK.addActionListener(this::btnOKActionPerformed); panBtn.add(btnOK); - btnClose = new JButton(resourceMap.getString("btnCancel.text")); + JButton btnClose = new JButton(resourceMap.getString("btnCancel.text")); btnClose.addActionListener(this::btnCloseActionPerformed); panBtn.add(btnClose); - //endregion Set up buttons - // layout main panel getContentPane().add(panMain, BorderLayout.CENTER); getContentPane().add(panBtn, BorderLayout.PAGE_END); @@ -631,7 +613,7 @@ private void initDeployLimitPanel(ResourceBundle resourceMap) { } private void refreshDeploymentLimits() { - if(deploymentLimits != null) { + if (deploymentLimits != null) { lblAllowedUnitsDesc.setText("" + deploymentLimits.getAllowedUnitTypeDesc() + ""); lblQuantityLimitDesc.setText("" +deploymentLimits.getQuantityLimitDesc(scenario, campaign) + ""); lblRequiredPersonnelDesc.setText("" + deploymentLimits.getRequiredPersonnelDesc(campaign) + ""); @@ -662,7 +644,7 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { BorderFactory.createEmptyBorder(0, 0, 10, 0), BorderFactory.createTitledBorder(resourceMap.getString("panPlanetaryConditions.title")))); - btnPlanetaryConditions = new JButton(resourceMap.getString("btnPlanetaryConditions.text")); + JButton btnPlanetaryConditions = new JButton(resourceMap.getString("btnPlanetaryConditions.text")); btnPlanetaryConditions.addActionListener(evt -> changePlanetaryConditions()); btnPlanetaryConditions.setEnabled(scenario.getStatus().isCurrent()); GridBagConstraints gbc = new GridBagConstraints(); @@ -803,7 +785,7 @@ private void initMapPanel(ResourceBundle resourceMap) { BorderFactory.createEmptyBorder(0, 0, 10, 0), BorderFactory.createTitledBorder(resourceMap.getString("panMap.title")))); - btnMapSettings = new JButton(resourceMap.getString("btnMapSettings.text")); + JButton btnMapSettings = new JButton(resourceMap.getString("btnMapSettings.text")); btnMapSettings.addActionListener(evt -> changeMapSettings()); btnMapSettings.setEnabled(scenario.getStatus().isCurrent()); GridBagConstraints gbc = new GridBagConstraints(); @@ -890,7 +872,7 @@ private void initObjectivesPanel(ResourceBundle resourceMap) { panObjectives = new JPanel(new BorderLayout()); JPanel panBtns = new JPanel(new GridLayout(1,0)); - btnAddObjective = new JButton(resourceMap.getString("btnAddObjective.text")); + JButton btnAddObjective = new JButton(resourceMap.getString("btnAddObjective.text")); btnAddObjective.addActionListener(evt -> addObjective()); btnAddObjective.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnAddObjective); @@ -978,7 +960,7 @@ private void initLootPanel(ResourceBundle resourceMap) { panLoot = new JPanel(new BorderLayout()); JPanel panBtns = new JPanel(new GridLayout(1,0)); - btnAddLoot = new JButton(resourceMap.getString("btnAddLoot.text")); + JButton btnAddLoot = new JButton(resourceMap.getString("btnAddLoot.text")); btnAddLoot.addActionListener(evt -> addLoot()); btnAddLoot.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnAddLoot); @@ -1059,7 +1041,7 @@ private void initOtherForcesPanel(ResourceBundle resourceMap) { panOtherForces = new JPanel(new BorderLayout()); JPanel panBtns = new JPanel(new GridLayout(1,0)); - btnAddForce = new JButton(resourceMap.getString("btnAddForce.text")); + JButton btnAddForce = new JButton(resourceMap.getString("btnAddForce.text")); btnAddForce.addActionListener(evt -> addForce()); btnAddForce.setEnabled(scenario.getStatus().isCurrent()); panBtns.add(btnAddForce); @@ -1110,14 +1092,12 @@ private void addForce() { private void editForce() { BotForce bf = forcesModel.getBotForceAt(forcesTable.getSelectedRow()); String nameOld = bf.getName(); - if (null != bf) { - CustomizeBotForceDialog cbfd = new CustomizeBotForceDialog(frame, true, bf, campaign); - cbfd.setVisible(true); - refreshForcesTable(); - if(!bf.getName().equals(nameOld)) { - checkForceRename(nameOld, bf.getName()); - refreshObjectiveTable(); - } + CustomizeBotForceDialog cbfd = new CustomizeBotForceDialog(frame, true, bf, campaign); + cbfd.setVisible(true); + refreshForcesTable(); + if (!bf.getName().equals(nameOld)) { + checkForceRename(nameOld, bf.getName()); + refreshObjectiveTable(); } } @@ -1151,8 +1131,8 @@ private void refreshForcesTable() { * If a force was renamed, we need to change its name in any corresponding scenario objectives */ private void checkForceRename(String nameOld, String nameNew) { - for(ScenarioObjective objective : objectives) { - if(objective.getAssociatedForceNames().contains(nameOld)) { + for (ScenarioObjective objective : objectives) { + if (objective.getAssociatedForceNames().contains(nameOld)) { objective.removeForce(nameOld); objective.addForce(nameNew); } @@ -1163,7 +1143,7 @@ private void checkForceRename(String nameOld, String nameNew) { * If a force is deleted, check scenario objectives and remove it there as well */ private void checkForceDelete(String nameRemove) { - for(ScenarioObjective objective : objectives) { + for (ScenarioObjective objective : objectives) { if (objective.getAssociatedForceNames().contains(nameRemove)) { objective.removeForce(nameRemove); } diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index 76e6a62246..d0e2d62c00 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -23,6 +23,12 @@ import mekhq.MHQConstants; import mekhq.MekHQ; import mekhq.campaign.mission.*; +import mekhq.campaign.mission.ObjectiveEffect.EffectScalingType; +import mekhq.campaign.mission.ObjectiveEffect.ObjectiveEffectConditionType; +import mekhq.campaign.mission.ObjectiveEffect.ObjectiveEffectType; +import mekhq.campaign.mission.ScenarioObjective.ObjectiveAmountType; +import mekhq.campaign.mission.ScenarioObjective.ObjectiveCriterion; +import mekhq.campaign.mission.ScenarioObjective.TimeLimitType; import javax.swing.*; import java.awt.*; @@ -33,26 +39,23 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private ScenarioObjective objective; private List botForceNames; - private JFrame frame; - private JPanel panObjectiveType; private JPanel panForce; private JPanel panTimeLimits; - private JPanel panEffect; private JPanel panObjectiveEffect; private JTextField txtShortDescription; - private JComboBox cboObjectiveType; + private JComboBox cboObjectiveType; private JComboBox cboDirection; private JSpinner spnAmount; private SpinnerNumberModel modelPercent; private SpinnerNumberModel modelFixed; - private MMComboBox cboCountType; + private MMComboBox cboCountType; private JComboBox cboForceName; private JSpinner spnScore; - private JComboBox cboScalingType; - private JComboBox cboEffectType; - private JComboBox cboEffectCondition; + private JComboBox cboScalingType; + private JComboBox cboEffectType; + private JComboBox cboEffectCondition; private JList successEffects; private JList failureEffects; @@ -60,7 +63,7 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { private JButton btnRemoveFailure; private JComboBox cboTimeLimitDirection; - private JComboBox cboTimeScaling; + private JComboBox cboTimeScaling; private JSpinner spnTimeLimit; private JList forceNames; @@ -77,13 +80,12 @@ public class CustomizeScenarioObjectiveDialog extends JDialog { public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioObjective objective, List botForceNames) { super(parent, modal); - this.frame = parent; this.objective = objective; this.botForceNames = botForceNames; initialize(); - for(String forceName : objective.getAssociatedForceNames()) { + for (String forceName : objective.getAssociatedForceNames()) { forceModel.addElement(forceName); } @@ -98,7 +100,7 @@ public CustomizeScenarioObjectiveDialog(JFrame parent, boolean modal, ScenarioOb cboTimeScaling.setSelectedItem(objective.getTimeLimitType()); updateTimeLimitUI(); cboTimeLimitDirection.setSelectedIndex(objective.isTimeLimitAtMost() ? 0 : 1); - if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { + if (objective.getTimeLimitType() == TimeLimitType.ScaledToPrimaryUnitCount) { spnTimeLimit.setValue(objective.getTimeLimitScaleFactor()); } else { if (objective.getTimeLimit() != null) { @@ -258,7 +260,7 @@ private void initialize() { private void initObjectiveTypePanel() { panObjectiveType = new JPanel(new GridBagLayout()); cboObjectiveType = new JComboBox<>(); - for (ScenarioObjective.ObjectiveCriterion objectiveType : ScenarioObjective.ObjectiveCriterion.values()) { + for (ObjectiveCriterion objectiveType : ObjectiveCriterion.values()) { cboObjectiveType.addItem(objectiveType); } cboObjectiveType.addActionListener(e -> this.setDirectionDropdownVisibility()); @@ -267,7 +269,7 @@ private void initObjectiveTypePanel() { modelFixed = new SpinnerNumberModel(0, 0, null, 1); spnAmount = new JSpinner(modelPercent); - cboCountType = new MMComboBox("cboCountType", ScenarioObjective.ObjectiveAmountType.values()); + cboCountType = new MMComboBox<>("cboCountType", ObjectiveAmountType.values()); cboCountType.addActionListener(etv -> switchNumberModel()); @@ -303,7 +305,7 @@ private void initForcePanel(ResourceBundle resourceMap) { cboForceName = new JComboBox<>(); cboForceName.addItem(MHQConstants.EGO_OBJECTIVE_NAME); - for(String name : botForceNames) { + for (String name : botForceNames) { cboForceName.addItem(name); } @@ -369,7 +371,7 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { gbcRight.gridy++; panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectScaling.text")), gbcLeft); cboScalingType = new JComboBox<>(); - for (ObjectiveEffect.EffectScalingType scalingType : ObjectiveEffect.EffectScalingType.values()) { + for (EffectScalingType scalingType : EffectScalingType.values()) { cboScalingType.addItem(scalingType); } panObjectiveEffect.add(cboScalingType, gbcRight); @@ -378,7 +380,7 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { gbcRight.gridy++; panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectType.text")), gbcLeft); cboEffectType = new JComboBox<>(); - for (ObjectiveEffect.ObjectiveEffectType scalingType : ObjectiveEffect.ObjectiveEffectType.values()) { + for (ObjectiveEffectType scalingType : ObjectiveEffectType.values()) { cboEffectType.addItem(scalingType); } panObjectiveEffect.add(cboEffectType, gbcRight); @@ -387,8 +389,8 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { gbcRight.gridy++; panObjectiveEffect.add(new JLabel(resourceMap.getString("lblEffectCondition.text")), gbcLeft); cboEffectCondition = new JComboBox<>(); - cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess); - cboEffectCondition.addItem(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure); + cboEffectCondition.addItem(ObjectiveEffectConditionType.ObjectiveSuccess); + cboEffectCondition.addItem(ObjectiveEffectConditionType.ObjectiveFailure); panObjectiveEffect.add(cboEffectCondition, gbcRight); JButton btnAdd = new JButton(resourceMap.getString("btnAdd.text")); @@ -405,11 +407,11 @@ private void initObjectiveEffectPanel(ResourceBundle resourceMap) { failureEffects.addListSelectionListener(e -> btnRemoveFailure.setEnabled(!failureEffects.getSelectedValuesList().isEmpty())); btnRemoveSuccess = new JButton(resourceMap.getString("btnRemove.text")); - btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess)); + btnRemoveSuccess.addActionListener(e -> this.removeEffect(ObjectiveEffectConditionType.ObjectiveSuccess)); btnRemoveSuccess.setEnabled(false); btnRemoveFailure = new JButton(resourceMap.getString("btnRemove.text")); - btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveFailure)); + btnRemoveFailure.addActionListener(e -> this.removeEffect(ObjectiveEffectConditionType.ObjectiveFailure)); btnRemoveFailure.setEnabled(false); JPanel panBottom = new JPanel(new GridBagLayout()); @@ -458,7 +460,7 @@ private void initTimeLimitPanel() { cboTimeLimitDirection.addItem("at least"); cboTimeScaling = new JComboBox<>(); - for (ScenarioObjective.TimeLimitType timeLimitType : ScenarioObjective.TimeLimitType.values()) { + for (TimeLimitType timeLimitType : TimeLimitType.values()) { cboTimeScaling.addItem(timeLimitType); } cboTimeScaling.addActionListener(e -> this.updateTimeLimitUI()); @@ -481,7 +483,7 @@ private void initTimeLimitPanel() { private void switchNumberModel() { int value = (int) spnAmount.getValue(); - if(cboCountType.getSelectedItem() == ScenarioObjective.ObjectiveAmountType.Percentage) { + if(cboCountType.getSelectedItem() == ObjectiveAmountType.Percentage) { if(value > 100) { value = 100; } @@ -499,11 +501,11 @@ private void switchNumberModel() { private void addEffect() { ObjectiveEffect effect = new ObjectiveEffect(); - effect.howMuch = (int) spnScore.getValue();; - effect.effectScaling = (ObjectiveEffect.EffectScalingType) cboScalingType.getSelectedItem(); - effect.effectType = (ObjectiveEffect.ObjectiveEffectType) cboEffectType.getSelectedItem(); + effect.howMuch = (int) spnScore.getValue(); + effect.effectScaling = (EffectScalingType) cboScalingType.getSelectedItem(); + effect.effectType = (ObjectiveEffectType) cboEffectType.getSelectedItem(); - if (cboEffectCondition.getSelectedItem() == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { + if (cboEffectCondition.getSelectedItem() == ObjectiveEffectConditionType.ObjectiveSuccess) { successEffectsModel.addElement(effect); successEffects.repaint(); } else { @@ -513,11 +515,11 @@ private void addEffect() { pack(); } - private void removeEffect(ObjectiveEffect.ObjectiveEffectConditionType conditionType) { + private void removeEffect(ObjectiveEffectConditionType conditionType) { JList targetList; DefaultListModel modelToUpdate; - if (conditionType == ObjectiveEffect.ObjectiveEffectConditionType.ObjectiveSuccess) { + if (conditionType == ObjectiveEffectConditionType.ObjectiveSuccess) { targetList = successEffects; modelToUpdate = (DefaultListModel) successEffects.getModel(); btnRemoveSuccess.setEnabled(false); @@ -556,7 +558,7 @@ private void removeDetails() { } private void setDirectionDropdownVisibility() { - switch ((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()) { + switch ((ObjectiveCriterion) cboObjectiveType.getSelectedItem()) { case PreventReachMapEdge: case ReachMapEdge: cboDirection.setVisible(true); @@ -568,8 +570,7 @@ private void setDirectionDropdownVisibility() { } private void updateTimeLimitUI() { - boolean enable = !cboTimeScaling.getSelectedItem().equals(ScenarioObjective.TimeLimitType.None); - + boolean enable = !cboTimeScaling.getSelectedItem().equals(TimeLimitType.None); spnTimeLimit.setEnabled(enable); cboTimeLimitDirection.setEnabled(enable); } @@ -579,10 +580,10 @@ public ScenarioObjective getObjective() { } private void saveObjectiveAndClose() { - objective.setObjectiveCriterion((ScenarioObjective.ObjectiveCriterion) cboObjectiveType.getSelectedItem()); + objective.setObjectiveCriterion((ObjectiveCriterion) cboObjectiveType.getSelectedItem()); objective.setDescription(txtShortDescription.getText()); int number = (int) spnAmount.getValue(); - if (cboCountType.getSelectedItem().equals(ScenarioObjective.ObjectiveAmountType.Percentage)) { + if (cboCountType.getSelectedItem().equals(ObjectiveAmountType.Percentage)) { objective.setPercentage(number); objective.setFixedAmount(null); } else { @@ -617,9 +618,9 @@ private void saveObjectiveAndClose() { } int timeLimit = (int) spnTimeLimit.getValue(); - objective.setTimeLimitType((ScenarioObjective.TimeLimitType) cboTimeScaling.getSelectedItem()); + objective.setTimeLimitType((TimeLimitType) cboTimeScaling.getSelectedItem()); if (spnTimeLimit.isEnabled()) { - if (objective.getTimeLimitType() == ScenarioObjective.TimeLimitType.ScaledToPrimaryUnitCount) { + if (objective.getTimeLimitType() == TimeLimitType.ScaledToPrimaryUnitCount) { objective.setTimeLimitScaleFactor(timeLimit); } else { objective.setTimeLimit(timeLimit); diff --git a/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java index cee9ce47f0..bcc5dcd736 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java @@ -18,20 +18,12 @@ */ package mekhq.gui.dialog; -import megamek.client.bot.princess.BehaviorSettings; -import megamek.client.bot.princess.Princess; import megamek.client.ui.GBC; -import megamek.client.ui.Messages; -import megamek.client.ui.dialogs.BotConfigDialog; -import megamek.client.ui.enums.DialogResult; -import megamek.client.ui.swing.GUIPreferences; import megamek.client.ui.swing.util.UIUtil; +import megamek.client.ui.swing.util.UIUtil.TipButton; import megamek.common.IStartingPositions; import megamek.common.Player; import mekhq.MekHQ; -import mekhq.campaign.Campaign; -import mekhq.campaign.mission.BotForce; -import mekhq.campaign.mission.IPlayerSettings; import javax.swing.*; import javax.swing.text.DefaultFormatterFactory; @@ -47,14 +39,12 @@ public class EditDeploymentDialog extends JDialog { - private JFrame frame; - Player player; private int currentStartPos; private final JPanel panStartButtons = new JPanel(); - private final UIUtil.TipButton[] butStartPos = new UIUtil.TipButton[11]; + private final TipButton[] butStartPos = new TipButton[11]; private final NumberFormatter numFormatter = new NumberFormatter(NumberFormat.getIntegerInstance()); private final DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory(numFormatter); private final JFormattedTextField txtOffset = new JFormattedTextField(formatterFactory, 0); @@ -80,7 +70,7 @@ private void initComponents() { panStartButtons.setAlignmentX(Component.LEFT_ALIGNMENT); for (int i = 0; i < 11; i++) { - butStartPos[i] = new UIUtil.TipButton(""); + butStartPos[i] = new TipButton(""); butStartPos[i].addActionListener(startListener); } panStartButtons.setLayout(new GridLayout(4, 3)); @@ -153,7 +143,6 @@ private void initComponents() { private void updateStartGrid() { StringBuilder[] butText = new StringBuilder[11]; StringBuilder[] butTT = new StringBuilder[11]; - boolean[] hasPlayer = new boolean[11]; for (int i = 0; i < 11; i++) { butText[i] = new StringBuilder(); diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 99c210c52c..decfb76179 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -18,7 +18,6 @@ */ package mekhq.gui.dialog; -import megamek.client.ui.swing.lobby.ChatLounge; import megamek.client.ui.swing.lobby.LobbyUtility; import megamek.client.ui.swing.minimap.Minimap; import megamek.common.Board; @@ -34,9 +33,6 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.awt.image.FilteredImageSource; -import java.awt.image.ImageFilter; -import java.awt.image.ImageProducer; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -46,14 +42,9 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static megamek.client.ui.swing.lobby.LobbyUtility.drawMinimapLabel; -import static megamek.client.ui.swing.util.UIUtil.scaleStringForGUI; public class EditMapSettingsDialog extends JDialog { - private JFrame frame; private int mapSizeX; private int mapSizeY; private String map; @@ -155,7 +146,7 @@ private void initComponents() { for (BoardDimensions size : GameManager.getBoardSizes()) { comboMapSize.addItem(size); } - if(mapSizeX > 0 & mapSizeY > 0) { + if (mapSizeX > 0 & mapSizeY > 0) { comboMapSize.setSelectedItem(new BoardDimensions(mapSizeX, mapSizeY)); } else { // if no board size yet set, use the default @@ -172,7 +163,7 @@ private void initComponents() { ArrayList generators = new ArrayList<>(); if (directoryListing != null) { for (File child : directoryListing) { - if(child.isFile()) { + if (child.isFile()) { String s = child.getName().replace(".xml", ""); generators.add(s); } @@ -188,7 +179,7 @@ private void initComponents() { listFixedMaps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); refreshBoardList(); - if(usingFixedMap) { + if (usingFixedMap) { listFixedMaps.setSelectedValue(map, true); scrChooseMap.setViewportView(listFixedMaps); } else { @@ -196,7 +187,7 @@ private void initComponents() { scrChooseMap.setViewportView(listMapGenerators); } - comboBoardType = new JComboBox(); + comboBoardType = new JComboBox<>(); for (int i = Scenario.T_GROUND; i <= Scenario.T_SPACE; i++) { comboBoardType.addItem(Scenario.getBoardTypeName(i)); } @@ -224,7 +215,7 @@ private void initComponents() { gbc.weightx = 1.0; panMain.add(panSizeRandom, gbc); panMain.add(panSizeFixed, gbc); - if(usingFixedMap) { + if (usingFixedMap) { panSizeRandom.setVisible(false); } else { panSizeFixed.setVisible(false); @@ -252,7 +243,7 @@ private void initComponents() { } private void changeBoardType() { - if(comboBoardType.getSelectedIndex() == Scenario.T_SPACE) { + if (comboBoardType.getSelectedIndex() == Scenario.T_SPACE) { checkFixed.setSelected(false); checkFixed.setEnabled(false); panSizeRandom.setVisible(true); @@ -268,7 +259,7 @@ private void changeBoardType() { } private void changeMapType() { - if(checkFixed.isSelected()) { + if (checkFixed.isSelected()) { panSizeRandom.setVisible(false); panSizeFixed.setVisible(true); scrChooseMap.setViewportView(listFixedMaps); @@ -294,14 +285,14 @@ private void refreshBoardList() { public void done() { boardType = comboBoardType.getSelectedIndex(); usingFixedMap = checkFixed.isSelected(); - if(usingFixedMap) { + if (usingFixedMap) { map = listFixedMaps.getSelectedValue(); BoardDimensions boardSize = (BoardDimensions) comboMapSize.getSelectedItem(); mapSizeX = boardSize.width(); mapSizeY = boardSize.height(); } else { map = listMapGenerators.getSelectedValue(); - if(listMapGenerators.getSelectedIndex() == 0) { + if (listMapGenerators.getSelectedIndex() == 0) { map = null; } mapSizeX = (int) spnMapX.getValue(); @@ -364,7 +355,7 @@ public Component getListCellRendererComponent(JList list, Object value, // Found or created an icon; finish the panel setText(""); if (listFixedMaps.isEnabled()) { - //setToolTipText(scaleStringForGUI(createBoardTooltip(board))); + setToolTipText(board); } else { setToolTipText(null); } diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 7a1e501a55..309d18699d 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -21,6 +21,8 @@ import megamek.client.ui.baseComponents.MMComboBox; import megamek.common.UnitType; import mekhq.campaign.mission.ScenarioDeploymentLimit; +import mekhq.campaign.mission.ScenarioDeploymentLimit.CountType; +import mekhq.campaign.mission.ScenarioDeploymentLimit.QuantityType; import javax.swing.*; import java.awt.*; @@ -29,20 +31,18 @@ public class EditScenarioDeploymentLimitDialog extends JDialog { - private JFrame frame; private ScenarioDeploymentLimit deploymentLimit; private boolean newLimit; private JSpinner spnQuantity; - private MMComboBox choiceQuantityType; - private MMComboBox choiceCountType; + private MMComboBox choiceQuantityType; + private MMComboBox choiceCountType; private JCheckBox checkAllUnits; private JCheckBox[] checkAllowedUnits; public EditScenarioDeploymentLimitDialog(JFrame parent, boolean modal, ScenarioDeploymentLimit limit) { super(parent, modal); - this.frame = parent; - if(limit == null) { + if (limit == null) { deploymentLimit = new ScenarioDeploymentLimit(); newLimit = true; } else { @@ -87,7 +87,7 @@ private void initComponents() { JLabel lblQuantityType = new JLabel("Quantity Type:"); panMain.add(lblQuantityType, leftGbc); - choiceQuantityType = new MMComboBox("choiceQuantityType", ScenarioDeploymentLimit.QuantityType.values()); + choiceQuantityType = new MMComboBox<>("choiceQuantityType", QuantityType.values()); choiceQuantityType.setSelectedItem(deploymentLimit.getQuantityType()); choiceQuantityType.addActionListener(this::setQuantityModel); panMain.add(choiceQuantityType, rightGbc); @@ -96,7 +96,7 @@ private void initComponents() { JLabel lblCountType = new JLabel("Maximum Type:"); leftGbc.gridy++; panMain.add(lblCountType, leftGbc); - choiceCountType = new MMComboBox("choiceCountType", ScenarioDeploymentLimit.CountType.values()); + choiceCountType = new MMComboBox<>("choiceCountType", CountType.values()); choiceCountType.setSelectedItem(deploymentLimit.getCountType()); choiceCountType.addActionListener(this::setQuantityModel); rightGbc.gridy++; @@ -121,7 +121,7 @@ private void initComponents() { checkAllUnits.addActionListener(this::checkAllUnits); panAllowedUnits.add(checkAllUnits); checkAllowedUnits = new JCheckBox [UnitType.SIZE]; - for(int i = UnitType.MEK; i < UnitType.SIZE; i++) { + for (int i = UnitType.MEK; i < UnitType.SIZE; i++) { JCheckBox check = new JCheckBox(UnitType.getTypeName(i)); check.setSelected(deploymentLimit.getAllowedUnitTypes().contains(i)); check.setEnabled(!checkAllUnits.isSelected()); @@ -151,8 +151,8 @@ private void initComponents() { } private void checkAllUnits(ActionEvent evt) { - for(JCheckBox box : checkAllowedUnits) { - if(checkAllUnits.isSelected()) { + for (JCheckBox box : checkAllowedUnits) { + if (checkAllUnits.isSelected()) { box.setSelected(false); box.setEnabled(false); } else { @@ -163,18 +163,18 @@ private void checkAllUnits(ActionEvent evt) { private void setQuantityModel(ActionEvent evt) { int currentQuantity = (int) spnQuantity.getValue(); - if(currentQuantity < 1) { + if (currentQuantity < 1) { currentQuantity = 1; } - ScenarioDeploymentLimit.CountType currentCountType = choiceCountType.getSelectedItem(); - ScenarioDeploymentLimit.QuantityType currentQuantityType = choiceQuantityType.getSelectedItem(); - if(currentQuantityType == ScenarioDeploymentLimit.QuantityType.PERCENT) { - if(currentQuantity > 100) { + CountType currentCountType = choiceCountType.getSelectedItem(); + QuantityType currentQuantityType = choiceQuantityType.getSelectedItem(); + if (currentQuantityType == QuantityType.PERCENT) { + if (currentQuantity > 100) { currentQuantity = 100; } spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, 100, 5)); } else { - if(currentCountType == ScenarioDeploymentLimit.CountType.UNIT) { + if (currentCountType == CountType.UNIT) { spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, null, 1)); } else { spnQuantity.setModel(new SpinnerNumberModel(currentQuantity, 1, null, 500)); @@ -186,10 +186,10 @@ private void complete(ActionEvent evt) { deploymentLimit.setQuantityLimit((int) spnQuantity.getValue()); deploymentLimit.setQuantityType(choiceQuantityType.getSelectedItem()); deploymentLimit.setCountType(choiceCountType.getSelectedItem()); - ArrayList allowed = new ArrayList(); - if(!checkAllUnits.isSelected()) { - for(int i = UnitType.MEK; i < UnitType.SIZE; i++) { - if(checkAllowedUnits[i].isSelected()) { + ArrayList allowed = new ArrayList<>(); + if (!checkAllUnits.isSelected()) { + for (int i = UnitType.MEK; i < UnitType.SIZE; i++) { + if (checkAllowedUnits[i].isSelected()) { allowed.add(i); } } @@ -199,7 +199,7 @@ private void complete(ActionEvent evt) { } private void cancel(ActionEvent evt) { - if(newLimit) { + if (newLimit) { deploymentLimit = null; } this.setVisible(false); diff --git a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java index ca5116d0d2..1ba43f5f5c 100644 --- a/MekHQ/src/mekhq/gui/model/BotForceTableModel.java +++ b/MekHQ/src/mekhq/gui/model/BotForceTableModel.java @@ -22,11 +22,9 @@ package mekhq.gui.model; -import megamek.common.IStartingPositions; import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.mission.BotForce; -import mekhq.campaign.universe.Factions; import javax.swing.*; import javax.swing.table.AbstractTableModel; @@ -100,7 +98,7 @@ public Object getValueAt(int row, int col) { return botForce.getFixedEntityList().size() + " Units, BV: " + botForce.getFixedBV(); case COL_RANDOM: return ((null == botForce.getBotForceRandomizer()) ? "" : botForce.getBotForceRandomizer(). - getShortDescription(campaign)); + getShortDescription()); case COL_DEPLOYMENT: return Utilities.getDeploymentString(botForce); default: @@ -108,11 +106,6 @@ public Object getValueAt(int row, int col) { } } - @Override - public boolean isCellEditable(int row, int col) { - return false; - } - @Override public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); diff --git a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java index 4cb352b3ae..d4c6c6fef2 100644 --- a/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java +++ b/MekHQ/src/mekhq/gui/model/ObjectiveTableModel.java @@ -18,19 +18,20 @@ */ package mekhq.gui.model; -import megamek.common.Entity; -import mekhq.campaign.mission.Loot; import mekhq.campaign.mission.ObjectiveEffect; import mekhq.campaign.mission.ScenarioObjective; -import mekhq.campaign.parts.Part; +import mekhq.campaign.mission.ScenarioObjective.ObjectiveAmountType; +import mekhq.campaign.mission.ScenarioObjective.TimeLimitType; import javax.swing.*; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import java.awt.*; import java.util.List; -import java.util.stream.Collectors; +/** + * TableModel for displaying information about a scenario objective + */ public class ObjectiveTableModel extends AbstractTableModel { //region Variable Declarations protected String[] columnNames; @@ -94,20 +95,20 @@ public Object getValueAt(int row, int col) { case COL_CRITERION: return objective.getObjectiveCriterion().toString(); case COL_AMOUNT: - return objective.getAmountType().equals(ScenarioObjective.ObjectiveAmountType.Percentage) ? + return objective.getAmountType().equals(ObjectiveAmountType.Percentage) ? objective.getPercentage() + "%" : objective.getAmount() + " units"; case COL_TIME: - if(objective.getTimeLimitType().equals(ScenarioObjective.TimeLimitType.None)) { + if(objective.getTimeLimitType().equals(TimeLimitType.None)) { return "None"; } String timeDirection = objective.isTimeLimitAtMost() ? "At most " : "At least "; - return objective.getTimeLimitType().equals(ScenarioObjective.TimeLimitType.Fixed) ? + return objective.getTimeLimitType().equals(TimeLimitType.Fixed) ? timeDirection + objective.getTimeLimit() + " turns" : - timeDirection + "(" + objective.getTimeLimitScaleFactor() + "x unit count) turns"; + timeDirection + '(' + objective.getTimeLimitScaleFactor() + "x unit count) turns"; case COL_SUCCESS_EFFECT: - return Integer.toString(objective.getSuccessEffects().size()) + " Effect(s)"; + return objective.getSuccessEffects().size() + " Effect(s)"; case COL_FAILURE_EFFECT: - return Integer.toString(objective.getFailureEffects().size()) + " Effect(s)"; + return objective.getFailureEffects().size() + " Effect(s)"; default: return "?"; } @@ -125,7 +126,10 @@ public int getColumnWidth(int c) { } public int getAlignment(int col) { - return SwingConstants.LEFT; + switch (col) { + default: + return SwingConstants.LEFT; + } } public String getTooltip(int row, int col) { @@ -167,8 +171,8 @@ public void setData(List objectives) { fireTableDataChanged(); } - public ObjectiveTableModel.Renderer getRenderer() { - return new ObjectiveTableModel.Renderer(); + public Renderer getRenderer() { + return new Renderer(); } public class Renderer extends DefaultTableCellRenderer { From f330fea11187ff2f5a9f503f80366efa1b21f2d8 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 12:52:01 -0700 Subject: [PATCH 70/76] localize EditMapSettings and EditScenarioDeploymentLimits dialogs --- .../EditMapSettingsDialog.properties | 7 +++++ ...tScenarioDeploymentLimitsDialog.properties | 8 ++++++ .../gui/dialog/EditMapSettingsDialog.java | 16 +++++++----- .../EditScenarioDeploymentLimitDialog.java | 26 +++++++++---------- 4 files changed, 37 insertions(+), 20 deletions(-) create mode 100644 MekHQ/resources/mekhq/resources/EditMapSettingsDialog.properties create mode 100644 MekHQ/resources/mekhq/resources/EditScenarioDeploymentLimitsDialog.properties diff --git a/MekHQ/resources/mekhq/resources/EditMapSettingsDialog.properties b/MekHQ/resources/mekhq/resources/EditMapSettingsDialog.properties new file mode 100644 index 0000000000..ffa16929f9 --- /dev/null +++ b/MekHQ/resources/mekhq/resources/EditMapSettingsDialog.properties @@ -0,0 +1,7 @@ +dialog.title=Select Map +checkFixed.text=Use Fixed Map +listMapGenerators.none=None +lblBoardType.text=Board Type: +lblMapSize.text=Map Size: +btnOK.text=Done +btnCancel.text=Cancel \ No newline at end of file diff --git a/MekHQ/resources/mekhq/resources/EditScenarioDeploymentLimitsDialog.properties b/MekHQ/resources/mekhq/resources/EditScenarioDeploymentLimitsDialog.properties new file mode 100644 index 0000000000..a60fc98277 --- /dev/null +++ b/MekHQ/resources/mekhq/resources/EditScenarioDeploymentLimitsDialog.properties @@ -0,0 +1,8 @@ +dialog.title=Edit Scenario Deployment Limits +panAllowedUnits.title=Allowed Units +checkAllUnits.text=Allow all units +lblQuantityType.text=Quantity Type: +lblCountType.text=Maximum Type: +lblQuantity.text=Maximum Quantity: +btnOK.text=Done +btnCancel.text=Cancel diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index decfb76179..a6d25ed3cc 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -27,6 +27,7 @@ import megamek.common.util.fileUtils.MegaMekFile; import megamek.server.GameManager; import megamek.server.ServerBoardHelper; +import mekhq.MekHQ; import mekhq.campaign.mission.Scenario; import org.apache.logging.log4j.LogManager; @@ -109,6 +110,9 @@ public int getMapSizeY() { } private void initComponents() { + final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.EditMapSettingsDialog", + MekHQ.getMHQOptions().getLocale()); + setTitle(resourceMap.getString("dialog.title")); getContentPane().setLayout(new BorderLayout()); JPanel panMain = new JPanel(new GridBagLayout()); @@ -121,7 +125,7 @@ private void initComponents() { scrChooseMap.setPreferredSize(new Dimension(600, 800)); - checkFixed = new JCheckBox("Use fixed map"); + checkFixed = new JCheckBox(resourceMap.getString("checkFixed.text")); checkFixed.setSelected(usingFixedMap); checkFixed.addActionListener(evt -> changeMapType()); @@ -157,7 +161,7 @@ private void initComponents() { listMapGenerators = new JList<>(generatorModel); listMapGenerators.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - generatorModel.addElement("None"); + generatorModel.addElement(resourceMap.getString("listMapGenerators.none")); File dir = new File("data/mapgen/"); File[] directoryListing = dir.listFiles(); ArrayList generators = new ArrayList<>(); @@ -202,7 +206,7 @@ private void initComponents() { gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(5, 5, 5, 5); - panMain.add(new JLabel("Board Type:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblBoardType.text")), gbc); gbc.weightx = 1.0; gbc.gridx++; panMain.add(comboBoardType, gbc); @@ -210,7 +214,7 @@ private void initComponents() { gbc.gridx = 0; gbc.gridy++; gbc.weightx = 0.0; - panMain.add(new JLabel("Map Size:"), gbc); + panMain.add(new JLabel(resourceMap.getString("lblMapSize.text")), gbc); gbc.gridx++; gbc.weightx = 1.0; panMain.add(panSizeRandom, gbc); @@ -231,9 +235,9 @@ private void initComponents() { gbc.weighty = 1.0; panMain.add(scrChooseMap, gbc); - JButton btnOK = new JButton("Done"); + JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); btnOK.addActionListener(evt -> done()); - JButton btnCancel = new JButton("Cancel"); + JButton btnCancel = new JButton(resourceMap.getString("btnCancel.text")); btnCancel.addActionListener(evt -> cancel()); panButtons.add(btnOK); panButtons.add(btnCancel); diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 309d18699d..7794763848 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -20,6 +20,7 @@ import megamek.client.ui.baseComponents.MMComboBox; import megamek.common.UnitType; +import mekhq.MekHQ; import mekhq.campaign.mission.ScenarioDeploymentLimit; import mekhq.campaign.mission.ScenarioDeploymentLimit.CountType; import mekhq.campaign.mission.ScenarioDeploymentLimit.QuantityType; @@ -28,6 +29,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.util.ArrayList; +import java.util.ResourceBundle; public class EditScenarioDeploymentLimitDialog extends JDialog { @@ -55,11 +57,10 @@ public EditScenarioDeploymentLimitDialog(JFrame parent, boolean modal, ScenarioD } private void initComponents() { - //final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.EditScenarioDeploymentLimitsDialog", - // MekHQ.getMHQOptions().getLocale()); + final ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.EditScenarioDeploymentLimitsDialog", + MekHQ.getMHQOptions().getLocale()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - setName("Form"); - setTitle("Edit Scenario Deployment Limits"); + setTitle(resourceMap.getString("dialog.title")); getContentPane().setLayout(new BorderLayout()); JPanel panMain = new JPanel(new GridBagLayout()); @@ -85,17 +86,15 @@ private void initComponents() { rightGbc.fill = GridBagConstraints.HORIZONTAL; rightGbc.anchor = GridBagConstraints.NORTHWEST; - JLabel lblQuantityType = new JLabel("Quantity Type:"); - panMain.add(lblQuantityType, leftGbc); + panMain.add(new JLabel(resourceMap.getString("lblQuantityType.text")), leftGbc); choiceQuantityType = new MMComboBox<>("choiceQuantityType", QuantityType.values()); choiceQuantityType.setSelectedItem(deploymentLimit.getQuantityType()); choiceQuantityType.addActionListener(this::setQuantityModel); panMain.add(choiceQuantityType, rightGbc); - JLabel lblCountType = new JLabel("Maximum Type:"); leftGbc.gridy++; - panMain.add(lblCountType, leftGbc); + panMain.add(new JLabel(resourceMap.getString("lblCountType.text")), leftGbc); choiceCountType = new MMComboBox<>("choiceCountType", CountType.values()); choiceCountType.setSelectedItem(deploymentLimit.getCountType()); choiceCountType.addActionListener(this::setQuantityModel); @@ -103,9 +102,8 @@ private void initComponents() { panMain.add(choiceCountType, rightGbc); - JLabel lblQuantity = new JLabel("Maximum Quantity:"); leftGbc.gridy++; - panMain.add(lblQuantity, leftGbc); + panMain.add(new JLabel(resourceMap.getString("lblQuantity.text")), leftGbc); spnQuantity = new JSpinner(); spnQuantity.setValue(deploymentLimit.getQuantityLimit()); setQuantityModel(null); @@ -115,8 +113,8 @@ private void initComponents() { JPanel panAllowedUnits = new JPanel(new GridLayout(UnitType.SIZE+1, 1)); panAllowedUnits.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createEmptyBorder(0, 0, 10, 0), - BorderFactory.createTitledBorder("Allowed Units"))); - checkAllUnits = new JCheckBox("Allow all units"); + BorderFactory.createTitledBorder(resourceMap.getString("panAllowedUnits.title")))); + checkAllUnits = new JCheckBox(resourceMap.getString("checkAllUnits.text")); checkAllUnits.setSelected(deploymentLimit.getAllowedUnitTypes().isEmpty()); checkAllUnits.addActionListener(this::checkAllUnits); panAllowedUnits.add(checkAllUnits); @@ -139,9 +137,9 @@ private void initComponents() { gbc.gridheight = 3; panMain.add(panAllowedUnits, gbc); - JButton btnOk = new JButton("OK"); + JButton btnOk = new JButton(resourceMap.getString("btnOK.text")); btnOk.addActionListener(this::complete); - JButton btnClose = new JButton("Cancel"); + JButton btnClose = new JButton(resourceMap.getString("btnCancel.text")); btnClose.addActionListener(this::cancel); panButtons.add(btnOk); panButtons.add(btnClose); From 023479ae4951be7461f9c1ce2c651a3cce688d36 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:03:43 -0700 Subject: [PATCH 71/76] Switch to random map list when space is selected in EditMapSettingsDialog --- MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index a6d25ed3cc..80559b1893 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -255,6 +255,7 @@ private void changeBoardType() { listMapGenerators.setSelectedIndex(0); listMapGenerators.setEnabled(false); listFixedMaps.setEnabled(false); + scrChooseMap.setViewportView(listMapGenerators); } else { checkFixed.setEnabled(true); listMapGenerators.setEnabled(true); @@ -343,12 +344,6 @@ public Component getListCellRendererComponent(JList list, Object value, setToolTipText(null); return super.getListCellRendererComponent(list, new File(board).getName(), index, isSelected, cellHasFocus); } else { - // There is a base image: make it into an icon, store it and use it - //if (!listFixedMaps.isEnabled()) { - // ImageFilter filter = new GrayFilter(true, 50); - // ImageProducer producer = new FilteredImageSource(image.getSource(), filter); - // image = Toolkit.getDefaultToolkit().createImage(producer); - //} icon = new ImageIcon(image); mapIcons.put(board, icon); From 786100f8975698c79f9fb59d3b8402491e20731d Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:11:37 -0700 Subject: [PATCH 72/76] Disable buttons on completed scenario --- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 1a680db308..52d3a9764d 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -267,6 +267,7 @@ public Component getListCellRendererComponent(final JList list, final Object panInfo.add(new JLabel(resourceMap.getString("lblDeployment.text")), gbc); btnDeployment = new JButton(Utilities.getDeploymentString(player)); + btnDeployment.setEnabled(scenario.getStatus().isCurrent()); btnDeployment.addActionListener(evt -> changeDeployment()); gbc.gridx = 1; gbc.gridwidth = 1; @@ -546,9 +547,11 @@ private void initDeployLimitPanel(ResourceBundle resourceMap) { JPanel panButtons = new JPanel(new GridLayout(0, 2)); JButton btnEditLimits = new JButton("Edit Limits"); + btnEditLimits.setEnabled(scenario.getStatus().isCurrent()); btnEditLimits.addActionListener(this::editLimits); panButtons.add(btnEditLimits); JButton btnRemoveLimits = new JButton("Remove Limits"); + btnRemoveLimits.setEnabled(scenario.getStatus().isCurrent()); btnRemoveLimits.addActionListener(this::removeLimits); panButtons.add(btnRemoveLimits); GridBagConstraints gbc = new GridBagConstraints(); From 404ac9135d24268fe8a6e8e77822a436477bb299 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:20:19 -0700 Subject: [PATCH 73/76] Complete localization of CustomizeScenarioDialog --- .../CustomizeScenarioDialog.properties | 9 ++++++++- .../gui/dialog/CustomizeScenarioDialog.java | 20 +++++++++++-------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties index e478f3314b..2a3cdffc5f 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioDialog.properties @@ -1,5 +1,5 @@ btnCancel.text=Cancel -btnOkay.text=OK +btnOkay.text=Done lblName.text=
Scenario Name: lblDate.text=Scenario Date: lblDeployment.text=Deployment: @@ -40,3 +40,10 @@ panOtherForces.title=Other Forces btnAddForce.text=Add Force btnEditForce.text=Edit Force btnDeleteForce.text=Delete Force +panObjectives.title=Scenario Objectives +panLoot.title=Scenario Costs & Payouts +addEventButton.text=Apply Modifier +txtDesc.title=Description +txtReport.title=After-Action Report +btnEditLimits.text=Edit Limits +btnRemoveLimits.text=Remove Limits diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 52d3a9764d..756e01e10e 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -200,7 +200,11 @@ private void initComponents() { MekHQ.getMHQOptions().getLocale()); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setName("Form"); - setTitle(resourceMap.getString("title.new")); + if(newScenario) { + setTitle(resourceMap.getString("title.new")); + } else { + setTitle(resourceMap.getString("title")); + } JPanel panMain = new JPanel(new GridBagLayout()); JPanel panInfo = new JPanel(new GridBagLayout()); @@ -290,7 +294,7 @@ public Component getListCellRendererComponent(final JList list, final Object } panInfo.add(modifierBox, gbc); - JButton addEventButton = new JButton("Apply Modifier"); + JButton addEventButton = new JButton(resourceMap.getString("addEventButton.text")); addEventButton.addActionListener(this::btnAddModifierActionPerformed); gbc.gridx = 1; panInfo.add(addEventButton, gbc); @@ -316,14 +320,14 @@ public Component getListCellRendererComponent(final JList list, final Object panObjectives.setPreferredSize(new Dimension(400,150)); panObjectives.setMinimumSize(new Dimension(400,150)); panObjectives.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Scenario Objectives"), + BorderFactory.createTitledBorder(resourceMap.getString("panObjectives.title")), BorderFactory.createEmptyBorder(5,5,5,5))); initLootPanel(resourceMap); panLoot.setPreferredSize(new Dimension(400,150)); panLoot.setMinimumSize(new Dimension(400,150)); panLoot.setBorder(BorderFactory.createCompoundBorder( - BorderFactory.createTitledBorder("Scenario Costs & Payouts"), + BorderFactory.createTitledBorder(resourceMap.getString("panLoot.title")), BorderFactory.createEmptyBorder(5,5,5,5))); initOtherForcesPanel(resourceMap); @@ -333,7 +337,7 @@ public Component getListCellRendererComponent(final JList list, final Object panOtherForces.setPreferredSize(new Dimension(600,250)); panOtherForces.setMinimumSize(new Dimension(600,250)); - txtDesc = new MarkdownEditorPanel("Description"); + txtDesc = new MarkdownEditorPanel(resourceMap.getString("txtDesc.title")); txtDesc.setText(scenario.getDescription()); txtDesc.setMinimumSize(new Dimension(400, 100)); txtDesc.setPreferredSize(new Dimension(400, 250)); @@ -349,7 +353,7 @@ public Component getListCellRendererComponent(final JList list, final Object panWrite.add(txtDesc, gbc); if (!scenario.getStatus().isCurrent()) { - txtReport = new MarkdownEditorPanel("After-Action Report"); + txtReport = new MarkdownEditorPanel(resourceMap.getString("txtReport.title")); txtReport.setText(scenario.getReport()); txtReport.setMinimumSize(new Dimension(400, 100)); txtReport.setPreferredSize(new Dimension(400, 250)); @@ -546,11 +550,11 @@ private void initDeployLimitPanel(ResourceBundle resourceMap) { BorderFactory.createTitledBorder(resourceMap.getString("panDeploymentLimits.title")))); JPanel panButtons = new JPanel(new GridLayout(0, 2)); - JButton btnEditLimits = new JButton("Edit Limits"); + JButton btnEditLimits = new JButton(resourceMap.getString("btnEditLimits.text")); btnEditLimits.setEnabled(scenario.getStatus().isCurrent()); btnEditLimits.addActionListener(this::editLimits); panButtons.add(btnEditLimits); - JButton btnRemoveLimits = new JButton("Remove Limits"); + JButton btnRemoveLimits = new JButton(resourceMap.getString("btnRemoveLimits.text")); btnRemoveLimits.setEnabled(scenario.getStatus().isCurrent()); btnRemoveLimits.addActionListener(this::removeLimits); panButtons.add(btnRemoveLimits); From 878a73558d9603572f468e3f5c3e697ea7bc8aab Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:32:49 -0700 Subject: [PATCH 74/76] Use FlowLayout for buttons in dialogs --- .../mekhq/resources/CustomizeBotForceDialog.properties | 2 +- .../mekhq/resources/CustomizeScenarioObjectiveDialog.properties | 2 +- MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties | 2 +- MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java | 2 +- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 2 +- .../src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java | 2 +- MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java | 2 +- MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java | 2 +- .../src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties index 80f53d1783..dbb2a594ee 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeBotForceDialog.properties @@ -33,7 +33,7 @@ lblBaChance.text=Integrated BA Chance: lblBaChance.tooltip=Probability that this force includes
integrated Battle Armor units. lblLanceSize.text=Formation Size: lblLanceSize.tooltip=The minimum group size that units should be added in.
Larger values can lead to more approximate
results with force multiplier matching. -btnOK.text=OK +btnOK.text=Done btnClose.text=Cancel btnBehavior.text=Edit Behavior Settings btnLoadUnits.text=Load Fixed Units diff --git a/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties b/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties index 56486cc704..3befcb662f 100644 --- a/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties +++ b/MekHQ/resources/mekhq/resources/CustomizeScenarioObjectiveDialog.properties @@ -14,4 +14,4 @@ lblFailureEffects.text=Effects on Failure btnAdd.text=Add btnRemove.text=Remove btnCancel.text=Cancel -btnOK.text=OK \ No newline at end of file +btnOK.text=Done \ No newline at end of file diff --git a/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties b/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties index eb742ab82e..a243e62e3c 100644 --- a/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties +++ b/MekHQ/resources/mekhq/resources/EditDeploymentDialog.properties @@ -4,5 +4,5 @@ labDeploymentWidth.text=Deployment Zone Width labDeploymentWidth.tip=Deployment Zone width, in hexes labDeploymentAnyNW.text=Deployment Zone NW corner labDeploymentAnySE.text=Deployment Zone SE corner -btnOK.text=OK +btnOK.text=Done btnCancel.text=Cancel \ No newline at end of file diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java index dd4ab31eee..163f91bee9 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java @@ -133,7 +133,7 @@ private void initComponents() { getContentPane().add(panLeft, BorderLayout.WEST); getContentPane().add(panCenter, BorderLayout.CENTER); - JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JPanel panButtons = new JPanel(new FlowLayout()); JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); btnOK.addActionListener(this::done); JButton btnClose = new JButton(resourceMap.getString("btnClose.text")); diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 756e01e10e..090c58afe0 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -209,7 +209,7 @@ private void initComponents() { JPanel panMain = new JPanel(new GridBagLayout()); JPanel panInfo = new JPanel(new GridBagLayout()); JPanel panWrite = new JPanel(new GridBagLayout()); - JPanel panBtn = new JPanel(new GridLayout(0,2)); + JPanel panBtn = new JPanel(new FlowLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java index d0e2d62c00..9b4fc6acdc 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java @@ -243,7 +243,7 @@ private void initialize() { getContentPane().add(panMain, BorderLayout.CENTER); - JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JPanel panButtons = new JPanel(new FlowLayout()); JButton btnCancel = new JButton(resourceMap.getString("btnCancel.text")); btnCancel.addActionListener(e -> this.setVisible(false)); JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); diff --git a/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java index bcc5dcd736..e43e59d121 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditDeploymentDialog.java @@ -129,7 +129,7 @@ private void initComponents() { getContentPane().add(main, BorderLayout.CENTER); getContentPane().add(panStartButtons, BorderLayout.PAGE_START); - JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JPanel panButtons = new JPanel(new FlowLayout()); JButton btnOK = new JButton(resourceMap.getString("btnOK.text")); btnOK.addActionListener(this::done); JButton btnCancel = new JButton(resourceMap.getString("btnCancel.text")); diff --git a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java index 80559b1893..f64437b443 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java @@ -118,7 +118,7 @@ private void initComponents() { JPanel panMain = new JPanel(new GridBagLayout()); panSizeRandom = new JPanel(new GridBagLayout()); panSizeFixed = new JPanel(new BorderLayout()); - JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JPanel panButtons = new JPanel(new FlowLayout()); scrChooseMap = new JScrollPane(); scrChooseMap.setMinimumSize(new Dimension(600, 800)); diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 7794763848..42ec6723f0 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -64,7 +64,7 @@ private void initComponents() { getContentPane().setLayout(new BorderLayout()); JPanel panMain = new JPanel(new GridBagLayout()); - JPanel panButtons = new JPanel(new GridLayout(0, 2)); + JPanel panButtons = new JPanel(new FlowLayout()); GridBagConstraints leftGbc = new GridBagConstraints(); leftGbc.gridx = 0; From c44333674a02a93214161afa21d8beb6bb29a486 Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:35:08 -0700 Subject: [PATCH 75/76] Use insets in EditScenarioDeploymentLimitsDialog --- .../mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java index 42ec6723f0..cc193feba4 100644 --- a/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/EditScenarioDeploymentLimitDialog.java @@ -72,7 +72,7 @@ private void initComponents() { leftGbc.gridwidth = 1; leftGbc.weightx = 0.0; leftGbc.weighty = 0.0; - leftGbc.insets = new Insets(0, 0, 5, 10); + leftGbc.insets = new Insets(5, 5, 5, 10); leftGbc.fill = GridBagConstraints.NONE; leftGbc.anchor = GridBagConstraints.NORTHWEST; @@ -82,7 +82,7 @@ private void initComponents() { rightGbc.gridwidth = 1; rightGbc.weightx = 1.0; rightGbc.weighty = 0.0; - rightGbc.insets = new Insets(0, 10, 5, 0); + rightGbc.insets = new Insets(5, 10, 5, 5); rightGbc.fill = GridBagConstraints.HORIZONTAL; rightGbc.anchor = GridBagConstraints.NORTHWEST; @@ -134,6 +134,7 @@ private void initComponents() { gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.anchor = GridBagConstraints.NORTHWEST; + rightGbc.insets = new Insets(5, 5, 5, 5); gbc.gridheight = 3; panMain.add(panAllowedUnits, gbc); From 8d1c1e0640aa4bc295c5d8f9bff6d93b8adff52b Mon Sep 17 00:00:00 2001 From: Aaron Gullickson Date: Mon, 6 May 2024 13:59:56 -0700 Subject: [PATCH 76/76] Correct error with using old method --- MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java index 090c58afe0..8ba9906957 100644 --- a/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java @@ -735,7 +735,7 @@ private void initPlanetaryConditionsPanel(ResourceBundle resourceMap) { leftGbc.gridy = 1; panPlanetaryConditions.add(new JLabel(resourceMap.getString("lblTemperature.text")), leftGbc); - lblTemperatureDesc = new JLabel(PlanetaryConditions.getTemperatureDisplayableName(scenario.getModifiedTemperature())); + lblTemperatureDesc = new JLabel(PlanetaryConditions.getTemperatureDisplayableName(scenario.getTemperature())); rightGbc.gridx = 3; rightGbc.gridy = 1; rightGbc.gridwidth = 1;