Skip to content

Commit

Permalink
Merge pull request #6186 from SJuliez/pause-game
Browse files Browse the repository at this point in the history
Allow pausing a Princess-only game
  • Loading branch information
HammerGS authored Nov 23, 2024
2 parents b33b7a3 + a58a77b commit 0b2dda2
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 4 deletions.
4 changes: 4 additions & 0 deletions megamek/i18n/megamek/client/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,10 @@ KeyBinds.cmdNames.undoSingleStep=Undo Single Step
KeyBinds.cmdDesc.undoSingleStep=Undo single step in movement phase
KeyBinds.cmdNames.extendTurnTimer=Activates Turn Timer Extension
KeyBinds.cmdDesc.extendTurnTimer=When Turn Timer gets to 2 seconds left, reset timer.
KeyBinds.cmdNames.pause=Pause the Game
KeyBinds.cmdDesc.pause=Pauses the game. Works only when only Princess players with active units remain.
KeyBinds.cmdNames.unpause=Unpause the Game
KeyBinds.cmdDesc.unpause=Unpauses the game

#Key Bindings Overlay
KeyBindingsDisplay.fixedBinds=Toggle Unit Display and Minimap: Mouse Button 4\nZoom: Mouse Wheel\nTurn / Torso twist: Shift + Left-Click\nLine of Sight tool: Ctrl + Left-Click (two hexes)\nRuler tool: Alt + Left-Click (two hexes)
Expand Down
16 changes: 15 additions & 1 deletion megamek/mmconf/defaultKeyBinds.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<KeyBindings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="keyBindingSchema.xsd">
xsi:noNamespaceSchemaLocation="keyBindingSchema.xsd">
<KeyBind>
<command>scrollN</command> <!-- W -->
<keyCode>87</keyCode>
Expand Down Expand Up @@ -78,6 +78,20 @@
<isRepeatable>false</isRepeatable>
</KeyBind>

<KeyBind>
<command>pause</command> <!-- Ctrl+Shift-P -->
<keyCode>80</keyCode>
<modifier>192</modifier>
<isRepeatable>false</isRepeatable>
</KeyBind>

<KeyBind>
<command>unpause</command> <!-- Ctrl+Alt-P -->
<keyCode>80</keyCode>
<modifier>640</modifier>
<isRepeatable>false</isRepeatable>
</KeyBind>

<KeyBind>
<command>nextWeapon</command> <!-- Down -->
<keyCode>40</keyCode>
Expand Down
10 changes: 10 additions & 0 deletions megamek/src/megamek/client/AbstractClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ public synchronized void sendDone(boolean done) {
flushConn();
}

public void sendPause() {
send(new Packet(PacketCommand.PAUSE));
flushConn();
}

public void sendUnpause() {
send(new Packet(PacketCommand.UNPAUSE));
flushConn();
}

/**
* Receives player information from the message packet.
*
Expand Down
18 changes: 18 additions & 0 deletions megamek/src/megamek/client/ui/swing/StatusBarPhaseDisplay.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import javax.swing.ToolTipManager;
import javax.swing.border.EmptyBorder;

import megamek.client.AbstractClient;
import megamek.client.ui.GBC;
import megamek.client.ui.Messages;
import megamek.client.ui.swing.util.KeyBindReceiver;
Expand Down Expand Up @@ -157,8 +158,25 @@ public void actionPerformed(ActionEvent e) {
KeyBindParser.addPreferenceChangeListener(this);

MegaMekGUI.getKeyDispatcher().registerCommandAction(KeyCommandBind.EXTEND_TURN_TIMER, this, this::extendTimer);
MegaMekGUI.getKeyDispatcher().registerCommandAction(KeyCommandBind.PAUSE.cmd, this::pauseGameWhenOnlyBotUnitsRemain);
MegaMekGUI.getKeyDispatcher().registerCommandAction(KeyCommandBind.UNPAUSE.cmd,
() -> ((AbstractClient) clientgui.getClient()).sendUnpause());
}

private void pauseGameWhenOnlyBotUnitsRemain() {
if (isIgnoringEvents() || !isVisible()) {
return;
}
IGame game = getClientgui().getClient().getGame();
List<Player> nonBots = game.getPlayersList().stream().filter(p -> !p.isBot()).toList();
boolean liveUnitsRemaining = nonBots.stream().anyMatch(p -> game.getEntitiesOwnedBy(p) > 0);
if (liveUnitsRemaining) {
clientgui.getClient().sendChat("Pausing the game only works when only bot units remain.");
} else {
clientgui.getClient().sendChat("Requesting game pause.");
((AbstractClient) clientgui.getClient()).sendPause();
}
}

/** Returns the list of buttons that should be displayed. */
protected abstract List<MegaMekButton> getButtonList();
Expand Down
4 changes: 3 additions & 1 deletion megamek/src/megamek/client/ui/swing/util/KeyCommandBind.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ public enum KeyCommandBind {
TOGGLE_CONVERSIONMODE("toggleConversion", VK_M),
PREV_MODE("prevMode", VK_KP_DOWN),
NEXT_MODE("nextMode", VK_KP_UP),
PAUSE("pause", VK_P, CTRL_DOWN_MASK | SHIFT_DOWN_MASK),
UNPAUSE("unpause", VK_P, CTRL_DOWN_MASK | ALT_DOWN_MASK),

// --------- The following binds are used by the CommonMenuBar:
// Toggles isometric view on/off
Expand Down Expand Up @@ -218,4 +220,4 @@ public static String getDesc(KeyCommandBind k) {
String key = getKeyText(k.key);
return (mod.isEmpty() ? "" : mod + "+") + key;
}
}
}
4 changes: 4 additions & 0 deletions megamek/src/megamek/common/net/enums/PacketCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public enum PacketCommand {
/** A packet setting a Client's ready status (S -> C) or updating the Server on the Client's status (C -> S). */
PLAYER_READY,

/** A packet telling the server to pause / unpause packet handling (to interrupt a Princess-only game) */
PAUSE,
UNPAUSE,

CHAT,
ENTITY_ADD,
ENTITY_REMOVE,
Expand Down
31 changes: 29 additions & 2 deletions megamek/src/megamek/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ public void run() {
private static final String WARGAMES_RESPONSE = "Let's play global thermonuclear war.";

private final ConnectionListener connectionListener = new ConnectionListener() {

private boolean isPaused = false;
private final List<ReceivedPacket> pausedWaitingList = new ArrayList<>();

/**
* Called when it is sensed that a connection has terminated.
*/
Expand Down Expand Up @@ -252,11 +256,34 @@ public void packetReceived(PacketReceivedEvent e) {
// Some packets should be handled immediately
handle(rp.getConnectionId(), rp.getPacket());
break;
default:
case PAUSE:
if (!isPaused) {
logger.info("Pause packet received - pausing packet handling");
sendServerChat("Game is paused.");
}
isPaused = true;
break;
case UNPAUSE:
if (isPaused) {
logger.info("Unpause packet received - resuming packet handling");
sendServerChat("Game is resumed.");
}
isPaused = false;
synchronized (packetQueue) {
packetQueue.add(rp);
packetQueue.addAll(pausedWaitingList);
packetQueue.notifyAll();
}
pausedWaitingList.clear();
break;
default:
if (isPaused) {
pausedWaitingList.add(rp);
} else {
synchronized (packetQueue) {
packetQueue.add(rp);
packetQueue.notifyAll();
}
}
break;
}
}
Expand Down

0 comments on commit 0b2dda2

Please sign in to comment.