Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gamemaster mode can edit unit during game #4576

Merged
merged 5 commits into from
Jul 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1418,9 +1418,9 @@ CustomMechDialog.labDeploymentOffset=Deployment Zone Offset:
CustomMechDialog.labDeploymentOffsetTip=Deployment Zone Offset, in hexes from corresponding map edge
CustomMechDialog.labDeploymentWidth=Deployment Zone Width:
CustomMechDialog.labDeploymentWidthTip=Deployment Zone width, in hexes
CustomMechDialog.labDeployShutdown=Deploy Shutdown
CustomMechDialog.labDeployProne=Deploy Prone
CustomMechDialog.labDeployHullDown=Deploy Hull Down
CustomMechDialog.labDeployShutdown=Shutdown
CustomMechDialog.labDeployProne=Prone
CustomMechDialog.labDeployHullDown=Hull Down
CustomMechDialog.labDEST=DEST suit?
CustomMechDialog.labDriving=Driving:
CustomMechDialog.labDump=Dump this ammobin
Expand Down Expand Up @@ -1486,6 +1486,7 @@ CustomMechDialog.South=South
CustomMechDialog.StartOfGame=Start of game
CustomMechDialog.switchToRapidFire=Machine Gun ({0}) Switch to rapid-fire mode
CustomMechDialog.tabDeployment=Deployment
CustomMechDialog.tabState=State
CustomMechDialog.tabEquipment=Equipment
CustomMechDialog.tabPilot=Pilot
CustomMechDialog.tabCrew=Crew Abilities
Expand Down Expand Up @@ -4435,3 +4436,8 @@ CASCardPanel.MUL=Open MUL
CASCardPanel.conversionReport=Conversion Report
CASCardPanel.font=Font:
CASCardPanel.cardSize=Card Size:

#Gamemaster Menu Text
Gamemaster.Gamemaster=Gamemaster
Gamemaster.EditDamage=Edit Damage
Gamemaster.Configure=Configure
10 changes: 10 additions & 0 deletions megamek/src/megamek/client/ui/swing/ClientGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -2240,6 +2240,16 @@ public void gamePlayerConnected(GamePlayerConnectedEvent e) {

}

@Override
public void gameEntityChange(GameEntityChangeEvent e) {
if ((unitDisplay != null) && (unitDisplay.getCurrentEntity() != null)
&& (e.getEntity() != null)
&& (unitDisplay.getCurrentEntity().getId() == e.getEntity().getId())) {
// underlying object may have changed, so reset
unitDisplay.displayEntity(e.getEntity());
}
}

@Override
public void gameReport(GameReportEvent e) {
// Normally the Report Display is updated when the panel is
Expand Down
113 changes: 70 additions & 43 deletions megamek/src/megamek/client/ui/swing/CustomMechDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import megamek.common.util.fileUtils.MegaMekFile;
import megamek.common.verifier.*;
import megamek.common.weapons.bayweapons.ArtilleryBayWeapon;
import megamek.common.weapons.bayweapons.BayWeapon;
import megamek.common.weapons.bayweapons.CapitalMissileBayWeapon;

import javax.swing.*;
Expand All @@ -35,7 +34,6 @@
import java.awt.event.*;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
* A dialog that a player can use to customize his mech before battle.
Expand Down Expand Up @@ -78,12 +76,12 @@ public class CustomMechDialog extends AbstractButtonDialog implements ActionList
Messages.getString("CustomMechDialog.labDeploymentWidth"), SwingConstants.RIGHT);
private final JComboBox<String> choDeploymentRound = new JComboBox<>();
private final JComboBox<String> choDeploymentZone = new JComboBox<>();

// this might seem like kind of a dumb way to declare it, but JFormattedTextField doesn't have an overload that
// takes both a number formatter and a default value.
private final NumberFormatter numFormatter = new NumberFormatter();
private final DefaultFormatterFactory formatterFactory = new DefaultFormatterFactory(numFormatter);

private final JFormattedTextField txtDeploymentOffset = new JFormattedTextField(formatterFactory);
private final JFormattedTextField txtDeploymentWidth = new JFormattedTextField(formatterFactory);

Expand Down Expand Up @@ -148,6 +146,7 @@ public class CustomMechDialog extends AbstractButtonDialog implements ActionList
private ArrayList<DialogOptionComponent> partRepsComps = new ArrayList<>();

private final boolean editable;
private final boolean editableDeployment;

private OffBoardDirection direction = OffBoardDirection.NONE;
private int distance = 17;
Expand All @@ -157,13 +156,21 @@ public class CustomMechDialog extends AbstractButtonDialog implements ActionList
* Creates new CustomMechDialog
*/
public CustomMechDialog(ClientGUI clientgui, Client client, List<Entity> entities, boolean editable) {
this(clientgui, client, entities, editable, true);
}

