/*
* Copyright (c) 2017 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 <http://www.gnu.org/licenses/>.
*/
package mekhq.gui;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.ResourceBundle;
import java.util.UUID;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.filechooser.FileFilter;
import megamek.common.Entity;
import megamek.common.EntityListFile;
import megamek.common.event.Subscribe;
import megamek.common.options.GameOptions;
import megamek.common.util.EncodeControl;
import megameklab.com.util.UnitPrintManager;
import mekhq.MekHQ;
import mekhq.campaign.ResolveScenarioTracker;
import mekhq.campaign.event.MissionChangedEvent;
import mekhq.campaign.event.MissionCompletedEvent;
import mekhq.campaign.event.MissionNewEvent;
import mekhq.campaign.event.MissionRemovedEvent;
import mekhq.campaign.event.OptionsChangedEvent;
import mekhq.campaign.event.OrganizationChangedEvent;
import mekhq.campaign.event.ScenarioChangedEvent;
import mekhq.campaign.event.ScenarioNewEvent;
import mekhq.campaign.event.ScenarioRemovedEvent;
import mekhq.campaign.event.ScenarioResolvedEvent;
import mekhq.campaign.force.Force;
import mekhq.campaign.force.Lance;
import mekhq.campaign.mission.AtBContract;
import mekhq.campaign.mission.AtBScenario;
import mekhq.campaign.mission.Contract;
import mekhq.campaign.mission.Mission;
import mekhq.campaign.mission.Scenario;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.unit.Unit;
import mekhq.gui.adapter.ScenarioTableMouseAdapter;
import mekhq.gui.dialog.ChooseMulFilesDialog;
import mekhq.gui.dialog.CompleteMissionDialog;
import mekhq.gui.dialog.CustomizeAtBContractDialog;
import mekhq.gui.dialog.CustomizeMissionDialog;
import mekhq.gui.dialog.CustomizeScenarioDialog;
import mekhq.gui.dialog.MissionTypeDialog;
import mekhq.gui.dialog.NewAtBContractDialog;
import mekhq.gui.dialog.NewContractDialog;
import mekhq.gui.dialog.ResolveScenarioWizardDialog;
import mekhq.gui.dialog.RetirementDefectionDialog;
import mekhq.gui.model.ScenarioTableModel;
import mekhq.gui.view.AtBContractViewPanel;
import mekhq.gui.view.AtBScenarioViewPanel;
import mekhq.gui.view.ContractViewPanel;
import mekhq.gui.view.LanceAssignmentView;
import mekhq.gui.view.MissionViewPanel;
import mekhq.gui.view.ScenarioViewPanel;
/**
* Displays Mission/Contract and Scenario details.
*
*/
public final class BriefingTab extends CampaignGuiTab {
private static final long serialVersionUID = 5927572086088284329L;
private JPanel panBriefing;
private JPanel panScenario;
private LanceAssignmentView panLanceAssignment;
private JSplitPane splitScenario;
private JSplitPane splitBrief;
private JSplitPane splitMission;
private JTable scenarioTable;
private JComboBox<String> choiceMission;
private JScrollPane scrollMissionView;
private JScrollPane scrollScenarioView;
private JPanel panMissionButtons;
private JPanel panScenarioButtons;
private JButton btnAddScenario;
private JButton btnAddMission;
private JButton btnEditMission;
private JButton btnCompleteMission;
private JButton btnDeleteMission;
private JButton btnStartGame;
private JButton btnJoinGame;
private JButton btnLoadGame;
private JButton btnPrintRS;
private JButton btnGetMul;
private JButton btnClearAssignedUnits;
private JButton btnResolveScenario;
private ScenarioTableModel scenarioModel;
public int selectedMission;
public int selectedScenario;
BriefingTab(CampaignGUI gui, String tabName) {
super(gui, tabName);
selectedMission = -1;
selectedScenario = -1;
MekHQ.registerHandler(this);
}
@Override
public GuiTabType tabType() {
return GuiTabType.BRIEFING;
}
/*
* (non-Javadoc)
*
* @see mekhq.gui.CampaignGuiTab#initTab()
*/
@Override
public void initTab() {
ResourceBundle resourceMap = ResourceBundle.getBundle("mekhq.resources.CampaignGUI", //$NON-NLS-1$ ;
new EncodeControl());
GridBagConstraints gridBagConstraints;
panBriefing = new JPanel(new GridBagLayout());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.NONE;
gridBagConstraints.anchor = java.awt.GridBagConstraints.CENTER;
gridBagConstraints.weightx = 0.0;
gridBagConstraints.weighty = 0.0;
panBriefing.add(new JLabel(resourceMap.getString("lblMission.text")), //$NON-NLS-1$ ;
gridBagConstraints);
choiceMission = new JComboBox<String>();
choiceMission.addActionListener(ev -> changeMission());
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.anchor = GridBagConstraints.WEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 0.0;
panBriefing.add(choiceMission, gridBagConstraints);
panMissionButtons = new JPanel(new GridLayout(2, 3));
gridBagConstraints = new GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridheight = 2;
gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 0.0;
panBriefing.add(panMissionButtons, gridBagConstraints);
btnAddMission = new JButton(resourceMap.getString("btnAddMission.text")); // NOI18N
btnAddMission.setToolTipText(resourceMap.getString("btnAddMission.toolTipText")); // NOI18N
btnAddMission.addActionListener(ev -> addMission());
panMissionButtons.add(btnAddMission);
btnAddScenario = new JButton(resourceMap.getString("btnAddScenario.text")); // NOI18N
btnAddScenario.setToolTipText(resourceMap.getString("btnAddScenario.toolTipText")); // NOI18N
btnAddScenario.addActionListener(ev -> addScenario());
panMissionButtons.add(btnAddScenario);
btnEditMission = new JButton(resourceMap.getString("btnEditMission.text")); // NOI18N
btnEditMission.setToolTipText(resourceMap.getString("btnEditMission.toolTipText")); // NOI18N
btnEditMission.addActionListener(ev -> editMission());
panMissionButtons.add(btnEditMission);
btnCompleteMission = new JButton(resourceMap.getString("btnCompleteMission.text")); // NOI18N
btnCompleteMission.setToolTipText(resourceMap.getString("btnCompleteMission.toolTipText")); // NOI18N
btnCompleteMission.addActionListener(ev -> completeMission());
panMissionButtons.add(btnCompleteMission);
btnDeleteMission = new JButton(resourceMap.getString("btnDeleteMission.text")); // NOI18N
btnDeleteMission.setToolTipText(resourceMap.getString("btnDeleteMission.toolTipText")); // NOI18N
btnDeleteMission.setName("btnDeleteMission"); // NOI18N
btnDeleteMission.addActionListener(ev -> deleteMission());
panMissionButtons.add(btnDeleteMission);
scrollMissionView = new JScrollPane();
scrollMissionView.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollMissionView.setViewportView(null);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 2;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
panBriefing.add(scrollMissionView, gridBagConstraints);
scenarioModel = new ScenarioTableModel(getCampaign());
scenarioTable = new JTable(scenarioModel);
scenarioTable.setShowGrid(false);
scenarioTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
scenarioTable.addMouseListener(new ScenarioTableMouseAdapter(getCampaignGui(),
scenarioTable, scenarioModel));
scenarioTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
scenarioTable.setIntercellSpacing(new Dimension(0, 0));
scenarioTable.getSelectionModel().addListSelectionListener(ev -> refreshScenarioView());
JScrollPane scrollScenarioTable = new JScrollPane(scenarioTable);
scrollScenarioTable.setMinimumSize(new java.awt.Dimension(200, 200));
scrollScenarioTable.setPreferredSize(new java.awt.Dimension(200, 200));
splitMission = new JSplitPane(JSplitPane.VERTICAL_SPLIT, panBriefing, scrollScenarioTable);
splitMission.setOneTouchExpandable(true);
splitMission.setResizeWeight(1.0);
panScenario = new JPanel(new GridBagLayout());
panScenarioButtons = new JPanel(new GridLayout(3, 3));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 0.0;
panScenario.add(panScenarioButtons, gridBagConstraints);
btnStartGame = new JButton(resourceMap.getString("btnStartGame.text")); // NOI18N
btnStartGame.setToolTipText(resourceMap.getString("btnStartGame.toolTipText")); // NOI18N
btnStartGame.addActionListener(ev -> startScenario());
btnStartGame.setEnabled(false);
panScenarioButtons.add(btnStartGame);
btnJoinGame = new JButton(resourceMap.getString("btnJoinGame.text")); // NOI18N
btnJoinGame.setToolTipText(resourceMap.getString("btnJoinGame.toolTipText")); // NOI18N
btnJoinGame.addActionListener(ev -> joinScenario());
btnJoinGame.setEnabled(false);
panScenarioButtons.add(btnJoinGame);
btnLoadGame = new JButton(resourceMap.getString("btnLoadGame.text")); // NOI18N
btnLoadGame.setToolTipText(resourceMap.getString("btnLoadGame.toolTipText")); // NOI18N
btnLoadGame.addActionListener(ev -> loadScenario());
btnLoadGame.setEnabled(false);
panScenarioButtons.add(btnLoadGame);
btnPrintRS = new JButton(resourceMap.getString("btnPrintRS.text")); // NOI18N
btnPrintRS.setToolTipText(resourceMap.getString("btnPrintRS.toolTipText")); // NOI18N
btnPrintRS.addActionListener(ev -> printRecordSheets());
btnPrintRS.setEnabled(false);
panScenarioButtons.add(btnPrintRS);
btnGetMul = new JButton(resourceMap.getString("btnGetMul.text")); // NOI18N
btnGetMul.setToolTipText(resourceMap.getString("btnGetMul.toolTipText")); // NOI18N
btnGetMul.setName("btnGetMul"); // NOI18N
btnGetMul.addActionListener(ev -> deployListFile());
btnGetMul.setEnabled(false);
panScenarioButtons.add(btnGetMul);
btnResolveScenario = new JButton(resourceMap.getString("btnResolveScenario.text")); // NOI18N
btnResolveScenario.setToolTipText(resourceMap.getString("btnResolveScenario.toolTipText")); // NOI18N
btnResolveScenario.addActionListener(ev -> resolveScenario());
btnResolveScenario.setEnabled(false);
panScenarioButtons.add(btnResolveScenario);
btnClearAssignedUnits = new JButton(resourceMap.getString("btnClearAssignedUnits.text")); // NOI18N
btnClearAssignedUnits.setToolTipText(resourceMap.getString("btnClearAssignedUnits.toolTipText")); // NOI18N
btnClearAssignedUnits.addActionListener(ev -> clearAssignedUnits());
btnClearAssignedUnits.setEnabled(false);
panScenarioButtons.add(btnClearAssignedUnits);
scrollScenarioView = new JScrollPane();
scrollScenarioView.setViewportView(null);
scrollScenarioView.setMinimumSize(new java.awt.Dimension(450, 600));
scrollScenarioView.setPreferredSize(new java.awt.Dimension(450, 600));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
panScenario.add(scrollScenarioView, gridBagConstraints);
/* ATB */
panLanceAssignment = new LanceAssignmentView(getCampaign());
JScrollPane paneLanceDeployment = new JScrollPane(panLanceAssignment);
paneLanceDeployment.setMinimumSize(new java.awt.Dimension(200, 300));
paneLanceDeployment.setPreferredSize(new java.awt.Dimension(200, 300));
paneLanceDeployment.setVisible(getCampaign().getCampaignOptions().getUseAtB());
splitScenario = new javax.swing.JSplitPane(javax.swing.JSplitPane.VERTICAL_SPLIT, panScenario,
paneLanceDeployment);
splitScenario.setOneTouchExpandable(true);
splitScenario.setResizeWeight(1.0);
splitBrief = new javax.swing.JSplitPane(javax.swing.JSplitPane.HORIZONTAL_SPLIT, splitMission, splitScenario);
splitBrief.setOneTouchExpandable(true);
splitBrief.setResizeWeight(0.5);
splitBrief.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, ev -> refreshScenarioView());
setLayout(new BorderLayout());
add(splitBrief, BorderLayout.CENTER);
}
private void addMission() {
MissionTypeDialog mtd = new MissionTypeDialog(getFrame(), true);
mtd.setVisible(true);
if (mtd.isContract()) {
NewContractDialog ncd = getCampaignOptions().getUseAtB()
? new NewAtBContractDialog(getFrame(), true, getCampaign())
: new NewContractDialog(getFrame(), true, getCampaign());
ncd.setVisible(true);
this.setVisible(false);
if (ncd.getContractId() != -1) {
selectedMission = ncd.getContractId();
}
} else {
CustomizeMissionDialog cmd = new CustomizeMissionDialog(getFrame(), true, null, getCampaign());
cmd.setVisible(true);
this.setVisible(false);
if (cmd.getMissionId() != -1) {
selectedMission = cmd.getMissionId();
}
}
}
private void editMission() {
Mission mission = getCampaign().getMission(selectedMission);
if (null != mission) {
if (getCampaign().getCampaignOptions().getUseAtB() && mission instanceof AtBContract) {
CustomizeAtBContractDialog cmd = new CustomizeAtBContractDialog(getFrame(), true, (AtBContract) mission,
getCampaign(), getIconPackage().getCamos());
cmd.setVisible(true);
if (cmd.getMissionId() != -1) {
selectedMission = cmd.getMissionId();
}
} else {
CustomizeMissionDialog cmd = new CustomizeMissionDialog(getFrame(), true, mission, getCampaign());
cmd.setVisible(true);
if (cmd.getMissionId() != -1) {
selectedMission = cmd.getMissionId();
}
}
MekHQ.triggerEvent(new MissionChangedEvent(mission));
}
}
private void completeMission() {
Mission mission = getCampaign().getMission(selectedMission);
if (null != mission) {
if (mission.hasPendingScenarios()) {
JOptionPane.showMessageDialog(getFrame(), "You cannot complete a mission that has pending scenarios",
"Pending Scenarios", JOptionPane.WARNING_MESSAGE);
} else {
CompleteMissionDialog cmd = new CompleteMissionDialog(getFrame(), true, mission);
cmd.setVisible(true);
if (cmd.getStatus() > Mission.S_ACTIVE) {
getCampaign().completeMission(mission.getId(), cmd.getStatus());
if (getCampaign().getCampaignOptions().getUseAtB() && mission instanceof AtBContract) {
if (((AtBContract) mission).contractExtended(getCampaign())) {
mission.setStatus(Mission.S_ACTIVE);
} else {
if (getCampaign().getCampaignOptions().doRetirementRolls()) {
RetirementDefectionDialog rdd = new RetirementDefectionDialog(getCampaignGui(),
(AtBContract) mission, true);
rdd.setVisible(true);
if (rdd.wasAborted()) {
/*
* Once the retirement rolls have been made,
* the outstanding payouts can be resolved
* without reference to the contract and the
* dialog can be accessed through the menu.
*/
if (!getCampaign().getRetirementDefectionTracker().isOutstanding(mission.getId())) {
mission.setStatus(Mission.S_ACTIVE);
}
} else {
if (null != getCampaign().getRetirementDefectionTracker()
.getRetirees((AtBContract) mission)
&& getCampaign().getFinances().getBalance() >= rdd.totalPayout()) {
final int[] admins = { Person.T_ADMIN_COM, Person.T_ADMIN_HR,
Person.T_ADMIN_LOG, Person.T_ADMIN_TRA };
for (int role : admins) {
Person admin = getCampaign().findBestInRole(role, SkillType.S_ADMIN);
if (admin != null) {
admin.setXp(admin.getXp() + 1);
getCampaign()
.addReport(admin.getHyperlinkedName() + " has gained 1 XP.");
}
}
}
if (!getCampaign().applyRetirement(rdd.totalPayout(), rdd.getUnitAssignments())) {
mission.setStatus(Mission.S_ACTIVE);
}
}
}
}
}
}
if (!mission.isActive()) {
if (getCampaign().getCampaignOptions().getUseAtB() && mission instanceof AtBContract) {
((AtBContract) mission).checkForFollowup(getCampaign());
}
if (getCampaign().getSortedMissions().size() > 0) {
selectedMission = getCampaign().getSortedMissions().get(0).getId();
} else {
selectedMission = -1;
}
}
}
}
}
private void deleteMission() {
Mission mission = getCampaign().getMission(selectedMission);
MekHQ.logMessage("Attempting to Delete Mission, Mission ID: " + mission.getId());
if (0 != JOptionPane.showConfirmDialog(null, "Are you sure you want to delete this mission?", "Delete mission?",
JOptionPane.YES_NO_OPTION)) {
return;
}
getCampaign().removeMission(mission.getId());
if (getCampaign().getSortedMissions().size() > 0) {
selectedMission = getCampaign().getSortedMissions().get(0).getId();
} else {
selectedMission = -1;
}
MekHQ.triggerEvent(new MissionRemovedEvent(mission));
}
private void addScenario() {
Mission m = getCampaign().getMission(selectedMission);
if (null != m) {
CustomizeScenarioDialog csd = new CustomizeScenarioDialog(getFrame(), true, null, m, getCampaign());
csd.setVisible(true);
}
}
protected void clearAssignedUnits() {
if (0 == JOptionPane.showConfirmDialog(null, "Do you really want to remove all units from this scenario?",
"Clear Units?", JOptionPane.YES_NO_OPTION)) {
int row = scenarioTable.getSelectedRow();
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
if (null == scenario) {
return;
}
scenario.clearAllForcesAndPersonnel(getCampaign());
}
}
protected void resolveScenario() {
int row = scenarioTable.getSelectedRow();
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
if (null == scenario) {
return;
}
boolean control = JOptionPane.showConfirmDialog(getFrame(),
"Did your side control the battlefield at the end of the scenario?", "Control of Battlefield?",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION;
ResolveScenarioTracker tracker = new ResolveScenarioTracker(scenario, getCampaign(), control);
ChooseMulFilesDialog chooseFilesDialog = new ChooseMulFilesDialog(getFrame(), true, tracker);
chooseFilesDialog.setVisible(true);
if (chooseFilesDialog.wasCancelled()) {
return;
}
// tracker.postProcessEntities(control);
ResolveScenarioWizardDialog resolveDialog = new ResolveScenarioWizardDialog(getFrame(), true, tracker);
resolveDialog.setVisible(true);
if (getCampaign().getCampaignOptions().getUseAtB()
&& getCampaign().getMission(scenario.getMissionId()) instanceof AtBContract
&& getCampaign().getRetirementDefectionTracker().getRetirees().size() > 0) {
RetirementDefectionDialog rdd = new RetirementDefectionDialog(getCampaignGui(),
(AtBContract) getCampaign().getMission(scenario.getMissionId()), false);
rdd.setVisible(true);
if (!rdd.wasAborted()) {
getCampaign().applyRetirement(rdd.totalPayout(), rdd.getUnitAssignments());
}
}
MekHQ.triggerEvent(new ScenarioResolvedEvent(scenario));
}
protected void printRecordSheets() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
Vector<UUID> uids = scenario.getForces(getCampaign()).getAllUnits();
if (uids.size() == 0) {
return;
}
Vector<Entity> chosen = new Vector<Entity>();
// ArrayList<Unit> toDeploy = new ArrayList<Unit>();
StringBuffer undeployed = new StringBuffer();
for (UUID uid : uids) {
Unit u = getCampaign().getUnit(uid);
if (null != u.getEntity()) {
if (null == u.checkDeployment()) {
chosen.add(u.getEntity());
} else {
undeployed.append("\n").append(u.getName()).append(" (").append(u.checkDeployment()).append(")");
}
}
}
if (undeployed.length() > 0) {
Object[] options = { "Continue", "Cancel" };
int n = JOptionPane.showOptionDialog(getFrame(),
"The following units could not be deployed:" + undeployed.toString(), "Could not deploy some units",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
if (n == 1) {
return;
}
}
if (chosen.size() > 0) {
UnitPrintManager.printAllUnits(chosen, true);
}
}
protected void loadScenario() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
if (null != scenario) {
getCampaignGui().getApplication().startHost(scenario, true, null);
}
}
protected void startScenario() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
Vector<UUID> uids = scenario.getForces(getCampaign()).getAllUnits();
if (uids.size() == 0) {
return;
}
ArrayList<Unit> chosen = new ArrayList<Unit>();
// ArrayList<Unit> toDeploy = new ArrayList<Unit>();
StringBuffer undeployed = new StringBuffer();
for (UUID uid : uids) {
Unit u = getCampaign().getUnit(uid);
if (null != u.getEntity()) {
if (null == u.checkDeployment()) {
// Make sure the unit's entity and pilot are fully up to
// date!
u.resetPilotAndEntity();
// Add and run
chosen.add(u);
// So MegaMek has correct crew sizes
u.getEntity().getCrew().setSize(u.getActiveCrew().size());
} else {
undeployed.append("\n").append(u.getName()).append(" (").append(u.checkDeployment()).append(")");
}
}
}
if (undeployed.length() > 0) {
Object[] options = { "Continue", "Cancel" };
int n = JOptionPane.showOptionDialog(getFrame(),
"The following units could not be deployed:" + undeployed.toString(), "Could not deploy some units",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
if (n == 1) {
return;
}
}
if (getCampaign().getCampaignOptions().getUseAtB() && scenario instanceof AtBScenario) {
((AtBScenario) scenario).refresh(getCampaign());
/*
* For standard battles, any deployed unit not part of the lance
* assigned to the battle is assumed to be reinforcements.
*/
if (null != ((AtBScenario) scenario).getLance(getCampaign())) {
int assignedForceId = ((AtBScenario) scenario).getLance(getCampaign()).getForceId();
int cmdrStrategy = 0;
Person commander = getCampaign().getPerson(Lance.findCommander(assignedForceId, getCampaign()));
if (null != commander && null != commander.getSkill(SkillType.S_STRATEGY)) {
cmdrStrategy = commander.getSkill(SkillType.S_STRATEGY).getLevel();
}
for (Force f : scenario.getForces(getCampaign()).getSubForces()) {
if (f.getId() != assignedForceId) {
Vector<UUID> units = f.getAllUnits();
int slowest = 12;
for (UUID id : units) {
if (chosen.contains(getCampaign().getUnit(id))) {
int speed = getCampaign().getUnit(id).getEntity().getWalkMP();
if (getCampaign().getUnit(id).getEntity().getJumpMP() > 0) {
if (getCampaign().getUnit(id).getEntity() instanceof megamek.common.Infantry) {
speed = getCampaign().getUnit(id).getEntity().getJumpMP();
} else {
speed++;
}
}
slowest = Math.min(slowest, speed);
}
}
int deployRound = Math.max(0, 12 - slowest - cmdrStrategy);
for (UUID id : units) {
if (chosen.contains(getCampaign().getUnit(id))) {
getCampaign().getUnit(id).getEntity().setDeployRound(deployRound);
}
}
}
}
}
}
if (chosen.size() > 0) {
// Ensure that the MegaMek year GameOption matches the campaign year
GameOptions gameOpts = getCampaign().getGameOptions();
int campaignYear = getCampaign().getCalendar().get(Calendar.YEAR);
if (gameOpts.intOption("year") != campaignYear) {
gameOpts.getOption("year").setValue(campaignYear);
}
getCampaignGui().getApplication().startHost(scenario, false, chosen);
}
}
protected void joinScenario() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
Vector<UUID> uids = scenario.getForces(getCampaign()).getAllUnits();
if (uids.size() == 0) {
return;
}
ArrayList<Unit> chosen = new ArrayList<Unit>();
// ArrayList<Unit> toDeploy = new ArrayList<Unit>();
StringBuffer undeployed = new StringBuffer();
for (UUID uid : uids) {
Unit u = getCampaign().getUnit(uid);
if (null != u.getEntity()) {
if (null == u.checkDeployment()) {
// Make sure the unit's entity and pilot are fully up to
// date!
u.resetPilotAndEntity();
// Add and run
chosen.add(u);
// So MegaMek has correct crew sizes
u.getEntity().getCrew().setSize(u.getActiveCrew().size());
} else {
undeployed.append("\n").append(u.getName()).append(" (").append(u.checkDeployment()).append(")");
}
}
}
if (undeployed.length() > 0) {
Object[] options = { "Continue", "Cancel" };
int n = JOptionPane.showOptionDialog(getFrame(),
"The following units could not be deployed:" + undeployed.toString(), "Could not deploy some units",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
if (n == 1) {
return;
}
}
if (chosen.size() > 0) {
getCampaignGui().getApplication().joinGame(scenario, chosen);
}
}
protected void deployListFile() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
Vector<UUID> uids = scenario.getForces(getCampaign()).getAllUnits();
if (uids.size() == 0) {
return;
}
ArrayList<Entity> chosen = new ArrayList<Entity>();
// ArrayList<Unit> toDeploy = new ArrayList<Unit>();
StringBuffer undeployed = new StringBuffer();
for (UUID uid : uids) {
Unit u = getCampaign().getUnit(uid);
if (null != u.getEntity()) {
if (null == u.checkDeployment()) {
// Make sure the unit's entity and pilot are fully up to
// date!
u.resetPilotAndEntity();
// So MegaMek has correct crew sizes
u.getEntity().getCrew().setSize(u.getActiveCrew().size());
// Add the entity
chosen.add(u.getEntity());
} else {
undeployed.append("\n").append(u.getName()).append(" (").append(u.checkDeployment()).append(")");
}
}
}
if (undeployed.length() > 0) {
Object[] options = { "Continue", "Cancel" };
int n = JOptionPane.showOptionDialog(getFrame(),
"The following units could not be deployed:" + undeployed.toString(), "Could not deploy some units",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
if (n == 1) {
return;
}
}
JFileChooser saveList = new JFileChooser(".");
saveList.setDialogTitle("Deploy Units");
saveList.setFileFilter(new FileFilter() {
@Override
public boolean accept(File dir) {
if (dir.isDirectory()) {
return true;
}
return dir.getName().endsWith(".mul");
}
@Override
public String getDescription() {
return "MUL file";
}
});
saveList.setSelectedFile(new File(scenario.getName() + ".mul")); //$NON-NLS-1$
int returnVal = saveList.showSaveDialog(this);
if ((returnVal != JFileChooser.APPROVE_OPTION) || (saveList.getSelectedFile() == null)) {
// I want a file, y'know!
return;
}
File unitFile = saveList.getSelectedFile();
if (unitFile != null) {
if (!(unitFile.getName().toLowerCase().endsWith(".mul") //$NON-NLS-1$
|| unitFile.getName().toLowerCase().endsWith(".xml"))) { //$NON-NLS-1$
try {
unitFile = new File(unitFile.getCanonicalPath() + ".mul"); //$NON-NLS-1$
} catch (IOException ie) {
// nothing needs to be done here
return;
}
}
try {
// Save the player's entities to the file.
// FIXME: this is not working
EntityListFile.saveTo(unitFile, chosen);
} catch (IOException excep) {
excep.printStackTrace(System.err);
}
}
if (undeployed.length() > 0) {
JOptionPane.showMessageDialog(getFrame(),
"The following units could not be deployed:" + undeployed.toString(), "Could not deploy some units",
JOptionPane.WARNING_MESSAGE);
}
}
public void refreshMissions() {
choiceMission.removeAllItems();
for (Mission m : getCampaign().getSortedMissions()) {
String desc = m.getName();
if (!m.isActive()) {
desc += " (Complete)";
}
choiceMission.addItem(desc);
if (m.getId() == selectedMission) {
choiceMission.setSelectedItem(m.getName());
}
}
if (choiceMission.getSelectedIndex() == -1 && getCampaign().getSortedMissions().size() > 0) {
selectedMission = getCampaign().getSortedMissions().get(0).getId();
choiceMission.setSelectedIndex(0);
}
changeMission();
if (getCampaign().getCampaignOptions().getUseAtB()) {
refreshLanceAssignments();
}
}
public void refreshScenarioView() {
int row = scenarioTable.getSelectedRow();
if (row < 0) {
scrollScenarioView.setViewportView(null);
btnStartGame.setEnabled(false);
btnJoinGame.setEnabled(false);
btnLoadGame.setEnabled(false);
btnGetMul.setEnabled(false);
btnClearAssignedUnits.setEnabled(false);
btnResolveScenario.setEnabled(false);
btnPrintRS.setEnabled(false);
selectedScenario = -1;
return;
}
Scenario scenario = scenarioModel.getScenario(scenarioTable.convertRowIndexToModel(row));
selectedScenario = scenario.getId();
if (getCampaign().getCampaignOptions().getUseAtB() && (scenario instanceof AtBScenario)) {
scrollScenarioView.setViewportView(
new AtBScenarioViewPanel((AtBScenario) scenario, getCampaign(), getIconPackage(), getFrame()));
} else {
scrollScenarioView.setViewportView(new ScenarioViewPanel(scenario, getCampaign(), getIconPackage()));
}
// This odd code is to make sure that the scrollbar stays at the top
// I can't just call it here, because it ends up getting reset somewhere
// later
javax.swing.SwingUtilities.invokeLater(() -> scrollScenarioView.getVerticalScrollBar().setValue(0));
boolean unitsAssigned = scenario.getForces(getCampaign()).getAllUnits().size() > 0;
boolean canStartGame = scenario.isCurrent() && unitsAssigned;
if (getCampaign().getCampaignOptions().getUseAtB() && scenario instanceof AtBScenario) {
canStartGame = canStartGame && getCampaign().getDate().equals(scenario.getDate());
}
btnStartGame.setEnabled(canStartGame);
btnJoinGame.setEnabled(canStartGame);
btnLoadGame.setEnabled(canStartGame);
btnGetMul.setEnabled(scenario.isCurrent() && unitsAssigned);
btnClearAssignedUnits.setEnabled(scenario.isCurrent() && unitsAssigned);
btnResolveScenario.setEnabled(canStartGame);
btnPrintRS.setEnabled(scenario.isCurrent() && unitsAssigned);
}
public void refreshLanceAssignments() {
panLanceAssignment.refresh();
}
/*
* (non-Javadoc)
*
* @see mekhq.gui.CampaignGuiTab#refreshAll()
*/
@Override
public void refreshAll() {
refreshMissions();
refreshScenarioTableData();
}
public void changeMission() {
int idx = choiceMission.getSelectedIndex();
btnEditMission.setEnabled(false);
btnCompleteMission.setEnabled(false);
btnDeleteMission.setEnabled(false);
btnAddScenario.setEnabled(false);
if (idx >= 0 && idx < getCampaign().getSortedMissions().size()) {
Mission m = getCampaign().getSortedMissions().get(idx);
if (null != m) {
selectedMission = m.getId();
if (getCampaign().getCampaignOptions().getUseAtB() && m instanceof AtBContract) {
scrollMissionView.setViewportView(new AtBContractViewPanel((AtBContract) m, getCampaign()));
} else if (m instanceof Contract) {
scrollMissionView.setViewportView(new ContractViewPanel((Contract) m));
} else {
scrollMissionView.setViewportView(new MissionViewPanel(m));
}
// This odd code is to make sure that the scrollbar stays at the
// top
// I can't just call it here, because it ends up getting reset
// somewhere later
javax.swing.SwingUtilities.invokeLater(() -> scrollMissionView.getVerticalScrollBar().setValue(0));
btnEditMission.setEnabled(true);
btnCompleteMission.setEnabled(m.isActive());
btnDeleteMission.setEnabled(true);
btnAddScenario.setEnabled(m.isActive());
}
} else {
selectedMission = -1;
scrollMissionView.setViewportView(null);
}
refreshScenarioTableData();
}
public void refreshScenarioTableData() {
Mission m = getCampaign().getMission(selectedMission);
if (null != m) {
scenarioModel.setData(m.getScenarios());
} else {
scenarioModel.setData(new ArrayList<Scenario>());
}
selectedScenario = -1;
}
private ActionScheduler scenarioDataScheduler = new ActionScheduler(this::refreshScenarioTableData);
private ActionScheduler scenarioViewScheduler = new ActionScheduler(this::refreshScenarioView);
private ActionScheduler missionsScheduler = new ActionScheduler(this::refreshMissions);
private ActionScheduler lanceAssignmentScheduler = new ActionScheduler(this::refreshLanceAssignments);
@Subscribe
public void handle(OptionsChangedEvent ev) {
splitScenario.getBottomComponent().setVisible(getCampaignOptions().getUseAtB());
splitScenario.resetToPreferredSizes();
}
@Subscribe
public void handle(ScenarioChangedEvent ev) {
if (ev.getScenario() != null && ev.getScenario().getMissionId() == selectedMission) {
scenarioTable.repaint();
if (ev.getScenario().getId() == selectedScenario) {
scenarioViewScheduler.schedule();
}
}
}
@Subscribe
public void handle(OrganizationChangedEvent ev) {
scenarioDataScheduler.schedule();
if (getCampaignOptions().getUseAtB()) {
lanceAssignmentScheduler.schedule();
}
}
@Subscribe
public void handle(ScenarioNewEvent ev) {
scenarioDataScheduler.schedule();
}
@Subscribe
public void handle(ScenarioRemovedEvent ev) {
scenarioDataScheduler.schedule();
}
@Subscribe
public void handle(MissionNewEvent ev) {
missionsScheduler.schedule();
}
@Subscribe
public void handle(MissionRemovedEvent ev) {
missionsScheduler.schedule();
}
@Subscribe
public void handle(MissionCompletedEvent ev) {
missionsScheduler.schedule();
}
@Subscribe
public void handle(MissionChangedEvent ev) {
if (ev.getMission().getId() == selectedMission) {
changeMission();
}
}
}