Skip to content

Commit

Permalink
feat: fire fight arguments added
Browse files Browse the repository at this point in the history
  • Loading branch information
Scoppio committed Nov 16, 2024
1 parent a4c6b6a commit 0811d62
Show file tree
Hide file tree
Showing 18 changed files with 343 additions and 95 deletions.
17 changes: 16 additions & 1 deletion megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4636,7 +4636,14 @@ SBFTargetDialog.title=Targeting
Gamemaster.Gamemaster=Gamemaster
Gamemaster.EditDamage=Edit Damage (unstable)
Gamemaster.Configure=Configure (unstable)
Gamemaster.Traitor.title=Traitor
Gamemaster.Traitor.confirm=Confirm
Gamemaster.Traitor=Traitor Unit
Gamemaster.Traitor.text=Traitor Unit {0}
Gamemaster.Traitor.text.noplayers=No players available. Units cannot have their ownership passed to players that aren't assigned to a team.
Gamemaster.Traitor.text.selectplayer=Choose the player to gain ownership of this unit, {0}, when it turns traitor
Gamemaster.Traitor.confirmation={0} will switch to {1}'s side at the end of this turn. Are you sure?

Gamemaster.dialog.confirm=Confirm
Gamemaster.KillUnit=Kill Unit
Gamemaster.KillUnit.text=Kill Unit {0}
Expand Down Expand Up @@ -4710,4 +4717,12 @@ Gamemaster.cmd.orbitalbombardment.help=Calls an orbital bombardment on the board
Gamemaster.cmd.orbitalbombardment.dmg=Total damage at target hex.
Gamemaster.cmd.orbitalbombardment.radius=Radius of the bombardment.
Gamemaster.cmd.orbitalbombardment.error.outofbounds=Specified hex is not on the board.
Gamemaster.cmd.orbitalbombardment.success=Orbital bombardment incoming!
Gamemaster.cmd.orbitalbombardment.success=Orbital bombardment incoming!
# Firefight
Gamemaster.cmd.firefight.longName=Firefight
Gamemaster.cmd.firefight.reason=Fire extinguished
Gamemaster.cmd.firefight.help=Extinguishes a fire on the board.
# No Fire
Gamemaster.cmd.nofire.longName=No Fires
Gamemaster.cmd.nofire.help=Extinguishes all fires on the board.