/**
* Creates new CustomMechDialog
*/
public CustomMechDialog(ClientGUI clientgui, Client client, List<Entity> entities, boolean editable, boolean editableDeployment) {
super(clientgui.getFrame(), "CustomizeMechDialog", "CustomMechDialog.title");

this.entities = entities;
this.clientgui = clientgui;
this.client = client;
this.space = clientgui.getClient().getMapSettings().getMedium() == Board.T_SPACE;
this.editable = editable;
this.editableDeployment = editableDeployment;

// Ensure we have at least one passed entity, anything less makes no sense
if (entities.size() < 1) {
Expand All @@ -172,7 +179,6 @@ public CustomMechDialog(ClientGUI clientgui, Client client, List<Entity> entitie

initialize();
}

public String getSelectedTab() {
return tabAll.getTitleAt(tabAll.getSelectedIndex());
}
Expand All @@ -182,7 +188,7 @@ public void setSelectedTab(int idx) {
tabAll.setSelectedIndex(idx);
}
}

public void setSelectedTab(String tabName) {
for (int i = 0; i < tabAll.getTabCount(); i++) {
if (tabAll.getTitleAt(i).equals(tabName)) {
Expand Down Expand Up @@ -331,7 +337,7 @@ private void addOption(IOption option, GridBagLayout gridbag, GridBagConstraints
PilotSPAHelper.weaponSpecialistValidWeaponNames(entity, gameOptions()).forEach(optionComp::addValue);
optionComp.setSelected(option.stringValue());
}

if ((OptionsConstants.GUNNERY_SANDBLASTER).equals(option.getName())) {
optionComp.addValue(Messages.getString("CustomMechDialog.None"));
PilotSPAHelper.sandblasterValidWeaponNames(entity, gameOptions()).forEach(optionComp::addValue);
Expand Down Expand Up @@ -396,7 +402,7 @@ public int getStatus() {

private void refreshDeployment() {
Entity entity = entities.get(0);

if (entity instanceof QuadVee) {
choStartingMode.removeItemListener(this);
choStartingMode.removeAllItems();
Expand All @@ -423,11 +429,11 @@ private void refreshDeployment() {
updateStartingModeOptions();
choStartingMode.addItemListener(this);
}

choDeploymentZone.removeItemListener(this);
txtDeploymentOffset.setEnabled(false);
txtDeploymentWidth.setEnabled(false);

choDeploymentRound.removeAllItems();
choDeploymentRound.addItem(Messages.getString("CustomMechDialog.StartOfGame"));

Expand All @@ -445,7 +451,7 @@ private void refreshDeployment() {
if (entity.getTransportId() != Entity.NONE) {
choDeploymentRound.setEnabled(false);
}

choDeploymentZone.removeAllItems();
choDeploymentZone.addItem(Messages.getString("CustomMechDialog.useOwners"));
choDeploymentZone.addItem(Messages.getString("CustomMechDialog.deployAny"));
Expand All @@ -461,16 +467,23 @@ private void refreshDeployment() {
choDeploymentZone.addItem(Messages.getString("CustomMechDialog.deployCenter"));

choDeploymentZone.setSelectedIndex(entity.getStartingPos(false) + 1);

choDeploymentZone.addItemListener(this);

txtDeploymentOffset.setText(Integer.toString(entity.getStartingOffset(false)));
txtDeploymentWidth.setText(Integer.toString(entity.getStartingWidth(false)));

boolean enableDeploymentZoneControls = choDeploymentZone.isEnabled() && (choDeploymentZone.getSelectedIndex() > 0);
txtDeploymentOffset.setEnabled(enableDeploymentZoneControls);
txtDeploymentWidth.setEnabled(enableDeploymentZoneControls);


// disable some options if not allowed to edit deployment
choStartingMode.setEnabled(editableDeployment);
choDeploymentZone.setEnabled(editableDeployment);
txtDeploymentOffset.setEnabled(editableDeployment);
txtDeploymentWidth.setEnabled(editableDeployment);
choDeploymentRound.setEnabled(editableDeployment);

chHidden.removeActionListener(this);
boolean enableHidden = !(entity instanceof Dropship) && !entity.isAirborne() && !entity.isAirborneVTOLorWIGE();
labHidden.setEnabled(enableHidden);
Expand Down Expand Up @@ -531,7 +544,7 @@ public void actionPerformed(ActionEvent actionEvent) {
maxDistance = nDistance;
}
}

}
Slider sl = new Slider(
clientgui.frame,
Expand All @@ -545,7 +558,7 @@ public void actionPerformed(ActionEvent actionEvent) {
butOffBoardDistance.setText(Integer.toString(distance));
return;
}

if (actionEvent.getActionCommand().equals("missing")) {
//If we're down to a single crew member, do not allow any more to be removed.
final long remaining = Arrays.stream(panCrewMember).filter(p -> !p.getMissing()).count();
Expand Down Expand Up @@ -887,41 +900,53 @@ protected void okAction() {
}

okay = true;
clientgui.chatlounge.refreshEntities();
if ((clientgui != null) && (clientgui.chatlounge != null)) {
clientgui.chatlounge.refreshEntities();
}

// Check validity of units after customization
EntityVerifier verifier = EntityVerifier.getInstance(new MegaMekFile(
Configuration.unitsDir(), EntityVerifier.CONFIG_FILENAME).getFile());
for (Entity entity : entities) {
EntityVerifier verifier = EntityVerifier.getInstance(new MegaMekFile(
Configuration.unitsDir(), EntityVerifier.CONFIG_FILENAME).getFile());
TestEntity testEntity = null;
if (entity instanceof Mech) {
testEntity = new TestMech((Mech) entity, verifier.mechOption, null);
} else if ((entity instanceof Tank)
&& !(entity instanceof GunEmplacement)) {
if (entity.isSupportVehicle()) {
testEntity = new TestSupportVehicle(entity, verifier.tankOption, null);
} else {
testEntity = new TestTank((Tank) entity, verifier.tankOption, null);
}
} else if (entity.getEntityType() == Entity.ETYPE_AERO
&& entity.getEntityType() != Entity.ETYPE_DROPSHIP
&& entity.getEntityType() != Entity.ETYPE_SMALL_CRAFT
&& entity.getEntityType() != Entity.ETYPE_FIGHTER_SQUADRON
&& entity.getEntityType() != Entity.ETYPE_JUMPSHIP
&& entity.getEntityType() != Entity.ETYPE_SPACE_STATION) {
testEntity = new TestAero((Aero) entity, verifier.mechOption, null);
} else if (entity instanceof BattleArmor) {
testEntity = new TestBattleArmor((BattleArmor) entity, verifier.baOption, null);
} else if (entity instanceof Infantry) {
testEntity = new TestInfantry((Infantry) entity, verifier.infOption, null);
}
TestEntity testEntity = getTestEntity(entity, verifier);
int gameTL = TechConstants.getGameTechLevel(client.getGame(), entity.isClan());
entity.setDesignValid((testEntity == null) || testEntity.correctEntity(new StringBuffer(), gameTL));
}

setVisible(false);
}

/**
* copied from megameklab.util.UnitUtil.getEntityVerifier
* @param unit the supplied entity
* @param entityVerifier the entity verifier loaded from a UnitVerifierOptions.xml
* @return a TestEntity instance for the supplied Entity.
*/
public static TestEntity getTestEntity(Entity unit, EntityVerifier entityVerifier) {
// FIXME move the same method from megameklab.util.UnitUtil.getEntityVerifier to common
TestEntity testEntity = null;
if (unit.hasETypeFlag(Entity.ETYPE_MECH)) {
testEntity = new TestMech((Mech) unit, entityVerifier.mechOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_PROTOMECH)) {
testEntity = new TestProtomech((Protomech) unit, entityVerifier.protomechOption, null);
} else if (unit.isSupportVehicle()) {
testEntity = new TestSupportVehicle(unit, entityVerifier.tankOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_TANK)) {
testEntity = new TestTank((Tank) unit, entityVerifier.tankOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_SMALL_CRAFT)) {
testEntity = new TestSmallCraft((SmallCraft) unit, entityVerifier.aeroOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_JUMPSHIP)) {
testEntity = new TestAdvancedAerospace((Jumpship) unit, entityVerifier.aeroOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_AERO)) {
testEntity = new TestAero((Aero) unit, entityVerifier.aeroOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_BATTLEARMOR)) {
testEntity = new TestBattleArmor((BattleArmor) unit, entityVerifier.baOption, null);
} else if (unit.hasETypeFlag(Entity.ETYPE_INFANTRY)) {
testEntity = new TestInfantry((Infantry)unit, entityVerifier.infOption, null);
}
return testEntity;
}

@Override
public void itemStateChanged(ItemEvent itemEvent) {
if (itemEvent.getSource().equals(choStartingMode)) {
Expand All @@ -935,7 +960,7 @@ public void itemStateChanged(ItemEvent itemEvent) {
chDeployProne.setSelected(false);
return;
}

if (itemEvent.getSource().equals(choDeploymentZone)) {
boolean enableDeploymentZoneControls = choDeploymentZone.isEnabled() && (choDeploymentZone.getSelectedIndex() > 0);
txtDeploymentOffset.setEnabled(enableDeploymentZoneControls);
Expand Down Expand Up @@ -1074,7 +1099,9 @@ protected Container createCenterPane() {
}
tabAll.addTab(Messages.getString("CustomMechDialog.tabEquipment"), scrEquip);
}
tabAll.addTab(Messages.getString("CustomMechDialog.tabDeployment"), new JScrollPane(panDeploy));
tabAll.addTab(Messages.getString(
editableDeployment ? "CustomMechDialog.tabDeployment" : "CustomMechDialog.tabState" ),
new JScrollPane(panDeploy));
if (quirksEnabled && !multipleEntities) {
JScrollPane scrQuirks = new JScrollPane(panQuirks);
scrQuirks.getVerticalScrollBar().setUnitIncrement(16);
Expand Down
Loading