Skip to content

Commit

Permalink
Merge pull request #4576 from pakfront/gm-damage
Browse files Browse the repository at this point in the history
Gamemaster mode can edit unit during game
  • Loading branch information
SJuliez authored Jul 16, 2023
2 parents e8f04ab + e362abc commit 7d4e2fd
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 81 deletions.
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 @@ -2244,6 +2244,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

0 comments on commit 7d4e2fd

Please sign in to comment.