89 changes: 51 additions & 38 deletions megamek/src/megamek/client/ui/swing/MapMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -229,17 +229,7 @@ private JMenuItem TargetMenuItem(Targetable t) {
JMenuItem item = new JMenuItem(Messages.getString("ClientGUI.targetMenuItem")
+ t.getDisplayName());

String targetCode;

if (t instanceof Entity) {
targetCode = "E|" + ((Entity) t).getId();
} else if (t instanceof BuildingTarget) {
targetCode = "B|" + t.getPosition().getX() + "|" + t.getPosition().getY() + "|" + t.getTargetType();
} else if (t instanceof MinefieldTarget) {
targetCode = "M|" + t.getPosition().getX() + "|" + t.getPosition().getY();
} else {
targetCode = "H|" + t.getPosition().getX() + "|" + t.getPosition().getY() + "|" + t.getTargetType();
}
String targetCode = getTargetCode(t);

item.setActionCommand(targetCode);
item.addActionListener(evt -> {
Expand All @@ -255,6 +245,21 @@ private JMenuItem TargetMenuItem(Targetable t) {
return item;
}

private static String getTargetCode(Targetable t) {
String targetCode;

if (t instanceof Entity) {
targetCode = "E|" + ((Entity) t).getId();
} else if (t instanceof BuildingTarget) {
targetCode = "B|" + t.getPosition().getX() + "|" + t.getPosition().getY() + "|" + t.getTargetType();
} else if (t instanceof MinefieldTarget) {
targetCode = "M|" + t.getPosition().getX() + "|" + t.getPosition().getY();
} else {
targetCode = "H|" + t.getPosition().getX() + "|" + t.getPosition().getY() + "|" + t.getTargetType();
}
return targetCode;
}

private @Nullable JMenuItem createChargeMenuItem() {
if (!client.getGame().getEntities(coords).hasNext()) {
return null;
Expand Down Expand Up @@ -403,9 +408,7 @@ private JMenu createSpecialHexDisplayMenu() {
*/
private JMenu createGamemasterMenu() {
JMenu menu = new JMenu(Messages.getString("Gamemaster.Gamemaster"));
if (!client.getLocalPlayer().getGameMaster()) {
return menu;
} else {
if (client.getLocalPlayer().getGameMaster()) {
JMenu dmgMenu = new JMenu(Messages.getString("Gamemaster.EditDamage"));
JMenu cfgMenu = new JMenu(Messages.getString("Gamemaster.Configure"));
JMenu traitorMenu = new JMenu(Messages.getString("Gamemaster.Traitor"));
Expand Down Expand Up @@ -435,8 +438,8 @@ private JMenu createGamemasterMenu() {
menu.addSeparator();
}
menu.add(specialCommandsMenu);
return menu;
}
return menu;
}

/**
Expand All @@ -446,17 +449,19 @@ private JMenu createGamemasterMenu() {
private JMenu createGMSpecialCommandsMenu() {
JMenu menu = new JMenu(Messages.getString("Gamemaster.SpecialCommands"));
List.of(
new KillCommand(null, null),
new OrbitalBombardmentCommand(null, null),
new ChangeOwnershipCommand(null, null),
new ChangeWeatherCommand(null, null),
new DisasterCommand(null, null),
new KillCommand(null, null),
new FirefightCommand(null, null),
new FirestarterCommand(null, null),
new FirestormCommand(null, null),
new RemoveSmokeCommand(null, null),
new ChangeWeatherCommand(null, null)
new NoFiresCommand(null, null),
new OrbitalBombardmentCommand(null, null),
new RemoveSmokeCommand(null, null)
).forEach(cmd -> {
JMenuItem item = new JMenuItem(cmd.getLongName());
item.addActionListener(evt -> new GamemasterCommandPanel(gui.getFrame(), gui, cmd).setVisible(true));
item.addActionListener(evt -> new GamemasterCommandPanel(gui.getFrame(), gui, cmd, coords).setVisible(true));
menu.add(item);
});

Expand Down Expand Up @@ -488,17 +493,22 @@ JMenuItem createUnitEditorMenuItem(Entity entity) {
return item;
}

private JMenuItem createTraitorMenuItem(Entity en) {
/**
* Create traitor menu for game master options
* @param entity the entity to create the traitor menu for
* @return JMenu the traitor menu
*/
private JMenuItem createTraitorMenuItem(Entity entity) {
// Traitor Command
JMenuItem item = new JMenuItem(Messages.getString("Gamemaster.Traitor") + " " + en.getDisplayName());
JMenuItem item = new JMenuItem(Messages.getString("Gamemaster.Traitor.text", entity.getDisplayName()));
item.addActionListener(evt -> {
gui.getBoardView().setShouldIgnoreKeys(false);
var players = client.getGame().getPlayersList();
Integer[] playerIds = new Integer[players.size() - 1];
String[] playerNames = new String[players.size() - 1];
String[] options = new String[players.size() - 1];

Player currentOwner = en.getOwner();
Player currentOwner = entity.getOwner();
// Loop through the players vector and fill in the arrays
int idx = 0;
for (var player : players) {
Expand All @@ -515,15 +525,14 @@ private JMenuItem createTraitorMenuItem(Entity en) {
// No players available?
if (idx == 0) {
JOptionPane.showMessageDialog(gui.getFrame(),
"No players available. Units cannot be traitored to players "
+ "that aren't assigned to a team.");
Messages.getString("Gamemaster.Traitor.text.noplayers"));
return;
}

// Dialog for choosing which player to transfer to
String option = (String) JOptionPane.showInputDialog(gui.getFrame(),
"Choose the player to gain ownership of this unit (" + en.getDisplayName() + ") when it turns traitor",
"Traitor", JOptionPane.QUESTION_MESSAGE, null,
Messages.getString("Gamemaster.Traitor.text.selectplayer", entity.getDisplayName()),
Messages.getString("Gamemaster.Traitor.title"), JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);

// Verify that we have a valid option...
Expand All @@ -535,27 +544,33 @@ private JMenuItem createTraitorMenuItem(Entity en) {
// And now we perform the actual transfer
int confirm = JOptionPane.showConfirmDialog(
gui.getFrame(),
en.getDisplayName() + " will switch to " + name
+ "'s side at the end of this turn. Are you sure?",
"Confirm",
Messages.getString("Gamemaster.Traitor.confirmation", entity.getDisplayName(), name),
Messages.getString("Gamemaster.Traitor.confirm"),
JOptionPane.YES_NO_OPTION);

if (confirm == JOptionPane.YES_OPTION) {
client.sendChat(String.format("/changeOwner %d %d", en.getId(), id));
client.sendChat(String.format("/changeOwner %d %d", entity.getId(), id));
}
}
});

return item;
}

private JMenuItem createKillMenuItem(Entity en) {
JMenuItem item = new JMenuItem(Messages.getString("Gamemaster.KillUnit.text", en.getDisplayName()));
/**
* Create a menu for killing a specific entity
*
* @param entity the entity to create the kill menu for
* @return JMenuItem the kill menu item
*/
private JMenuItem createKillMenuItem(Entity entity) {
JMenuItem item = new JMenuItem(Messages.getString("Gamemaster.KillUnit.text", entity.getDisplayName()));
item.addActionListener(evt -> {
int confirm = JOptionPane.showConfirmDialog(
gui.getFrame(), Messages.getString("Gamemaster.KillUnit.confirmation", en.getDisplayName()),
gui.getFrame(), Messages.getString("Gamemaster.KillUnit.confirmation", entity.getDisplayName()),
Messages.getString("Gamemaster.dialog.confirm"), JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
client.sendChat(String.format("/kill %d", en.getId()));
client.sendChat(String.format("/kill %d", entity.getId()));
}
});
return item;
Expand Down Expand Up @@ -1509,9 +1524,7 @@ private void selectTarget() {

if (list.size() == 1) {
myTarget = selectedEntity = list.firstElement();

if (currentPanel instanceof FiringDisplay) {
FiringDisplay panel = (FiringDisplay) currentPanel;
if (currentPanel instanceof FiringDisplay panel) {
panel.target(myTarget);
} else if (currentPanel instanceof PhysicalDisplay) {
((PhysicalDisplay) currentPanel).target(myTarget);
Expand Down
8 changes: 7 additions & 1 deletion megamek/src/megamek/client/ui/swing/boardview/BoardView.java
Original file line number Diff line number Diff line change
Expand Up @@ -1456,10 +1456,16 @@ private Mounted<?> selectedWeapon() {
return (clientgui != null) ? clientgui.getDisplayedWeapon().orElse(null) : null;
}

/**
* Draw the orbital bombardment attacks on the board view
*
* @author Luana Coppio
* @param boardGraphics The graphics object to draw on
*/
private void drawOrbitalBombardmentHexes(Graphics boardGraphics) {
Image orbitalBombardmentImage = tileManager.getOrbitalBombardmentImage();
Rectangle view = boardGraphics.getClipBounds();
boolean justDraw = false;

// Compute the origin of the viewing area
int drawX = (view.x / (int) (HEX_WC * scale)) - 1;
int drawY = (view.y / (int) (HEX_H * scale)) - 1;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package megamek.client.ui.swing.gmCommands;

import megamek.client.ui.swing.ClientGUI;
import megamek.common.Coords;
import megamek.common.annotations.Nullable;
import megamek.server.commands.GamemasterServerCommand;
import megamek.server.commands.arguments.Argument;
import megamek.server.commands.arguments.EnumArgument;
Expand All @@ -14,15 +16,26 @@
import java.util.Map;
import java.util.Objects;

// JPanel wrapper for game master commands
/**
* Dialog for executing a gamemaster command.
*/
public class GamemasterCommandPanel extends JDialog {
private final GamemasterServerCommand command;
private final ClientGUI client;

public GamemasterCommandPanel(JFrame parent, ClientGUI client, GamemasterServerCommand command) {
private final Coords coords;

/**
* Constructor for the dialog for executing a gamemaster command.
*
* @param parent The parent frame.
* @param client The client GUI.
* @param command The command to render.
*/
public GamemasterCommandPanel(JFrame parent, ClientGUI client, GamemasterServerCommand command, @Nullable Coords coords) {
super(parent, command.getName(), true);
this.command = command;
this.client = client;
this.coords = coords;
initializeUI(parent);
}

Expand Down Expand Up @@ -87,9 +100,22 @@ private JComponent getArgumentComponent(Argument<?> argument, JPanel argumentPan
return null;
}

private boolean isArgumentX(Argument<?> argument) {
return argument.getName().equals("x");
}

private boolean isArgumentY(Argument<?> argument) {
return argument.getName().equals("y");
}

private int getIntArgumentDefaultValue(IntegerArgument intArg) {
return intArg.hasDefaultValue() ? intArg.getValue() : isArgumentX(intArg) ? coords.getX() :
isArgumentY(intArg) ? coords.getY() : 0;
}

private JSpinner createSpinner(IntegerArgument intArg) {
return new JSpinner(new SpinnerNumberModel(
intArg.hasDefaultValue() ? intArg.getValue() : 0,
getIntArgumentDefaultValue(intArg),
intArg.getMinValue(),
intArg.getMaxValue(),
1));
Expand Down Expand Up @@ -141,6 +167,13 @@ private JButton getExecuteButton(Map<String, JComponent> argumentComponents) {
return executeButton;
}

/**
* Execute the command with the given arguments.
* It runs the command using the client chat, this way the command is sent to the server.
* All arguments are loaded as named variables in the form of "argumentName=argumentValue".
*
* @param argumentComponents The components that hold the arguments selected.
*/
private void executeCommand(Map<String, JComponent> argumentComponents) {
List<Argument<?>> arguments = command.defineArguments();
String[] args = new String[arguments.size()];
Expand All @@ -166,6 +199,7 @@ private void executeCommand(Map<String, JComponent> argumentComponents) {
}
}
}

client.getClient().sendChat("/" + command.getName() + " " + String.join(" ", args));
}
}
20 changes: 0 additions & 20 deletions megamek/src/megamek/common/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -2084,24 +2084,4 @@ public static int encodeCustomDeploymentZoneID(int zoneID) {
return zoneID + NUM_ZONES_X2;
}

public void clearOrbitalBombardmentIcons() {
for (Coords coords : specialHexes.keySet()) {
removeOrbitalBombardmentIcons(coords);
}
}

public void removeOrbitalBombardmentIcons(Coords coords) {
// Do nothing if the coords aren't on this board.
if (!this.contains(coords) || null == specialHexes.get(coords)) {
return;
}

// Use iterator so we can remove while traversing
for (Iterator<SpecialHexDisplay> iterator = specialHexes.get(coords).iterator(); iterator.hasNext();) {
SpecialHexDisplay shd = iterator.next();
if (ORBITAL_BOMBARDMENT.equals(shd.getType())) {
iterator.remove();
}
}
}
}
3 changes: 3 additions & 0 deletions megamek/src/megamek/common/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -4790,6 +4790,9 @@ public List<CriticalSlot> getCriticalSlots(int location) {
return result;
}

/**
* @return true if the entity has any critical slot that isn't damaged yet
*/
public boolean hasUndamagedCriticalSlots() {
return IntStream.range(0, locations())
.mapToLong(i -> getCriticalSlots(i)
Expand Down
14 changes: 12 additions & 2 deletions megamek/src/megamek/common/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -2203,15 +2203,25 @@ public int removeSpecificEntityTurnsFor(Entity entity) {
return turnsToRemove.size();
}

public void setOrbitalBombardmentVector(Vector<OrbitalBombardment> v) {
orbitalBombardmentAttacks = v;
/**
* Set the new vector of orbital bombardments for this round.
* @param orbitalBombardments
*/
public void setOrbitalBombardmentVector(Vector<OrbitalBombardment> orbitalBombardments) {
orbitalBombardmentAttacks = orbitalBombardments;
processGameEvent(new GameBoardChangeEvent(this));
}

/**
* Resets the orbital bombardment attacks list.
*/
public void resetOrbitalBombardmentAttacks() {
orbitalBombardmentAttacks.removeAllElements();
}

/**
* @return an Enumeration of orbital bombardment attacks.
*/
public Enumeration<OrbitalBombardment> getOrbitalBombardmentAttacks() {
return orbitalBombardmentAttacks.elements();
}
Expand Down
Loading

0 comments on commit 0811d62

Please sign in to comment.