computeTurnDetails() {
// add line for last moves
turnDetails.add(String.format(turnDetailsFormat,
- accumLegal ? validTextColor : invalidTextColor,
- accumTypeCount == 1 ? "" : "x" + accumTypeCount,
- accumType, unicodeIcon, accumMP, "*".repeat(accumDanger)));
+ accumLegal ? validTextColor : invalidTextColor,
+ accumTypeCount == 1 ? "" : "x" + accumTypeCount,
+ accumType, unicodeIcon, accumMP, "*".repeat(accumDanger)));
return turnDetails;
}
private boolean shouldDesignateFlightPath(Entity entity) {
return entity != null
- && game.hasBoardLocation(finalPosition(), finalBoardId())
- && entity.isAirborne()
- && game.getBoard(entity).isLowAltitude()
- && game.getBoard(entity).getEmbeddedBoardHexes().contains(finalPosition())
- && cmd != null
- // Only designate a flight path when movement ends in that hex legally (all velocity used)
- && cmd.isMoveLegal()
- // Interpreting TW p.242 to include that the unit must have entered that hex in this movement and cannot
- // just hover at velocity 0, doing flight paths at will; with aero-on-ground move, there is naturally
- // no flight path without actually moving
- && cmd.getDistanceTravelled() > 0;
+ && game.hasBoardLocation(finalPosition(), finalBoardId())
+ && entity.isAirborne()
+ && game.getBoard(entity).isLowAltitude()
+ && game.getBoard(entity).getEmbeddedBoardHexes().contains(finalPosition())
+ && cmd != null
+ // Only designate a flight path when movement ends in that hex legally (all velocity used)
+ && cmd.isMoveLegal()
+ // Interpreting TW p.242 to include that the unit must have entered that hex in this movement and cannot
+ // just hover at velocity 0, doing flight paths at will; with aero-on-ground move, there is naturally
+ // no flight path without actually moving
+ && cmd.getDistanceTravelled() > 0;
}
private int flightPathTarget(Entity entity) {
@@ -1655,8 +1780,8 @@ private int flightPathTarget(Entity entity) {
private int groundMapAtAtmosphericHex() {
if (game.hasBoardLocation(finalPosition(), finalBoardId())
- && game.getBoard(finalBoardId()).isLowAltitude()
- && game.getBoard(finalBoardId()).getEmbeddedBoardHexes().contains(finalPosition())) {
+ && game.getBoard(finalBoardId()).isLowAltitude()
+ && game.getBoard(finalBoardId()).getEmbeddedBoardHexes().contains(finalPosition())) {
return game.getBoard(finalBoardId()).getEmbeddedBoardAt(finalPosition());
} else {
// fall back to the standard map to be safe
@@ -1684,6 +1809,7 @@ private void beginMyTurn() {
}
startTimer();
+
}
/**
@@ -1697,16 +1823,17 @@ private synchronized void endMyTurn() {
// end my turn, then.
disableButtons();
Entity next = game
- .getNextEntity(game.getTurnIndex());
+ .getNextEntity(game.getTurnIndex());
if (game.getPhase().isMovement()
- && (null != next)
- && (null != currentlySelectedEntity)
- && (next.getOwnerId() != currentlySelectedEntity.getOwnerId())) {
+ && (null != next)
+ && (null != currentlySelectedEntity)
+ && (next.getOwnerId() != currentlySelectedEntity.getOwnerId())) {
clientgui.maybeShowUnitDisplay();
}
currentEntity = Entity.NONE;
clearFlightPath();
clientgui.boardViews().forEach(IBoardView::clearMarkedHexes);
+ markDeploymentHexes(null);
// Return the highlight sprite back to its original color
clientgui.boardViews().forEach(bv -> ((BoardView) bv).setHighlightColor(Color.WHITE));
clientgui.setSelectedEntityNum(Entity.NONE);
@@ -1806,10 +1933,21 @@ private void disableButtons() {
}
/**
- * Clears out the currently selected movement data and resets it.
+ * Clears out the previous movement by calling the clear with deployment kept
*/
@Override
public void clear() {
+ clear(true);
+ }
+
+ /**
+ * Clears out the currently selected movement data and resets it.
+ */
+ private void clear(boolean keepDeployment) {
+ boolean wasWalkOn = (deploymentAnchor(cmd) != null);
+ DeploymentAnchor anchor = keepDeployment ? deploymentAnchor(cmd) : null;
+ int savedGear = gear;
+
final Entity currentlySelectedEntity = currentEntity();
// Cancel escape pod hex selection if active
@@ -1844,14 +1982,52 @@ public void clear() {
currentlySelectedEntity.setMovementMode(EntityMovementMode.QUAD);
}
+
// create new current and considered paths
cmd = new MovePath(game, currentlySelectedEntity);
+ gear = MovementDisplay.GEAR_LAND;
+
+ if (anchor != null) {
+ // Press escape once
+ // entity.isAero will check if a unit is a LAM in Fighter mode
+ if ((currentlySelectedEntity instanceof IAero aero) && (currentlySelectedEntity.isAero())) {
+ currentlySelectedEntity.setAltitude(anchor.elevation());
+ if (anchor.elevation() == 0) {
+ aero.land();
+ } else {
+ aero.liftOff(anchor.elevation());
+ }
+ } else {
+ currentlySelectedEntity.setElevation(anchor.elevation());
+ }
+ currentlySelectedEntity.setPosition(anchor.coords());
+ currentlySelectedEntity.setBoardId(anchor.boardId());
+ currentlySelectedEntity.setFacing(anchor.facing());
+ currentlySelectedEntity.setDeployed(true);
+ addStepToMovePath(MoveStepType.DEPLOY);
+ markDeploymentHexes(null);
+ if (savedGear == GEAR_JUMP) {
+ gear = GEAR_JUMP;
+ initializeJumpMovePath();
+ }
+ } else if (wasWalkOn) {
+ // Press escape twice
+ if (currentlySelectedEntity.isDeployed()) {
+ clientgui.boardViews().forEach(bv -> bv.clearMarkedHexes());
+ clearMovementSprites();
+ markDeploymentHexes(currentlySelectedEntity);
+ currentlySelectedEntity.setDeployed(false);
+ currentlySelectedEntity.setPosition(null);
+ clientgui.boardViews().forEach(bv -> ((BoardView) bv).redrawEntity(currentlySelectedEntity));
+ refreshButtons();
+ }
+ return;
+ }
+
clientgui.updateFiringArc(currentlySelectedEntity);
clientgui.showSensorRanges(currentlySelectedEntity, cmd.getFinalCoords());
computeCFWarningHexes(currentlySelectedEntity);
- // set to "walk," or the equivalent
- gear = MovementDisplay.GEAR_LAND;
jumpSubGear = GEAR_SUB_STANDARD;
clearFlightPath();
Color walkColor = GUIP.getMoveDefaultColor();
@@ -1899,7 +2075,7 @@ public void clear() {
if (currentlySelectedEntity instanceof LandAirMek) {
updateConvertModeButton();
if (currentlySelectedEntity.getMovementMode().isWiGE() &&
- (currentlySelectedEntity.getAltitude() <= 3)) {
+ (currentlySelectedEntity.getAltitude() <= 3)) {
updateHoverButton();
}
getBtn(MoveCommand.MOVE_MORE).setEnabled(numButtonGroups > 1);
@@ -1924,14 +2100,24 @@ private void removeLastStep() {
LOGGER.warn("Cannot process removeLastStep() request, cmd is null!");
return;
}
-
- cmd.removeLastStep();
-
final Entity currentlySelectedEntity = currentEntity();
if (currentlySelectedEntity == null) {
LOGGER.warn("Cannot process removeLastStep for a null currentlySelectedEntity.");
return;
- } else if (cmd.length() == 0) {
+ }
+ if (cmd.getLastStep() == null) {
+ LOGGER.warn("No steps to remove.");
+ return;
+ }
+ if (cmd.getLastStep().getType() == MoveStepType.DEPLOY) {
+ currentlySelectedEntity.setDeployed(false);
+ currentlySelectedEntity.setPosition(null);
+ clientgui.boardViews().forEach(bv -> ((BoardView) bv).redrawEntity(currentlySelectedEntity));
+ markDeploymentHexes(currentlySelectedEntity);
+ }
+ cmd.removeLastStep();
+
+ if (cmd.length() == 0) {
clear();
if ((gear == MovementDisplay.GEAR_JUMP) && !cmd.isJumping()) {
initializeJumpMovePath();
@@ -1958,9 +2144,12 @@ private void removeLastStep() {
}
private void initializeJumpMovePath() {
- addStepToMovePath(MoveStepType.START_JUMP);
- if (jumpSubGear == GEAR_SUB_MEK_BOOSTERS) {
- addStepToMovePath(MoveStepType.JUMP_MEK_MECHANICAL_BOOSTER);
+ Entity currentlySelectedEntity = currentEntity();
+ if ((currentlySelectedEntity != null) && currentlySelectedEntity.isDeployed()) {
+ addStepToMovePath(MoveStepType.START_JUMP);
+ if (jumpSubGear == GEAR_SUB_MEK_BOOSTERS) {
+ addStepToMovePath(MoveStepType.JUMP_MEK_MECHANICAL_BOOSTER);
+ }
}
}
@@ -1989,27 +2178,27 @@ private boolean removeIllegalSteps() {
/**
* Whether this move would put the unit under water somewhere its existing damage turns into a hole.
*
- * A location already stripped of armour is breached the moment it goes under, with no roll to survive it
- * (TW p.121), and that destroys a vehicle outright. The player cannot see that coming from the movement
- * display, so it is worth asking before the water closes over it.
+ * A location already stripped of armour is breached the moment it goes under, with no roll to survive it (TW
+ * p.121), and that destroys a vehicle outright. The player cannot see that coming from the movement display, so it
+ * is worth asking before the water closes over it.
*
* @param movingEntity the unit being moved, or {@code null} if none is selected
* @param movePath the move being considered
- *
* @return {@code true} if the move ends the unit's war
*/
- private boolean movesIntoWaterThatWouldDestroyIt(@Nullable Entity movingEntity, MovePath movePath) {
+ private boolean movesIntoWaterThatWouldDestroyIt(@Nullable Entity movingEntity,
+ MovePath movePath) {
if (!EnvironmentalSealingRules.wouldBeDestroyedByWaterBreach(movingEntity)) {
return false;
}
for (MoveStep step : movePath.getStepVector()) {
Hex hex = game.getHex(step.getPosition(), step.getBoardId());
boolean goesUnderTheSurface = (hex != null)
- && (hex.terrainLevel(Terrains.WATER) > 0)
- && (step.getElevation() < hex.getLevel());
+ && (hex.terrainLevel(Terrains.WATER) > 0)
+ && (step.getElevation() < hex.getLevel());
if (goesUnderTheSurface) {
LOGGER.debug("[EnvironmentalSealing] {}: warning about a doomed move - a location has no armour "
- + "left and hex {} puts it under water", movingEntity.getShortName(), step.getPosition());
+ + "left and hex {} puts it under water", movingEntity.getShortName(), step.getPosition());
return true;
}
}
@@ -2023,7 +2212,7 @@ private boolean checkNags() {
Entity currentlySelectedEntity = currentEntity();
if (needNagForNoAction()) {
- if ((currentlySelectedEntity != null) && (cmd.length() == 0) && !currentlySelectedEntity.isAirborne()) {
+ if ((currentlySelectedEntity != null) && cmd.length() == 0 && !currentlySelectedEntity.isAirborne()) {
// Hmm... no movement steps confirm this action
String title = Messages.getString("MovementDisplay.ConfirmNoMoveDlg.title");
String body = Messages.getString("MovementDisplay.ConfirmNoMoveDlg.message");
@@ -2046,12 +2235,12 @@ private boolean checkNags() {
if (needNagForMASC()) {
if ((currentlySelectedEntity != null) &&
- cmd.hasActiveMASC() &&
- !(currentlySelectedEntity instanceof VTOL)) {
+ cmd.hasActiveMASC() &&
+ !(currentlySelectedEntity instanceof VTOL)) {
// pop up are you sure dialog
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmMASCRoll",
- currentlySelectedEntity.getMASCTarget());
+ currentlySelectedEntity.getMASCTarget());
if (checkNagForMASC(title, body)) {
return true;
}
@@ -2060,11 +2249,11 @@ private boolean checkNags() {
if (needNagForMASC()) {
if ((currentlySelectedEntity != null) &&
- !(currentlySelectedEntity instanceof VTOL) &&
- cmd.hasActiveSupercharger()) {
+ !(currentlySelectedEntity instanceof VTOL) &&
+ cmd.hasActiveSupercharger()) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmSuperchargerRoll",
- currentlySelectedEntity.getSuperchargerTarget());
+ currentlySelectedEntity.getSuperchargerTarget());
if (checkNagForMASC(title, body)) {
return true;
}
@@ -2073,9 +2262,9 @@ private boolean checkNags() {
if (needNagForSprint()) {
boolean sprintOrVtolSprint = cmd.getLastStepMovementType() == EntityMovementType.MOVE_SPRINT ||
- cmd.getLastStepMovementType() == EntityMovementType.MOVE_VTOL_SPRINT;
+ cmd.getLastStepMovementType() == EntityMovementType.MOVE_VTOL_SPRINT;
boolean quadVeeVehicle = cmd.getEntity() instanceof QuadVee &&
- cmd.getEntity().getConversionMode() == QuadVee.CONV_MODE_VEHICLE;
+ cmd.getEntity().getConversionMode() == QuadVee.CONV_MODE_VEHICLE;
boolean tankOrQuadVee = cmd.getEntity() instanceof Tank || quadVeeVehicle;
// no need to nag for vehicles using overdrive if they already get a PSR nag
boolean psrNag = tankOrQuadVee && needNagForPSR();
@@ -2101,7 +2290,7 @@ private boolean checkNags() {
// check for unsafe takeoffs
if (needNagForPSR()) {
boolean verticalTakeoffOrTakeoff = cmd.contains(MoveStepType.VERTICAL_TAKE_OFF) ||
- cmd.contains(MoveStepType.TAKEOFF);
+ cmd.contains(MoveStepType.TAKEOFF);
if ((currentlySelectedEntity != null) && verticalTakeoffOrTakeoff) {
boolean unsecure = false;
for (Entity loaded : currentlySelectedEntity.getLoadedUnits()) {
@@ -2135,10 +2324,10 @@ private boolean checkNags() {
// changing altitude voluntarily.
if (needNagForPSR()) {
if (Compute.useSpheroidAtmosphere(game, currentlySelectedEntity) &&
- !cmd.contains(MoveStepType.HOVER) &&
- !cmd.contains(MoveStepType.VERTICAL_LAND) &&
- !cmd.contains(MoveStepType.UP) &&
- !cmd.contains(MoveStepType.DOWN)) {
+ !cmd.contains(MoveStepType.HOVER) &&
+ !cmd.contains(MoveStepType.VERTICAL_LAND) &&
+ !cmd.contains(MoveStepType.UP) &&
+ !cmd.contains(MoveStepType.DOWN)) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.SpheroidAltitudeLoss") + thrustCheck;
if (checkNagForPSR(title, body)) {
@@ -2152,9 +2341,9 @@ private boolean checkNags() {
if ((currentlySelectedEntity != null) && cmd.shouldMechanicalJumpCauseFallDamage()) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmMechanicalJumpFallDamage",
- cmd.getJumpMaxElevationChange(),
- currentlySelectedEntity.getMechanicalJumpBoosterMP(),
- cmd.getJumpMaxElevationChange() - currentlySelectedEntity.getMechanicalJumpBoosterMP());
+ cmd.getJumpMaxElevationChange(),
+ currentlySelectedEntity.getMechanicalJumpBoosterMP(),
+ cmd.getJumpMaxElevationChange() - currentlySelectedEntity.getMechanicalJumpBoosterMP());
if (checkNagForMechanicalJumpFallDamage(title, body)) {
return true;
}
@@ -2165,7 +2354,7 @@ private boolean checkNags() {
if (movesIntoWaterThatWouldDestroyIt(currentlySelectedEntity, cmd)) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmDoomedMove",
- currentlySelectedEntity.getShortName());
+ currentlySelectedEntity.getShortName());
if (checkNagForDoomedMove(title, body)) {
return true;
}
@@ -2196,29 +2385,29 @@ private boolean checkNags() {
if (needNagForOther()) {
if ((currentlySelectedEntity != null) && (null != cmd) && currentlySelectedEntity.isAero()) {
boolean airborneOrSpaceborne = currentlySelectedEntity.isAirborne() ||
- currentlySelectedEntity.isSpaceborne();
+ currentlySelectedEntity.isSpaceborne();
boolean unusedVelocity;
if (null != cmd.getLastStep()) {
unusedVelocity = cmd.getLastStep().getVelocityLeft() > 0;
} else {
unusedVelocity = (((IAero) currentlySelectedEntity).getCurrentVelocity() > 0) &&
- (currentlySelectedEntity.delta_distance == 0);
+ (currentlySelectedEntity.delta_distance == 0);
}
boolean offOrReturn = cmd.contains(MoveStepType.OFF) || cmd.contains(MoveStepType.RETURN);
if (airborneOrSpaceborne &&
- !game.useVectorMove() &&
- !((IAero) currentlySelectedEntity).isOutControlTotal() &&
- unusedVelocity &&
- !offOrReturn &&
- !cmd.contains(MoveStepType.LAND) &&
- !cmd.contains(MoveStepType.VERTICAL_LAND) &&
- !cmd.contains(MoveStepType.EJECT) &&
- !cmd.contains(MoveStepType.FLEE)) {
+ !game.useVectorMove() &&
+ !((IAero) currentlySelectedEntity).isOutControlTotal() &&
+ unusedVelocity &&
+ !offOrReturn &&
+ !cmd.contains(MoveStepType.LAND) &&
+ !cmd.contains(MoveStepType.VERTICAL_LAND) &&
+ !cmd.contains(MoveStepType.EJECT) &&
+ !cmd.contains(MoveStepType.FLEE)) {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.VelocityLeft.title") + ": "
- + Messages.getString("MovementDisplay.VelocityLeft.message"), currentEntity());
+ Messages.getString("MovementDisplay.VelocityLeft.title") + ": "
+ + Messages.getString("MovementDisplay.VelocityLeft.message"), currentEntity());
// always return true here, or airborne units will make illegal moves.
return true;
}
@@ -2228,8 +2417,8 @@ private boolean checkNags() {
// check to see if spheroids will drop an elevation
if (needNagForOther()) {
if (currentlySelectedEntity instanceof LandAirMek &&
- currentlySelectedEntity.isAssaultDropInProgress() &&
- cmd.getFinalConversionMode() == EntityMovementMode.AERODYNE) {
+ currentlySelectedEntity.isAssaultDropInProgress() &&
+ cmd.getFinalConversionMode() == EntityMovementMode.AERODYNE) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.insufficientAltitudeForConversion") + thrustCheck;
if (!clientgui.doYesNoDialog(title, body)) {
@@ -2240,21 +2429,21 @@ private boolean checkNags() {
if (needNagForOther()) {
if (currentEntity() != null
- && (currentEntity() instanceof ConvInfantry infantry)
- && infantry.hasMicrolite()) {
+ && (currentEntity() instanceof ConvInfantry infantry)
+ && infantry.hasMicrolite()) {
boolean finalElevation = (currentEntity().getElevation() != cmd.getFinalElevation());
boolean airborneVTOLOrWIGEOrFinalElevation = currentEntity().isAirborneVTOLorWIGE()
- || finalElevation;
+ || finalElevation;
int terrainLevelBuilding = game.getBoard(currentEntity()).getHex(cmd.getFinalCoords())
- .terrainLevel(Terrains.BLDG_ELEV);
+ .terrainLevel(Terrains.BLDG_ELEV);
int terrainLevelBridge = game.getBoard(currentEntity()).getHex(cmd.getFinalCoords())
- .terrainLevel(Terrains.BRIDGE_ELEV);
+ .terrainLevel(Terrains.BRIDGE_ELEV);
if (airborneVTOLOrWIGEOrFinalElevation
- && !cmd.contains(MoveStepType.FORWARDS)
- && !cmd.contains(MoveStepType.FLEE)
- && cmd.getFinalElevation() > 0
- && terrainLevelBuilding < cmd.getFinalElevation()
- && terrainLevelBridge < cmd.getFinalElevation()) {
+ && !cmd.contains(MoveStepType.FORWARDS)
+ && !cmd.contains(MoveStepType.FLEE)
+ && cmd.getFinalElevation() > 0
+ && terrainLevelBuilding < cmd.getFinalElevation()
+ && terrainLevelBridge < cmd.getFinalElevation()) {
String title = Messages.getString("MovementDisplay.MicroliteMove.title");
String body = Messages.getString("MovementDisplay.MicroliteMove.message");
if (!clientgui.doYesNoDialog(title, body)) {
@@ -2268,12 +2457,12 @@ private boolean checkNags() {
boolean landOrVerticalLand = cmd.contains(MoveStepType.LAND) || cmd.contains(MoveStepType.VERTICAL_LAND);
if ((currentlySelectedEntity != null) && landOrVerticalLand) {
Set landingPath = ((IAero) currentlySelectedEntity).getLandingCoords(cmd.contains(MoveStepType.VERTICAL_LAND),
- cmd.getFinalCoords(),
- cmd.getFinalFacing());
+ cmd.getFinalCoords(),
+ cmd.getFinalFacing());
if (landingPath.stream()
- .map(c -> game.getBoard(currentEntity()).getHex(c))
- .filter(Objects::nonNull)
- .anyMatch(h -> h.containsTerrain(Terrains.ROUGH) || h.containsTerrain(Terrains.RUBBLE))) {
+ .map(c -> game.getBoard(currentEntity()).getHex(c))
+ .filter(Objects::nonNull)
+ .anyMatch(h -> h.containsTerrain(Terrains.ROUGH) || h.containsTerrain(Terrains.RUBBLE))) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmLandingGearDamage");
if (!clientgui.doYesNoDialog(title, body)) {
@@ -2287,9 +2476,9 @@ private boolean checkNags() {
if (currentlySelectedEntity instanceof ConvInfantry infantry) {
InfantryMount mount = infantry.getMount();
if ((mount != null) &&
- currentlySelectedEntity.getMovementMode().isSubmarine() &&
- (currentlySelectedEntity.underwaterRounds >= mount.getUWEndurance()) &&
- cmd.isAllUnderwater(game)) {
+ currentlySelectedEntity.getMovementMode().isSubmarine() &&
+ (currentlySelectedEntity.underwaterRounds >= mount.getUWEndurance()) &&
+ cmd.isAllUnderwater(game)) {
String title = Messages.getString("MovementDisplay.areYouSure");
String body = Messages.getString("MovementDisplay.ConfirmMountSuffocation");
if (!clientgui.doYesNoDialog(title, body)) {
@@ -2348,7 +2537,8 @@ public synchronized void ready() {
/**
* Returns new {@link MovePath} for the currently selected movement type
*/
- private void currentMove(Coords dest, int boardId) {
+ private void currentMove(Coords dest,
+ int boardId) {
if (shiftHeld || (gear == GEAR_TURN)) {
if (buttons.get(MoveCommand.MOVE_TURN).isEnabled()) {
cmd.rotatePathfinder(cmd.getFinalCoords().direction(dest), false, ManeuverType.MAN_NONE);
@@ -2362,7 +2552,7 @@ private void currentMove(Coords dest, int boardId) {
Coords src = (cmd.getLastStep() != null) ? cmd.getLastStep().getPosition() : currentEntity().getPosition();
int direction = src.direction(dest);
MoveStepType moveStepType = MoveStepType.stepTypeForRelativeDirection(direction,
- currentEntity().getFacing());
+ currentEntity().getFacing());
cmd.findSimplePathTo(dest, moveStepType, src.direction(dest), currentEntity().getFacing());
} else if (gear == GEAR_STRAFE) {
@@ -2417,21 +2607,21 @@ private void currentMove(Coords dest, int boardId) {
extendPathTo(dest, boardId, MoveStepType.FORWARDS);
} else if (gear == GEAR_IM_MEL) {
addStepsToMovePath(true,
- true,
- ManeuverType.MAN_IMMELMAN,
- MoveStepType.UP,
- MoveStepType.UP,
- MoveStepType.DEC,
- MoveStepType.DEC);
+ true,
+ ManeuverType.MAN_IMMELMAN,
+ MoveStepType.UP,
+ MoveStepType.UP,
+ MoveStepType.DEC,
+ MoveStepType.DEC);
cmd.rotatePathfinder(cmd.getFinalCoords().direction(dest), true, ManeuverType.MAN_IMMELMAN);
gear = GEAR_LAND;
} else if (gear == GEAR_SPLIT_S) {
addStepsToMovePath(true,
- true,
- ManeuverType.MAN_SPLIT_S,
- MoveStepType.DOWN,
- MoveStepType.DOWN,
- MoveStepType.ACC);
+ true,
+ ManeuverType.MAN_SPLIT_S,
+ MoveStepType.DOWN,
+ MoveStepType.DOWN,
+ MoveStepType.ACC);
cmd.rotatePathfinder(cmd.getFinalCoords().direction(dest), true, ManeuverType.MAN_SPLIT_S);
gear = GEAR_LAND;
}
@@ -2477,14 +2667,15 @@ private void currentMove(Coords dest, int boardId) {
* @param dest the rubble hex the player clicked
* @param boardId the board the destination hex is on
*/
- private void planClearRubbleMove(Coords dest, int boardId) {
+ private void planClearRubbleMove(Coords dest,
+ int boardId) {
// Drive into the chosen rubble hex (the bulldozer override makes the entry legal) and clear it.
Hex targetHex = game.getBoard(boardId).getHex(dest);
if (!BulldozerRules.hasClearableRubble(targetHex)) {
LOGGER.debug("[Bulldozer] {}: clear-rubble target {} has no clearable rubble; ignoring click",
- currentEntity().getDisplayName(), dest);
+ currentEntity().getDisplayName(), dest);
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.clearRubbleIllegalTerrain.toast"), currentEntity());
+ Messages.getString("MovementDisplay.clearRubbleIllegalTerrain.toast"), currentEntity());
return;
}
Entity clearingUnit = currentEntity();
@@ -2492,31 +2683,31 @@ private void planClearRubbleMove(Coords dest, int boardId) {
// (QA feedback); the prompt names the actual tool - bulldozer or backhoe.
int requiredTurns = BulldozerRules.totalClearingTurns(clearingUnit, targetHex, game);
boolean confirmed = clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.clearRubbleConfirm.title"),
- Messages.getString("MovementDisplay.clearRubbleConfirm.message",
- BulldozerRules.clearingToolName(clearingUnit), requiredTurns));
+ Messages.getString("MovementDisplay.clearRubbleConfirm.title"),
+ Messages.getString("MovementDisplay.clearRubbleConfirm.message",
+ BulldozerRules.clearingToolName(clearingUnit), requiredTurns));
if (!confirmed) {
LOGGER.debug("[Bulldozer] {}: player declined to clear rubble at {}",
- clearingUnit.getDisplayName(), dest);
+ clearingUnit.getDisplayName(), dest);
return;
}
// The blade must engage the rubble: a front-mounted bulldozer drives in forwards; a rear-mounted
// one (e.g. the Reverse Buffel) backs into the hex so its rear blade leads.
boolean rearBlade = !clearingUnit.hasFrontMountedBulldozer()
- && clearingUnit.hasRearMountedBulldozer();
+ && clearingUnit.hasRearMountedBulldozer();
MoveStepType approach = rearBlade ? MoveStepType.BACKWARDS : MoveStepType.FORWARDS;
LOGGER.debug("[Bulldozer] {}: clear-rubble target at {} (rubble level {}), {}-mounted blade -> {}",
- clearingUnit.getDisplayName(), dest, targetHex.terrainLevel(Terrains.RUBBLE),
- rearBlade ? "rear" : "front", approach);
+ clearingUnit.getDisplayName(), dest, targetHex.terrainLevel(Terrains.RUBBLE),
+ rearBlade ? "rear" : "front", approach);
extendPathTo(dest, boardId, approach);
if (cmd.getFinalCoords().equals(dest)) {
addStepToMovePath(MoveStepType.CLEAR_RUBBLE);
} else {
LOGGER.debug("[Bulldozer] {}: could not reach rubble hex {} {} (path ended at {})",
- clearingUnit.getDisplayName(), dest, rearBlade ? "in reverse" : "forwards",
- cmd.getFinalCoords());
+ clearingUnit.getDisplayName(), dest, rearBlade ? "in reverse" : "forwards",
+ cmd.getFinalCoords());
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.clearRubbleUnreachable.toast"), clearingUnit);
+ Messages.getString("MovementDisplay.clearRubbleUnreachable.toast"), clearingUnit);
}
}
@@ -2528,7 +2719,9 @@ private void planClearRubbleMove(Coords dest, int boardId) {
* @param boardId The destination
* @param type The step type to use
*/
- private void extendPathTo(Coords dest, int boardId, MoveStepType type) {
+ private void extendPathTo(Coords dest,
+ int boardId,
+ MoveStepType type) {
if (cmd.getFinalBoardId() == boardId) {
cmd.findPathTo(dest, type);
}
@@ -2552,7 +2745,7 @@ public synchronized void hexMoused(BoardViewEvent boardViewEvent) {
// don't make a movement path for aeros if advanced movement is on
boolean noPath = (currentlySelectedEntity != null && currentlySelectedEntity.isAero())
- && game.useVectorMove();
+ && game.useVectorMove();
// ignore buttons other than 1
if (!clientgui.getClient().isMyTurn() || ((boardViewEvent.getButton() != MouseEvent.BUTTON1))) {
@@ -2561,7 +2754,7 @@ public synchronized void hexMoused(BoardViewEvent boardViewEvent) {
// control pressed means a line of sight check.
// added ALT_MASK by kenn
if (((boardViewEvent.getModifiers() & InputEvent.CTRL_DOWN_MASK) != 0) ||
- ((boardViewEvent.getModifiers() & InputEvent.ALT_DOWN_MASK) != 0)) {
+ ((boardViewEvent.getModifiers() & InputEvent.ALT_DOWN_MASK) != 0)) {
return;
}
@@ -2570,25 +2763,25 @@ public synchronized void hexMoused(BoardViewEvent boardViewEvent) {
// selection and discard it). A click is handled as a selection here and consumes the event.
if (bridgeSelectionStage != BridgeSelectionStage.NONE) {
if ((boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_CLICKED)
- && (boardViewEvent.getCoords() != null)) {
+ && (boardViewEvent.getCoords() != null)) {
LOGGER.debug("[BuildBridge] board click during stage {} at {}", bridgeSelectionStage,
- boardViewEvent.getCoords());
+ boardViewEvent.getCoords());
handleBridgeSelectionClick(boardViewEvent.getCoords());
}
return;
}
if ((currentlySelectedEntity != null) && (gear == GEAR_FLIGHTPATH)
- && (boardViewEvent.getBoardId() == flightPathTarget(currentlySelectedEntity))
- && (boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_CLICKED)) {
+ && (boardViewEvent.getBoardId() == flightPathTarget(currentlySelectedEntity))
+ && (boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_CLICKED)) {
if (flightPath != null) {
boardViewEvent.getBoardView().removeSprite(flightPath);
}
clearFlightPath();
flightPathPosition = boardViewEvent.getCoords();
List line = BoardHelper.coordsLine(game.getBoard(boardViewEvent.getBoardId()),
- flightPathPosition,
- finalFacing());
+ flightPathPosition,
+ finalFacing());
currentlySelectedEntity.setPassedThrough(new Vector<>(line));
flightPath = new FlyOverSprite(boardViewEvent.getBoardView(), currentlySelectedEntity);
boardViewEvent.getBoardView().addSprite(flightPath);
@@ -2597,24 +2790,113 @@ public synchronized void hexMoused(BoardViewEvent boardViewEvent) {
}
if ((currentlySelectedEntity != null)
- && (gear == GEAR_LANDING_AERO)
- && (boardViewEvent.getBoardId()
- == game.getBoard(currentlySelectedEntity).getEmbeddedBoardAt(currentlySelectedEntity.getPosition()))
- && (boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_CLICKED)
- && (currentlySelectedEntity instanceof IAero aero)
- && hasLandingMoveStep()) {
+ && (gear == GEAR_LANDING_AERO)
+ && (boardViewEvent.getBoardId()
+ == game.getBoard(currentlySelectedEntity).getEmbeddedBoardAt(currentlySelectedEntity.getPosition()))
+ && (boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_CLICKED)
+ && (currentlySelectedEntity instanceof IAero aero)
+ && hasLandingMoveStep()) {
finalizeAeroLandFromAtmosphereMap(aero, boardViewEvent);
return;
}
+ if (Game.rulesManager.getRulesGame().isWalkOnDeployment() && currentlySelectedEntity != null) {
+ if (cmd == null) {
+ cmd = new MovePath(game, currentlySelectedEntity);
+ }
+ Coords coords = boardViewEvent.getCoords();
+ int boardId = boardViewEvent.getBoardId();
+ if (!currentlySelectedEntity.isDeployed() && boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_DRAGGED) {
+ DeploymentHelper deploymentHelper = new DeploymentHelper(clientgui);
+ if (!deploymentHelper.checkDeployment(game.getBoard(boardId),
+ currentlySelectedEntity,
+ coords,
+ false)) {
+ return;
+ }
+ if (originalFacing == -1) {
+ deploymentHelper.setStartingFacing(currentlySelectedEntity, game.getPlayersList(), coords);
+ }
+ DeploymentPosition deploymentPosition = deploymentHelper.determineDeploymentPosition(
+ currentlySelectedEntity,
+ coords,
+ game.getBoard(boardId),
+ lastHexDeploymentOptions,
+ lastDeploymentOption);
+ if (deploymentPosition == null) {
+
+ return;
+ }
+ int elevation = deploymentPosition.elevation();
+ int facing = deploymentPosition.facing();
+ originalFacing = facing;
+ lastDeploymentOption = deploymentPosition.lastDeploymentOption();
+ if (game.getBoard(boardId).isLegalDeployment(coords, currentlySelectedEntity)
+ && !currentlySelectedEntity.isLocationProhibited(
+ coords,
+ boardId,
+ elevation)) {
+ // entity.isAero will check if a unit is a LAM in Fighter mode
+ if ((currentlySelectedEntity instanceof IAero aero) && (currentlySelectedEntity.isAero())) {
+ currentlySelectedEntity.setAltitude(elevation);
+ if (elevation == 0) {
+ aero.land();
+ } else {
+ aero.liftOff(elevation);
+ }
+ } else {
+ currentlySelectedEntity.setElevation(elevation);
+ }
+ currentlySelectedEntity.setPosition(coords);
+ currentlySelectedEntity.setBoardId(boardId);
+ currentlySelectedEntity.setFacing(facing);
+ currentlySelectedEntity.setSecondaryFacing(facing);
+ currentlySelectedEntity.setDeployed(true);
+ cmd = new MovePath(game, currentlySelectedEntity);
+ addStepToMovePath(MoveStepType.DEPLOY);
+ if (gear == GEAR_JUMP) {
+ initializeJumpMovePath();
+ }
+ } else {
+ String msg = Messages.getString("DeploymentDisplay.cantDeployInto",
+ currentlySelectedEntity.getShortName(),
+ coords.getBoardNum());
+ clientgui.addToast(ToastLevel.ERROR, msg, currentlySelectedEntity);
+ }
+ clientgui.boardViews().forEach(bv -> ((BoardView) bv).redrawEntity(currentlySelectedEntity));
+ clientgui.updateFiringArc(currentlySelectedEntity);
+ clientgui.showSensorRanges(currentlySelectedEntity);
+ clientgui.boardViews().forEach(IBoardView::repaint);
+ refreshButtons();
+ return;
+
+ }
+ }
+
// check for shifty goodness
if (shiftHeld == ((boardViewEvent.getModifiers() & InputEvent.SHIFT_DOWN_MASK) == 0)) {
shiftHeld = (boardViewEvent.getModifiers() & InputEvent.SHIFT_DOWN_MASK) != 0;
}
+ // Check for deployment and shift held
+ if (shiftHeld &&
+ (cmd != null) &&
+ cmd.getLastStep() != null &&
+ Game.rulesManager.getRulesGame().isWalkOnDeployment()) {
+ MoveStep lastStep = cmd.getLastStep();
+ if (lastStep.getType() == MoveStepType.START_JUMP) {
+ lastStep = cmd.getStep(0);
+ }
+ if ((lastStep != null) && lastStep.getType() == MoveStepType.DEPLOY) {
+ processDeploymentTurn(currentlySelectedEntity, boardViewEvent.getCoords());
+ refreshButtons();
+ return;
+ }
+ }
+
Coords currPosition = cmd != null ?
- cmd.getFinalCoords() :
- currentlySelectedEntity != null ? currentlySelectedEntity.getPosition() : null;
+ cmd.getFinalCoords() :
+ currentlySelectedEntity != null ? currentlySelectedEntity.getPosition() : null;
if ((boardViewEvent.getType() == BoardViewEvent.BOARD_HEX_DRAGGED) && !noPath) {
if (!boardViewEvent.getCoords().equals(currPosition) || shiftHeld || (gear == MovementDisplay.GEAR_TURN)) {
@@ -2649,8 +2931,8 @@ && hasLandingMoveStep()) {
final Targetable target = chooseTarget(boardViewEvent.getCoords());
if ((target == null) || target.equals(currentlySelectedEntity) || !target.isAero()) {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantRam") + ": "
- + Messages.getString("MovementDisplay.NoTarget"), currentEntity());
+ Messages.getString("MovementDisplay.CantRam") + ": "
+ + Messages.getString("MovementDisplay.NoTarget"), currentEntity());
clear();
return;
}
@@ -2658,31 +2940,31 @@ && hasLandingMoveStep()) {
// check if it's a valid ram
// First I need to add moves to the path if advanced
if (currentlySelectedEntity != null &&
- currentlySelectedEntity.isAero() &&
- game.useVectorMove()) {
+ currentlySelectedEntity.isAero() &&
+ game.useVectorMove()) {
cmd.clipToPossible();
}
addStepToMovePath(MoveStepType.RAM);
ToHitData toHit = new RamAttackAction(currentEntity,
- target.getTargetType(),
- target.getId(),
- target.getPosition()).toHit(game, cmd);
+ target.getTargetType(),
+ target.getId(),
+ target.getPosition()).toHit(game, cmd);
if (toHit.getValue() != TargetRoll.IMPOSSIBLE &&
- target instanceof IAero targetAero &&
- currentlySelectedEntity instanceof IAero attackingEntity) {
+ target instanceof IAero targetAero &&
+ currentlySelectedEntity instanceof IAero attackingEntity) {
// Determine how much damage the charger will take.
int toAttacker = RamAttackAction.getDamageTakenBy(attackingEntity,
- (Entity) targetAero,
- cmd.getSecondFinalPosition(currentlySelectedEntity.getPosition()),
- cmd.getHexesMoved(),
- targetAero.getCurrentVelocity());
+ (Entity) targetAero,
+ cmd.getSecondFinalPosition(currentlySelectedEntity.getPosition()),
+ cmd.getHexesMoved(),
+ targetAero.getCurrentVelocity());
int toDefender = RamAttackAction.getDamageFor(attackingEntity,
- (Entity) targetAero,
- cmd.getSecondFinalPosition(currentlySelectedEntity.getPosition()),
- cmd.getHexesMoved(),
- targetAero.getCurrentVelocity());
+ (Entity) targetAero,
+ cmd.getSecondFinalPosition(currentlySelectedEntity.getPosition()),
+ cmd.getHexesMoved(),
+ targetAero.getCurrentVelocity());
// Warn if this ram would dishonor the player in the eyes of a Forced Withdrawal bot.
String ramDishonorWarning = needNagForDishonor()
@@ -2698,15 +2980,16 @@ && hasLandingMoveStep()) {
// Ask the player if they want to charge.
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.RamDialog.title",
- target.getDisplayName()),
- Messages.getString("MovementDisplay.RamDialog.message",
- toHit.getValueAsString(),
- Compute.oddsAbove(toHit.getValue(),
- currentlySelectedEntity.hasAbility(OptionsConstants.PILOT_APTITUDE_PILOTING)),
- toHit.getDesc(),
- toDefender,
- toHit.getTableDesc(),
- toAttacker))) {
+ target.getDisplayName()),
+ Messages.getString("MovementDisplay.RamDialog.message",
+ toHit.getValueAsString(),
+ Compute.oddsAbove(toHit.getValue(),
+ currentlySelectedEntity.hasAbility(
+ OptionsConstants.PILOT_APTITUDE_PILOTING)),
+ toHit.getDesc(),
+ toDefender,
+ toHit.getTableDesc(),
+ toAttacker))) {
// if they answer yes, charge the target.
cmd.getLastStep().setTarget(target);
ready();
@@ -2719,7 +3002,8 @@ && hasLandingMoveStep()) {
}
// if not valid, tell why
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantRam") + ": " + toHit.getDesc(), currentEntity());
+ Messages.getString("MovementDisplay.CantRam") + ": " + toHit.getDesc(),
+ currentEntity());
clear();
return;
} else if (gear == MovementDisplay.GEAR_CHARGE) {
@@ -2727,10 +3011,11 @@ && hasLandingMoveStep()) {
final Targetable target = chooseTarget(boardViewEvent.getCoords());
if (currentlySelectedEntity != null && ((target == null) || target.equals(currentlySelectedEntity))) {
String cantMsg = Messages.getString(currentlySelectedEntity.isAirborneVTOLorWIGE() ?
- "MovementDisplay.CantRam" :
- "MovementDisplay.CantCharge");
+ "MovementDisplay.CantRam" :
+ "MovementDisplay.CantCharge");
clientgui.addToast(ToastLevel.WARNING,
- cantMsg + ": " + Messages.getString("MovementDisplay.NoTarget"), currentEntity());
+ cantMsg + ": " + Messages.getString("MovementDisplay.NoTarget"),
+ currentEntity());
clear();
computeMovementEnvelope(currentlySelectedEntity);
return;
@@ -2741,14 +3026,14 @@ && hasLandingMoveStep()) {
if (target != null) {
if (currentlySelectedEntity != null && currentlySelectedEntity.isAirborneVTOLorWIGE()) {
toHit = new AirMekRamAttackAction(currentEntity,
- target.getTargetType(),
- target.getId(),
- target.getPosition()).toHit(game, cmd);
+ target.getTargetType(),
+ target.getId(),
+ target.getPosition()).toHit(game, cmd);
} else {
toHit = new ChargeAttackAction(currentEntity,
- target.getTargetType(),
- target.getId(),
- target.getPosition()).toHit(game, cmd);
+ target.getTargetType(),
+ target.getId(),
+ target.getPosition()).toHit(game, cmd);
}
}
@@ -2758,31 +3043,31 @@ && hasLandingMoveStep()) {
int toAttacker = 0;
if (currentlySelectedEntity.isAirborneVTOLorWIGE()) {
toAttacker = AirMekRamAttackAction.getDamageTakenBy(currentlySelectedEntity,
- target,
- cmd.getHexesMoved());
+ target,
+ cmd.getHexesMoved());
toDefender = AirMekRamAttackAction.getDamageFor(currentlySelectedEntity, cmd.getHexesMoved());
} else {
// Front-mounted saw charge uses flat damage (TM pp.241-243)
if (ChargeAttackAction.hasFrontMountedSaw(currentlySelectedEntity)
- && target.getTargetType() == Targetable.TYPE_ENTITY) {
+ && target.getTargetType() == Targetable.TYPE_ENTITY) {
toDefender = ChargeAttackAction.getMaxSawChargeDamage(
- currentlySelectedEntity, (Entity) target);
+ currentlySelectedEntity, (Entity) target);
} else {
toDefender = ChargeAttackAction.getDamageFor(
- currentlySelectedEntity, game.getOptions()
- .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_CHARGE_DAMAGE),
- cmd.getHexesMoved());
+ currentlySelectedEntity, game.getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_CHARGE_DAMAGE),
+ cmd.getHexesMoved());
}
if (target.getTargetType() == Targetable.TYPE_ENTITY) {
Entity te = (Entity) target;
toAttacker = ChargeAttackAction.getDamageTakenBy(currentlySelectedEntity,
- te,
- game
- .getOptions()
- .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_CHARGE_DAMAGE),
- cmd.getHexesMoved());
+ te,
+ game
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_CHARGE_DAMAGE),
+ cmd.getHexesMoved());
} else if ((target.getTargetType() == Targetable.TYPE_FUEL_TANK) ||
- (target.getTargetType() == Targetable.TYPE_BUILDING)) {
+ (target.getTargetType() == Targetable.TYPE_BUILDING)) {
IBuilding bldg = game.getBoard(currentlySelectedEntity).getBuildingAt(moveto);
toAttacker = ChargeAttackAction.getDamageTakenBy(currentlySelectedEntity, bldg, moveto);
}
@@ -2808,22 +3093,22 @@ && hasLandingMoveStep()) {
// Ask the player if they want to charge.
if (clientgui.doYesNoDialog(Messages.getString(title, target.getDisplayName()),
- Messages.getString(msg,
- toHit.getValueAsString(),
- Compute.oddsAbove(toHit.getValue()),
- toHit.getDesc(),
- toDefender,
- toHit.getTableDesc(),
- toAttacker))) {
+ Messages.getString(msg,
+ toHit.getValueAsString(),
+ Compute.oddsAbove(toHit.getValue()),
+ toHit.getDesc(),
+ toDefender,
+ toHit.getTableDesc(),
+ toAttacker))) {
// if they answer yes, charge the target.
cmd.getLastStep().setTarget(target);
if (currentlySelectedEntity.hasShield()) {
boolean hasLance = false;
for (MiscMounted getClub : currentlySelectedEntity.getClubs()) {
if (getClub.getType().hasFlag(MiscTypeFlag.S_LANCE)
- && !getClub.isDestroyed()
- && !getClub.isBreached()
- && !getClub.isMissing()) {
+ && !getClub.isDestroyed()
+ && !getClub.isBreached()
+ && !getClub.isMissing()) {
hasLance = true;
}
}
@@ -2831,15 +3116,16 @@ && hasLandingMoveStep()) {
if (!hasLance) {
// Do we want to raise the shield?
if (clientgui.doYesNoDialog(Messages.getString(
- "MovementDisplay.ChargeDialog.RaiseShield"),
- Messages.getString("MovementDisplay.ChargeDialog.ShieldMessage"))) {
+ "MovementDisplay.ChargeDialog.RaiseShield"),
+ Messages.getString(
+ "MovementDisplay.ChargeDialog.ShieldMessage"))) {
for (MiscMounted m : currentlySelectedEntity.getMisc()) {
MiscType type = m.getType();
if (((m.getLocation() == Mek.LOC_LEFT_ARM) || (m.getLocation()
- == Mek.LOC_RIGHT_ARM))
- && type.hasFlag(MiscType.F_SHIELD)
- && !m.isInoperable()
- && (currentlySelectedEntity.getInternal(m.getLocation()) > 0)) {
+ == Mek.LOC_RIGHT_ARM))
+ && type.hasFlag(MiscType.F_SHIELD)
+ && !m.isInoperable()
+ && (currentlySelectedEntity.getInternal(m.getLocation()) > 0)) {
// Only one shield needs to be raised
m.setMode(MiscType.S_ACTIVE_SHIELD);
Enumeration shieldModes = m.getType().getModes();
@@ -2852,7 +3138,7 @@ && hasLandingMoveStep()) {
nMode++;
}
clientgui.getClient().sendModeChange(currentlySelectedEntity.getId(),
- m.equipmentIndex(), nMode);
+ m.equipmentIndex(), nMode);
break;
}
}
@@ -2868,9 +3154,10 @@ && hasLandingMoveStep()) {
}
// if not valid, tell why
String chargeReason = (toHit != null) ? toHit.getDesc()
- : Messages.getString("MovementDisplay.CantCharge.unknown");
+ : Messages.getString("MovementDisplay.CantCharge.unknown");
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantCharge") + ": " + chargeReason, currentEntity());
+ Messages.getString("MovementDisplay.CantCharge") + ": " + chargeReason,
+ currentEntity());
clear();
@@ -2884,8 +3171,8 @@ && hasLandingMoveStep()) {
final Targetable target = chooseTarget(boardViewEvent.getCoords());
if ((target == null) || target.equals(currentlySelectedEntity)) {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantDFA") + ": "
- + Messages.getString("MovementDisplay.NoTarget"), currentEntity());
+ Messages.getString("MovementDisplay.CantDFA") + ": "
+ + Messages.getString("MovementDisplay.NoTarget"), currentEntity());
clear();
if (currentlySelectedEntity != null) {
@@ -2901,12 +3188,12 @@ && hasLandingMoveStep()) {
if (currentlySelectedEntity != null) {
// Calculate piloting roll to stay standing after DFA
PilotingRollData pilotRoll = currentlySelectedEntity.getBasePilotingRoll(
- EntityMovementType.MOVE_JUMP);
+ EntityMovementType.MOVE_JUMP);
pilotRoll.addModifier(Game.rulesManager.getRulesPSR().getSuccessfulDFAModifier(),
- Messages.getString(
- "MovementDisplay"
- + ".DFADialog"
- + ".dfaModifier"));
+ Messages.getString(
+ "MovementDisplay"
+ + ".DFADialog"
+ + ".dfaModifier"));
// Warn if this DFA would dishonor the player in the eyes of a Forced Withdrawal bot.
String dfaDishonorWarning = needNagForDishonor()
@@ -2921,18 +3208,20 @@ && hasLandingMoveStep()) {
}
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.DFADialog.title",
- target.getDisplayName()),
- Messages.getString("MovementDisplay.DFADialog.message",
- toHit.getValueAsString(),
- Compute.oddsAbove(toHit.getValue()),
- toHit.getDesc(),
- DfaAttackAction.getDamageFor(currentlySelectedEntity,
- target.isConventionalInfantry()),
- toHit.getTableDesc(),
- DfaAttackAction.getDamageTakenBy(currentlySelectedEntity),
- pilotRoll.getValueAsString(),
- Compute.oddsAbove(pilotRoll.getValue()),
- pilotRoll.getDesc()))) {
+ target.getDisplayName()),
+ Messages.getString("MovementDisplay.DFADialog.message",
+ toHit.getValueAsString(),
+ Compute.oddsAbove(toHit.getValue()),
+ toHit.getDesc(),
+ DfaAttackAction.getDamageFor(
+ currentlySelectedEntity,
+ target.isConventionalInfantry()),
+ toHit.getTableDesc(),
+ DfaAttackAction.getDamageTakenBy(
+ currentlySelectedEntity),
+ pilotRoll.getValueAsString(),
+ Compute.oddsAbove(pilotRoll.getValue()),
+ pilotRoll.getDesc()))) {
// if they answer yes, DFA the target
cmd.getLastStep().setTarget(target);
ready();
@@ -2947,48 +3236,50 @@ && hasLandingMoveStep()) {
if (toHit != null) {
// if not valid, tell why
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantDFA") + ": " + toHit.getDesc(), currentEntity());
+ Messages.getString("MovementDisplay.CantDFA") + ": " + toHit.getDesc(),
+ currentEntity());
}
clear();
return;
}
- updateDonePanel();
- updateProneButtons();
- updateChaffButton();
- updateRACButton();
- updateSearchlightButton();
- updateLoadButtons();
- updateElevationButtons();
- updateElevatorButtons();
- updateTakeOffButtons();
- updateLandButtons();
- updateEvadeButton();
- updateBootleggerButton();
- updateShutdownButton();
- updateStartupButton();
- updateSelfDestructButton();
- updateTraitorButton();
- updateFlyOffButton();
- updateLaunchButton();
- updateDropButton();
- updateConvertModeButton();
- updateRecklessButton();
- updateBraceButton();
- updateHoverButton();
- updateManeuverButton();
- updateSpeedButtons();
- updateThrustButton();
- updateRollButton();
- updateTurnButton();
- updateTakeCoverButton();
- updateLayMineButton();
- checkFuel();
- checkOOC();
- checkAtmosphere();
+ refreshButtons();
}
}
+ private void refreshButtons() {
+ updateProneButtons();
+ updateRACButton();
+ updateSearchlightButton();
+ updateElevationButtons();
+ updateElevatorButtons();
+ updateTakeOffButtons();
+ updateLandButtons();
+ updateFlyOffButton();
+ updateLaunchButton();
+ updateLoadButtons();
+ updateDropButton();
+ updateConvertModeButton();
+ updateRecklessButton();
+ updateHoverButton();
+ updateManeuverButton();
+ updateEvadeButton();
+ updateBootleggerButton();
+ updateShutdownButton();
+ updateStartupButton();
+ updateSelfDestructButton();
+ updateTraitorButton();
+ updateSpeedButtons();
+ updateThrustButton();
+ updateRollButton();
+ updateTakeCoverButton();
+ updateLayMineButton();
+ updateBraceButton();
+ checkFuel();
+ checkOOC();
+ checkAtmosphere();
+ }
+
private void updateTakeCoverButton() {
final GameOptions gOpts = game.getOptions();
boolean isInfantry = (currentEntity() instanceof Infantry);
@@ -3038,8 +3329,8 @@ private synchronized void updateProneButtons() {
} else if (cmd.getFinalHullDown()) {
if (isMek) {
setGetUpEnabled(!currentEntity.isImmobile()
- && !currentEntity.isStuck()
- && !((Mek) currentEntity).cannotStandUpFromHullDown());
+ && !currentEntity.isStuck()
+ && !((Mek) currentEntity).cannotStandUpFromHullDown());
} else {
setGetUpEnabled(!currentEntity.isImmobile() && !currentEntity.isStuck());
}
@@ -3048,22 +3339,22 @@ private synchronized void updateProneButtons() {
} else {
setGetUpEnabled(false);
setGoProneEnabled(!currentEntity.isImmobile() &&
- isMek &&
- !currentEntity.isStuck() &&
- !(getBtn(MoveCommand.MOVE_GET_UP).isEnabled()));
+ isMek &&
+ !currentEntity.isStuck() &&
+ !(getBtn(MoveCommand.MOVE_GET_UP).isEnabled()));
if (!(currentEntity instanceof Tank) &&
- !(currentEntity instanceof QuadVee
- && currentEntity.getConversionMode() == QuadVee.CONV_MODE_VEHICLE)) {
+ !(currentEntity instanceof QuadVee
+ && currentEntity.getConversionMode() == QuadVee.CONV_MODE_VEHICLE)) {
setHullDownEnabled(currentEntity.canGoHullDown());
} else {
// So that the vehicle can move and go hull-down, we have to check if it's moved into a fortified
// position
if (cmd.getLastStep() != null) {
boolean hullDownEnabled = game
- .getOptions()
- .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_HULL_DOWN);
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_HULL_DOWN);
Hex occupiedHex = game.getBoard(currentEntity)
- .getHex(cmd.getLastStep().getPosition());
+ .getHex(cmd.getLastStep().getPosition());
boolean fortifiedHex = occupiedHex.containsTerrain(Terrains.FORTIFIED);
// Large Vehicles cannot use infantry-built (fortified) hexes for cover (TO:AR p.19).
boolean isLargeVehicle = (currentEntity instanceof Tank tank) && tank.isLargeVehicleForHullDown();
@@ -3079,8 +3370,8 @@ private synchronized void updateProneButtons() {
// Two-state Hull Down button: "Go Hull Down" when the unit can enter hull-down, "Hull Down" (current
// state) once it already is, so the player can tell at a glance whether the unit is in cover.
getBtn(MoveCommand.MOVE_HULL_DOWN).setText(Messages.getString(cmd.getFinalHullDown()
- ? "MovementDisplay.moveHullDownActive"
- : "MovementDisplay.moveHullDownGo"));
+ ? "MovementDisplay.moveHullDownActive"
+ : "MovementDisplay.moveHullDownGo"));
}
private void updateRACButton() {
@@ -3091,16 +3382,16 @@ private void updateRACButton() {
isUnJammingRAC = false;
GameOptions opts = game.getOptions();
setUnjamEnabled(currentEntity.canUnjamRAC() &&
- ((gear == MovementDisplay.GEAR_LAND) ||
- (gear == MovementDisplay.GEAR_TURN) ||
- (gear == MovementDisplay.GEAR_BACKUP)) &&
- ((cmd.getMpUsed() <= currentEntity.getWalkMP()) ||
- (cmd.getLastStep().isOnlyPavementOrRoad() &&
+ ((gear == MovementDisplay.GEAR_LAND) ||
+ (gear == MovementDisplay.GEAR_TURN) ||
+ (gear == MovementDisplay.GEAR_BACKUP)) &&
+ ((cmd.getMpUsed() <= currentEntity.getWalkMP()) ||
+ (cmd.getLastStep().isOnlyPavementOrRoad() &&
(cmd.getMpUsed() <= (currentEntity.getWalkMP() + 1)))) &&
- !(opts.booleanOption(OptionsConstants.ADVANCED_TAC_OPS_TANK_CREWS) &&
- (cmd.getMpUsed() > 0) &&
- (currentEntity instanceof Tank) &&
- (currentEntity.getCrew().getSize() < 2)));
+ !(opts.booleanOption(OptionsConstants.ADVANCED_TAC_OPS_TANK_CREWS) &&
+ (cmd.getMpUsed() > 0) &&
+ (currentEntity instanceof Tank) &&
+ (currentEntity.getCrew().getSize() < 2)));
}
private void updateSearchlightButton() {
@@ -3109,11 +3400,11 @@ private void updateSearchlightButton() {
return;
}
boolean isNight = game
- .getPlanetaryConditions()
- .getLight()
- .isDuskOrFullMoonOrMoonlessOrPitchBack();
+ .getPlanetaryConditions()
+ .getLight()
+ .isDuskOrFullMoonOrMoonlessOrPitchBack();
setSearchlightEnabled(isNight && currentEntity.hasSearchlight() && !cmd.contains(MoveStepType.SEARCHLIGHT),
- currentEntity.isUsingSearchlight());
+ currentEntity.isUsingSearchlight());
}
private synchronized void updateElevationButtons() {
@@ -3126,20 +3417,20 @@ private synchronized void updateElevationButtons() {
// then use altitude not elevation
setRaiseEnabled(currentEntity.canGoUp(cmd.getFinalAltitude(), cmd.getFinalCoords(), cmd.getFinalBoardId()));
setLowerEnabled(currentEntity.canGoDown(cmd.getFinalAltitude(),
- cmd.getFinalCoords(),
- cmd.getFinalBoardId()));
+ cmd.getFinalCoords(),
+ cmd.getFinalBoardId()));
return;
}
// WiGEs (and LAMs and glider ProtoMeks) cannot go up if they've used ground movement.
if (currentEntity.getMovementMode().isWiGE() &&
- !currentEntity.isAirborneVTOLorWIGE() &&
- (cmd.getMpUsed() > 0) &&
- !cmd.contains(MoveStepType.UP)) {
+ !currentEntity.isAirborneVTOLorWIGE() &&
+ (cmd.getMpUsed() > 0) &&
+ !cmd.contains(MoveStepType.UP)) {
setRaiseEnabled(false);
} else {
setRaiseEnabled(currentEntity.canGoUp(cmd.getFinalElevation(),
- cmd.getFinalCoords(),
- cmd.getFinalBoardId()));
+ cmd.getFinalCoords(),
+ cmd.getFinalBoardId()));
}
setLowerEnabled(currentEntity.canGoDown(cmd.getFinalElevation(), cmd.getFinalCoords(), cmd.getFinalBoardId()));
}
@@ -3184,16 +3475,17 @@ private synchronized void updateElevatorButtons() {
IndustrialElevator elevator = game.getIndustrialElevator(BoardLocation.of(finalPos, finalBoardId));
if (elevator == null) {
LOGGER.debug("[IndustrialElevator] Buttons disabled for {}: elevator terrain at {} but no elevator "
- + "registered with the game", currentEntity.getShortName(), finalPos);
+ + "registered with the game", currentEntity.getShortName(), finalPos);
setElevatorUpEnabled(false);
setElevatorDownEnabled(false);
return;
}
if (!elevator.isFunctional()) {
LOGGER.debug("[IndustrialElevator] Buttons disabled for {}: elevator at {} is disabled",
- currentEntity.getShortName(), finalPos);
+ currentEntity.getShortName(), finalPos);
showElevatorStateToast(currentEntity, finalPos, "disabled", ToastLevel.WARNING,
- Messages.getString("MovementDisplay.ElevatorToast.disabled", currentEntity.getShortName()));
+ Messages.getString("MovementDisplay.ElevatorToast.disabled",
+ currentEntity.getShortName()));
setElevatorUpEnabled(false);
setElevatorDownEnabled(false);
return;
@@ -3201,20 +3493,22 @@ private synchronized void updateElevatorButtons() {
int currentLoad = (int) elevator.getCurrentLoad(game);
if (currentLoad > elevator.getCapacityTons()) {
LOGGER.debug("[IndustrialElevator] Buttons disabled for {}: elevator at {} overloaded ({}t / {}t)",
- currentEntity.getShortName(), finalPos, currentLoad, elevator.getCapacityTons());
+ currentEntity.getShortName(), finalPos, currentLoad, elevator.getCapacityTons());
showElevatorStateToast(currentEntity, finalPos, "overloaded", ToastLevel.WARNING,
- Messages.getString("MovementDisplay.ElevatorToast.overloaded",
- currentEntity.getShortName(), currentLoad, elevator.getCapacityTons()));
+ Messages.getString("MovementDisplay.ElevatorToast.overloaded",
+ currentEntity.getShortName(),
+ currentLoad,
+ elevator.getCapacityTons()));
setElevatorUpEnabled(false);
setElevatorDownEnabled(false);
return;
}
if (!elevator.isPlatformAt(finalElevation)) {
LOGGER.debug("[IndustrialElevator] Buttons disabled for {}: platform at level {}, unit at level {}",
- currentEntity.getShortName(), elevator.getPlatformLevel(), finalElevation);
+ currentEntity.getShortName(), elevator.getPlatformLevel(), finalElevation);
showElevatorStateToast(currentEntity, finalPos, "platform" + elevator.getPlatformLevel(), ToastLevel.INFO,
- Messages.getString("MovementDisplay.ElevatorToast.platformElsewhere",
- currentEntity.getShortName(), elevator.getPlatformLevel()));
+ Messages.getString("MovementDisplay.ElevatorToast.platformElsewhere",
+ currentEntity.getShortName(), elevator.getPlatformLevel()));
setElevatorUpEnabled(false);
setElevatorDownEnabled(false);
return;
@@ -3235,7 +3529,11 @@ private synchronized void updateElevatorButtons() {
* @param level the toast level
* @param message the ready-to-display toast text
*/
- private void showElevatorStateToast(Entity entity, Coords hexPos, String state, ToastLevel level, String message) {
+ private void showElevatorStateToast(Entity entity,
+ Coords hexPos,
+ String state,
+ ToastLevel level,
+ String message) {
String toastKey = entity.getId() + "|" + hexPos + "|" + state;
if (toastKey.equals(lastElevatorToastKey)) {
return;
@@ -3254,10 +3552,10 @@ private synchronized void updateTakeOffButtons() {
final Entity currentEntity = currentEntity();
if ((currentEntity instanceof IAero aero)
- && currentEntity.isAero()
- && !currentEntity.isAirborne()
- && !currentEntity.isShutDown()
- && (usingAeroOnGroundMovement() || hasAtmosphericMapForLiftOff(game, currentEntity))) {
+ && currentEntity.isAero()
+ && !currentEntity.isAirborne()
+ && !currentEntity.isShutDown()
+ && (usingAeroOnGroundMovement() || hasAtmosphericMapForLiftOff(game, currentEntity))) {
setTakeOffEnabled(aero.canTakeOffHorizontally());
setVTakeOffEnabled(aero.canTakeOffVertically());
} else {
@@ -3272,12 +3570,13 @@ private boolean usingAeroOnGroundMovement() {
/**
* @return True when there is a position on an existing atmospheric map that corresponds to the entity's current
- * ground map. TW p.88
+ * ground map. TW p.88
*/
- public static boolean hasAtmosphericMapForLiftOff(IGame game, Entity entity) {
+ public static boolean hasAtmosphericMapForLiftOff(IGame game,
+ Entity entity) {
Board groundBoard = game.getBoard(entity);
return (groundBoard != null) && (game.getEnclosingBoard(groundBoard) != null)
- && game.getEnclosingBoard(groundBoard).isLowAltitude();
+ && game.getEnclosingBoard(groundBoard).isLowAltitude();
}
private synchronized void updateLandButtons() {
@@ -3300,10 +3599,10 @@ private synchronized void updateLandButtons() {
// Without aero on ground movement, allow landing when over a ground map hex on an atmospheric map
if (!usingAeroOnGroundMovement()
- && (!game.hasBoardLocationOf(selectedEntity)
- || !selectedEntity.isAirborne()
- || !game.isOnAtmosphericMap(selectedEntity)
- || !game.getBoard(selectedEntity).getEmbeddedBoardHexes().contains(finalPosition()))) {
+ && (!game.hasBoardLocationOf(selectedEntity)
+ || !selectedEntity.isAirborne()
+ || !game.isOnAtmosphericMap(selectedEntity)
+ || !game.getBoard(selectedEntity).getEmbeddedBoardHexes().contains(finalPosition()))) {
return;
}
@@ -3353,9 +3652,9 @@ private void updateHoverButton() {
return;
}
} else if (!(currentEntity instanceof ProtoMek) &&
- !(currentEntity instanceof LandAirMek && (currentEntity.getConversionMode()
- == LandAirMek.CONV_MODE_AIR_MEK)) &&
- (currentEntity.getAltitude() <= 3)) {
+ !(currentEntity instanceof LandAirMek && (currentEntity.getConversionMode()
+ == LandAirMek.CONV_MODE_AIR_MEK)) &&
+ (currentEntity.getAltitude() <= 3)) {
return;
}
@@ -3388,10 +3687,20 @@ private synchronized void updateSpeedButtons() {
return;
}
+ if (!currentEntity.isDeployed()) {
+ return;
+ }
if (!currentEntity.isAero()) {
return;
}
+ // Large craft only use aero speed controls when not landed on the ground map.
+ if (currentEntity.isDropShip() && currentEntity.isAeroLandedOnGroundMap()) {
+ setAccEnabled(false);
+ setDecEnabled(false);
+ return;
+ }
+
IAero a = (IAero) currentEntity;
// only allow acceleration and deceleration if the cmd is empty or the
@@ -3409,7 +3718,7 @@ private synchronized void updateSpeedButtons() {
nextVelocity = last.getVelocityN();
}
- if (null == last) {
+ if (null == last || pathZeroOrDeploy()) {
setAccEnabled(true);
if (currentVelocity > 0) {
setDecEnabled(true);
@@ -3436,14 +3745,14 @@ private synchronized void updateSpeedButtons() {
setAccNEnabled(false);
setDecNEnabled(false);
if (Stream.of(MoveStepType.ACC, MoveStepType.DEC, MoveStepType.DECELERATION)
- .noneMatch(moveStepType -> cmd.contains(moveStepType))) {
+ .noneMatch(moveStepType -> cmd.contains(moveStepType))) {
setAccNEnabled(true);
}
if (!cmd.contains(MoveStepType.ACC) &&
- !cmd.contains(MoveStepType.DEC) &&
- !cmd.contains(MoveStepType.ACCELERATION) &&
- (nextVelocity > 0)) {
+ !cmd.contains(MoveStepType.DEC) &&
+ !cmd.contains(MoveStepType.ACCELERATION) &&
+ (nextVelocity > 0)) {
setDecNEnabled(true);
}
@@ -3456,8 +3765,8 @@ private synchronized void updateSpeedButtons() {
// Disable accelerate/decelerate if a jumpship has changed facing
if ((a instanceof Jumpship) &&
- ((Jumpship) a).hasStationKeepingDrive() &&
- (cmd.contains(MoveStepType.TURN_LEFT) || cmd.contains(MoveStepType.TURN_RIGHT))) {
+ ((Jumpship) a).hasStationKeepingDrive() &&
+ (cmd.contains(MoveStepType.TURN_LEFT) || cmd.contains(MoveStepType.TURN_RIGHT))) {
setDecNEnabled(false);
setAccNEnabled(false);
}
@@ -3506,8 +3815,8 @@ private void updateFlyOffButton() {
// Check if at altitude 10 - can climb out of atmosphere (requires both return flyover and climb out options)
boolean canClimbOut = altitude == 10 && board.isGround()
- && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER)
- && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_CLIMB_OUT);
+ && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER)
+ && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_CLIMB_OUT);
// Check if can fly off edge (calculate before using)
boolean canFlyOffEdge = false;
@@ -3515,27 +3824,27 @@ private void updateFlyOffButton() {
// for spheroids in atmosphere we just need to check being on the edge
if (a.isSpheroid() && !board.isSpace()) {
canFlyOffEdge = (position != null) &&
- (currentEntity.getWalkMP() > 0) &&
- ((position.getX() == 0) ||
- (position.getX() == (board.getWidth() - 1)) ||
- (position.getY() == 0) ||
- (position.getY() == (board.getHeight() - 1)));
+ (currentEntity.getWalkMP() > 0) &&
+ ((position.getX() == 0) ||
+ (position.getX() == (board.getWidth() - 1)) ||
+ (position.getY() == 0) ||
+ (position.getY() == (board.getHeight() - 1)));
} else if (position != null) {
// for all aerodynes and spheroids in space, it is more complicated - the nose of the aircraft must be facing
// in the right direction, and there must be velocity remaining
boolean evenX = (position.getX() % 2) == 0;
canFlyOffEdge = (velocityLeft > 0) &&
- (((position.getX() == 0) && ((facing == 5) || (facing == 4))) ||
- ((position.getX() == (board.getWidth() - 1)) &&
+ (((position.getX() == 0) && ((facing == 5) || (facing == 4))) ||
+ ((position.getX() == (board.getWidth() - 1)) &&
((facing == 1) || (facing == 2))) ||
- ((position.getY() == 0) &&
+ ((position.getY() == 0) &&
((facing == 1) || (facing == 5) || (facing == 0)) &&
evenX) ||
- ((position.getY() == 0) && (facing == 0)) ||
- ((position.getY() == (board.getHeight() - 1)) &&
+ ((position.getY() == 0) && (facing == 0)) ||
+ ((position.getY() == (board.getHeight() - 1)) &&
((facing == 2) || (facing == 3) || (facing == 4)) &&
!evenX) ||
- ((position.getY() == (board.getHeight() - 1)) && (facing == 3)));
+ ((position.getY() == (board.getHeight() - 1)) && (facing == 3)));
}
// Determine button state and label
@@ -3561,17 +3870,17 @@ private void updateLaunchButton() {
}
setLaunchEnabled(!currentEntity.getLaunchableFighters().isEmpty() ||
- !currentEntity.getLaunchableSmallCraft().isEmpty() ||
- !currentEntity.getLaunchableDropships().isEmpty());
+ !currentEntity.getLaunchableSmallCraft().isEmpty() ||
+ !currentEntity.getLaunchableDropships().isEmpty());
}
/**
* @param bay Instance
* @param droppedUnits Set of unit ids of entities already dropped this turn.
- *
* @return true if there are available droppable units in this bay
*/
- private boolean checkBayDropEnable(Bay bay, Set droppedUnits) {
+ private boolean checkBayDropEnable(Bay bay,
+ Set droppedUnits) {
// If this bay has unloaded more units this turn than
// it has doors* for, we should move on
// *(excluding Infantry, see StratOps pg. 20)
@@ -3615,10 +3924,10 @@ private boolean checkBayDropEnable(Bay bay, Set droppedUnits) {
/**
* @param compartment Instance
* @param droppedUnits Set of unit ids of entities already dropped this turn.
- *
* @return true if there are available droppable units in this compartment
*/
- private boolean checkCompartmentDropEnable(InfantryCompartment compartment, Set droppedUnits) {
+ private boolean checkCompartmentDropEnable(InfantryCompartment compartment,
+ Set droppedUnits) {
List droppableUnits = compartment.getDroppableUnits();
return droppableUnits.stream().map(Entity::getId).anyMatch(u -> !droppedUnits.contains(u));
}
@@ -3666,7 +3975,7 @@ private void updateEvadeButton() {
}
setEvadeEnabled((cmd.getLastStepMovementType() != EntityMovementType.MOVE_JUMP) &&
- (cmd.getLastStepMovementType() != EntityMovementType.MOVE_SPRINT));
+ (cmd.getLastStepMovementType() != EntityMovementType.MOVE_SPRINT));
}
private void updateBootleggerButton() {
@@ -3677,8 +3986,8 @@ private void updateBootleggerButton() {
}
if (!game
- .getOptions()
- .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_VEHICLE_ADVANCED_MANEUVERS)) {
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_VEHICLE_ADVANCED_MANEUVERS)) {
return;
}
@@ -3687,8 +3996,8 @@ private void updateBootleggerButton() {
}
if (currentEntity.getMovementMode() != EntityMovementMode.WHEELED &&
- currentEntity.getMovementMode() != EntityMovementMode.HOVER &&
- currentEntity.getMovementMode() != EntityMovementMode.VTOL) {
+ currentEntity.getMovementMode() != EntityMovementMode.HOVER &&
+ currentEntity.getMovementMode() != EntityMovementMode.VTOL) {
return;
}
@@ -3731,8 +4040,8 @@ private void updateSelfDestructButton() {
}
if (!game
- .getOptions()
- .booleanOption(OptionsConstants.ADVANCED_TAC_OPS_SELF_DESTRUCT)) {
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_TAC_OPS_SELF_DESTRUCT)) {
return;
}
@@ -3741,9 +4050,9 @@ private void updateSelfDestructButton() {
}
setSelfDestructEnabled(currentEntity.hasEngine() &&
- currentEntity.getEngine().isFusion() &&
- !currentEntity.getSelfDestructing() &&
- !currentEntity.getSelfDestructInitiated());
+ currentEntity.getEngine().isFusion() &&
+ !currentEntity.getSelfDestructing() &&
+ !currentEntity.getSelfDestructInitiated());
}
private void updateTraitorButton() {
@@ -3777,7 +4086,7 @@ private void updateConvertModeButton() {
boolean canConvert = false;
for (int i = 0; i < 3; i++) {
if (i != currentEntity.getConversionMode()
- && ((LandAirMek) currentEntity).canConvertTo(currentEntity.getConversionMode(), i)) {
+ && ((LandAirMek) currentEntity).canConvertTo(currentEntity.getConversionMode(), i)) {
canConvert = true;
}
}
@@ -3786,7 +4095,7 @@ private void updateConvertModeButton() {
return;
}
} else if (!((currentEntity instanceof QuadVee) || ((currentEntity instanceof Mek)
- && ((Mek) currentEntity).hasTracks()))) {
+ && ((Mek) currentEntity).hasTracks()))) {
setModeConvertEnabled(false);
return;
}
@@ -3803,7 +4112,7 @@ private void updateConvertModeButton() {
}
if ((currentEntity instanceof QuadVee) && (((QuadVee) currentEntity).conversionCost()
- > currentEntity.getRunMP())) {
+ > currentEntity.getRunMP())) {
setModeConvertEnabled(false);
return;
}
@@ -3825,7 +4134,7 @@ private void updateRecklessButton() {
if (currentEntity instanceof ProtoMek) {
setRecklessEnabled(false);
} else {
- setRecklessEnabled((null == cmd) || (cmd.length() == 0));
+ setRecklessEnabled((null == cmd) || (pathZeroOrDeploy()));
}
}
@@ -3840,8 +4149,8 @@ private void updateBraceButton() {
}
setBraceEnabled(!movePath.contains(MoveStepType.BRACE) &&
- movePath.isValidPositionForBrace(movePath.getFinalCoords(), finalBoardId(),
- movePath.getFinalFacing()));
+ movePath.isValidPositionForBrace(movePath.getFinalCoords(), finalBoardId(),
+ movePath.getFinalFacing()));
}
private void updateClimbButton() {
@@ -3858,11 +4167,13 @@ private void updateClimbButton() {
* @param edgeTarget the lower hex the player clicked (adjacent to entity start)
* @param isRoutedAround true if {@link #cmd} contains 2+ FORWARDS steps from a planner detour
*/
- private void rebuildPathForEdgeDescent(Mek edgeMek, Coords edgeTarget, boolean isRoutedAround) {
+ private void rebuildPathForEdgeDescent(Mek edgeMek,
+ Coords edgeTarget,
+ boolean isRoutedAround) {
if (isRoutedAround) {
cmd = new MovePath(game, edgeMek);
cmd.rotatePathfinder(edgeMek.getPosition().direction(edgeTarget), false,
- ManeuverType.MAN_NONE);
+ ManeuverType.MAN_NONE);
cmd.addStep(MoveStepType.CLIMB_MODE_ON);
cmd.addStep(MoveStepType.FORWARDS);
} else {
@@ -3907,7 +4218,7 @@ private ClimbingChoiceDialog.ClimbingOption showContinueClimbingDialog(Mek mek)
* which can be wrong if the path walked or turned before reaching the cliff.
*/
private ClimbingChoiceDialog.ClimbingOption showStartClimbingDialog(Mek mek,
- @Nullable MoveStep climbingStep) {
+ @Nullable MoveStep climbingStep) {
return showClimbingLevelDialog(mek, false, climbingStep);
}
@@ -3919,15 +4230,15 @@ private ClimbingChoiceDialog.ClimbingOption showStartClimbingDialog(Mek mek,
* @param climbingStep for a fresh climb, the path's climbing step (used to derive source/target hexes when the
* path walks or turns before climbing); may be null to fall back to entity-derived
* position/facing (the continuation case)
- *
* @return the chosen option, or null if cancelled / no levels remain
*/
- private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boolean isContinuation,
- @megamek.common.annotations.Nullable MoveStep climbingStep) {
+ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek,
+ boolean isContinuation,
+ @megamek.common.annotations.Nullable MoveStep climbingStep) {
LOGGER.debug("[CLIMB-TRACE] showClimbingLevelDialog: entity={}, isContinuation={}, " +
- "position={}, elevation={}, facing={}, climbingStep={}",
- mek.getDisplayName(), isContinuation, mek.getPosition(), mek.getElevation(), mek.getFacing(),
- (climbingStep != null) ? climbingStep.getPosition() : "null");
+ "position={}, elevation={}, facing={}, climbingStep={}",
+ mek.getDisplayName(), isContinuation, mek.getPosition(), mek.getElevation(), mek.getFacing(),
+ (climbingStep != null) ? climbingStep.getPosition() : "null");
int costPerLevel = ClimbingHelper.getClimbingMPCostPerLevel(mek);
int walkMP = mek.getWalkMP();
int currentElevation = mek.getElevation();
@@ -3966,9 +4277,9 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
int totalLevelsRemaining = targetLevel - currentAbsolute;
LOGGER.debug("[CLIMB-TRACE] showClimbingLevelDialog: sourceCoords={}, sourceElevation={}, "
- + "targetLevel={}, currentAbsolute={}, totalLevelsRemaining={}, targetHex={}, isBuilding={}",
- sourceCoords, sourceElevation, targetLevel, currentAbsolute, totalLevelsRemaining,
- targetCoords, targetHex.containsTerrain(Terrains.BUILDING));
+ + "targetLevel={}, currentAbsolute={}, totalLevelsRemaining={}, targetHex={}, isBuilding={}",
+ sourceCoords, sourceElevation, targetLevel, currentAbsolute, totalLevelsRemaining,
+ targetCoords, targetHex.containsTerrain(Terrains.BUILDING));
if (totalLevelsRemaining <= 0) {
LOGGER.debug("[CLIMB-TRACE] showClimbingLevelDialog: no levels remaining, returning null");
@@ -3999,12 +4310,12 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
// player knows the click on the cliff hex had no effect (otherwise it looks
// like the path silently truncates).
LOGGER.debug("[CLIMB-TRACE] showClimbingLevelDialog: no MP left for climbing "
- + "(walkMP={}, mpAlreadyUsed={}), returning null",
- walkMP, mpAlreadyUsed);
+ + "(walkMP={}, mpAlreadyUsed={}), returning null",
+ walkMP, mpAlreadyUsed);
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.ClimbingDialog.noMpToast",
- mek.getDisplayName(), mpAlreadyUsed, walkMP, costPerLevel),
- mek);
+ Messages.getString("MovementDisplay.ClimbingDialog.noMpToast",
+ mek.getDisplayName(), mpAlreadyUsed, walkMP, costPerLevel),
+ mek);
return null;
}
@@ -4013,25 +4324,25 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
String headerMessage;
if (isContinuation) {
messageKey = isBuilding
- ? "MovementDisplay.ClimbingDialog.continueBuilding"
- : "MovementDisplay.ClimbingDialog.continueCliff";
+ ? "MovementDisplay.ClimbingDialog.continueBuilding"
+ : "MovementDisplay.ClimbingDialog.continueCliff";
headerMessage = Messages.getString(messageKey,
- mek.getDisplayName(), currentElevation, totalLevelsRemaining,
- costPerLevel, availableMP);
+ mek.getDisplayName(), currentElevation, totalLevelsRemaining,
+ costPerLevel, availableMP);
} else {
messageKey = isBuilding
- ? "MovementDisplay.ClimbingDialog.startBuilding"
- : "MovementDisplay.ClimbingDialog.startCliff";
+ ? "MovementDisplay.ClimbingDialog.startBuilding"
+ : "MovementDisplay.ClimbingDialog.startCliff";
headerMessage = Messages.getString(messageKey,
- mek.getDisplayName(), totalLevelsRemaining,
- costPerLevel, availableMP);
+ mek.getDisplayName(), totalLevelsRemaining,
+ costPerLevel, availableMP);
}
// Calculate PSR info for climbing
int basePiloting = mek.getCrew().getPiloting();
int climbableArms = ClimbingHelper.countClimbableArms(mek);
int climbPsrMod = ClimbingHelper.CLIMBING_PSR_MODIFIER
- + ((climbableArms == 1) ? ClimbingHelper.ONE_ARM_PSR_MODIFIER : 0);
+ + ((climbableArms == 1) ? ClimbingHelper.ONE_ARM_PSR_MODIFIER : 0);
int climbPsrTarget = basePiloting + climbPsrMod;
// Build climbing options
@@ -4039,11 +4350,11 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
for (int i = 1; i <= maxLevels; i++) {
int cost = i * costPerLevel;
String baseLabel = (i == 1)
- ? Messages.getString("MovementDisplay.ClimbingDialog.levelOption", i, cost)
- : Messages.getString("MovementDisplay.ClimbingDialog.levelsOption", i, cost);
+ ? Messages.getString("MovementDisplay.ClimbingDialog.levelOption", i, cost)
+ : Messages.getString("MovementDisplay.ClimbingDialog.levelsOption", i, cost);
String label = baseLabel + " - PSR " + climbPsrTarget + "+ per level";
climbingOptions.add(new ClimbingChoiceDialog.ClimbingOption(i, cost, label,
- ClimbingChoiceDialog.ClimbingActionType.CLIMB_UP));
+ ClimbingChoiceDialog.ClimbingActionType.CLIMB_UP));
}
// Climb Down: controlled descent at the same MP cost and PSRs as climbing up
// (TO:AR p.20). Available whenever there's anywhere to descend — including the
@@ -4056,11 +4367,11 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
for (int i = 1; i <= maxDescend; i++) {
int cost = i * costPerLevel;
String baseLabel = (i == 1)
- ? Messages.getString("MovementDisplay.ClimbingDialog.descendOption", i, cost)
- : Messages.getString("MovementDisplay.ClimbingDialog.descendOptions", i, cost);
+ ? Messages.getString("MovementDisplay.ClimbingDialog.descendOption", i, cost)
+ : Messages.getString("MovementDisplay.ClimbingDialog.descendOptions", i, cost);
String label = baseLabel + " - PSR " + climbPsrTarget + "+ per level";
climbingOptions.add(new ClimbingChoiceDialog.ClimbingOption(i, cost, label,
- ClimbingChoiceDialog.ClimbingActionType.CLIMB_DOWN));
+ ClimbingChoiceDialog.ClimbingActionType.CLIMB_DOWN));
}
}
// Dangle-and-Drop: available mid-climb or mid-dangle with 2 functional arms
@@ -4069,9 +4380,10 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
if (isContinuation && (descendableLevels > 0) && ClimbingHelper.canDangle(mek)) {
int dangleLevels = Math.min(ClimbingHelper.DANGLE_LEVELS_PER_TURN, descendableLevels);
climbingOptions.add(new ClimbingChoiceDialog.ClimbingOption(dangleLevels, 0,
- Messages.getString("MovementDisplay.ClimbingDialog.dangleOption",
- dangleLevels) + " - no PSR",
- ClimbingChoiceDialog.ClimbingActionType.DANGLE_DOWN));
+ Messages.getString(
+ "MovementDisplay.ClimbingDialog.dangleOption",
+ dangleLevels) + " - no PSR",
+ ClimbingChoiceDialog.ClimbingActionType.DANGLE_DOWN));
}
// Drop option: available from any climbing or dangling position (TO:AR p.20).
// From dangling: PSR modifiers reduced by 2. From climbing: standard leaping modifiers.
@@ -4091,23 +4403,24 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
int legTarget = basePiloting + (2 * effectiveDrop);
int fallTarget = basePiloting + effectiveDrop;
String dropLabel = Messages.getString("MovementDisplay.ClimbingDialog.dropOption",
- ClimbingHelper.DROP_MP_COST)
- + ((effectiveDrop > 0)
- ? " - Leg PSR " + legTarget + "+, Fall PSR " + fallTarget + "+"
- : " - sink to floor (no PSR)");
+ ClimbingHelper.DROP_MP_COST)
+ + ((effectiveDrop > 0)
+ ? " - Leg PSR " + legTarget + "+, Fall PSR " + fallTarget + "+"
+ : " - sink to floor (no PSR)");
climbingOptions.add(new ClimbingChoiceDialog.ClimbingOption(totalDropDistance,
- ClimbingHelper.DROP_MP_COST, dropLabel,
- ClimbingChoiceDialog.ClimbingActionType.DROP));
+ ClimbingHelper.DROP_MP_COST, dropLabel,
+ ClimbingChoiceDialog.ClimbingActionType.DROP));
}
if (isContinuation) {
climbingOptions.add(new ClimbingChoiceDialog.ClimbingOption(0, 0,
- Messages.getString("MovementDisplay.ClimbingDialog.clingOption"),
- ClimbingChoiceDialog.ClimbingActionType.CLING));
+ Messages.getString(
+ "MovementDisplay.ClimbingDialog.clingOption"),
+ ClimbingChoiceDialog.ClimbingActionType.CLING));
}
// Show the dialog
ClimbingChoiceDialog dialog = new ClimbingChoiceDialog(
- clientgui.getFrame(), headerMessage, climbingOptions);
+ clientgui.getFrame(), headerMessage, climbingOptions);
dialog.setVisible(true);
ClimbingChoiceDialog.ClimbingOption chosen = dialog.getFirstChoice();
@@ -4121,10 +4434,10 @@ private ClimbingChoiceDialog.ClimbingOption showClimbingLevelDialog(Mek mek, boo
private void updateClimbModeButtonText() {
boolean climbModeOn = (cmd != null) ? cmd.getFinalClimbMode()
- : (currentEntity() != null && currentEntity().climbMode());
+ : (currentEntity() != null && currentEntity().climbMode());
String baseLabel = climbModeOn
- ? Messages.getString("MovementDisplay.moveClimbModeOn")
- : Messages.getString("MovementDisplay.moveClimbModeOff");
+ ? Messages.getString("MovementDisplay.moveClimbModeOn")
+ : Messages.getString("MovementDisplay.moveClimbModeOff");
ClimbModeContext context = computeClimbModeContext(climbModeOn);
String label;
if (context.fullLabel() != null) {
@@ -4150,8 +4463,10 @@ private void updateClimbModeButtonText() {
* @param tooltip HTML tooltip describing the toggle's current effect
*/
private record ClimbModeContext(@megamek.common.annotations.Nullable String suffix,
- @megamek.common.annotations.Nullable String fullLabel,
- String tooltip) {}
+ @megamek.common.annotations.Nullable String fullLabel,
+ String tooltip) {
+
+ }
/**
* Inspects the entity's current/pending position and facing to determine what the Climb Mode toggle currently
@@ -4178,9 +4493,9 @@ private ClimbModeContext computeClimbModeContext(boolean climbModeOn) {
// each mode does. Leaping matters for the at-edge case (no climb dialog, but leaping
// still gates the fall-vs-illegal behaviour).
boolean tacOpsClimbing = game.getOptions()
- .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_CLIMBING);
+ .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_CLIMBING);
boolean tacOpsLeaping = game.getOptions()
- .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_LEAPING);
+ .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_LEAPING);
Hex curHex = game.getBoard(entity).getHex(curPos);
Coords frontPos = curPos.translated(curFacing);
Hex frontHex = game.getBoard(entity).getHex(frontPos);
@@ -4189,16 +4504,16 @@ private ClimbModeContext computeClimbModeContext(boolean climbModeOn) {
boolean bridgeFront = (frontHex != null) && frontHex.containsTerrain(Terrains.BRIDGE);
if (bridgeHere || bridgeFront) {
String bridgeTipKey = tacOpsClimbing
- ? "MovementDisplay.climbModeTip.bridge"
- : "MovementDisplay.climbModeTip.bridge.standard";
+ ? "MovementDisplay.climbModeTip.bridge"
+ : "MovementDisplay.climbModeTip.bridge.standard";
// Bridge gets an action-style label override — "Move onto Bridge" / "Move under
// Bridge" reads more clearly than "Climbing Bridge" / "Move Thru Bridge" because
// it tells the player which physical level the current toggle puts them at.
String bridgeBtn = climbModeOn
- ? Messages.getString("MovementDisplay.climbModeBtn.bridgeOnto")
- : Messages.getString("MovementDisplay.climbModeBtn.bridgeUnder");
+ ? Messages.getString("MovementDisplay.climbModeBtn.bridgeOnto")
+ : Messages.getString("MovementDisplay.climbModeBtn.bridgeUnder");
return new ClimbModeContext(Messages.getString("MovementDisplay.climbModeCtx.bridge"),
- bridgeBtn, Messages.getString(bridgeTipKey));
+ bridgeBtn, Messages.getString(bridgeTipKey));
}
if (frontHex != null) {
int curAlt = ((curHex != null) ? curHex.getLevel() : 0) + curElevation;
@@ -4212,20 +4527,20 @@ private ClimbModeContext computeClimbModeContext(boolean climbModeOn) {
if (diff >= ClimbingHelper.MIN_CLIMBING_LEVELS) {
boolean isBuilding = frontHex.containsTerrain(Terrains.BUILDING);
String suffixKey = isBuilding
- ? "MovementDisplay.climbModeCtx.upBuilding"
- : "MovementDisplay.climbModeCtx.upCliff";
+ ? "MovementDisplay.climbModeCtx.upBuilding"
+ : "MovementDisplay.climbModeCtx.upCliff";
String tipKey;
if (tacOpsClimbing) {
tipKey = isBuilding
- ? "MovementDisplay.climbModeTip.upBuilding"
- : "MovementDisplay.climbModeTip.upCliff";
+ ? "MovementDisplay.climbModeTip.upBuilding"
+ : "MovementDisplay.climbModeTip.upCliff";
} else {
tipKey = isBuilding
- ? "MovementDisplay.climbModeTip.upBuilding.standard"
- : "MovementDisplay.climbModeTip.upCliff.standard";
+ ? "MovementDisplay.climbModeTip.upBuilding.standard"
+ : "MovementDisplay.climbModeTip.upCliff.standard";
}
return new ClimbModeContext(Messages.getString(suffixKey), null,
- Messages.getString(tipKey, diff));
+ Messages.getString(tipKey, diff));
}
// At edge of a 3+ level drop: with TacOps Climbing ON the descent dialog fires;
// with it OFF, behaviour depends on TacOps Leaping (leap-with-fall-PSRs vs illegal).
@@ -4239,14 +4554,14 @@ private ClimbModeContext computeClimbModeContext(boolean climbModeOn) {
tipKey = "MovementDisplay.climbModeTip.atEdge.standardIllegal";
}
return new ClimbModeContext(Messages.getString("MovementDisplay.climbModeCtx.atEdge"), null,
- Messages.getString(tipKey, -diff));
+ Messages.getString(tipKey, -diff));
}
// Building adjacent (small one): toggle controls roof vs walk-through. Works in
// both rule modes since the step is within normal max elevation change.
if (frontHex.containsTerrain(Terrains.BUILDING)
- || ((curHex != null) && curHex.containsTerrain(Terrains.BUILDING))) {
+ || ((curHex != null) && curHex.containsTerrain(Terrains.BUILDING))) {
return new ClimbModeContext(Messages.getString("MovementDisplay.climbModeCtx.building"), null,
- Messages.getString("MovementDisplay.climbModeTip.building"));
+ Messages.getString("MovementDisplay.climbModeTip.building"));
}
}
return new ClimbModeContext(null, null, Messages.getString("MovementDisplay.climbModeTip.none"));
@@ -4305,10 +4620,10 @@ private void updateBombButton() {
}
if (currentEntity().isBomber()
- && ((currentEntity() instanceof LandAirMek)
- || game.getOptions()
- .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_VTOL_ATTACKS))
- && ((IBomber) currentEntity()).getBombPoints() > 0) {
+ && ((currentEntity() instanceof LandAirMek)
+ || game.getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_COMBAT_TAC_OPS_VTOL_ATTACKS))
+ && ((IBomber) currentEntity()).getBombPoints() > 0) {
setBombEnabled(true);
}
}
@@ -4325,19 +4640,21 @@ private synchronized void updateLoadButtons() {
updateDropCargoButton();
}
- /** Updates the status of the "pickup cargo" button */
+ /**
+ * Updates the status of the "pickup cargo" button
+ */
private void updatePickupCargoButton() {
final Entity currentEntity = currentEntity();
// there has to be an entity, objects are on the ground,
// the entity can pick them up
if ((currentEntity == null) ||
- ((game.getGroundObjects(finalPosition(), currentEntity).isEmpty())
- && (game.getEntitiesVector(finalPosition())
- .stream()
- .filter(currentEntity::canPickupCarryableObject)
- .toList()
- .isEmpty())) ||
- ((cmd.getLastStep() != null) && (cmd.getLastStep().getType() == MoveStepType.PICKUP_CARGO))) {
+ ((game.getGroundObjects(finalPosition(), currentEntity).isEmpty())
+ && (game.getEntitiesVector(finalPosition())
+ .stream()
+ .filter(currentEntity::canPickupCarryableObject)
+ .toList()
+ .isEmpty())) ||
+ ((cmd.getLastStep() != null) && (cmd.getLastStep().getType() == MoveStepType.PICKUP_CARGO))) {
setPickupCargoEnabled(false);
return;
}
@@ -4345,17 +4662,19 @@ private void updatePickupCargoButton() {
setPickupCargoEnabled(true);
}
- /** Updates the status of the "drop cargo" button */
+ /**
+ * Updates the status of the "drop cargo" button
+ */
private void updateDropCargoButton() {
final Entity currentlySelectedEntity = currentEntity();
// there has to be an entity, objects are on the ground, the entity can pick them up
if ((currentlySelectedEntity == null)
- || (currentlySelectedEntity.getCarriedObjects().isEmpty()
- && currentlySelectedEntity.getTransports()
- .stream()
- .filter(t -> t instanceof ExternalCargo)
- .flatMap(t -> t.getCarryables().stream())
- .toList().isEmpty())) {
+ || (currentlySelectedEntity.getCarriedObjects().isEmpty()
+ && currentlySelectedEntity.getTransports()
+ .stream()
+ .filter(t -> t instanceof ExternalCargo)
+ .flatMap(t -> t.getCarryables().stream())
+ .toList().isEmpty())) {
setDropCargoEnabled(false);
return;
}
@@ -4363,12 +4682,18 @@ private void updateDropCargoButton() {
setDropCargoEnabled(true);
}
- /** Updates the status of the Load button. */
+ /**
+ * Updates the status of the Load button.
+ */
private void updateLoadButton() {
final Entity currentEntity = currentEntity();
+ if (!currentEntity.isDeployed()) {
+ setLoadEnabled(false);
+ return;
+ }
if ((currentEntity == null) || (currentEntity.getWalkMP() <= 0 && !currentEntity.isAerospace()) || (
- currentEntity.isAerospace()
- && currentEntity.isAirborne())) {
+ currentEntity.isAerospace()
+ && currentEntity.isAirborne())) {
setLoadEnabled(false);
return;
}
@@ -4380,17 +4705,23 @@ private void updateLoadButton() {
}
final boolean canLoad = candidates
- .stream()
- .filter(other -> !currentEntity.canTow(other.getId()))
- .filter(Entity::isLoadableThisTurn)
- .anyMatch(other -> currentEntity.canLoad(other, true, cmd.getFinalElevation()) &&
- other.getTargetBay() == UNSET_BAY);
+ .stream()
+ .filter(other -> !currentEntity.canTow(other.getId()))
+ .filter(Entity::isLoadableThisTurn)
+ .anyMatch(other -> currentEntity.canLoad(other, true, cmd.getFinalElevation()) &&
+ other.getTargetBay() == UNSET_BAY);
setLoadEnabled(canLoad);
}
- /** Updates the status of the Unload button. */
+ /**
+ * Updates the status of the Unload button.
+ */
private void updateUnloadButton() {
final Entity currentEntity = currentEntity();
+ if (!currentEntity.isDeployed()) {
+ setUnloadEnabled(false);
+ return;
+ }
if (currentEntity == null) {
setUnloadEnabled(false);
return;
@@ -4402,9 +4733,9 @@ private void updateUnloadButton() {
}
final boolean legalGear = ((gear == GEAR_LAND) ||
- (gear == GEAR_TURN) ||
- (gear == GEAR_BACKUP) ||
- (gear == GEAR_JUMP));
+ (gear == GEAR_TURN) ||
+ (gear == GEAR_BACKUP) ||
+ (gear == GEAR_JUMP));
final int unloadEl = cmd.getFinalElevation();
final Hex hex = game.getBoard(currentEntity).getHex(cmd.getFinalCoords());
boolean canUnloadHere = false;
@@ -4412,19 +4743,19 @@ private void updateUnloadButton() {
// A unit that has somehow exited the map is assumed to be unable to unload
if (isFinalPositionOnBoard()) {
canUnloadHere = unloadableUnits.stream()
- .anyMatch(en -> en.isElevationValid(unloadEl, hex) || (en.getJumpMP() > 0));
+ .anyMatch(en -> en.isElevationValid(unloadEl, hex) || (en.getJumpMP() > 0));
// Zip lines, TO pg 219
if (game.getOptions().booleanOption(ADVANCED_GROUND_MOVEMENT_TAC_OPS_ZIPLINES)
- && (currentEntity instanceof VTOL)) {
+ && (currentEntity instanceof VTOL)) {
canUnloadHere |= unloadableUnits.stream()
- .filter(Entity::isInfantry)
- .anyMatch(en -> !((Infantry) en).isMechanized());
+ .filter(Entity::isInfantry)
+ .anyMatch(en -> !((Infantry) en).isMechanized());
}
// Glider wings allow infantry to exit VTOLs as if jump infantry (IO p.85)
if (currentEntity instanceof VTOL) {
canUnloadHere |= unloadableUnits.stream()
- .filter(Entity::isInfantry)
- .anyMatch(en -> ((Infantry) en).canExitVTOLWithGliderWings());
+ .filter(Entity::isInfantry)
+ .anyMatch(en -> ((Infantry) en).canExitVTOLWithGliderWings());
}
}
setUnloadEnabled(legalGear && canUnloadHere && !unloadableUnits.isEmpty());
@@ -4445,15 +4776,17 @@ private void updateMountButton() {
mpUsed = cmd.getMpUsed();
}
final boolean canMount = isFinalPositionOnBoard() &&
- !movingEntity.isAirborne() &&
- (mpUsed <= Math.ceil(movingEntity.getWalkMP() / 2.0)) &&
- !Compute.getMountableUnits(movingEntity, pos, finalBoardId(),
- elev + game.getBoard(movingEntity).getHex(pos).getLevel(),
- game).isEmpty();
+ !movingEntity.isAirborne() &&
+ (mpUsed <= Math.ceil(movingEntity.getWalkMP() / 2.0)) &&
+ !Compute.getMountableUnits(movingEntity, pos, finalBoardId(),
+ elev + game.getBoard(movingEntity).getHex(pos).getLevel(),
+ game).isEmpty();
setMountEnabled(canMount);
}
- /** Updates the status of the Tow and Disconnect buttons. */
+ /**
+ * Updates the status of the Tow and Disconnect buttons.
+ */
private void updateTowingButtons() {
final Entity currentEntity = currentEntity();
if ((currentEntity == null) || (currentEntity instanceof SmallCraft)) {
@@ -4463,21 +4796,21 @@ private void updateTowingButtons() {
}
final boolean legalGear = ((gear == GEAR_LAND) ||
- (gear == GEAR_TURN) ||
- (gear == GEAR_BACKUP) ||
- (gear == GEAR_JUMP));
+ (gear == GEAR_TURN) ||
+ (gear == GEAR_BACKUP) ||
+ (gear == GEAR_JUMP));
final Hex hex = game.getBoard(currentEntity).getHex(cmd.getFinalCoords());
final int unloadEl = cmd.getFinalElevation();
final boolean canDropTrailerHere = towedUnits.stream().anyMatch(en -> en.isElevationValid(unloadEl, hex));
// An off board train stays hooked up. There is no board hex to leave a trailer in, and the train is the only
// thing holding the trailer's place off the map edge.
setDisconnectEnabled(legalGear && isFinalPositionOnBoard() && canDropTrailerHere
- && !currentEntity.isOffBoard());
+ && !currentEntity.isOffBoard());
final boolean canTow = currentEntity.getHitchLocations()
- .stream()
- .flatMap(c -> game.getEntitiesVector(c).stream())
- .anyMatch(e -> currentEntity.canTow(e.getId()));
+ .stream()
+ .flatMap(c -> game.getEntitiesVector(c).stream())
+ .anyMatch(e -> currentEntity.canTow(e.getId()));
setTowEnabled(canTow);
}
@@ -4493,7 +4826,7 @@ private Coords finalPosition() {
*/
private boolean isFinalPositionOnBoard() {
return game.getBoard(currentEntity().getBoardId())
- .contains(cmd == null ? currentEntity().getPosition() : cmd.getFinalCoords());
+ .contains(cmd == null ? currentEntity().getPosition() : cmd.getFinalCoords());
}
private int finalBoardId() {
@@ -4514,8 +4847,8 @@ private void updateLayMineButton() {
setLayMineEnabled(false);
} else if (currentEntity instanceof BattleArmor) {
setLayMineEnabled(cmd.getLastStep() == null ||
- cmd.isJumping() ||
- cmd.getLastStepMovementType().equals(EntityMovementType.MOVE_VTOL_WALK));
+ cmd.isJumping() ||
+ cmd.getLastStepMovementType().equals(EntityMovementType.MOVE_VTOL_WALK));
} else {
setLayMineEnabled(true);
}
@@ -4543,12 +4876,15 @@ private Entity getMountedUnit() {
} else if (mountableUnits.size() > 1) {
// If we have multiple choices, display a selection dialog.
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.MountUnitDialog.message", currentEntity.getShortName()),
- Messages.getString("MovementDisplay.MountUnitDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(mountableUnits),
- null);
+ Messages.getString(
+ "MovementDisplay.MountUnitDialog.message",
+ currentEntity.getShortName()),
+ Messages.getString(
+ "MovementDisplay.MountUnitDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(mountableUnits),
+ null);
choice = (Entity) SharedUtility.getTargetPicked(mountableUnits, input);
} else {
// Only one choice.
@@ -4569,12 +4905,15 @@ private Entity getMountedUnit() {
}
if (bayChoices.size() > 1) {
String bayString = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.MountUnitBayNumberDialog.message", choice.getShortName()),
- Messages.getString("MovementDisplay.MountUnitBayNumberDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- retVal,
- null);
+ Messages.getString(
+ "MovementDisplay.MountUnitBayNumberDialog.message",
+ choice.getShortName()),
+ Messages.getString(
+ "MovementDisplay.MountUnitBayNumberDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ retVal,
+ null);
currentEntity.setTargetBay(MathUtility.parseInt(bayString.substring(0, bayString.indexOf(" "))));
// We need to update the entity here so that the server knows
// about our target bay
@@ -4598,7 +4937,7 @@ private Entity getMountedUnit() {
for (Entity other : game.getEntitiesVector(coords)) {
// Only allow selecting units that aren't already getting loaded
if (other.isLoadableThisTurn() && (currentEntity() != null) && currentEntity().canLoad(other, true,
- cmd.getFinalElevation()) && (other.getTargetBay() == UNSET_BAY)) {
+ cmd.getFinalElevation()) && (other.getTargetBay() == UNSET_BAY)) {
choices.addElement(other);
}
}
@@ -4613,24 +4952,25 @@ private Entity getMountedUnit() {
// If we have multiple choices, display a selection dialog.
if (choices.size() > 1) {
String input = (String) JOptionPane
- .showInputDialog(clientgui.getFrame(),
- Messages.getString(
- "DeploymentDisplay.loadUnitDialog.message",
- currentEntity().getShortName(),
- currentEntity().getUnusedString()),
- Messages.getString("DeploymentDisplay.loadUnitDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(choices),
- null);
+ .showInputDialog(clientgui.getFrame(),
+ Messages.getString(
+ "DeploymentDisplay.loadUnitDialog.message",
+ currentEntity().getShortName(),
+ currentEntity().getUnusedString()),
+ Messages.getString("DeploymentDisplay.loadUnitDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(choices),
+ null);
choice = (Entity) SharedUtility.getTargetPicked(choices, input); // Add matching notification below
} else {
// Only one choice.
choice = choices.getFirst();
// Notify user
clientgui.addToast(ToastLevel.INFO,
- Messages.getString("DeploymentDisplay.loadUnitToDefault.message",
- currentEntity().getShortName(), choice.getShortName()), currentEntity());
+ Messages.getString("DeploymentDisplay.loadUnitToDefault.message",
+ currentEntity().getShortName(), choice.getShortName()),
+ currentEntity());
}
// Handle canceled dialog
@@ -4650,27 +4990,29 @@ private Entity getMountedUnit() {
if (bayChoices.size() == 1) {
clientgui.addToast(ToastLevel.INFO,
- Messages.getString("MovementDisplay.loadUnitBayNumberDefault.message",
- currentEntity().getShortName(), choice.getShortName(),
- String.format("Bay %s", bayChoices.getFirst())), currentEntity());
+ Messages.getString("MovementDisplay.loadUnitBayNumberDefault.message",
+ currentEntity().getShortName(), choice.getShortName(),
+ String.format("Bay %s", bayChoices.getFirst())), currentEntity());
choice.setTargetBay(bayChoices.getFirst());
} else if (bayChoices.size() > 1) {
String[] bayChoicesArray = new String[bayChoices.size()];
int i = 0;
for (Integer bayNumber : bayChoices) {
bayChoicesArray[i++] = bayNumber.toString()
- + " (Free Slots: "
- + (int) currentEntity().getBayById(bayNumber).getUnused()
- + ")";
+ + " (Free Slots: "
+ + (int) currentEntity().getBayById(bayNumber).getUnused()
+ + ")";
}
String bayString = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.loadUnitBayNumberDialog.message",
- currentEntity().getShortName()),
- Messages.getString("MovementDisplay.loadUnitBayNumberDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- bayChoicesArray,
- null);
+ Messages.getString(
+ "MovementDisplay.loadUnitBayNumberDialog.message",
+ currentEntity().getShortName()),
+ Messages.getString(
+ "MovementDisplay.loadUnitBayNumberDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ bayChoicesArray,
+ null);
// Handle canceled dialog
if (bayString == null) {
return null;
@@ -4692,17 +5034,19 @@ private Entity getMountedUnit() {
int i = 0;
for (Integer bayNumber : bayChoices) {
clampChoicesArray[i++] = bayNumber > 0 ?
- Messages.getString("MovementDisplay.loadProtoClampMountDialog.rear") :
- Messages.getString("MovementDisplay.loadProtoClampMountDialog.front");
+ Messages.getString("MovementDisplay.loadProtoClampMountDialog.rear") :
+ Messages.getString("MovementDisplay.loadProtoClampMountDialog.front");
}
String bayString = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.loadProtoClampMountDialog.message",
- currentEntity().getShortName()),
- Messages.getString("MovementDisplay.loadProtoClampMountDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- clampChoicesArray,
- null);
+ Messages.getString(
+ "MovementDisplay.loadProtoClampMountDialog.message",
+ currentEntity().getShortName()),
+ Messages.getString(
+ "MovementDisplay.loadProtoClampMountDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ clampChoicesArray,
+ null);
if (bayString == null) {
// Cancelled out, best to cancel the loading.
@@ -4710,7 +5054,7 @@ private Entity getMountedUnit() {
}
choice.setTargetBay(bayString.equals(Messages.getString(
- "MovementDisplay.loadProtoClampMountDialog.front")) ? 0 : 1);
+ "MovementDisplay.loadProtoClampMountDialog.front")) ? 0 : 1);
// We need to update the entity here so that the server knows
// about our target bay
clientgui.getClient().sendUpdateEntity(choice);
@@ -4726,7 +5070,7 @@ private Entity getMountedUnit() {
* loaded units.
*
* @return The Entity that the player wants to tow. This value may be null if there are no eligible
- * targets
+ * targets
*/
private Entity getTowedUnit() {
Entity choice;
@@ -4752,12 +5096,15 @@ private Entity getTowedUnit() {
// If we have multiple choices, display a selection dialog.
if (choices.size() > 1) {
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("DeploymentDisplay.towUnitDialog.message", currentEntity().getShortName()),
- Messages.getString("DeploymentDisplay.towUnitDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(choices),
- null);
+ Messages.getString(
+ "DeploymentDisplay.towUnitDialog.message",
+ currentEntity().getShortName()),
+ Messages.getString(
+ "DeploymentDisplay.towUnitDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(choices),
+ null);
choice = (Entity) SharedUtility.getTargetPicked(choices, input);
} else {
// Only one choice.
@@ -4768,11 +5115,14 @@ private Entity getTowedUnit() {
// We need lots of data about the hitch to store in different places. Save that
// here
final class HitchChoice {
+
private final int id;
private final int number;
private final TankTrailerHitch hitch;
- private HitchChoice(int id, int number, TankTrailerHitch t) {
+ private HitchChoice(int id,
+ int number,
+ TankTrailerHitch t) {
this.id = id;
this.number = number;
this.hitch = t;
@@ -4823,8 +5173,8 @@ public String toString() {
if (transporter.canTow(choice)) {
TankTrailerHitch tankTrailerHitch = (TankTrailerHitch) transporter;
HitchChoice hitch = new HitchChoice(entity.getId(),
- entity.getTransports().indexOf(transporter),
- tankTrailerHitch);
+ entity.getTransports().indexOf(transporter),
+ tankTrailerHitch);
hitchChoices.add(hitch);
}
}
@@ -4839,12 +5189,15 @@ public String toString() {
retVal[i++] = hc.toString();
}
String selection = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.loadUnitHitchDialog.message", currentEntity().getShortName()),
- Messages.getString("MovementDisplay.loadUnitHitchDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- retVal,
- null);
+ Messages.getString(
+ "MovementDisplay.loadUnitHitchDialog.message",
+ currentEntity().getShortName()),
+ Messages.getString(
+ "MovementDisplay.loadUnitHitchDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ retVal,
+ null);
HitchChoice hc = null;
if (selection != null) {
for (HitchChoice hitchChoice : hitchChoices) {
@@ -4894,14 +5247,16 @@ private Entity getDisconnectedUnit() {
} else if (currentEntity.getAllTowedUnits().size() > 1) {
// If we have multiple choices, display a selection dialog.
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.DisconnectUnitDialog.message",
- currentEntity.getShortName(),
- currentEntity.getUnusedString()),
- Messages.getString("MovementDisplay.DisconnectUnitDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(towedUnits),
- null);
+ Messages.getString(
+ "MovementDisplay.DisconnectUnitDialog.message",
+ currentEntity.getShortName(),
+ currentEntity.getUnusedString()),
+ Messages.getString(
+ "MovementDisplay.DisconnectUnitDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(towedUnits),
+ null);
choice = (Entity) SharedUtility.getTargetPicked(towedUnits, input);
} else {
// Only one choice.
@@ -4929,18 +5284,20 @@ private Entity getDisconnectedUnit() {
} else if (unloadableUnits.size() > 1) {
// Only show the units we are not already planning to unload
List filteredUnits = unloadableUnits
- .stream()
- .filter(entity -> entity.getTargetBay() == UNSET_BAY).collect(Collectors.toList());
+ .stream()
+ .filter(entity -> entity.getTargetBay() == UNSET_BAY).collect(Collectors.toList());
// If we have multiple choices, display a selection dialog.
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.UnloadUnitDialog.message",
- currentEntity.getShortName(),
- currentEntity.getUnusedString()),
- Messages.getString("MovementDisplay.UnloadUnitDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(filteredUnits),
- null);
+ Messages.getString(
+ "MovementDisplay.UnloadUnitDialog.message",
+ currentEntity.getShortName(),
+ currentEntity.getUnusedString()),
+ Messages.getString(
+ "MovementDisplay.UnloadUnitDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(filteredUnits),
+ null);
choice = (Entity) SharedUtility.getTargetPicked(filteredUnits, input);
} else {
// Only one choice.
@@ -4956,7 +5313,6 @@ private Entity getDisconnectedUnit() {
* Returns a position to unload a unit into or null if the player cancels the dialog.
*
* @param unloaded The unit to unload
- *
* @return The position to unload to
*/
private @Nullable Coords getUnloadPosition(Entity unloaded) {
@@ -5012,7 +5368,7 @@ private Entity getDisconnectedUnit() {
if (ring.isEmpty()) {
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.NoPlaceToUnload.message"), currentEntity());
+ Messages.getString("MovementDisplay.NoPlaceToUnload.message"), currentEntity());
return null;
}
String[] choices = new String[ring.size()];
@@ -5021,15 +5377,15 @@ private Entity getDisconnectedUnit() {
choices[i++] = c.toString();
}
String selected = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.ChooseHex" + ".message",
- currentEntity.getShortName(),
- currentEntity.getUnusedString()),
- Messages.getString("MovementDisplay.ChooseHex.title"),
-
- JOptionPane.QUESTION_MESSAGE,
- null,
- choices,
- null);
+ Messages.getString("MovementDisplay.ChooseHex" + ".message",
+ currentEntity.getShortName(),
+ currentEntity.getUnusedString()),
+ Messages.getString("MovementDisplay.ChooseHex.title"),
+
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ choices,
+ null);
if (selected == null) {
return null;
}
@@ -5046,7 +5402,6 @@ private Entity getDisconnectedUnit() {
/**
* @param abandoned - The vessel we're escaping from
- *
* @return Uses player input to find a legal hex where an EjectedCrew unit can be placed
*/
private Coords getEjectPosition(Entity abandoned) {
@@ -5066,7 +5421,7 @@ private Coords getEjectPosition(Entity abandoned) {
ring = Compute.getAcceptableUnloadPositions(ring, finalBoardId(), crew, game, elev);
if (ring.isEmpty()) {
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.NoPlaceToEject.message"), currentEntity());
+ Messages.getString("MovementDisplay.NoPlaceToEject.message"), currentEntity());
return null;
}
String[] choices = new String[ring.size()];
@@ -5075,10 +5430,12 @@ private Coords getEjectPosition(Entity abandoned) {
choices[i++] = c.toString();
}
String selected = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.ChooseEjectHex.message",
- abandoned.getShortName(), abandoned.getUnusedString()),
- Messages.getString("MovementDisplay.ChooseHex.title"),
- JOptionPane.QUESTION_MESSAGE, null, choices, null);
+ Messages.getString(
+ "MovementDisplay.ChooseEjectHex.message",
+ abandoned.getShortName(),
+ abandoned.getUnusedString()),
+ Messages.getString("MovementDisplay.ChooseHex.title"),
+ JOptionPane.QUESTION_MESSAGE, null, choices, null);
if (selected == null) {
return null;
}
@@ -5116,10 +5473,10 @@ private synchronized void updateRecoveryButton() {
// Is the other unit friendly and not the current entity? must be done with its movement it also must
// be the same heading and velocity
if ((other instanceof Aero oa) &&
- other.isDone() &&
- other.canLoad(currentEntity) &&
- (cmd.getFinalFacing() == other.getFacing()) &&
- !other.isCapitalFighter()) {
+ other.isDone() &&
+ other.canLoad(currentEntity) &&
+ (cmd.getFinalFacing() == other.getFacing()) &&
+ !other.isCapitalFighter()) {
// now let's check velocity
// depends on movement rules
if (game.useVectorMove()) {
@@ -5183,10 +5540,10 @@ private synchronized void updateJoinButton() {
// Is the other unit friendly and not the current entity? Must be done with its movement it also must be
// the same heading and velocity
if (currentEntity.getOwner().equals(other.getOwner()) &&
- other.isCapitalFighter() &&
- other.isDone() &&
- other.canLoad(currentEntity) &&
- (cmd.getFinalFacing() == other.getFacing())) {
+ other.isCapitalFighter() &&
+ other.isDone() &&
+ other.canLoad(currentEntity) &&
+ (cmd.getFinalFacing() == other.getFacing())) {
// now let's check velocity
// depends on movement rules
Aero oa = (Aero) other;
@@ -5256,9 +5613,9 @@ private TreeMap> getLaunchedUnits() {
}
String[] names = new String[currentFighters.size()];
String question = Messages.getString("MovementDisplay.LaunchFighterDialog.message",
- currentEntity.getShortName(),
- doors * 2,
- bayNum);
+ currentEntity.getShortName(),
+ doors * 2,
+ bayNum);
for (int loop = 0; loop < names.length; loop++) {
names[loop] = currentFighters.get(loop).getShortName();
}
@@ -5267,11 +5624,11 @@ private TreeMap> getLaunchedUnits() {
ChoiceDialog choiceDialog = null;
while (!doIt) {
choiceDialog = new ChoiceDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.LaunchFighterDialog.title",
- currentBay.getTransporterType(),
- bayNum),
- question,
- names);
+ Messages.getString("MovementDisplay.LaunchFighterDialog.title",
+ currentBay.getTransporterType(),
+ bayNum),
+ question,
+ names);
choiceDialog.setVisible(true);
if (choiceDialog.getChoices() == null) {
doIt = true;
@@ -5290,8 +5647,8 @@ private TreeMap> getLaunchedUnits() {
}
modifier += currentFighters.get(choice).getCrew().getPiloting();
String damageMsg = Messages.getString("MovementDisplay.LaunchFighterDialog.controlroll",
- names[choice],
- modifier);
+ names[choice],
+ modifier);
pilotSkillRolls.append("\t").append(damageMsg).append("\n");
}
String title = Messages.getString("MovementDisplay.areYouSure");
@@ -5352,33 +5709,34 @@ private TreeMap> getUndockedUnits() {
if (!currentDropships.isEmpty()) {
String[] names = new String[currentDropships.size()];
String question = Messages.getString("MovementDisplay.LaunchDropshipDialog.message",
- currentlySelectedEntity.getShortName(),
- 1,
- collarNum);
+ currentlySelectedEntity.getShortName(),
+ 1,
+ collarNum);
for (int loop = 0; loop < names.length; loop++) {
names[loop] = currentDropships.get(loop).getShortName();
}
boolean doIt = false;
ChoiceDialog choiceDialog = new ChoiceDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.LaunchDropshipDialog.title",
- collar.getTransporterType(),
- collarNum),
- question,
- names);
+ Messages.getString(
+ "MovementDisplay.LaunchDropshipDialog.title",
+ collar.getTransporterType(),
+ collarNum),
+ question,
+ names);
while (!doIt) {
choiceDialog = new ChoiceDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.LaunchDropshipDialog.title",
- collar.getTransporterType(),
- collarNum),
- question,
- names);
+ Messages.getString("MovementDisplay.LaunchDropshipDialog.title",
+ collar.getTransporterType(),
+ collarNum),
+ question,
+ names);
choiceDialog.setVisible(true);
if ((choiceDialog.getChoices() != null) && (choiceDialog.getChoices().length > 1)) {
ConfirmDialog nag = new ConfirmDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.areYouSure"),
- Messages.getString("MovementDisplay.ConfirmLaunch"),
- true);
+ Messages.getString("MovementDisplay.areYouSure"),
+ Messages.getString("MovementDisplay.ConfirmLaunch"),
+ true);
nag.setVisible(true);
doIt = nag.getAnswer();
} else {
@@ -5393,7 +5751,7 @@ private TreeMap> getUndockedUnits() {
collarChoices.add(currentDropships.get(element).getId());
// Prompt the player to load passengers aboard the launching ship(s)
Entity en = game
- .getEntity(currentDropships.get(element).getId());
+ .getEntity(currentDropships.get(element).getId());
if (en instanceof SmallCraft) {
loadPassengerAtLaunch((SmallCraft) en);
}
@@ -5427,13 +5785,15 @@ private void loadPassengerAtLaunch(SmallCraft craft) {
int space = getSpace(craft, currentEntity);
ConfirmDialog takePassenger = new ConfirmDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.FillSmallCraftPassengerDialog.Title"),
- Messages.getString("MovementDisplay.FillSmallCraftPassengerDialog.message",
- craft.getShortName(),
- space,
- currentEntity.getShortName() + "'",
- currentEntity.getNPassenger()),
- false);
+ Messages.getString(
+ "MovementDisplay.FillSmallCraftPassengerDialog.Title"),
+ Messages.getString(
+ "MovementDisplay.FillSmallCraftPassengerDialog.message",
+ craft.getShortName(),
+ space,
+ currentEntity.getShortName() + "'",
+ currentEntity.getNPassenger()),
+ false);
takePassenger.setVisible(true);
if (takePassenger.getAnswer()) {
// Move the passengers
@@ -5447,7 +5807,8 @@ private void loadPassengerAtLaunch(SmallCraft craft) {
}
}
- private static int getSpace(SmallCraft craft, Entity currentEntity) {
+ private static int getSpace(SmallCraft craft,
+ Entity currentEntity) {
int space = 0;
for (Bay b : craft.getTransportBays()) {
if ((b instanceof CargoBay) || (b instanceof InfantryBay) || (b instanceof BattleArmorBay)) {
@@ -5527,21 +5888,21 @@ private TreeMap> getDroppedUnits() {
if (!currentUnits.isEmpty() && (isInfantryTransporter || (doorsEligibleForDrop > 0))) {
String[] names = new String[currentUnits.size()];
String question = Messages.getString("MovementDisplay.DropUnitDialog.message",
- doorsEligibleForDrop,
- bayNum);
+ doorsEligibleForDrop,
+ bayNum);
for (int loop = 0; loop < names.length; loop++) {
names[loop] = currentUnits.get(loop).getShortName();
}
// If this is an infantry-transporting bay (cargo, Infantry Bay, etc.), no limit on drops
int max = (isInfantryTransporter) ? -1 : doorsEligibleForDrop;
ChoiceDialog choiceDialog = new ChoiceDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.DropUnitDialog.title",
- currentTransporter.getTransporterType(),
- bayNum),
- question,
- names,
- false,
- max);
+ Messages.getString("MovementDisplay.DropUnitDialog.title",
+ currentTransporter.getTransporterType(),
+ bayNum),
+ question,
+ names,
+ false,
+ max);
choiceDialog.setVisible(true);
if (choiceDialog.getAnswer()) {
// load up the choices
@@ -5579,11 +5940,11 @@ private int getRecoveryUnit() {
// Is the other unit friendly and not the current entity? Must be done with its movement it also must be
// the same heading and velocity
if ((other instanceof Aero oa) &&
- !oa.isOutControlTotal() &&
- other.isDone() &&
- other.canLoad(currentEntity) &&
- currentEntity.isLoadableThisTurn() &&
- (cmd.getFinalFacing() == other.getFacing())) {
+ !oa.isOutControlTotal() &&
+ other.isDone() &&
+ other.canLoad(currentEntity) &&
+ currentEntity.isLoadableThisTurn() &&
+ (cmd.getFinalFacing() == other.getFacing())) {
// now let's check velocity
// depends on movement rules
if (game.useVectorMove()) {
@@ -5604,7 +5965,7 @@ private int getRecoveryUnit() {
if (choices.size() == 1) {
if (choices.getFirst().mpUsed > 0) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.RecoverSureDialog.title"),
- Messages.getString("MovementDisplay.RecoverSureDialog.message"))) {
+ Messages.getString("MovementDisplay.RecoverSureDialog.message"))) {
return choices.getFirst().getId();
}
} else {
@@ -5614,19 +5975,21 @@ private int getRecoveryUnit() {
}
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.RecoverFighterDialog.message"),
- Messages.getString("MovementDisplay.RecoverFighterDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(choices),
- null);
+ Messages.getString(
+ "MovementDisplay.RecoverFighterDialog.message"),
+ Messages.getString(
+ "MovementDisplay.RecoverFighterDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(choices),
+ null);
Entity picked = (Entity) SharedUtility.getTargetPicked(choices, input);
if (picked != null) {
// if this unit is thrusting, make sure they are aware
if (picked.mpUsed > 0) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.RecoverSureDialog.title"),
- Messages.getString("MovementDisplay.RecoverSureDialog.message"))) {
+ Messages.getString("MovementDisplay.RecoverSureDialog.message"))) {
return picked.getId();
}
} else {
@@ -5653,11 +6016,11 @@ private int getUnitJoined() {
// Is the other unit friendly and not the current entity? Must be done with its movement it also must be
// the same heading and velocity
if ((other instanceof Aero oa) &&
- !oa.isOutControlTotal() &&
- other.isDone() &&
- other.canLoad(currentEntity) &&
- currentEntity.isLoadableThisTurn() &&
- (cmd.getFinalFacing() == other.getFacing())) {
+ !oa.isOutControlTotal() &&
+ other.isDone() &&
+ other.canLoad(currentEntity) &&
+ currentEntity.isLoadableThisTurn() &&
+ (cmd.getFinalFacing() == other.getFacing())) {
// now let's check velocity
// depends on movement rules
if (game.useVectorMove()) {
@@ -5680,12 +6043,14 @@ private int getUnitJoined() {
}
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.JoinSquadronDialog.message"),
- Messages.getString("MovementDisplay.JoinSquadronDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- SharedUtility.getDisplayArray(choices),
- null);
+ Messages.getString(
+ "MovementDisplay.JoinSquadronDialog.message"),
+ Messages.getString(
+ "MovementDisplay.JoinSquadronDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ SharedUtility.getDisplayArray(choices),
+ null);
Entity picked = (Entity) SharedUtility.getTargetPicked(choices, input);
if (picked != null) {
return picked.getId();
@@ -5716,8 +6081,8 @@ private void checkOOC() {
setForwardIniEnabled(true);
if (currentEntity instanceof Aero) {
setLaunchEnabled(!currentEntity.getLaunchableFighters().isEmpty() ||
- !currentEntity.getLaunchableSmallCraft().isEmpty() ||
- !currentEntity.getLaunchableDropships().isEmpty());
+ !currentEntity.getLaunchableSmallCraft().isEmpty() ||
+ !currentEntity.getLaunchableDropships().isEmpty());
}
}
}
@@ -5731,7 +6096,9 @@ private void updateMoreButton() {
}
}
- /** Checks Aerospace for remaining fuel and adjusts buttons when necessary. */
+ /**
+ * Checks Aerospace for remaining fuel and adjusts buttons when necessary.
+ */
private void checkFuel() {
final Entity currentEntity = currentEntity();
if ((currentEntity == null) || !currentEntity.isAero()) {
@@ -5746,8 +6113,8 @@ private void checkFuel() {
setForwardIniEnabled(true);
if (currentEntity instanceof Aero) {
setLaunchEnabled(!currentEntity.getLaunchableFighters().isEmpty() ||
- !currentEntity.getLaunchableSmallCraft().isEmpty() ||
- !currentEntity.getLaunchableDropships().isEmpty());
+ !currentEntity.getLaunchableSmallCraft().isEmpty() ||
+ !currentEntity.getLaunchableDropships().isEmpty());
}
updateRACButton();
updateJoinButton();
@@ -5807,11 +6174,13 @@ private Targetable chooseTarget(Coords pos) {
} else if (targets.size() > 1) {
// If we have multiple choices, display a selection dialog.
choice = TargetChoiceDialog.showSingleChoiceDialog(clientgui.getFrame(),
- "MovementDisplay.ChooseTargetDialog.title",
- Messages.getString("MovementDisplay.ChooseTargetDialog.message", pos.getBoardNum()),
- targets,
- clientgui,
- currentEntity());
+ "MovementDisplay.ChooseTargetDialog.title",
+ Messages.getString(
+ "MovementDisplay.ChooseTargetDialog.message",
+ pos.getBoardNum()),
+ targets,
+ clientgui,
+ currentEntity());
}
@@ -5837,12 +6206,13 @@ private void dumpBombs() {
// available
int numFighters = currentEntity().getActiveSubEntities().size();
BombPayloadDialog dumpBombsDialog = new BombPayloadDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.BombDumpDialog.title"),
- currentEntity().getBombLoadout(),
- false,
- true,
- -1,
- numFighters);
+ Messages.getString(
+ "MovementDisplay.BombDumpDialog.title"),
+ currentEntity().getBombLoadout(),
+ false,
+ true,
+ -1,
+ numFighters);
dumpBombsDialog.setVisible(true);
if (dumpBombsDialog.getAnswer()) {
dumpBombsDialog.getChoices();
@@ -5859,14 +6229,14 @@ private void dumpBombs() {
if (diceRoll.getIntValue() < psr.getValue()) {
report.choose(false);
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.DumpFailure.message"), currentEntity());
+ Messages.getString("MovementDisplay.DumpFailure.message"), currentEntity());
// failed the roll, so dump all bombs
currentEntity().getBombLoadout();
} else {
// avoided damage
report.choose(true);
clientgui.addToast(ToastLevel.SUCCESS,
- Messages.getString("MovementDisplay.DumpSuccessful.message"), currentEntity());
+ Messages.getString("MovementDisplay.DumpSuccessful.message"), currentEntity());
}
}
@@ -5945,7 +6315,8 @@ private boolean addManeuver(int type) {
}
}
- private void setStatusBarTextOthersTurn(@Nullable Player player, String s) {
+ private void setStatusBarTextOthersTurn(@Nullable Player player,
+ String s) {
String playerName = (player != null) ? player.getName() : "Unknown";
setStatusBarText(Messages.getString("MovementDisplay.its_others_turn", playerName) + s);
}
@@ -5965,8 +6336,8 @@ public void gameTurnChange(GameTurnChangeEvent e) {
// generated
// Except on the first turn
if (game.getPhase().isSimultaneous(game) &&
- (e.getPreviousPlayerId() != clientgui.getClient().getLocalPlayerNumber()) &&
- (game.getTurnIndex() != 0)) {
+ (e.getPreviousPlayerId() != clientgui.getClient().getLocalPlayerNumber()) &&
+ (game.getTurnIndex() != 0)) {
return;
}
@@ -5974,9 +6345,9 @@ public void gameTurnChange(GameTurnChangeEvent e) {
// if all our entities are actually done, don't start up the turn.
if (game
- .getPlayerEntities(clientgui.getClient().getLocalPlayer(), false)
- .stream()
- .allMatch(Entity::isDone)) {
+ .getPlayerEntities(clientgui.getClient().getLocalPlayer(), false)
+ .stream()
+ .allMatch(Entity::isDone)) {
setStatusBarTextOthersTurn(e.getPlayer(), s);
clientgui.bingOthersTurn();
return;
@@ -6010,6 +6381,7 @@ public void gameTurnChange(GameTurnChangeEvent e) {
@Override
public void gamePhaseChange(GamePhaseChangeEvent e) {
// In case of a /reset command, ensure the state gets reset
+ markDeploymentHexes(null);
if (game.getPhase().isLounge()) {
endMyTurn();
}
@@ -6028,7 +6400,8 @@ public void gamePhaseChange(GamePhaseChangeEvent e) {
}
}
- private int maxMP(Entity en, int mvMode) {
+ private int maxMP(Entity en,
+ int mvMode) {
int maxMP;
if (mvMode == GEAR_DFA) {
maxMP = en.getJumpMP();
@@ -6040,8 +6413,8 @@ private int maxMP(Entity en, int mvMode) {
} else if (mvMode == GEAR_BACKUP) {
maxMP = en.getWalkMP();
} else if ((currentEntity() instanceof Mek) &&
- !(currentEntity() instanceof QuadVee) &&
- (currentEntity().getMovementMode() == EntityMovementMode.TRACKED)) {
+ !(currentEntity() instanceof QuadVee) &&
+ (currentEntity().getMovementMode() == EntityMovementMode.TRACKED)) {
// A non-QuadVee `Mek that is using tracked movement is limited to walking
maxMP = en.getWalkMP();
} else {
@@ -6132,7 +6505,9 @@ private void computeSimpleMovementEnvelope(Entity suggestion) {
clientgui.showMovementEnvelope(entity, movementEnvelopeMP, movementGear);
}
- private ShortestPathFinder getShortestPathFinder(Entity en, int maxMP, MoveStepType stepType) {
+ private ShortestPathFinder getShortestPathFinder(Entity en,
+ int maxMP,
+ MoveStepType stepType) {
ShortestPathFinder shortestPathFinder;
if (en.isAerodyne() && !en.isAeroLandedOnGroundMap()) {
shortestPathFinder = ShortestPathFinder.newInstanceOfOneToAllAero(maxMP, stepType, game);
@@ -6201,7 +6576,7 @@ public void computeModifierEnvelope() {
LongestPathFinder lpf = LongestPathFinder.newInstanceOfLongestPath(maxMP, stepType, currentEntity.getGame());
final int timeLimit = PreferenceManager.getClientPreferences().getMaxPathfinderTime();
StopConditionTimeout timeoutCondition = new StopConditionTimeout<>(
- timeLimit * 10);
+ timeLimit * 10);
lpf.addStopCondition(timeoutCondition);
lpf.run(movePath);
clientgui.showMovementModifiers(lpf.getLongestComputedPaths());
@@ -6214,9 +6589,9 @@ private int getMaxMP(Entity currentEntity) {
} else if (gear == GEAR_BACKUP) {
maxMP = currentEntity.getWalkMP();
} else if (
- (currentEntity instanceof Mek mek) &&
- !(mek instanceof QuadVee) &&
- (mek.getMovementMode() == EntityMovementMode.TRACKED)) {
+ (currentEntity instanceof Mek mek) &&
+ !(mek instanceof QuadVee) &&
+ (mek.getMovementMode() == EntityMovementMode.TRACKED)) {
// A non-QuadVee `Mek that is using tracked movement (or converting to it) is limited to walking
maxMP = mek.getWalkMP();
} else {
@@ -6230,8 +6605,8 @@ private int getMaxMP(Entity currentEntity) {
*
* The warnings mark hexes where the unit's weight would bring a building down, and they are worked out once
* when the unit is selected. A gamemaster removing a building, or changing its construction factor, changes the
- * answer without the unit having moved, so they have to be worked out again - otherwise the marker sits over a
- * hex whose building is no longer there.
+ * answer without the unit having moved, so they have to be worked out again - otherwise the marker sits over a hex
+ * whose building is no longer there.
*/
@Override
public void gameBoardChanged(GameBoardChangeEvent event) {
@@ -6287,17 +6662,17 @@ public synchronized void actionPerformed(ActionEvent ev) {
String title = Messages.getString("MovementDisplay.UnjamRAC.title");
String msg = Messages.getString("MovementDisplay.UnjamRAC.message");
if ((gear == MovementDisplay.GEAR_JUMP) ||
- (gear == MovementDisplay.GEAR_CHARGE) ||
- (gear == MovementDisplay.GEAR_DFA) ||
- ((cmd.getMpUsed() > entity.getWalkMP()) &&
- !(cmd.getLastStep().isOnlyPavementOrRoad() &&
- (cmd.getMpUsed() <= (entity.getWalkMP() + 1)))) ||
- (opts.booleanOption("tacops_tank_crews") &&
- (cmd.getMpUsed() > 0) &&
- (entity instanceof Tank) &&
- (entity.getCrew().getSize() < 2)) ||
- (gear == MovementDisplay.GEAR_SWIM) ||
- (gear == MovementDisplay.GEAR_RAM)) {
+ (gear == MovementDisplay.GEAR_CHARGE) ||
+ (gear == MovementDisplay.GEAR_DFA) ||
+ ((cmd.getMpUsed() > entity.getWalkMP()) &&
+ !(cmd.getLastStep().isOnlyPavementOrRoad() &&
+ (cmd.getMpUsed() <= (entity.getWalkMP() + 1)))) ||
+ (opts.booleanOption("tacops_tank_crews") &&
+ (cmd.getMpUsed() > 0) &&
+ (entity instanceof Tank) &&
+ (entity.getCrew().getSize() < 2)) ||
+ (gear == MovementDisplay.GEAR_SWIM) ||
+ (gear == MovementDisplay.GEAR_RAM)) {
setUnjamEnabled(false);
} else if (clientgui.doYesNoDialog(title, msg)) {
@@ -6324,9 +6699,9 @@ public synchronized void actionPerformed(ActionEvent ev) {
computeMovementEnvelope(entity);
} else if (actionCmd.equals(MoveCommand.MOVE_JUMP.getCmd())) {
if ((gear != MovementDisplay.GEAR_JUMP) &&
- !((cmd.getLastStep() != null) &&
- cmd.getLastStep().isFirstStep() &&
- (cmd.getLastStep().getType() == MoveStepType.LAY_MINE))) {
+ !((cmd.getLastStep() != null) &&
+ cmd.getLastStep().isFirstStep() &&
+ (cmd.getLastStep().getType() == MoveStepType.LAY_MINE))) {
clear();
}
gear = MovementDisplay.GEAR_JUMP;
@@ -6335,9 +6710,9 @@ public synchronized void actionPerformed(ActionEvent ev) {
String[] choices = { "Mechanical Jump Boosters", "Jump Jets" };
int jumpChoice = JOptionPane.showOptionDialog(JOptionPane.getFrameForComponent(this),
- "Choose jump type:", "Choose Jump Type",
- JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
- null, choices, choices[1]);
+ "Choose jump type:", "Choose Jump Type",
+ JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
+ null, choices, choices[1]);
if (jumpChoice == 0) {
jumpSubGear = GEAR_SUB_MEK_BOOSTERS;
@@ -6360,8 +6735,8 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
gear = MovementDisplay.GEAR_SWIM;
entity.setMovementMode((entity instanceof BipedMek) ?
- EntityMovementMode.BIPED_SWIM :
- EntityMovementMode.QUAD_SWIM);
+ EntityMovementMode.BIPED_SWIM :
+ EntityMovementMode.QUAD_SWIM);
} else if (actionCmd.equals(MoveCommand.MOVE_MODE_CONVERT.getCmd())) {
EntityMovementMode nextMode = entity.nextConversionMode(cmd.getFinalConversionMode());
// LAMs may have to skip the next mode due to damage
@@ -6419,8 +6794,8 @@ public synchronized void actionPerformed(ActionEvent ev) {
clear();
if (!game.containsMinefield(entity.getPosition())) {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.CantClearMinefield") + ": "
- + Messages.getString("MovementDisplay.NoMinefield"), currentEntity());
+ Messages.getString("MovementDisplay.CantClearMinefield") + ": "
+ + Messages.getString("MovementDisplay.NoMinefield"), currentEntity());
return;
}
@@ -6453,12 +6828,12 @@ public synchronized void actionPerformed(ActionEvent ev) {
String title = Messages.getString("MovementDisplay.ChooseMinefieldDialog.title");
String body = Messages.getString("MovementDisplay.ChooseMinefieldDialog.message");
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- body,
- title,
- JOptionPane.QUESTION_MESSAGE,
- null,
- choices,
- null);
+ body,
+ title,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ choices,
+ null);
Minefield mf = null;
if (input != null) {
for (int loop = 0; loop < choices.length; loop++) {
@@ -6506,7 +6881,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
if (opts.booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_CAREFUL_STAND)
- && (entity.getWalkMP() > 2)) {
+ && (entity.getWalkMP() > 2)) {
String title = Messages.getString("MovementDisplay.CarefulStand.title");
String body = Messages.getString("MovementDisplay.CarefulStand.message");
boolean response = clientgui.doYesNoDialog(title, body);
@@ -6551,12 +6926,12 @@ public synchronized void actionPerformed(ActionEvent ev) {
String title = "Choose Brace Location";
String body = "Choose the location to brace:";
String option = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- body,
- title,
- JOptionPane.QUESTION_MESSAGE,
- null,
- locationNames,
- locationNames[0]);
+ body,
+ title,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ locationNames,
+ locationNames[0]);
// Verify that we have a valid option...
if (option != null) {
@@ -6566,8 +6941,8 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
}
} else if (actionCmd.equals(MoveCommand.MOVE_FLEE.getCmd()) &&
- clientgui.doYesNoDialog(Messages.getString("MovementDisplay.EscapeDialog.title"),
- Messages.getString("MovementDisplay.EscapeDialog.message"))) {
+ clientgui.doYesNoDialog(Messages.getString("MovementDisplay.EscapeDialog.title"),
+ Messages.getString("MovementDisplay.EscapeDialog.message"))) {
addStepToMovePath(MoveStepType.FLEE);
ready();
clear();
@@ -6576,14 +6951,14 @@ public synchronized void actionPerformed(ActionEvent ev) {
} else if (actionCmd.equals(MoveCommand.MOVE_EJECT.getCmd())) {
if (entity instanceof Tank) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.AbandonDialog.title"),
- Messages.getString("MovementDisplay.AbandonDialog.message"))) {
+ Messages.getString("MovementDisplay.AbandonDialog.message"))) {
clear();
addStepToMovePath(MoveStepType.EJECT);
ready();
}
} else if (entity.isLargeCraft()) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.AbandonDialog.title"),
- Messages.getString("MovementDisplay.AbandonDialog.message"))) {
+ Messages.getString("MovementDisplay.AbandonDialog.message"))) {
clear();
// If we're abandoning while grounded, find a legal position to put an
// EjectedCrew unit
@@ -6596,7 +6971,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
ready();
}
} else if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.AbandonDialog1.title"),
- Messages.getString("MovementDisplay.AbandonDialog1.message"))) {
+ Messages.getString("MovementDisplay.AbandonDialog1.message"))) {
clear();
addStepToMovePath(MoveStepType.EJECT);
ready();
@@ -6605,8 +6980,8 @@ public synchronized void actionPerformed(ActionEvent ev) {
// Mek abandonment (two-phase per TacOps:AR p.165)
if ((entity instanceof Mek mek) && mek.canAbandon()) {
if (clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.MekAbandonDialog.title"),
- Messages.getString("MovementDisplay.MekAbandonDialog.message"))) {
+ Messages.getString("MovementDisplay.MekAbandonDialog.title"),
+ Messages.getString("MovementDisplay.MekAbandonDialog.message"))) {
clear();
addStepToMovePath(MoveStepType.ABANDON);
ready();
@@ -6653,13 +7028,13 @@ public synchronized void actionPerformed(ActionEvent ev) {
Entity other = getUnloadedUnit();
if (other != null) {
if (!other.isInfantry() ||
- currentEntity() instanceof SmallCraft ||
- (currentEntity().isSupportVehicle() && (currentEntity().getWeightClass()
- == EntityWeightClass.WEIGHT_LARGE_SUPPORT))
- // FIXME: unclear why towed/towing is checked here:
- ||
- !currentEntity().getAllTowedUnits().isEmpty() ||
- currentEntity().getTowedBy() != Entity.NONE) {
+ currentEntity() instanceof SmallCraft ||
+ (currentEntity().isSupportVehicle() && (currentEntity().getWeightClass()
+ == EntityWeightClass.WEIGHT_LARGE_SUPPORT))
+ // FIXME: unclear why towed/towing is checked here:
+ ||
+ !currentEntity().getAllTowedUnits().isEmpty() ||
+ currentEntity().getTowedBy() != Entity.NONE) {
// unload into adjacent hexes
Coords pos = getUnloadPosition(other);
if (null != pos) {
@@ -6679,9 +7054,9 @@ public synchronized void actionPerformed(ActionEvent ev) {
ready();
} else {
List filteredUnits = unloadableUnits
- .stream()
- .filter(unloadable -> unloadable.getTargetBay() == UNSET_BAY)
- .toList();
+ .stream()
+ .filter(unloadable -> unloadable.getTargetBay() == UNSET_BAY)
+ .toList();
if (filteredUnits.isEmpty()) {
ready();
}
@@ -6697,11 +7072,14 @@ public synchronized void actionPerformed(ActionEvent ev) {
} else if (actionCmd.equals(MoveCommand.MOVE_DROP_CARGO.getCmd())) {
var options = currentEntity().getDistinctCarriedObjects();
List moreOptions = entity.getTransports()
- .stream()
- .filter(t -> t instanceof ExternalCargo)
- .map(t -> t.getCarryables().toArray(ICarryable[]::new))
- .flatMap(Arrays::stream)
- .toList().stream().filter(carryable -> !options.contains(carryable)).toList();
+ .stream()
+ .filter(t -> t instanceof ExternalCargo)
+ .map(t -> t.getCarryables().toArray(ICarryable[]::new))
+ .flatMap(Arrays::stream)
+ .toList()
+ .stream()
+ .filter(carryable -> !options.contains(carryable))
+ .toList();
List fullOptions = new ArrayList<>(options);
fullOptions.addAll(moreOptions);
@@ -6719,12 +7097,12 @@ public synchronized void actionPerformed(ActionEvent ev) {
String title = "Choose Cargo to Drop";
String body = "Choose the cargo to drop:";
String option = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- body,
- title,
- JOptionPane.QUESTION_MESSAGE,
- null,
- locationMap.keySet().toArray(),
- locationMap.keySet().toArray()[0]);
+ body,
+ title,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ locationMap.keySet().toArray(),
+ locationMap.keySet().toArray()[0]);
// Verify that we have a valid option...
if (option != null) {
@@ -6740,18 +7118,18 @@ public synchronized void actionPerformed(ActionEvent ev) {
// On-demand Descend dialog: only meaningful for a mid-climb / dangling Mek.
// Replaces the auto-prompt that fired at turn start.
if ((entity instanceof Mek climbingMek) && entity.isClimbing()
- && ClimbingHelper.canClimb(entity)) {
+ && ClimbingHelper.canClimb(entity)) {
promptContinueClimbing(climbingMek);
}
} else if (actionCmd.equals(MoveCommand.MOVE_LOWER_ELEVATION.getCmd())) {
if (entity.isAero()) {
PlanetaryConditions conditions = game.getPlanetaryConditions();
boolean spheroidOrLessThanThin = ((IAero) entity).isSpheroid() ||
- conditions.getAtmosphere().isLighterThan(Atmosphere.THIN);
+ conditions.getAtmosphere().isLighterThan(Atmosphere.THIN);
if ((null != cmd.getLastStep()) &&
- (cmd.getLastStep().getNDown() == 1) &&
- (cmd.getLastStep().getVelocity() < 12) &&
- !spheroidOrLessThanThin) {
+ (cmd.getLastStep().getNDown() == 1) &&
+ (cmd.getLastStep().getVelocity() < 12) &&
+ !spheroidOrLessThanThin) {
addStepToMovePath(MoveStepType.ACC, true);
computeMovementEnvelope(entity);
}
@@ -6766,22 +7144,22 @@ public synchronized void actionPerformed(ActionEvent ev) {
boolean turningOn = !cmd.getFinalClimbMode();
MoveStep ms = cmd.getLastStep();
if ((ms != null) &&
- ((ms.getType() == MoveStepType.CLIMB_MODE_ON) || (ms.getType() == MoveStepType.CLIMB_MODE_OFF))) {
+ ((ms.getType() == MoveStepType.CLIMB_MODE_ON) || (ms.getType() == MoveStepType.CLIMB_MODE_OFF))) {
turningOn = (ms.getType() == MoveStepType.CLIMB_MODE_OFF);
}
if (turningOn && game.getOptions()
- .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_CLIMBING)) {
+ .booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_TAC_OPS_CLIMBING)) {
String reason = ClimbingHelper.getClimbingImpossibleReason(entity);
if (reason != null) {
JOptionPane.showMessageDialog(clientgui.getFrame(), reason,
- Messages.getString("MovementDisplay.ClimbingDialog.title"),
- JOptionPane.WARNING_MESSAGE);
+ Messages.getString("MovementDisplay.ClimbingDialog.title"),
+ JOptionPane.WARNING_MESSAGE);
}
}
ms = cmd.getLastStep();
if ((ms != null) &&
- ((ms.getType() == MoveStepType.CLIMB_MODE_ON) || (ms.getType() == MoveStepType.CLIMB_MODE_OFF))) {
+ ((ms.getType() == MoveStepType.CLIMB_MODE_ON) || (ms.getType() == MoveStepType.CLIMB_MODE_OFF))) {
MoveStep lastStep = cmd.getLastStep();
cmd.removeLastStep();
// Add another climb mode step. Without this, we end up with 3 effect modes: no climb step, climb step
@@ -6813,8 +7191,8 @@ public synchronized void actionPerformed(ActionEvent ev) {
m.setEmpSetting(empDialog.getSetting());
}
if (cmd.getLastStep() == null &&
- entity instanceof BattleArmor &&
- entity.getMovementMode().equals(EntityMovementMode.INF_JUMP)) {
+ entity instanceof BattleArmor &&
+ entity.getMovementMode().equals(EntityMovementMode.INF_JUMP)) {
initializeJumpMovePath();
gear = GEAR_JUMP;
Color jumpColor = GUIP.getMoveJumpColor();
@@ -6831,7 +7209,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
addStepToMovePath(MoveStepType.DIG_IN);
} else {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.digInIllegalTerrain.toast"), entity);
+ Messages.getString("MovementDisplay.digInIllegalTerrain.toast"), entity);
}
} else if (actionCmd.equals(MoveCommand.MOVE_HIT_DECK.getCmd())) {
addStepToMovePath(MoveStepType.HIT_THE_DECK);
@@ -6839,14 +7217,14 @@ public synchronized void actionPerformed(ActionEvent ev) {
// facing-selection dialog, so hint that turning in place (free) designates the facing.
if ((entity instanceof ConvInfantry convInfantry) && convInfantry.hasActiveFieldWeapon()) {
clientgui.addToast(ToastLevel.INFO,
- Messages.getString("MovementDisplay.hitDeckFacing.toast"), entity);
+ Messages.getString("MovementDisplay.hitDeckFacing.toast"), entity);
}
} else if (actionCmd.equals(MoveCommand.MOVE_FORTIFY.getCmd())) {
if (MoveStep.isFortifiableTerrain(game.getHexOf(entity))) {
addStepToMovePath(MoveStepType.FORTIFY);
} else {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.fortifyIllegalTerrain.toast"), entity);
+ Messages.getString("MovementDisplay.fortifyIllegalTerrain.toast"), entity);
}
} else if (actionCmd.equals(MoveCommand.MOVE_CLEAR_RUBBLE.getCmd())) {
// Enter target-selection: the player clicks the rubble hex to drive into and clear (TacOps).
@@ -6855,7 +7233,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
gear = MovementDisplay.GEAR_CLEAR_RUBBLE;
LOGGER.debug("[Bulldozer] {}: entering clear-rubble target mode - awaiting rubble hex selection",
- entity.getDisplayName());
+ entity.getDisplayName());
setStatusBarText(Messages.getString("MovementDisplay.status.selectRubbleHex"));
computeMovementEnvelope(entity);
} else if (actionCmd.equals(MoveCommand.MOVE_BUILD_BRIDGE.getCmd())) {
@@ -6898,7 +7276,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
addStepToMovePath(MoveStepType.BOOTLEGGER);
} else if (actionCmd.equals(MoveCommand.MOVE_SHUTDOWN.getCmd())) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.ShutdownDialog.title"),
- Messages.getString("MovementDisplay.ShutdownDialog.message"))) {
+ Messages.getString("MovementDisplay.ShutdownDialog.message"))) {
addStepToMovePath(MoveStepType.SHUTDOWN);
ready();
}
@@ -6907,12 +7285,12 @@ public synchronized void actionPerformed(ActionEvent ev) {
boolean proceedWithStartup;
if (entity.isPendingAbandon()) {
proceedWithStartup = clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.StartupCancelAbandonDialog.title"),
- Messages.getString("MovementDisplay.StartupCancelAbandonDialog.message"));
+ Messages.getString("MovementDisplay.StartupCancelAbandonDialog.title"),
+ Messages.getString("MovementDisplay.StartupCancelAbandonDialog.message"));
} else {
proceedWithStartup = clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.StartupDialog.title"),
- Messages.getString("MovementDisplay.StartupDialog.message"));
+ Messages.getString("MovementDisplay.StartupDialog.title"),
+ Messages.getString("MovementDisplay.StartupDialog.message"));
}
if (proceedWithStartup) {
clear();
@@ -6921,7 +7299,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
} else if (actionCmd.equals(MoveCommand.MOVE_SELF_DESTRUCT.getCmd())) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.SelfDestructDialog.title"),
- Messages.getString("MovementDisplay.SelfDestructDialog.message"))) {
+ Messages.getString("MovementDisplay.SelfDestructDialog.message"))) {
addStepToMovePath(MoveStepType.SELF_DESTRUCT);
ready();
}
@@ -6934,13 +7312,14 @@ public synchronized void actionPerformed(ActionEvent ev) {
} else if (actionCmd.equals(MoveCommand.MOVE_HOVER.getCmd())) {
addStepToMovePath(MoveStepType.HOVER);
if (entity instanceof LandAirMek
- && entity.getMovementMode() == EntityMovementMode.WIGE
- && entity.isAirborne()) {
+ && entity.getMovementMode() == EntityMovementMode.WIGE
+ && entity.isAirborne()) {
gear = GEAR_LAND;
}
} else if (actionCmd.equals(MoveCommand.MOVE_MANEUVER.getCmd())) {
ManeuverChoiceDialog choiceDialog = new ManeuverChoiceDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.ManeuverDialog.title"));
+ Messages.getString(
+ "MovementDisplay.ManeuverDialog.title"));
IAero a = (IAero) entity;
MoveStep last = cmd.getLastStep();
@@ -6961,7 +7340,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
ceil = 0;
}
choiceDialog.checkPerformability(vel, altitude, ceil, a.isVSTOL(), distance, board,
- cmd);
+ cmd);
choiceDialog.setVisible(true);
int manType = choiceDialog.getChoice();
updateMove((manType > ManeuverType.MAN_NONE) && addManeuver(manType));
@@ -6975,7 +7354,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
addStepToMovePath(MoveStepType.LAUNCH, launched);
}
} else if (actionCmd.equals(MoveCommand.MOVE_RECOVER.getCmd()) ||
- actionCmd.equals(MoveCommand.MOVE_DOCK.getCmd())) {
+ actionCmd.equals(MoveCommand.MOVE_DOCK.getCmd())) {
// if more than one unit is available as a carrier, then bring up an option dialog
int recoverer = getRecoveryUnit();
if (recoverer != NO_UNIT_SELECTED) {
@@ -7010,11 +7389,12 @@ public synchronized void actionPerformed(ActionEvent ev) {
} else if (actionCmd.equals(MoveCommand.MOVE_TAKE_OFF.getCmd())) {
if (currentEntity().isAero() && (null != ((IAero) currentEntity()).hasRoomForHorizontalTakeOff())) {
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.NoTakeOffDialog.message",
- ((IAero) currentEntity()).hasRoomForHorizontalTakeOff()), currentEntity());
+ Messages.getString("MovementDisplay.NoTakeOffDialog.message",
+ ((IAero) currentEntity()).hasRoomForHorizontalTakeOff()),
+ currentEntity());
} else {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.TakeOffDialog.title"),
- Messages.getString("MovementDisplay.TakeOffDialog.message"))) {
+ Messages.getString("MovementDisplay.TakeOffDialog.message"))) {
clear();
addStepToMovePath(MoveStepType.TAKEOFF);
ready();
@@ -7022,7 +7402,7 @@ public synchronized void actionPerformed(ActionEvent ev) {
}
} else if (actionCmd.equals(MoveCommand.MOVE_VERT_TAKE_OFF.getCmd())) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.TakeOffDialog.title"),
- Messages.getString("MovementDisplay.TakeOffDialog.message"))) {
+ Messages.getString("MovementDisplay.TakeOffDialog.message"))) {
clear();
addStepToMovePath(MoveStepType.VERTICAL_TAKE_OFF);
ready();
@@ -7062,18 +7442,18 @@ public synchronized void actionPerformed(ActionEvent ev) {
// No players available?
if (idx == 0) {
clientgui.addToast(ToastLevel.WARNING,
- Messages.getString("MovementDisplay.NoTraitorPlayers"));
+ Messages.getString("MovementDisplay.NoTraitorPlayers"));
return;
}
// Dialog for choosing which player to transfer to
String option = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- "Choose the player to gain ownership of this unit (" + e.getDisplayName() + ") when it turns traitor",
- "Traitor",
- JOptionPane.QUESTION_MESSAGE,
- null,
- options,
- options[0]);
+ "Choose the player to gain ownership of this unit (" + e.getDisplayName() + ") when it turns traitor",
+ "Traitor",
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ options,
+ options[0]);
// Verify that we have a valid option...
if (option != null) {
@@ -7083,53 +7463,34 @@ public synchronized void actionPerformed(ActionEvent ev) {
// And now we perform the actual transfer
int confirm = JOptionPane.showConfirmDialog(clientgui.getFrame(),
- e.getDisplayName() + " will switch to " + name + "'s side at the end of this turn. Are you sure?",
- "Confirm",
- JOptionPane.YES_NO_OPTION);
+ e.getDisplayName() + " will switch to " + name + "'s side at the end of this turn. Are you sure?",
+ "Confirm",
+ JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
// the /traitor command sets the pending switch on the server's own copy of the unit, where the
// END phase resolves it; sending the whole unit back for one field would carry stale state along
LOGGER.info("[Traitor] Requesting switch of {} (unit id {}) to player {} ({})",
- e.getDisplayName(), e.getId(), id, name);
+ e.getDisplayName(), e.getId(), id, name);
clientgui.getClient().sendChat(String.format("/traitor %d %d", e.getId(), id));
}
}
} else if (actionCmd.equals(MoveCommand.MOVE_CHAFF.getCmd())) {
if (clientgui.doYesNoDialog(Messages.getString("MovementDisplay.ConfirmChaff.title"),
- Messages.getString("MovementDisplay.ConfirmChaff.message"))) {
+ Messages.getString("MovementDisplay.ConfirmChaff.message"))) {
isUsingChaff = true;
}
+ } else if (actionCmd.equals(MoveCommand.MOVE_CLEAR_DEPLOY.getCmd())) {
+ clear(false);
+ Entity currentlySelectedEntity = currentEntity();
+ if (currentlySelectedEntity != null) {
+ lastDeploymentOption = null;
+ lastHexDeploymentOptions.clear();
+ originalFacing = -1;
+ }
+
}
- updateProneButtons();
- updateRACButton();
- updateSearchlightButton();
- updateElevationButtons();
- updateElevatorButtons();
- updateTakeOffButtons();
- updateLandButtons();
- updateFlyOffButton();
- updateLaunchButton();
- updateLoadButtons();
- updateDropButton();
- updateConvertModeButton();
- updateRecklessButton();
- updateHoverButton();
- updateManeuverButton();
- updateEvadeButton();
- updateBootleggerButton();
- updateShutdownButton();
- updateStartupButton();
- updateSelfDestructButton();
- updateTraitorButton();
- updateSpeedButtons();
- updateThrustButton();
- updateRollButton();
- updateTakeCoverButton();
- updateLayMineButton();
- updateBraceButton();
- checkFuel();
- checkOOC();
- checkAtmosphere();
+
+ refreshButtons();
// If small craft / DropShip that has unloaded units, then only allowed to
// unload more
@@ -7142,7 +7503,6 @@ public synchronized void actionPerformed(ActionEvent ev) {
/**
* @param ce The entity to test
- *
* @return True when the given unit is a Mek with both jump jets and mechanical jump boosters.
*/
private boolean mustChooseJumpType(Entity ce) {
@@ -7156,7 +7516,7 @@ private void processPickupCargoCommand() {
var options = game.getGroundObjects(finalPosition());
options.addAll(game.getEntitiesVector(finalPosition()).stream().filter(Entity::isCarryableObject).toList());
var displayedOptions =
- options.stream().filter(o -> currentEntity().canPickupCarryableObject(o)).toList();
+ options.stream().filter(o -> currentEntity().canPickupCarryableObject(o)).toList();
// if there's only one thing to pick up, pick it up. regardless of how many objects we are picking up, we may
// have to choose the location with which to pick it up
@@ -7177,12 +7537,12 @@ private void processPickupCargoCommand() {
String title = "Choose Cargo to Pick Up";
String body = "Choose the cargo to pick up:";
ICarryable option = (ICarryable) JOptionPane.showInputDialog(clientgui.getFrame(),
- body,
- title,
- JOptionPane.QUESTION_MESSAGE,
- null,
- displayedOptions.toArray(),
- displayedOptions.getFirst());
+ body,
+ title,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ displayedOptions.toArray(),
+ displayedOptions.getFirst());
if (option != null) {
Integer pickupLocation = getPickupLocation(option);
@@ -7215,12 +7575,12 @@ private Integer getPickupLocation(ICarryable cargo) {
String title = "Choose Pickup Location";
String body = "Choose the location with which to pick up cargo:";
String locationChoice = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- body,
- title,
- JOptionPane.QUESTION_MESSAGE,
- null,
- locationMap.keySet().toArray(),
- locationMap.keySet().toArray()[0]);
+ body,
+ title,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ locationMap.keySet().toArray(),
+ locationMap.keySet().toArray()[0]);
if (locationChoice != null) {
pickupLocation = locationMap.get(locationChoice);
@@ -7244,7 +7604,7 @@ private void adjustConvertSteps(EntityMovementMode endMode) {
// Since conversion is not allowed in water, we shouldn't have to deal with the possibility of `swim` modes.
// Account for grounded LAMs in fighter mode with movement type wheeled
if (currentEntity().getMovementMode() == endMode || (currentEntity().isAero()
- && endMode == EntityMovementMode.AERODYNE)) {
+ && endMode == EntityMovementMode.AERODYNE)) {
cmd.clear();
return;
}
@@ -7301,16 +7661,16 @@ public boolean accept(Entity acc) {
buffer = entity.getDisplayName();
} else {
buffer = Messages.getString("MovementDisplay.EntityAt",
- entity.getDisplayName(),
- transport.getPosition().getBoardNum());
+ entity.getDisplayName(),
+ transport.getPosition().getBoardNum());
}
names[index] = buffer;
}
// Show the choices to the player
int[] indexes = clientgui.doChoiceDialog(Messages.getString("MovementDisplay.UnloadStrandedUnitsDialog.title"),
- Messages.getString("MovementDisplay.UnloadStrandedUnitsDialog.message"),
- names);
+ Messages.getString("MovementDisplay.UnloadStrandedUnitsDialog.message"),
+ names);
// Convert the indexes into selected entity IDs and tell the server.
int[] ids = null;
@@ -7467,10 +7827,11 @@ private void setFlyOffEnabled(boolean enabled) {
setFlyOffEnabled(enabled, false);
}
- private void setFlyOffEnabled(boolean enabled, boolean isClimbOut) {
+ private void setFlyOffEnabled(boolean enabled,
+ boolean isClimbOut) {
String label = isClimbOut
- ? Messages.getString("MovementDisplay.butClimbOut")
- : Messages.getString("MovementDisplay.MoveOff");
+ ? Messages.getString("MovementDisplay.butClimbOut")
+ : Messages.getString("MovementDisplay.MoveOff");
getBtn(MoveCommand.MOVE_FLY_OFF).setText(label);
getBtn(MoveCommand.MOVE_FLY_OFF).setEnabled(enabled);
clientgui.getMenuBar().setEnabled(MoveCommand.MOVE_FLY_OFF.getCmd(), enabled);
@@ -7506,8 +7867,8 @@ private void handleFlyOffOrClimbOut() {
// Check if can climb out (altitude 10 on ground map, requires both return flyover and climb out options)
boolean canClimbOut = (altitude == 10) && isGroundBoard
- && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER)
- && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_CLIMB_OUT);
+ && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER)
+ && game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_CLIMB_OUT);
// Check if can fly off edge (same logic as updateFlyOffButton)
boolean canFlyOffEdge = false;
@@ -7516,25 +7877,25 @@ private void handleFlyOffOrClimbOut() {
if (aero.isSpheroid() && !board.isSpace()) {
// Spheroids in atmosphere just need to be on edge
canFlyOffEdge = (entity.getWalkMP() > 0) &&
- ((position.getX() == 0) ||
- (position.getX() == (board.getWidth() - 1)) ||
- (position.getY() == 0) ||
- (position.getY() == (board.getHeight() - 1)));
+ ((position.getX() == 0) ||
+ (position.getX() == (board.getWidth() - 1)) ||
+ (position.getY() == 0) ||
+ (position.getY() == (board.getHeight() - 1)));
} else {
// Aerodynes and space - need correct facing and velocity
boolean evenX = (position.getX() % 2) == 0;
canFlyOffEdge = (velocityLeft > 0) &&
- (((position.getX() == 0) && ((facing == 5) || (facing == 4))) ||
- ((position.getX() == (board.getWidth() - 1)) &&
+ (((position.getX() == 0) && ((facing == 5) || (facing == 4))) ||
+ ((position.getX() == (board.getWidth() - 1)) &&
((facing == 1) || (facing == 2))) ||
- ((position.getY() == 0) &&
+ ((position.getY() == 0) &&
((facing == 1) || (facing == 5) || (facing == 0)) &&
evenX) ||
- ((position.getY() == 0) && (facing == 0)) ||
- ((position.getY() == (board.getHeight() - 1)) &&
+ ((position.getY() == 0) && (facing == 0)) ||
+ ((position.getY() == (board.getHeight() - 1)) &&
((facing == 2) || (facing == 3) || (facing == 4)) &&
!evenX) ||
- ((position.getY() == (board.getHeight() - 1)) && (facing == 3)));
+ ((position.getY() == (board.getHeight() - 1)) && (facing == 3)));
}
}
@@ -7544,8 +7905,8 @@ private void handleFlyOffOrClimbOut() {
// Both options available - ask player to choose
// Yes = climb out, No = fly off edge
doClimbOut = clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.ClimbOrFlyOff.title"),
- Messages.getString("MovementDisplay.ClimbOrFlyOff.message"));
+ Messages.getString("MovementDisplay.ClimbOrFlyOff.title"),
+ Messages.getString("MovementDisplay.ClimbOrFlyOff.message"));
} else if (canClimbOut) {
doClimbOut = true;
}
@@ -7553,8 +7914,8 @@ private void handleFlyOffOrClimbOut() {
if (doClimbOut) {
// Climb out path
if (clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.ClimbOutDialog.title"),
- Messages.getString("MovementDisplay.ClimbOutDialog.message"))) {
+ Messages.getString("MovementDisplay.ClimbOutDialog.title"),
+ Messages.getString("MovementDisplay.ClimbOutDialog.message"))) {
IGameOptions opts = game.getOptions();
if (opts.booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER)) {
@@ -7572,12 +7933,12 @@ private void handleFlyOffOrClimbOut() {
} else {
// Normal fly off edge path (existing behavior)
if (clientgui.doYesNoDialog(
- Messages.getString("MovementDisplay.FlyOffDialog.title"),
- Messages.getString("MovementDisplay.FlyOffDialog.message"))) {
+ Messages.getString("MovementDisplay.FlyOffDialog.title"),
+ Messages.getString("MovementDisplay.FlyOffDialog.message"))) {
IGameOptions opts = game.getOptions();
if (opts.booleanOption(OptionsConstants.ADVANCED_AERO_RULES_RETURN_FLYOVER) &&
- clientgui.doYesNoDialog(
+ clientgui.doYesNoDialog(
Messages.getString("MovementDisplay.ReturnFly.title"),
Messages.getString("MovementDisplay.ReturnFly.message"))) {
addStepToMovePath(MoveStepType.RETURN);
@@ -7597,21 +7958,21 @@ private void handleFlyOffOrClimbOut() {
@Deprecated(since = "0.51.0", forRemoval = true)
private OffBoardDirection showEdgeSelectionDialog() {
String[] options = {
- Messages.getString("MovementDisplay.Edge.North"),
- Messages.getString("MovementDisplay.Edge.South"),
- Messages.getString("MovementDisplay.Edge.East"),
- Messages.getString("MovementDisplay.Edge.West")
+ Messages.getString("MovementDisplay.Edge.North"),
+ Messages.getString("MovementDisplay.Edge.South"),
+ Messages.getString("MovementDisplay.Edge.East"),
+ Messages.getString("MovementDisplay.Edge.West")
};
int result = JOptionPane.showOptionDialog(
- clientgui.getFrame(),
- Messages.getString("MovementDisplay.ClimbOutEdge.message"),
- Messages.getString("MovementDisplay.ClimbOutEdge.title"),
- JOptionPane.DEFAULT_OPTION,
- JOptionPane.QUESTION_MESSAGE,
- null,
- options,
- options[0]);
+ clientgui.getFrame(),
+ Messages.getString("MovementDisplay.ClimbOutEdge.message"),
+ Messages.getString("MovementDisplay.ClimbOutEdge.title"),
+ JOptionPane.DEFAULT_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ options,
+ options[0]);
return switch (result) {
case 0 -> OffBoardDirection.NORTH;
@@ -7647,7 +8008,8 @@ private void setChaffEnabled(boolean enabled) {
clientgui.getMenuBar().setEnabled(MoveCommand.MOVE_CHAFF.getCmd(), enabled);
}
- private void setSearchlightEnabled(boolean enabled, boolean state) {
+ private void setSearchlightEnabled(boolean enabled,
+ boolean state) {
if (state) {
getBtn(MoveCommand.MOVE_SEARCHLIGHT).setText(Messages.getString("MovementDisplay.butSearchlightOff"));
} else {
@@ -7873,9 +8235,9 @@ private void updateTurnButton() {
}
setTurnEnabled(!currentEntity.isImmobile() &&
- !currentEntity.isStuck() &&
- ((currentEntity.getWalkMP() > 0) || (currentEntity.getJumpMP() > 0)) &&
- !(cmd.isJumping() && (currentEntity instanceof Mek) && (jumpSubGear == GEAR_SUB_MEK_BOOSTERS)));
+ !currentEntity.isStuck() &&
+ ((currentEntity.getWalkMP() > 0) || (currentEntity.getJumpMP() > 0)) &&
+ !(cmd.isJumping() && (currentEntity instanceof Mek) && (jumpSubGear == GEAR_SUB_MEK_BOOSTERS)));
}
@Nullable
@@ -7896,7 +8258,8 @@ private void performAeroLand(LandingDirection landingDirection) {
}
}
- private void finalizeAeroLandFromGroundMap(IAero aero, LandingDirection landingDirection) {
+ private void finalizeAeroLandFromGroundMap(IAero aero,
+ LandingDirection landingDirection) {
if (!game.isOnGroundMap((Entity) aero)) {
LOGGER.warn("Selected aero landing from ground map for unit that isn't on a ground map!");
return;
@@ -7904,7 +8267,8 @@ private void finalizeAeroLandFromGroundMap(IAero aero, LandingDirection landingD
String failMessage = aero.hasRoomForLanding(landingDirection);
if (failMessage != null) {
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.NoLandingDialog.message", failMessage), currentEntity());
+ Messages.getString("MovementDisplay.NoLandingDialog.message", failMessage),
+ currentEntity());
} else {
landingConfirmation.ask();
if (landingConfirmation.isOkSelected()) {
@@ -7915,11 +8279,12 @@ private void finalizeAeroLandFromGroundMap(IAero aero, LandingDirection landingD
}
}
- private void startAeroLandNoGroundMove(Entity entity, LandingDirection landingDirection) {
+ private void startAeroLandNoGroundMove(Entity entity,
+ LandingDirection landingDirection) {
if (!game.hasBoardLocationOf(entity)
- || !entity.isAirborne()
- || !game.isOnAtmosphericMap(entity)
- || !game.getBoard(entity).getEmbeddedBoardHexes().contains(finalPosition())) {
+ || !entity.isAirborne()
+ || !game.isOnAtmosphericMap(entity)
+ || !game.getBoard(entity).getEmbeddedBoardHexes().contains(finalPosition())) {
LOGGER.warn("No ground map to land on in the present hex!");
return;
}
@@ -7933,7 +8298,8 @@ private void startAeroLandNoGroundMove(Entity entity, LandingDirection landingDi
new LandingHexNotice(clientgui).show();
}
- private void finalizeAeroLandFromAtmosphereMap(IAero aero, BoardViewEvent event) {
+ private void finalizeAeroLandFromAtmosphereMap(IAero aero,
+ BoardViewEvent event) {
if (!hasLandingMoveStep()) {
LOGGER.error("No landing move path; can't determine if vertical or horizontal landing!");
return;
@@ -7942,7 +8308,8 @@ private void finalizeAeroLandFromAtmosphereMap(IAero aero, BoardViewEvent event)
String failMessage = aero.hasRoomForLanding(event.getBoardId(), event.getCoords(), landingDirection);
if (failMessage != null) {
clientgui.addToast(ToastLevel.ERROR,
- Messages.getString("MovementDisplay.NoLandingDialog.message", failMessage), currentEntity());
+ Messages.getString("MovementDisplay.NoLandingDialog.message", failMessage),
+ currentEntity());
} else {
landingConfirmation.ask();
if (landingConfirmation.isOkSelected()) {
@@ -7979,7 +8346,7 @@ private void startEscapePodHexSelection(Tank tank) {
List hexesAtRange = tankPos.allAtDistance(range);
for (Coords coords : hexesAtRange) {
if (board.contains(coords) &&
- ComputeArc.isInArc(tankPos, facing, coords, Compute.ARC_REAR)) {
+ ComputeArc.isInArc(tankPos, facing, coords, Compute.ARC_REAR)) {
validEscapePodHexes.add(coords);
}
}
@@ -8054,7 +8421,7 @@ private void handleBridgeSelectionClick(Coords clicked) {
// player WHY the hex is not valid for this step rather than just that it isn't.
String reason = bridgeInvalidClickReason(clicked);
LOGGER.debug("[BuildBridge] ignoring {} at stage {} - {} (valid: {})", clicked, bridgeSelectionStage,
- reason, validBridgeSelectionHexes);
+ reason, validBridgeSelectionHexes);
clientgui.addToast(ToastLevel.WARNING, reason, currentEntity());
return;
}
@@ -8062,7 +8429,8 @@ private void handleBridgeSelectionClick(Coords clicked) {
switch (bridgeSelectionStage) {
case SECTION -> advanceToBridgeDirectionStage(clicked);
case DIRECTION -> resolveBridgeDirection(clicked);
- case NONE -> {}
+ case NONE -> {
+ }
}
}
@@ -8070,7 +8438,6 @@ private void handleBridgeSelectionClick(Coords clicked) {
* Builds a player-facing explanation of why the clicked hex is not valid for the current bridge selection stage.
*
* @param clicked the rejected hex
- *
* @return a localized reason, ending with how to proceed
*/
private String bridgeInvalidClickReason(Coords clicked) {
@@ -8088,7 +8455,9 @@ private String bridgeInvalidClickReason(Coords clicked) {
/**
* @return why the clicked hex cannot be the bridge hex (stage 1)
*/
- private String bridgeSectionClickReason(ConvInfantry convInfantry, Board board, Coords clicked) {
+ private String bridgeSectionClickReason(ConvInfantry convInfantry,
+ Board board,
+ Coords clicked) {
if ((convInfantry.getPosition() == null) || (convInfantry.getPosition().distance(clicked) != 1)) {
return Messages.getString("MovementDisplay.BuildBridge.reason.middleNotAdjacent");
}
@@ -8117,11 +8486,11 @@ private String bridgeSectionClickReason(ConvInfantry convInfantry, Board board,
*
* @param board the board the gap is on
* @param clicked the rejected hex
- *
* @return a localized repair reason, or null if the hex is not next to a bridge at all (the caller falls back to
- * the generic reason)
+ * the generic reason)
*/
- private @Nullable String bridgeRepairClickReason(Board board, Coords clicked) {
+ private @Nullable String bridgeRepairClickReason(Board board,
+ Coords clicked) {
for (int spanDirection = 0; spanDirection < 6; spanDirection++) {
Hex neighbor = board.getHex(clicked.translated(spanDirection));
if ((neighbor == null) || !neighbor.containsTerrain(Terrains.BRIDGE)) {
@@ -8135,9 +8504,9 @@ private String bridgeSectionClickReason(ConvInfantry convInfantry, Board board,
// The hex is the broken section of this bridge; report why the straight repair across the span fails.
int straightExits = BridgeConstruction.exitsFor(spanDirection, backDirection);
BridgeConstruction.BridgeRepairIssue issue = BridgeConstruction.bridgeRepairIssue(board, clicked,
- straightExits);
+ straightExits);
LOGGER.debug("[BridgeRepair] {} rejected as a repair site: straight orientation across the span toward {} "
- + "gives {}", clicked, clicked.translated(spanDirection), issue);
+ + "gives {}", clicked, clicked.translated(spanDirection), issue);
return switch (issue) {
case VALID -> null;
case FAR_SIDE_UNANCHORED -> Messages.getString("MovementDisplay.BuildBridge.reason.repairFarSide");
@@ -8150,9 +8519,11 @@ private String bridgeSectionClickReason(ConvInfantry convInfantry, Board board,
/**
* @return why the clicked far end is not a valid bridge end for the chosen bridge hex (stage 2), using the site
- * validator's reason for the span from the engineer's hex to the clicked far end
+ * validator's reason for the span from the engineer's hex to the clicked far end
*/
- private String bridgeDirectionClickReason(ConvInfantry convInfantry, Board board, Coords clicked) {
+ private String bridgeDirectionClickReason(ConvInfantry convInfantry,
+ Board board,
+ Coords clicked) {
Coords middle = selectedBridgeMiddle;
if (middle.distance(clicked) != 1) {
return Messages.getString("MovementDisplay.BuildBridge.reason.endNotAdjacent");
@@ -8168,15 +8539,17 @@ private String bridgeDirectionClickReason(ConvInfantry convInfantry, Board board
/**
* @return the localized reason a bridge span at the given hex and exits is not a valid site
*/
- private String bridgeSiteIssueReason(Board board, Coords middle, int exits) {
+ private String bridgeSiteIssueReason(Board board,
+ Coords middle,
+ int exits) {
BridgeConstruction.BridgeSiteIssue issue = BridgeConstruction.bridgeSiteIssue(board, middle, exits);
return switch (issue) {
case OFF_BOARD -> Messages.getString("MovementDisplay.BuildBridge.reason.offBoard");
case OCCUPIED -> Messages.getString("MovementDisplay.BuildBridge.reason.occupied");
case RIMS_TOO_STEEP -> Messages.getString("MovementDisplay.BuildBridge.reason.tooSteep");
case NO_ANCHOR -> BridgeConstruction.isOverWater(board.getHex(middle))
- ? Messages.getString("MovementDisplay.BuildBridge.reason.noAnchorWater")
- : Messages.getString("MovementDisplay.BuildBridge.reason.noAnchorDry");
+ ? Messages.getString("MovementDisplay.BuildBridge.reason.noAnchorWater")
+ : Messages.getString("MovementDisplay.BuildBridge.reason.noAnchorDry");
case BAD_EXITS, VALID -> Messages.getString("MovementDisplay.BuildBridge.invalidHex");
};
}
@@ -8189,7 +8562,8 @@ private String bridgeSiteIssueReason(Board board, Coords middle, int exits) {
* @param selectedUnit the currently selected unit, or null if none
* @param gameOptions the active game options
*/
- private void updateBridgeBuildButton(@Nullable Entity selectedUnit, GameOptions gameOptions) {
+ private void updateBridgeBuildButton(@Nullable Entity selectedUnit,
+ GameOptions gameOptions) {
MegaMekButton button = getBtn(MoveCommand.MOVE_BUILD_BRIDGE);
if ((selectedUnit instanceof ConvInfantry building) && building.isBuildingBridge()) {
// Actively building: the button opens a chooser (Pause / Dismantle / Abandon)
@@ -8197,7 +8571,7 @@ private void updateBridgeBuildButton(@Nullable Entity selectedUnit, GameOptions
button.setToolTipText(Messages.getString("MovementDisplay.moveCancelBridge.tooltip"));
button.setEnabled(true);
} else if ((selectedUnit instanceof ConvInfantry resuming)
- && (resuming.isDismantlingBridge() || resuming.isBridgePaused())) {
+ && (resuming.isDismantlingBridge() || resuming.isBridgePaused())) {
// Paused or dismantling: the button opens a chooser (Resume / Abandon)
button.setText(Messages.getString("MovementDisplay.moveResumeBridge"));
button.setToolTipText(Messages.getString("MovementDisplay.moveResumeBridge.tooltip"));
@@ -8207,9 +8581,9 @@ private void updateBridgeBuildButton(@Nullable Entity selectedUnit, GameOptions
// label reflects both so players know the engineer can do either.
boolean repairAllowed = gameOptions.booleanOption(OptionsConstants.UNOFFICIAL_BRIDGE_REPAIR_ENGINEERS);
button.setText(Messages.getString(repairAllowed ? "MovementDisplay.moveBuildRepairBridge"
- : "MovementDisplay.moveBuildBridge"));
+ : "MovementDisplay.moveBuildBridge"));
button.setToolTipText(Messages.getString(repairAllowed ? "MovementDisplay.moveBuildRepairBridge.tooltip"
- : "MovementDisplay.moveBuildBridge.tooltip"));
+ : "MovementDisplay.moveBuildBridge.tooltip"));
button.setEnabled(canSelectBridgeBuild(selectedUnit, gameOptions));
}
}
@@ -8221,10 +8595,10 @@ private void updateBridgeBuildButton(@Nullable Entity selectedUnit, GameOptions
*
* @param unit the currently selected unit, or null if none
* @param gameOptions the active game options
- *
* @return {@code true} if the Build Bridge button should be enabled.
*/
- private boolean canSelectBridgeBuild(@Nullable Entity unit, GameOptions gameOptions) {
+ private boolean canSelectBridgeBuild(@Nullable Entity unit,
+ GameOptions gameOptions) {
if (!(unit instanceof ConvInfantry convInfantry)) {
return false;
}
@@ -8232,12 +8606,12 @@ private boolean canSelectBridgeBuild(@Nullable Entity unit, GameOptions gameOpti
String unitName = unit.getShortName();
if (!gameOptions.booleanOption(OptionsConstants.ADVANCED_BRIDGE_BUILDING_ENGINEERS)) {
LOGGER.debug("[BuildBridge] {}: button disabled - game option {} is off", unitName,
- OptionsConstants.ADVANCED_BRIDGE_BUILDING_ENGINEERS);
+ OptionsConstants.ADVANCED_BRIDGE_BUILDING_ENGINEERS);
return false;
}
if (!convInfantry.hasSpecialization(ConvInfantry.BRIDGE_ENGINEERS)) {
LOGGER.debug("[BuildBridge] {}: button disabled - no Bridge-Building Engineers specialization "
- + "(specialization bitmask is {})", unitName, convInfantry.getSpecializations());
+ + "(specialization bitmask is {})", unitName, convInfantry.getSpecializations());
return false;
}
if (!convInfantry.hasBridgeKit()) {
@@ -8246,30 +8620,30 @@ private boolean canSelectBridgeBuild(@Nullable Entity unit, GameOptions gameOpti
}
if (!convInfantry.canAffordBridge(ConvInfantry.BRIDGE_TYPE_LIGHT)) {
LOGGER.debug("[BuildBridge] {}: button disabled - bridge building budget spent ({} points left)",
- unitName, convInfantry.getBridgeBuildPoints());
+ unitName, convInfantry.getBridgeBuildPoints());
return false;
}
if (convInfantry.isBuildingBridge()) {
LOGGER.debug("[BuildBridge] {}: button disabled - already raising a bridge (turn {} of {})", unitName,
- convInfantry.getBridgeBuildTurns(), convInfantry.getBridgeBuildRequiredTurns());
+ convInfantry.getBridgeBuildTurns(), convInfantry.getBridgeBuildRequiredTurns());
return false;
}
// The platoon must be at ground level, or standing on a bridge deck - the latter lets engineers build the
// next span of a multi-hex crossing while standing on the span they just finished (TO:AUE).
Hex unitHex = game.getHex(unit.getPosition(), unit.getBoardId());
boolean onBridgeDeck = (unitHex != null) && unitHex.containsTerrain(Terrains.BRIDGE)
- && (unit.getElevation() == unitHex.terrainLevel(Terrains.BRIDGE_ELEV));
+ && (unit.getElevation() == unitHex.terrainLevel(Terrains.BRIDGE_ELEV));
if (!game.isOnGroundMap(unit) || (unit.getAltitude() != 0)
- || ((unit.getElevation() != 0) && !onBridgeDeck)) {
+ || ((unit.getElevation() != 0) && !onBridgeDeck)) {
LOGGER.debug("[BuildBridge] {}: button disabled - not at ground level or on a bridge deck "
- + "(altitude {}, elevation {}, onBridgeDeck {})", unitName, unit.getAltitude(),
- unit.getElevation(), onBridgeDeck);
+ + "(altitude {}, elevation {}, onBridgeDeck {})", unitName, unit.getAltitude(),
+ unit.getElevation(), onBridgeDeck);
return false;
}
List plans = computeValidBridgePlans(convInfantry);
if (plans.isEmpty()) {
LOGGER.debug("[BuildBridge] {}: button disabled - no valid bridge can be raised adjacent to {}",
- unitName, unit.getPosition());
+ unitName, unit.getPosition());
return false;
}
LOGGER.debug("[BuildBridge] {}: button enabled - {} valid bridge plan(s)", unitName, plans.size());
@@ -8284,7 +8658,6 @@ private boolean canSelectBridgeBuild(@Nullable Entity unit, GameOptions gameOpti
* later. TO:AUE.
*
* @param convInfantry the engineer platoon
- *
* @return the valid bridge plans, possibly empty
*/
private List computeValidBridgePlans(ConvInfantry convInfantry) {
@@ -8335,11 +8708,12 @@ private List computeValidBridgePlans(ConvInfantry convInfantry)
* @param board the board the gap is on
* @param engineerPosition the engineer platoon's hex
* @param middle the candidate gap hex (adjacent to the engineer)
- *
* @return {@code true} if the hex is a repairable gap (at least one repair plan was added)
*/
- private boolean addRepairPlansForGap(List plans, Board board, Coords engineerPosition,
- Coords middle) {
+ private boolean addRepairPlansForGap(List plans,
+ Board board,
+ Coords engineerPosition,
+ Coords middle) {
int originSide = middle.direction(engineerPosition);
boolean isRepairableGap = false;
for (int firstSide = 0; firstSide < 6; firstSide++) {
@@ -8393,15 +8767,20 @@ private void showBridgeActionChooser(ConvInfantry bridgePlatoon) {
labels.add(Messages.getString("MovementDisplay.BridgeAction.keep"));
String message = (bridgePlatoon.isBridgePaused() && !bridgePlatoon.isAdjacentToBridgeSite())
- ? Messages.getString("MovementDisplay.BridgeAction.messagePausedAway")
- : Messages.getString("MovementDisplay.BridgeAction.message");
+ ? Messages.getString("MovementDisplay.BridgeAction.messagePausedAway")
+ : Messages.getString("MovementDisplay.BridgeAction.message");
Object[] options = labels.toArray();
- int choice = JOptionPane.showOptionDialog(clientgui.getFrame(), message,
- Messages.getString("MovementDisplay.BridgeAction.title"),
- JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[options.length - 1]);
+ int choice = JOptionPane.showOptionDialog(clientgui.getFrame(),
+ message,
+ Messages.getString("MovementDisplay.BridgeAction.title"),
+ JOptionPane.DEFAULT_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ options,
+ options[options.length - 1]);
if ((choice < 0) || (choice >= steps.size())) {
LOGGER.debug("[BuildBridge] {}: bridge action chooser dismissed with no change",
- bridgePlatoon.getShortName());
+ bridgePlatoon.getShortName());
return;
}
MoveStepType step = steps.get(choice);
@@ -8429,25 +8808,26 @@ private void startBridgeBuildSelection() {
choices.add(Messages.getString("MovementDisplay.BuildBridgeDialog.medium"));
}
String input = (String) JOptionPane.showInputDialog(clientgui.getFrame(),
- Messages.getString("MovementDisplay.BuildBridgeDialog.message"),
- Messages.getString("MovementDisplay.BuildBridgeDialog.title"),
- JOptionPane.QUESTION_MESSAGE,
- null,
- choices.toArray(new String[0]),
- choices.getFirst());
+ Messages.getString(
+ "MovementDisplay.BuildBridgeDialog.message"),
+ Messages.getString("MovementDisplay.BuildBridgeDialog.title"),
+ JOptionPane.QUESTION_MESSAGE,
+ null,
+ choices.toArray(new String[0]),
+ choices.getFirst());
if (input == null) {
return;
}
selectedBridgeType = input.equals(Messages.getString("MovementDisplay.BuildBridgeDialog.medium"))
- ? ConvInfantry.BRIDGE_TYPE_MEDIUM : ConvInfantry.BRIDGE_TYPE_LIGHT;
+ ? ConvInfantry.BRIDGE_TYPE_MEDIUM : ConvInfantry.BRIDGE_TYPE_LIGHT;
LOGGER.debug("[BuildBridge] {}: chose bridge type {} (1=light, 2=medium)", convInfantry.getShortName(),
- selectedBridgeType);
+ selectedBridgeType);
bridgeBuildPlans.clear();
bridgeBuildPlans.addAll(computeValidBridgePlans(convInfantry));
if (bridgeBuildPlans.isEmpty()) {
LOGGER.debug("[BuildBridge] {}: selection aborted - no valid bridge plan adjacent to {}",
- convInfantry.getShortName(), convInfantry.getPosition());
+ convInfantry.getShortName(), convInfantry.getPosition());
return;
}
@@ -8485,9 +8865,9 @@ private void advanceToBridgeDirectionStage(Coords middle) {
bridgeSelectionStage = BridgeSelectionStage.DIRECTION;
showBridgeSelectionHexes(convInfantry, farEnds, "MovementDisplay.BuildBridge.selectDirection");
clientgui.addToast(ToastLevel.INFO, Messages.getString("MovementDisplay.BuildBridge.toast.sectionSet",
- middle.getBoardNum()), convInfantry);
+ middle.getBoardNum()), convInfantry);
LOGGER.debug("[BuildBridge] {}: bridge hex {} set, selecting far end from {}",
- convInfantry.getShortName(), middle, farEnds);
+ convInfantry.getShortName(), middle, farEnds);
}
/**
@@ -8514,21 +8894,22 @@ private void resolveBridgeDirection(Coords farEnd) {
* @param middle the hex the bridge will occupy
* @param exits the exits bitmask of the two hexsides the bridge connects
*/
- private void declareBridgeBuild(Coords middle, int exits) {
+ private void declareBridgeBuild(Coords middle,
+ int exits) {
int bridgeType = selectedBridgeType;
Entity engineer = currentEntity();
// Rebuilding a destroyed section (unofficial repair option) reads differently from raising a new bridge; the
// server makes the same determination from the site, this only chooses the player-facing wording.
boolean isRepair = game.getOptions().booleanOption(OptionsConstants.UNOFFICIAL_BRIDGE_REPAIR_ENGINEERS)
- && BridgeConstruction.isBridgeRepairSite(game.getBoard(engineer == null ? 0 : engineer.getBoardId()),
- middle, exits);
+ && BridgeConstruction.isBridgeRepairSite(game.getBoard(engineer == null ? 0 : engineer.getBoardId()),
+ middle, exits);
cancelBridgeBuildSelection();
clear();
LOGGER.info("[BuildBridge] declaring bridge {}: bridge hex {}, exits bitmask {}, type {} (1=light, 2=medium)",
- isRepair ? "repair" : "build", middle, exits, bridgeType);
+ isRepair ? "repair" : "build", middle, exits, bridgeType);
Map bridgeData = new HashMap<>();
bridgeData.put(MoveStep.BRIDGE_TARGET_X_KEY, middle.getX());
bridgeData.put(MoveStep.BRIDGE_TARGET_Y_KEY, middle.getY());
@@ -8537,9 +8918,11 @@ private void declareBridgeBuild(Coords middle, int exits) {
addStepToMovePath(MoveStepType.BUILD_BRIDGE, bridgeData);
if (engineer != null) {
String startToastKey = isRepair ? "MovementDisplay.repairBridge.toast.start"
- : "MovementDisplay.buildBridge.toast.start";
+ : "MovementDisplay.buildBridge.toast.start";
clientgui.addToast(ToastLevel.INFO, Messages.getString(startToastKey,
- engineer.getShortName(), middle.getBoardNum(), ConvInfantry.BRIDGE_BUILD_TURNS), engineer);
+ engineer.getShortName(),
+ middle.getBoardNum(),
+ ConvInfantry.BRIDGE_BUILD_TURNS), engineer);
}
ready();
}
@@ -8563,10 +8946,12 @@ private void cancelBridgeBuildSelection() {
* @param hexes the valid hexes to highlight for this stage
* @param statusBarKey the message key for the stage's status bar prompt
*/
- private void showBridgeSelectionHexes(ConvInfantry convInfantry, Set hexes, String statusBarKey) {
+ private void showBridgeSelectionHexes(ConvInfantry convInfantry,
+ Set hexes,
+ String statusBarKey) {
if (hexes.isEmpty()) {
LOGGER.debug("[BuildBridge] {}: selection aborted - no valid hexes for stage {}",
- convInfantry.getShortName(), bridgeSelectionStage);
+ convInfantry.getShortName(), bridgeSelectionStage);
cancelBridgeBuildSelection();
return;
}
@@ -8579,4 +8964,25 @@ private void showBridgeSelectionHexes(ConvInfantry convInfantry, Set hex
clientgui.showMovementEnvelope(convInfantry, highlightData, GEAR_LAND);
setStatusBarText(Messages.getString(statusBarKey));
}
+
+ private void processDeploymentTurn(Entity entity,
+ Coords coords) {
+ entity.setFacing(entity.getPosition().direction(coords));
+ entity.setSecondaryFacing(entity.getFacing());
+ cmd = new MovePath(game, entity);
+ addStepToMovePath(MoveStepType.DEPLOY);
+ if (gear == GEAR_JUMP) {
+ initializeJumpMovePath();
+ }
+ clientgui.boardViews().forEach(bv -> ((BoardView) bv).redrawEntity(entity));
+ clientgui.updateFiringArc(entity);
+ clientgui.showSensorRanges(entity);
+ }
+
+ private boolean pathZeroOrDeploy() {
+ if (cmd.length() == 0 || (cmd.length() == 1 && cmd.getLastStep().getType() == MoveStepType.DEPLOY)) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/megamek/src/megamek/client/ui/panels/phaseDisplay/commands/MoveCommand.java b/megamek/src/megamek/client/ui/panels/phaseDisplay/commands/MoveCommand.java
index 9e0b714c88e..aa8ef62889a 100644
--- a/megamek/src/megamek/client/ui/panels/phaseDisplay/commands/MoveCommand.java
+++ b/megamek/src/megamek/client/ui/panels/phaseDisplay/commands/MoveCommand.java
@@ -52,8 +52,9 @@ public enum MoveCommand implements StatusBarPhaseDisplay.PhaseCommand {
MOVE_TURN("moveTurn", MovementDisplay.CMD_GROUND | MovementDisplay.CMD_AERO),
MOVE_WALK("moveWalk", MovementDisplay.CMD_GROUND),
MOVE_JUMP("moveJump",
- MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
- MOVE_BACK_UP("moveBackUp", MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_VTOL | MovementDisplay.CMD_PROTOMEK),
+ MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
+ MOVE_BACK_UP("moveBackUp",
+ MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_VTOL | MovementDisplay.CMD_PROTOMEK),
MOVE_GET_UP("moveGetUp", MovementDisplay.CMD_MEK),
MOVE_FORWARD_INI("moveForwardIni", MovementDisplay.CMD_ALL),
MOVE_CHARGE("moveCharge", MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK),
@@ -77,15 +78,16 @@ public enum MoveCommand implements StatusBarPhaseDisplay.PhaseCommand {
MOVE_ELEVATOR_DOWN("moveElevatorDown", MovementDisplay.CMD_GROUND),
MOVE_SEARCHLIGHT("moveSearchlight", MovementDisplay.CMD_GROUND),
MOVE_LAY_MINE("moveLayMine",
- MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
+ MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
MOVE_HULL_DOWN("moveHullDown", MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK),
MOVE_CLIMB_MODE("moveClimbMode",
- MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
+ MovementDisplay.CMD_MEK | MovementDisplay.CMD_TANK | MovementDisplay.CMD_INF | MovementDisplay.CMD_PROTOMEK),
MOVE_DESCEND("moveDescend", MovementDisplay.CMD_MEK),
MOVE_SWIM("moveSwim", MovementDisplay.CMD_MEK),
MOVE_SHAKE_OFF("moveShakeOff", MovementDisplay.CMD_TANK | MovementDisplay.CMD_VTOL),
MOVE_BRACE("moveBrace", MovementDisplay.CMD_MEK),
MOVE_CHAFF("moveChaff", MovementDisplay.CMD_NON_INF),
+ MOVE_CLEAR_DEPLOY("moveClearDeploy", MovementDisplay.CMD_GROUND | MovementDisplay.CMD_AERO),
// Convert command to a single button, which can cycle through modes because MovePath state is available
MOVE_MODE_CONVERT("moveModeConvert", MovementDisplay.CMD_CONVERTER),
@@ -167,7 +169,8 @@ public enum MoveCommand implements StatusBarPhaseDisplay.PhaseCommand {
*/
public int priority;
- MoveCommand(String commandString, int commandFlag) {
+ MoveCommand(String commandString,
+ int commandFlag) {
cmd = commandString;
flag = commandFlag;
priority = ordinal();
@@ -210,9 +213,9 @@ public String getHotKeyDesc() {
String msgToggleMoveJump = Messages.getString("MovementDisplay.tooltip.ToggleMoveJump");
result += " " +
- msgToggleMoveJump +
- ": " +
- KeyCommandBind.getDesc(KeyCommandBind.TOGGLE_MOVE_MODE);
+ msgToggleMoveJump +
+ ": " +
+ KeyCommandBind.getDesc(KeyCommandBind.TOGGLE_MOVE_MODE);
break;
case MOVE_BACK_UP:
result += KeyCommandBind.getDesc(KeyCommandBind.MOVE_BACKUP);
@@ -237,14 +240,13 @@ public String getHotKeyDesc() {
String msgToggleMode = Messages.getString("MovementDisplay.tooltip.ToggleMode");
result += " " +
- msgToggleMode +
- ": " +
- KeyCommandBind.getDesc(KeyCommandBind.TOGGLE_CONVERSION_MODE);
+ msgToggleMode +
+ ": " +
+ KeyCommandBind.getDesc(KeyCommandBind.TOGGLE_CONVERSION_MODE);
break;
default:
break;
}
-
return result;
}
@@ -254,10 +256,11 @@ public String getHotKeyDesc() {
* @param unitFlag The unit flag to specify what unit type the commands are for.
* @param opts A {@link GameOptions} reference for checking game options
* @param forwardIni A flag to see if we can pass the turn to a teammate
- *
* @return An array of valid commands for the given parameters
*/
- public static MoveCommand[] values(int unitFlag, GameOptions opts, boolean forwardIni) {
+ public static MoveCommand[] values(int unitFlag,
+ GameOptions opts,
+ boolean forwardIni) {
boolean selfDestruct = false;
boolean advVehicle = false;
boolean vtolStrafe = false;
diff --git a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekCellFormatter.java b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekCellFormatter.java
index e26357ed196..fe274faae51 100644
--- a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekCellFormatter.java
+++ b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekCellFormatter.java
@@ -71,28 +71,43 @@ class LobbyMekCellFormatter {
private static final GUIPreferences GUIP = GUIPreferences.getInstance();
- /** Corner of the branch drawn before a carried or towed unit. Escaped to keep the source plain ASCII. */
+ /**
+ * Corner of the branch drawn before a carried or towed unit. Escaped to keep the source plain ASCII.
+ */
private static final String BRANCH_CORNER = "\u2514";
- /** One length of branch. Repeated once per level, so a deeper load reads as a longer arm. */
+ /**
+ * One length of branch. Repeated once per level, so a deeper load reads as a longer arm.
+ */
private static final String BRANCH_ARM = "\u2500";
- /** Top of the bracket drawn on the first member of a masterless C3 network (C3i, NC3, Nova CEWS). */
+ /**
+ * Top of the bracket drawn on the first member of a masterless C3 network (C3i, NC3, Nova CEWS).
+ */
private static final String BRANCH_TOP = "\u250c";
- /** Middle rung of the bracket drawn on inner members of a masterless C3 network. */
+ /**
+ * Middle rung of the bracket drawn on inner members of a masterless C3 network.
+ */
private static final String BRANCH_TEE = "\u251c";
- /** Stops a malformed C3 master chain from spinning while counting how deep a unit sits. */
+ /**
+ * Stops a malformed C3 master chain from spinning while counting how deep a unit sits.
+ */
private static final int MAX_C3_DEPTH = 3;
- /** Stops a malformed load loop from spinning while counting how deep a unit sits. */
+ /**
+ * Stops a malformed load loop from spinning while counting how deep a unit sits.
+ */
private static final int MAX_CARRIER_DEPTH = 16;
private LobbyMekCellFormatter() {
}
- static String unitTableEntry(InGameObject unit, ChatLounge lobby, boolean forceView, boolean compactView) {
+ static String unitTableEntry(InGameObject unit,
+ ChatLounge lobby,
+ boolean forceView,
+ boolean compactView) {
if (unit instanceof Entity) {
return compactView ? formatUnitCompact((Entity) unit, lobby, forceView)
: formatUnitFull((Entity) unit, lobby, forceView);
@@ -104,7 +119,10 @@ static String unitTableEntry(InGameObject unit, ChatLounge lobby, boolean forceV
}
}
- static String pilotTableEntry(InGameObject unit, boolean compactView, boolean hide, boolean rpgSkills) {
+ static String pilotTableEntry(InGameObject unit,
+ boolean compactView,
+ boolean hide,
+ boolean rpgSkills) {
if (unit instanceof Entity) {
return compactView ? formatPilotCompact((Entity) unit, hide, rpgSkills)
: formatPilotFull((Entity) unit, hide);
@@ -117,9 +135,9 @@ static String pilotTableEntry(InGameObject unit, boolean compactView, boolean hi
}
/**
- * Returns the branch drawn in front of a unit that rides on another, indented and lengthened by how deeply it
- * sits. A Mek inside a DropShip inside a JumpShip is drawn further in than the DropShip carrying it, so a stack
- * reads as a tree rather than a flat run of identical marks.
+ * Returns the branch drawn in front of a unit that rides on another, indented and lengthened by how deeply it sits.
+ * A Mek inside a DropShip inside a JumpShip is drawn further in than the DropShip carrying it, so a stack reads as
+ * a tree rather than a flat run of identical marks.
*/
static String carriedBranch(Entity entity) {
int depth = carriedDepth(entity);
@@ -131,7 +149,9 @@ static String carriedBranch(Entity entity) {
return " ".repeat(depth) + BRANCH_CORNER + BRANCH_ARM.repeat(depth) + " ";
}
- /** How many carriers sit above this unit: 1 for a DropShip in a JumpShip, 2 for a Mek inside that DropShip. */
+ /**
+ * How many carriers sit above this unit: 1 for a DropShip in a JumpShip, 2 for a Mek inside that DropShip.
+ */
private static int carriedDepth(Entity entity) {
int depth = 0;
Entity current = entity;
@@ -149,7 +169,9 @@ private static int carriedDepth(Entity entity) {
return depth;
}
- /** The unit this one rides on, carried in a bay or towed behind, or {@code null} when neither. */
+ /**
+ * The unit this one rides on, carried in a bay or towed behind, or {@code null} when neither.
+ */
private static Entity carrierOf(Entity entity) {
if (entity.getGame() == null) {
return null;
@@ -168,8 +190,8 @@ private static Entity carrierOf(Entity entity) {
/**
* Returns the tractor heading the train this unit is towed by, or {@code null} when it is not towed.
*
- * Deployment belongs to that tractor: a train goes where it goes. A trailer only gets a setting of its own once
- * the game starts and the tractor's is copied onto it, so the lobby has to read it from the head of the train.
+ * Deployment belongs to that tractor: a train goes where it goes. A trailer only gets a setting of its own once the
+ * game starts and the tractor's is copied onto it, so the lobby has to read it from the head of the train.
*
*/
private static Entity trainHeadOf(Entity entity) {
@@ -182,11 +204,11 @@ private static Entity trainHeadOf(Entity entity) {
/**
* Returns the branch drawn in front of a C3 network member, so a network reads as the tree from the rulebook's
- * configuration diagram. The C3 sorter wrapper keeps members adjacent in hierarchy order under every sorter, so
- * the branch always points at the row above it. Hierarchical C3 draws a corner per level below the network's
- * top unit (lance masters one level in, their slaves two). C3i, NC3 and Nova CEWS networks have no master, so
- * their members are drawn as a flat bracket instead: a top corner on the first member, rungs on inner members
- * and a bottom corner on the last, showing they belong together without inventing a hierarchy.
+ * configuration diagram. The C3 sorter wrapper keeps members adjacent in hierarchy order under every sorter, so the
+ * branch always points at the row above it. Hierarchical C3 draws a corner per level below the network's top unit
+ * (lance masters one level in, their slaves two). C3i, NC3 and Nova CEWS networks have no master, so their members
+ * are drawn as a flat bracket instead: a top corner on the first member, rungs on inner members and a bottom corner
+ * on the last, showing they belong together without inventing a hierarchy.
*/
static String c3Branch(Entity entity) {
if (!entity.hasAnyC3System()) {
@@ -208,7 +230,9 @@ static String c3Branch(Entity entity) {
return " ".repeat(depth) + BRANCH_CORNER + BRANCH_ARM.repeat(depth) + " ";
}
- /** The opening corner for a unit heading a hierarchical C3 network; empty for units networked with no one. */
+ /**
+ * The opening corner for a unit heading a hierarchical C3 network; empty for units networked with no one.
+ */
private static String hierarchicalNetworkTopBranch(Entity entity) {
Game game = entity.getGame();
if ((game == null) || !entity.hasC3()) {
@@ -222,7 +246,9 @@ private static String hierarchicalNetworkTopBranch(Entity entity) {
return "";
}
- /** How many masters sit above this unit: 1 for a lance master under a company commander, 2 for its slaves. */
+ /**
+ * How many masters sit above this unit: 1 for a lance master under a company commander, 2 for its slaves.
+ */
private static int c3Depth(Entity entity) {
int depth = 0;
Entity current = entity;
@@ -240,7 +266,9 @@ private static int c3Depth(Entity entity) {
return depth;
}
- /** The flat bracket for masterless networks; empty when the unit is not networked with anyone. */
+ /**
+ * The flat bracket for masterless networks; empty when the unit is not networked with anyone.
+ */
private static String peerNetworkBracket(Entity entity) {
Game game = entity.getGame();
String netId = entity.getC3NetId();
@@ -280,7 +308,9 @@ private static String peerNetworkBracket(Entity entity) {
* Creates and returns the display content of the Unit column for the given entity and for the non-compact display
* mode. When blindDrop is true, the unit details are not given.
*/
- static String formatUnitFull(Entity entity, ChatLounge lobby, boolean forceView) {
+ static String formatUnitFull(Entity entity,
+ ChatLounge lobby,
+ boolean forceView) {
StringBuilder result = new StringBuilder("" + fontHTML());
Client client = lobby.getClientGUI().getClient();
@@ -513,7 +543,7 @@ static String formatUnitFull(Entity entity, ChatLounge lobby, boolean forceView)
}
int so = entity.getStartingOffset(true);
int sw = entity.getStartingWidth(true);
- if ((so != 0) || (sw != 3)) {
+ if ((so != 0) || !(sw == 3 || (sw == 1 && Game.rulesManager.getRulesGame().isWalkOnDeployment()))) {
result.append(", ").append(so);
result.append(", ").append(sw);
}
@@ -705,6 +735,10 @@ static String formatUnitFull(Entity entity, ChatLounge lobby, boolean forceView)
result.append(", ").append(entity.getOffBoardDistance());
}
+ if (entity.getDeployRound() == Entity.DEPLOY_ROUND_PRE_GAME) {
+ firstEntry = dotSpacer(result, firstEntry);
+ result.append(getString("ChatLounge.deploysPreGame"));
+ }
if (entity.getDeployRound() > 0) {
firstEntry = dotSpacer(result, firstEntry);
result.append(getString("ChatLounge.deploysAfterRound", entity.getDeployRound()));
@@ -783,7 +817,9 @@ static String formatUnitFull(Entity entity, ChatLounge lobby, boolean forceView)
* Creates and returns the display content of the C3-MekTree cell for the given entity and for the compact display
* mode. Assumes that no enemy or blind-drop-hidden units are provided.
*/
- static String formatUnitCompact(Entity entity, ChatLounge lobby, boolean forceView) {
+ static String formatUnitCompact(Entity entity,
+ ChatLounge lobby,
+ boolean forceView) {
Client client = lobby.getClientGUI().getClient();
Game game = client.getGame();
GameOptions options = game.getOptions();
@@ -1116,7 +1152,8 @@ static String formatUnitCompact(Entity entity, ChatLounge lobby, boolean forceVi
* Creates and returns the display content of the C3-MekTree cell for the given entity and for the compact display
* mode. Assumes that no enemy or blind-drop-hidden units are provided.
*/
- static String formatForceCompact(Force force, ChatLounge lobby) {
+ static String formatForceCompact(Force force,
+ ChatLounge lobby) {
return formatForce(force, lobby);
}
@@ -1124,11 +1161,13 @@ static String formatForceCompact(Force force, ChatLounge lobby) {
* Creates and returns the display content of the C3-MekTree cell for the given entity and for the compact display
* mode. Assumes that no enemy or blind-drop-hidden units are provided.
*/
- static String formatForceFull(Force force, ChatLounge lobby) {
+ static String formatForceFull(Force force,
+ ChatLounge lobby) {
return formatForce(force, lobby);
}
- private static String formatForce(Force force, ChatLounge lobby) {
+ private static String formatForce(Force force,
+ ChatLounge lobby) {
Client client = lobby.getClientGUI().getClient();
Game game = client.getGame();
Player localPlayer = client.getLocalPlayer();
@@ -1207,7 +1246,9 @@ private static String formatForce(Force force, ChatLounge lobby) {
* Creates and returns the display content of the Pilot column for the given entity and for the compact display
* mode. When blindDrop is true, the pilot details are not given.
*/
- static String formatPilotCompact(Entity entity, boolean blindDrop, boolean rpgSkills) {
+ static String formatPilotCompact(Entity entity,
+ boolean blindDrop,
+ boolean rpgSkills) {
Crew pilot = entity.getCrew();
StringBuilder result = new StringBuilder("");
result.append(fontHTML());
@@ -1249,7 +1290,8 @@ static String formatPilotCompact(Entity entity, boolean blindDrop, boolean rpgSk
* Creates and returns the display content of the Pilot column for the given entity and for the non-compact display
* mode. When blindDrop is true, the pilot details are not given.
*/
- static String formatPilotFull(Entity entity, boolean blindDrop) {
+ static String formatPilotFull(Entity entity,
+ boolean blindDrop) {
StringBuilder result = new StringBuilder("");
final Crew crew = entity.getCrew();
@@ -1308,26 +1350,30 @@ static String formatPilotFull(Entity entity, boolean blindDrop) {
return result.toString();
}
- static void formatSpan(StringBuilder current, Color color) {
+ static void formatSpan(StringBuilder current,
+ Color color) {
current.append("");
}
@Deprecated(since = "0.51.0", forRemoval = true)
- static void formatSpan(StringBuilder current, String hexColor) {
+ static void formatSpan(StringBuilder current,
+ String hexColor) {
current.append("");
}
@Deprecated(since = "0.51.0", forRemoval = true)
- static void fullIDString(StringBuilder current, int id) {
+ static void fullIDString(StringBuilder current,
+ int id) {
formatSpan(current, uiGray());
current.append(" [ID: ").append(id).append("]");
}
- static boolean dotSpacer(StringBuilder current, boolean firstElement) {
+ static boolean dotSpacer(StringBuilder current,
+ boolean firstElement) {
if (!firstElement) {
current.append(MekTableModel.DOT_SPACER);
}
diff --git a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekPopup.java b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekPopup.java
index 7c6cdbcf7df..dfa041cd3b4 100644
--- a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekPopup.java
+++ b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/LobbyMekPopup.java
@@ -642,6 +642,12 @@ private static JMenu deployMenu(ClientGUI clientGui, boolean enabled, ActionList
// Late deployment
JMenu lateMenu = new JMenu("Deployment round");
+ if (Game.rulesManager.getRulesGame().isWalkOnDeployment()) {
+ lateMenu.add(menuItem(Messages.getString("ChatLounge.deploysPreGame"),
+ LMP_DEPLOY + "|" + Entity.DEPLOY_ROUND_PRE_GAME + eIds,
+ true,
+ listener));
+ }
lateMenu.add(menuItem("At game start", LMP_DEPLOY + "|0" + eIds, true, listener));
for (int i = 1; i < 11; i++) {
lateMenu.add(menuItem("Before round " + i, LMP_DEPLOY + "|" + i + eIds, true, listener));
@@ -800,7 +806,7 @@ private static JMenu c3Menu(boolean enabled, Collection entities, Client
} else if (!entity.isC3CompanyCommander()
&& (entity.hasC3M() ? lanceRolesCompatible(game, entity, other)
- : other.isC3IndependentMaster())) {
+ : other.isC3IndependentMaster())) {
// Slaves connect to lance masters; masters connect to company commanders or - forming an
// All-C3-Master lance (CR p.199) - to lance masters whose dependents are all masters too.
String item = "Connect to " + other.getShortNameRaw() + idString(game, other.getId());
@@ -823,9 +829,9 @@ private static JMenu c3Menu(boolean enabled, Collection entities, Client
}
/**
- * Returns true when the joining unit's role fits the dependents already connected to the given master. A lance
- * is homogeneous (CR p.199): all C3 Slaves, or - under the All-C3-Master rule - all C3 Masters in slave roles,
- * so a master may not join a lance of slaves and vice versa.
+ * Returns true when the joining unit's role fits the dependents already connected to the given master. A lance is
+ * homogeneous (CR p.199): all C3 Slaves, or - under the All-C3-Master rule - all C3 Masters in slave roles, so a
+ * master may not join a lance of slaves and vice versa.
*/
private static boolean lanceRolesCompatible(Game game, Entity joiningUnit, Entity master) {
boolean joinerIsMaster = joiningUnit.hasC3M();
diff --git a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerSettingsDialog.java b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerSettingsDialog.java
index e9e1e998ad8..e594010b422 100644
--- a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerSettingsDialog.java
+++ b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerSettingsDialog.java
@@ -38,12 +38,7 @@
import static megamek.client.ui.util.UIUtil.teamColor;
import static megamek.client.ui.util.UIUtil.uiYellow;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.FlowLayout;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.GridLayout;
+import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.Serial;
@@ -117,7 +112,9 @@ public class PlayerSettingsDialog extends AbstractButtonDialog {
private static final String CMD_REMOVE_GROUND_OBJECT = "CMD_REMOVE_GROUND_OBJECT_%d";
private static final String CMD_REMOVE_GROUND_OBJECT_PREFIX = "CMD_REMOVE_GROUND_OBJECT_";
- public PlayerSettingsDialog(ClientGUI cg, Client cl, BoardView bv) {
+ public PlayerSettingsDialog(ClientGUI cg,
+ Client cl,
+ BoardView bv) {
super(cg.getFrame(), "PlayerSettingsDialog", "PlayerSettingsDialog.title");
client = cl;
clientgui = cg;
@@ -160,8 +157,11 @@ public PlayerSettingsDialog(ClientGUI cg, Client cl, BoardView bv) {
private static final long serialVersionUID = -333065979253244440L;
@Override
- public Component getListCellRendererComponent(JList> list, Object value, int index, boolean isSelected,
- boolean cellHasFocus) {
+ public Component getListCellRendererComponent(JList> list,
+ Object value,
+ int index,
+ boolean isSelected,
+ boolean cellHasFocus) {
if (value == null) {
setText("General");
} else {
@@ -173,7 +173,8 @@ public Component getListCellRendererComponent(JList> list, Object value, int i
private final Comparator factionSorter = new Comparator<>() {
@Override
- public int compare(FactionRecord o1, FactionRecord o2) {
+ public int compare(FactionRecord o1,
+ FactionRecord o2) {
return o1.getName(year).compareTo(o2.getName(year));
}
};
@@ -183,62 +184,86 @@ protected void okAction() {
apply();
}
- /** Returns the chosen initiative modifier. */
+ /**
+ * Returns the chosen initiative modifier.
+ */
public int getInit() {
return parseField(fldInit);
}
- /** Returns the chosen conventional mines. */
+ /**
+ * Returns the chosen conventional mines.
+ */
public int getCnvMines() {
return parseField(fldConventional);
}
- /** Returns the chosen inferno mines. */
+ /**
+ * Returns the chosen inferno mines.
+ */
public int getInfMines() {
return parseField(fldInferno);
}
- /** Returns the chosen active mines. */
+ /**
+ * Returns the chosen active mines.
+ */
public int getActMines() {
return parseField(fldActive);
}
- /** Returns the chosen vibrabombs. */
+ /**
+ * Returns the chosen vibrabombs.
+ */
public int getVibMines() {
return parseField(fldVibrabomb);
}
- /** Returns the chosen EMP mines. */
+ /**
+ * Returns the chosen EMP mines.
+ */
public int getEmpMines() {
return parseField(fldEMP);
}
- /** Returns the chosen number of fortified hexes. */
+ /**
+ * Returns the chosen number of fortified hexes.
+ */
public int getFortifiedHexes() {
return parseField(fldFortifiedHexes);
}
-
- /** Returns the chosen number of tripwires */
+
+ /**
+ * Returns the chosen number of tripwires
+ */
public int getTripwires() {
- return parseField(fldTripwires);
+ return parseField(fldTripwires);
}
-
- /** Returns the chosen number of pitfalls */
+
+ /**
+ * Returns the chosen number of pitfalls
+ */
public int getPitfalls() {
- return parseField(fldPitfalls);
+ return parseField(fldPitfalls);
}
- /** Returns the start location offset */
+ /**
+ * Returns the start location offset
+ */
public int getStartOffset() {
return parseField(txtOffset);
}
- /** Returns the player start location width */
+ /**
+ * Returns the player start location width
+ */
public int getStartWidth() {
return parseField(txtWidth);
}
- /** Returns the chosen deployment position. */
+ /**
+ * Returns the chosen deployment position.
+ */
public int getStartPos() {
return currentPlayerStartPos;
}
@@ -266,7 +291,9 @@ public SkillGenerationOptionsPanel getSkillGenerationOptionsPanel() {
return skillGenerationOptionsPanel;
}
- /** Returns the player's email address. */
+ /**
+ * Returns the player's email address.
+ */
public String getEmail() {
return fldEmail.getText().trim();
}
@@ -280,14 +307,14 @@ public String getEmail() {
// Initiative Section
private final JLabel labInit = new TipLabel(Messages.getString("PlayerSettingsDialog.initMod"),
- SwingConstants.RIGHT);
+ SwingConstants.RIGHT);
private final TipTextField fldInit = new TipTextField(3);
// Mines Section
private final JLabel labConventional = new JLabel(getString("PlayerSettingsDialog.labConventional"),
- SwingConstants.RIGHT);
+ SwingConstants.RIGHT);
private final JLabel labVibrabomb = new JLabel(getString("PlayerSettingsDialog.labVibrabomb"),
- SwingConstants.RIGHT);
+ SwingConstants.RIGHT);
private final JLabel labActive = new JLabel(getString("PlayerSettingsDialog.labActive"), SwingConstants.RIGHT);
private final JLabel labInferno = new JLabel(getString("PlayerSettingsDialog.labInferno"), SwingConstants.RIGHT);
private final JLabel labEMP = new JLabel(getString("PlayerSettingsDialog.labEMP"), SwingConstants.RIGHT);
@@ -303,7 +330,7 @@ public String getEmail() {
// Fortifications Section
private final JLabel labFortifiedHexes = new JLabel(getString("PlayerSettingsDialog.labFortifiedHexes"),
- SwingConstants.RIGHT);
+ SwingConstants.RIGHT);
private final JTextField fldFortifiedHexes = new JTextField(3);
// Skills Section
@@ -319,6 +346,8 @@ public String getEmail() {
private final JFormattedTextField txtOffset;
private final JFormattedTextField txtWidth;
+ private final JLabel labWalkOn = new JLabel();
+ private final JLabel labWalkOnMore = new JLabel();
private JSpinner spinStartingAnyNWx;
private JSpinner spinStartingAnyNWy;
private JSpinner spinStartingAnySEx;
@@ -341,7 +370,7 @@ public String getEmail() {
private transient ReconfigurationParameters rp;
private int year;
private final JLabel labelAutoconfig = new TipLabel(Messages.getString("PlayerSettingsDialog.autoConfigFaction"),
- SwingConstants.LEFT);
+ SwingConstants.LEFT);
private final JComboBox cmbFaction = new JComboBox<>();
private final JButton butAutoconfigure = new JButton(Messages.getString("PlayerSettingsDialog.autoConfig"));
private final JButton butRandomize = new JButton(Messages.getString("PlayerSettingsDialog.randomize"));
@@ -369,7 +398,10 @@ protected Container createCenterPane() {
}
mainPanel.add(startSection());
mainPanel.add(initiativeSection());
- if (Game.rulesManager.getRulesGame().allowMinefields(client.getGame().getOptions().booleanOption(OptionsConstants.ADVANCED_MINEFIELDS))) {
+ if (Game.rulesManager.getRulesGame()
+ .allowMinefields(client.getGame()
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_MINEFIELDS))) {
mainPanel.add(mineSection());
}
mainPanel.add(fortificationSection());
@@ -505,7 +537,7 @@ private void addGroundObjectToUI(ICarryable groundObject) {
gbc.gridx = 3;
JButton btnRemove = new JButton("Remove");
btnRemove.setActionCommand(String.format(CMD_REMOVE_GROUND_OBJECT,
- player.getGroundObjectsToPlace().size() - 1));
+ player.getGroundObjectsToPlace().size() - 1));
btnRemove.addActionListener(listener);
groundSectionContent.add(btnRemove, gbc);
row.add(btnRemove);
@@ -558,8 +590,8 @@ private void removeGroundObject(String command) {
// they need to
for (int componentIndex = index; componentIndex < groundSectionComponents.size(); componentIndex++) {
((JButton) groundSectionComponents.get(index).get(2)).setActionCommand(String.format(
- CMD_REMOVE_GROUND_OBJECT,
- componentIndex));
+ CMD_REMOVE_GROUND_OBJECT,
+ componentIndex));
}
validate();
@@ -592,7 +624,6 @@ private JPanel deploymentParametersPanel() {
lblOffset.setToolTipText(Messages.getString("CustomMekDialog.labDeploymentOffsetTip"));
JLabel lblWidth = new JLabel(Messages.getString("CustomMekDialog.labDeploymentWidth"));
lblWidth.setToolTipText(Messages.getString("CustomMekDialog.labDeploymentWidthTip"));
-
txtOffset.setColumns(4);
txtWidth.setColumns(4);
@@ -600,6 +631,18 @@ private JPanel deploymentParametersPanel() {
result.add(txtOffset, GBC.eol());
result.add(lblWidth, GBC.std());
result.add(txtWidth, GBC.eol());
+ result.add(labWalkOn, GBC.eol());
+ result.add(labWalkOnMore, GBC.eol());
+ if (Game.rulesManager.getRulesGame().isWalkOnDeployment()) {
+ labWalkOn.setText(Messages.getString("PlayerSettingsDialog.labWalkOnDeployment"));
+ }
+ if (Game.rulesManager.getRulesGame().restrictDeploymentWidth(player, currentPlayerStartPos)) {
+ labWalkOnMore.setText(Messages.getString("PlayerSettingsDialog.labDeploymentWidthWalkOn"));
+ txtWidth.setEnabled(false);
+ } else {
+ labWalkOnMore.setText("");
+ txtWidth.setEnabled(true);
+ }
result.add(new JLabel(" "), GBC.eol());
result.add(new JLabel(Messages.getString("CustomMekDialog.labDeploymentCustomBox")), GBC.eol());
@@ -653,7 +696,7 @@ private void apply() {
// the newly selected home edge.
OffBoardDirection direction = OffBoardDirection.translateStartPosition(getStartPos());
if (direction != OffBoardDirection.NONE &&
- gOpts.booleanOption(OptionsConstants.BASE_SET_ARTY_PLAYER_HOME_EDGE)) {
+ gOpts.booleanOption(OptionsConstants.BASE_SET_ARTY_PLAYER_HOME_EDGE)) {
for (Entity entity : client.getGame().getPlayerEntities(client.getLocalPlayer(), false)) {
if (entity.getOffBoardDirection() != OffBoardDirection.NONE) {
entity.setOffBoard(entity.getOffBoardDistance(), direction);
@@ -715,13 +758,13 @@ private JPanel mineSection() {
panContent.add(fldInferno);
panContent.add(labEMP);
panContent.add(fldEMP);
-
+
String tooltip = Messages.getString("PlayerSettingsDialog.tripwireTT");
labTripwires.setToolTipText(tooltip);
- fldTripwires.setToolTipText(tooltip);
+ fldTripwires.setToolTipText(tooltip);
panContent.add(labTripwires);
panContent.add(fldTripwires);
-
+
tooltip = Messages.getString("PlayerSettingsDialog.pitfallTT");
labPitfalls.setToolTipText(tooltip);
fldPitfalls.setToolTipText(tooltip);
@@ -786,6 +829,12 @@ private void setupValues() {
txtWidth.setText(Integer.toString(player.getStartWidth()));
txtOffset.setText(Integer.toString(player.getStartOffset()));
+ if (Game.rulesManager.getRulesGame().restrictDeploymentWidth(player, player.getStartingPos())) {
+ txtWidth.setEnabled(false);
+ } else {
+ txtWidth.setEnabled(true);
+ }
+
MapSettings ms = clientgui.getClient().getMapSettings();
int bh = ms.getBoardHeight() * ms.getMapHeight();
int bw = ms.getBoardWidth() * ms.getMapWidth();
@@ -819,8 +868,8 @@ private void setupStartGrid() {
}
var currentBoard = clientgui.getClient().getGame().getPhase().isLounge() ?
- ServerBoardHelper.getPossibleGameBoard(clientgui.getClient().getMapSettings(), true) :
- clientgui.getClient().getGame().getBoard();
+ ServerBoardHelper.getPossibleGameBoard(clientgui.getClient().getMapSettings(), true) :
+ clientgui.getClient().getGame().getBoard();
var deploymentZones = currentBoard.getCustomDeploymentZones();
int extraRowCount = (int) Math.ceil(deploymentZones.size() / 3.0);
@@ -869,7 +918,9 @@ private void setupStartGrid() {
updateStartGrid();
}
- /** Assigns texts and tooltips to the starting positions grid. */
+ /**
+ * Assigns texts and tooltips to the starting positions grid.
+ */
private void updateStartGrid() {
Map butText = new HashMap<>();
Map butTT = new HashMap<>();
@@ -914,6 +965,14 @@ private void updateStartGrid() {
butText.get(currentPlayerStartPos).append(UIUtil.fontHTML(GUIPreferences.getInstance().getMyUnitColor()));
butText.get(currentPlayerStartPos).append("\u2B24");
+ if (Game.rulesManager.getRulesGame().restrictDeploymentWidth(player, currentPlayerStartPos)) {
+ txtWidth.setEnabled(false);
+ labWalkOnMore.setText(Messages.getString("PlayerSettingsDialog.labDeploymentWidthWalkOn"));
+ } else {
+ labWalkOnMore.setText("");
+ txtWidth.setEnabled(true);
+ }
+
// Turn off custom deployment if start is not Any
if (currentPlayerStartPos == Board.START_ANY) {
spinStartingAnyNWx.setEnabled(true);
@@ -995,10 +1054,10 @@ public void actionPerformed(ActionEvent e) {
} else if (butBotSettings.equals(e.getSource()) && client instanceof BotClient botClient) {
BehaviorSettings behavior = botClient.getBehaviorSettings();
var bcd = new BotConfigDialog(clientgui.getFrame(),
- client.getLocalPlayer().getName(),
- behavior,
- clientgui,
- botClient.getAIType());
+ client.getLocalPlayer().getName(),
+ behavior,
+ clientgui,
+ botClient.getAIType());
bcd.setVisible(true);
if (bcd.getResult() == DialogResult.CONFIRMED) {
botClient.setBehaviorSettings(bcd.getBehaviorSettings());
@@ -1074,12 +1133,13 @@ public String getFactionCode() {
return getFaction().getKey();
}
- public FactionRecord getFactionFromCode(String code, int year) {
+ public FactionRecord getFactionFromCode(String code,
+ int year) {
for (FactionRecord fRec : RATGenerator.getInstance().getFactionList()) {
if ((!fRec.isMinor()) &&
- !fRec.getKey().contains(".") &&
- fRec.isActiveInYear(year) &&
- fRec.getKey().equals(code)) {
+ !fRec.getKey().contains(".") &&
+ fRec.isActiveInYear(year) &&
+ fRec.getKey().equals(code)) {
return fRec;
}
}
diff --git a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerTable.java b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerTable.java
index 62fc43e61a9..bab289f90ca 100644
--- a/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerTable.java
+++ b/megamek/src/megamek/client/ui/panels/phaseDisplay/lobby/PlayerTable.java
@@ -37,19 +37,12 @@
import static megamek.client.ui.util.UIUtil.uiGreen;
import static megamek.client.ui.util.UIUtil.uiYellow;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.GridLayout;
-import java.awt.Image;
-import java.awt.Point;
+import java.awt.*;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
-import javax.swing.BorderFactory;
-import javax.swing.ImageIcon;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
+import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
@@ -60,10 +53,10 @@
import megamek.client.ui.Messages;
import megamek.client.ui.clientGUI.GUIPreferences;
import megamek.client.ui.util.UIUtil;
+import megamek.common.Player;
import megamek.common.board.Board;
import megamek.common.game.Game;
import megamek.common.interfaces.IStartingPositions;
-import megamek.common.Player;
import megamek.common.options.OptionsConstants;
class PlayerTable extends JTable {
@@ -73,7 +66,8 @@ class PlayerTable extends JTable {
PlayerTableModel model;
ChatLounge lobby;
- public PlayerTable(PlayerTableModel pm, ChatLounge cl) {
+ public PlayerTable(PlayerTableModel pm,
+ ChatLounge cl) {
super(pm);
model = pm;
lobby = cl;
@@ -129,9 +123,12 @@ public String getToolTipText(MouseEvent e) {
String msgNoInitiativeModifier = Messages.getString("ChatLounge.NoInitiativeModifier");
result.append(msgNoInitiativeModifier);
}
- if (Game.rulesManager.getRulesGame().allowMinefields(lobby.game().getOptions().booleanOption(OptionsConstants.ADVANCED_MINEFIELDS))) {
+ if (Game.rulesManager.getRulesGame()
+ .allowMinefields(lobby.game()
+ .getOptions()
+ .booleanOption(OptionsConstants.ADVANCED_MINEFIELDS))) {
int mines = player.getNbrMFConventional() + player.getNbrMFActive()
- + player.getNbrMFInferno() + player.getNbrMFVibra();
+ + player.getNbrMFInferno() + player.getNbrMFVibra();
String msgTotalMinefields = Messages.getString("ChatLounge.TotalMinefields");
result.append("
").append(msgTotalMinefields).append(": ").append(mines);
}
@@ -175,7 +172,8 @@ public Class> getColumnClass(int c) {
}
@Override
- public Object getValueAt(int row, int col) {
+ public Object getValueAt(int row,
+ int col) {
return getPlayerAt(row);
}
@@ -197,8 +195,12 @@ private void setImage(Image img) {
}
@Override
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
- boolean hasFocus, int row, int column) {
+ public Component getTableCellRendererComponent(JTable table,
+ Object value,
+ boolean isSelected,
+ boolean hasFocus,
+ int row,
+ int column) {
Player player = (Player) value;
super.getTableCellRendererComponent(table, getPlayerDescription(player), isSelected, hasFocus, row, column);
@@ -212,7 +214,7 @@ private StringBuilder getPlayerDescription(Player player) {
StringBuilder result = new StringBuilder("");
// First Line - Player Name
if ((lobby.client() instanceof BotClient) && player.equals(lobby.localPlayer())
- || lobby.client().getBots().containsKey(player.getName())) {
+ || lobby.client().getBots().containsKey(player.getName())) {
result.append(UIUtil.BOT_MARKER);
}
result.append(player.getName());
@@ -232,16 +234,16 @@ private StringBuilder getPlayerDescription(Player player) {
final var gOpts = lobby.game().getOptions();
if (gOpts.booleanOption(OptionsConstants.BASE_SET_PLAYER_DEPLOYMENT_TO_PLAYER_0)
- && !player.isBot()
- && player.getId() != 0) {
+ && !player.isBot()
+ && player.getId() != 0) {
result.append(msg_start).append(": ").append(Messages.getString("ChatLounge.Player0"));
} else if ((!lobby.client().getLocalPlayer().isGameMaster()
- && (isEnemy)
- && (gOpts.booleanOption(OptionsConstants.BASE_BLIND_DROP)
- || gOpts.booleanOption(OptionsConstants.BASE_REAL_BLIND_DROP)))) {
+ && (isEnemy)
+ && (gOpts.booleanOption(OptionsConstants.BASE_BLIND_DROP)
+ || gOpts.booleanOption(OptionsConstants.BASE_REAL_BLIND_DROP)))) {
result.append(msg_start).append(": ").append(Messages.getString("ChatLounge.Blind"));
} else if ((player.getStartingPos() >= 0)
- && (player.getStartingPos() <= IStartingPositions.START_LOCATION_NAMES.length)) {
+ && (player.getStartingPos() <= IStartingPositions.START_LOCATION_NAMES.length)) {
result.append(msg_start)
.append(": ")
.append(IStartingPositions.START_LOCATION_NAMES[player.getStartingPos()]);
@@ -265,7 +267,7 @@ private StringBuilder getPlayerDescription(Player player) {
}
int so = player.getStartOffset();
int sw = player.getStartWidth();
- if ((so != 0) || (sw != 3)) {
+ if ((so != 0) || !(sw == 3 || (sw == 1 && Game.rulesManager.getRulesGame().isWalkOnDeployment()))) {
result.append(", ").append(so);
result.append(", ").append(sw);
}
diff --git a/megamek/src/megamek/common/Player.java b/megamek/src/megamek/common/Player.java
index fe7da6f3773..bf7d44a6f37 100644
--- a/megamek/src/megamek/common/Player.java
+++ b/megamek/src/megamek/common/Player.java
@@ -147,7 +147,8 @@ public final class Player extends TurnOrdered {
//endregion Variable Declarations
//region Constructors
- public Player(int id, String name) {
+ public Player(int id,
+ String name) {
this.name = name;
this.id = id;
}
@@ -194,15 +195,16 @@ public boolean hasMinefields() {
}
return hasMinefields ||
- (numFortifiedHexes > 0) ||
- !getGroundObjectsToPlace().isEmpty();
+ (numFortifiedHexes > 0) ||
+ !getGroundObjectsToPlace().isEmpty();
}
/**
- * Given a minefield type from one of the TYPE_[MINEFIELDTYPE] constants in Minefield.java
- * and a count (preferably more than 0), set the count of that type of mine for this player.
+ * Given a minefield type from one of the TYPE_[MINEFIELDTYPE] constants in Minefield.java and a count (preferably
+ * more than 0), set the count of that type of mine for this player.
*/
- public void setMinefieldCount(int minefieldType, int count) {
+ public void setMinefieldCount(int minefieldType,
+ int count) {
minefieldCounts[minefieldType] = count;
}
@@ -231,8 +233,8 @@ public void setNbrMFEMP(int nbrMF) {
}
/**
- * Given a minefield type from one of the TYPE_[MINEFIELDTYPE] constants in Minefield.java
- * returns how many mines of that type this player has
+ * Given a minefield type from one of the TYPE_[MINEFIELDTYPE] constants in Minefield.java returns how many mines of
+ * that type this player has
*/
public int getMinefieldCount(int minefieldType) {
return minefieldCounts[minefieldType];
@@ -264,7 +266,7 @@ public int getNbrMFEMP() {
/**
* @return the number of fortified hexes this player may place during the minefield deployment phase
- * (Trench/Fieldworks Engineers, TO:AUE p.153)
+ * (Trench/Fieldworks Engineers, TO:AUE p.153)
*/
public int getNbrFortifiedHexes() {
return numFortifiedHexes;
@@ -352,12 +354,16 @@ public void setBot(boolean bot) {
this.bot = bot;
}
- /** @return true if this player may become a Game Master. Any human may be a GM */
+ /**
+ * @return true if this player may become a Game Master. Any human may be a GM
+ */
public boolean isGameMasterPermitted() {
return !bot;
}
- /** @return true if {@link #gameMaster} flag is true and {@link #isGameMasterPermitted()} */
+ /**
+ * @return true if {@link #gameMaster} flag is true and {@link #isGameMasterPermitted()}
+ */
public boolean isGameMaster() {
return (isGameMasterPermitted() && gameMaster);
}
@@ -379,7 +385,9 @@ public void setGameMaster(boolean gameMaster) {
this.gameMaster = gameMaster;
}
- /** @return true if {@link #observer} flag is true and not in VICTORY phase */
+ /**
+ * @return true if {@link #observer} flag is true and not in VICTORY phase
+ */
public boolean isObserver() {
if ((game != null) && game.getPhase().isVictory()) {
return false;
@@ -389,7 +397,6 @@ public boolean isObserver() {
/**
* @return true if this Player is not considered an observer.
- *
* @see #isObserver()
*/
public boolean isNotObserver() {
@@ -423,7 +430,7 @@ public void setArtilleryRevealAll(boolean artilleryRevealAll) {
/**
* @return {@code true} if the server should include enemy artillery attacks in this player's artillery packet (the
- * Rounds in the Air testing reveal); {@code false} for normal team-only (double-blind) behavior
+ * Rounds in the Air testing reveal); {@code false} for normal team-only (double-blind) behavior
*/
public boolean isArtilleryRevealAll() {
return artilleryRevealAll;
@@ -447,7 +454,9 @@ public boolean isSeeAllPermitted() {
return gameMaster || observer;
}
- /** set the {@link #observer} flag. Observers have no units add no team */
+ /**
+ * set the {@link #observer} flag. Observers have no units add no team
+ */
public void setObserver(boolean observer) {
this.observer = observer;
}
@@ -506,7 +515,7 @@ public PlayerColour getColour() {
* to say what the player looks like. Anything drawing something in a player's colour wants this.
*
* @return The colour of this player's colour camouflage, or the plain colour field when the camouflage
- * is an image rather than a colour
+ * is an image rather than a colour
*/
public PlayerColour getDisplayColour() {
if ((camouflage != null) && camouflage.isColourCamouflage()) {
@@ -668,18 +677,17 @@ public void changeInitialEntityCount(final int initialEntityCountChange) {
*/
public int getBV() {
return List.copyOf(game.getInGameObjects())
- .stream()
- .filter(this::isMyUnit)
- .filter(InGameObject::countForStrengthSum)
- .mapToInt(InGameObject::getStrength)
- .sum();
+ .stream()
+ .filter(this::isMyUnit)
+ .filter(InGameObject::countForStrengthSum)
+ .mapToInt(InGameObject::getStrength)
+ .sum();
}
/**
* Returns true when the given unit belongs to this Player.
*
* @param unit The unit
- *
* @return True when the unit belongs to "me", this Player
*/
public boolean isMyUnit(InGameObject unit) {
@@ -718,7 +726,7 @@ public int getConstantInitBonus() {
/**
* @return The victory points this player's side starts the game with, as set by a scenario's faction
- * definition; 0 unless a scenario set it
+ * definition; 0 unless a scenario set it
*/
public int getStartingVictoryPoints() {
return startingVictoryPoints;
@@ -763,7 +771,7 @@ public int getHQInitBonus() {
int bonus = 0;
for (InGameObject object : game.getInGameObjects()) {
if (object instanceof Entity entity && entity.getOwner().equals(this)
- && isActiveForCommandBonus(entity)) {
+ && isActiveForCommandBonus(entity)) {
bonus = Math.max(entity.getHQIniBonus(), bonus);
}
}
@@ -781,7 +789,7 @@ public int getQuirkInitBonus() {
int bonus = 0;
for (InGameObject object : game.getInGameObjects()) {
if (object instanceof Entity entity && entity.getOwner().equals(this)
- && isActiveForCommandBonus(entity)) {
+ && isActiveForCommandBonus(entity)) {
bonus = Math.max(bonus, entity.getQuirkIniBonus());
}
}
@@ -800,7 +808,7 @@ public String getQuirkInitBonusName() {
String bestQuirkName = null;
for (InGameObject object : game.getInGameObjects()) {
if (object instanceof Entity entity && entity.getOwner().equals(this)
- && isActiveForCommandBonus(entity)) {
+ && isActiveForCommandBonus(entity)) {
int entityBonus = entity.getQuirkIniBonus();
if (entityBonus > bestBonus) {
bestBonus = entityBonus;
@@ -868,12 +876,12 @@ public int getOverallCommandBonus() {
boolean useCommandInit = game.getOptions().booleanOption(OptionsConstants.RPG_COMMAND_INIT);
// entities are owned by this player, active, and not individual pilots
ArrayList entities = game.getInGameObjects()
- .stream()
- .filter(Entity.class::isInstance)
- .map(Entity.class::cast)
- .filter(entity -> (null != entity.getOwner()) &&
- entity.getOwner().equals(this))
- .collect(Collectors.toCollection(ArrayList::new));
+ .stream()
+ .filter(Entity.class::isInstance)
+ .map(Entity.class::cast)
+ .filter(entity -> (null != entity.getOwner()) &&
+ entity.getOwner().equals(this))
+ .collect(Collectors.toCollection(ArrayList::new));
int commandBonus = 0;
for (Entity entity : entities) {
int bonus = getIndividualCommandBonus(entity, useCommandInit);
@@ -892,7 +900,8 @@ public int getOverallCommandBonus() {
* @param useCommandInit boolean based on game options
*
*/
- public int getIndividualCommandBonus(Entity entity, boolean useCommandInit) {
+ public int getIndividualCommandBonus(Entity entity,
+ boolean useCommandInit) {
int bonus = 0;
// Only consider this during normal rounds when unit is deployed on board, or about to deploy this round.
if (isActiveForCommandBonus(entity)) {
@@ -939,7 +948,7 @@ public int getTCPInitBonus() {
continue;
}
boolean eligibleForBonus = (entity.isDeployed() && !entity.isOffBoard()) ||
- (entity.getDeployRound() == (game.getCurrentRound() + 1));
+ (entity.getDeployRound() == (game.getCurrentRound() + 1));
if (!eligibleForBonus) {
LOGGER.debug("TCP: {} skipped - not deployed or deploying next round", entity.getDisplayName());
continue;
@@ -950,7 +959,7 @@ public int getTCPInitBonus() {
continue;
}
if (!entity.hasAbility(OptionsConstants.MD_VDNI)
- && !entity.hasAbility(OptionsConstants.MD_BVDNI)) {
+ && !entity.hasAbility(OptionsConstants.MD_BVDNI)) {
LOGGER.debug("TCP: {} skipped - no VDNI/BVDNI", entity.getDisplayName());
continue;
}
@@ -983,7 +992,7 @@ public int getTCPInitBonus() {
}
LOGGER.debug("TCP: {} qualifies with bonus {} (deployed={}, deployRound={})",
- entity.getDisplayName(), bonus, entity.isDeployed(), entity.getDeployRound());
+ entity.getDisplayName(), bonus, entity.isDeployed(), entity.getDeployRound());
bestBonus = Math.max(bestBonus, bonus);
}
LOGGER.debug("TCP: Final TCP bonus for player {}: {}", name, bestBonus);
@@ -1030,7 +1039,6 @@ private boolean isEntityECMAffected(Entity entity) {
* crew, not captured, not an ejected pilot, and either deployed on-board or deploying next round.
*
* @param entity the entity to check
- *
* @return true if the entity can provide command bonuses
*/
private boolean isActiveForCommandBonus(Entity entity) {
@@ -1048,12 +1056,12 @@ public String getColorForPlayer() {
public String getColoredPlayerNameWithTeam() {
return "" +
- getName() +
- " (" +
- getTeamName() +
- ")";
+ getColour().getHexString(0x00F0F0F0) +
+ "'>" +
+ getName() +
+ " (" +
+ getTeamName() +
+ ")";
}
/**
@@ -1145,7 +1153,7 @@ public Player copy() {
/**
* @return The area of the board this player's units are allowed to flee from; An empty area as return value means
- * they may not flee at all.
+ * they may not flee at all.
*/
public HexArea getFleeZone() {
return fleeArea;
@@ -1156,7 +1164,6 @@ public HexArea getFleeZone() {
* flee.
*
* @param fleeArea The new flee area.
- *
* @see megamek.common.hexArea.BorderHexArea
*/
public void setFleeZone(HexArea fleeArea) {
diff --git a/megamek/src/megamek/common/board/Board.java b/megamek/src/megamek/common/board/Board.java
index 8dc0f8fcad6..848090a104b 100644
--- a/megamek/src/megamek/common/board/Board.java
+++ b/megamek/src/megamek/common/board/Board.java
@@ -71,6 +71,7 @@
import megamek.logging.MMLogger;
public class Board implements Serializable {
+
@Serial
private static final long serialVersionUID = -5744058872091016636L;
private static final MMLogger logger = MMLogger.create(Board.class);
@@ -115,29 +116,33 @@ public class Board implements Serializable {
* current year when saving.
*/
public static final String LICENSE_HEADER = """
- # MegaMek Data (C) %s by The MegaMek Team is licensed under CC BY-NC-SA 4.0.
- # To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/
- #
- # NOTICE: The MegaMek organization is a non-profit group of volunteers
- # creating free software for the BattleTech community.
- #
- # MechWarrior, BattleMech, `Mech and AeroTech are registered trademarks
- # of The Topps Company, Inc. All Rights Reserved.
- #
- # Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of
- # InMediaRes Productions, LLC.
- #
- # MechWarrior Copyright Microsoft Corporation. MegaMek Data was created under
- # Microsoft's "Game Content Usage Rules"
- # and it is not endorsed by or
- # affiliated with Microsoft.
- """;
-
- /** Regex pattern to extract the copyright year(s) from board file headers. */
+ # MegaMek Data (C) %s by The MegaMek Team is licensed under CC BY-NC-SA 4.0.
+ # To view a copy of this license, visit https://creativecommons.org/licenses/by-nc-sa/4.0/
+ #
+ # NOTICE: The MegaMek organization is a non-profit group of volunteers
+ # creating free software for the BattleTech community.
+ #
+ # MechWarrior, BattleMech, `Mech and AeroTech are registered trademarks
+ # of The Topps Company, Inc. All Rights Reserved.
+ #
+ # Catalyst Game Labs and the Catalyst Game Labs logo are trademarks of
+ # InMediaRes Productions, LLC.
+ #
+ # MechWarrior Copyright Microsoft Corporation. MegaMek Data was created under
+ # Microsoft's "Game Content Usage Rules"
+ # and it is not endorsed by or
+ # affiliated with Microsoft.
+ """;
+
+ /**
+ * Regex pattern to extract the copyright year(s) from board file headers.
+ */
private static final Pattern COPYRIGHT_YEAR_PATTERN = Pattern.compile(
- "#\\s*MegaMek Data \\(C\\)\\s*(\\d{4})(?:-(\\d{4}))?");
+ "#\\s*MegaMek Data \\(C\\)\\s*(\\d{4})(?:-(\\d{4}))?");
- /** The original copyright year from the loaded board file, or -1 if none found. */
+ /**
+ * The original copyright year from the loaded board file, or -1 if none found.
+ */
private int originalCopyrightYear = -1;
// The min and max elevation values for this board.
@@ -187,7 +192,9 @@ public class Board implements Serializable {
*/
private final Map> annotations = new HashMap<>();
- /** Tags associated with this board to facilitate searching for it. */
+ /**
+ * Tags associated with this board to facilitate searching for it.
+ */
private final Set tags = new HashSet<>();
private int boardId = 0;
@@ -239,7 +246,8 @@ public Board() {
* @param width the width dimension.
* @param height the height dimension.
*/
- public Board(int width, int height) {
+ public Board(int width,
+ int height) {
this.width = width;
this.height = height;
data = new Hex[width * height];
@@ -253,7 +261,9 @@ public Board(int width, int height) {
* @param height the height dimension
* @param data the Hexes of the new board
*/
- public Board(int width, int height, Hex... data) {
+ public Board(int width,
+ int height,
+ Hex... data) {
this.width = width;
this.height = height;
this.data = Arrays.copyOf(data, data.length);
@@ -264,10 +274,10 @@ public Board(int width, int height, Hex... data) {
*
* @param width the width of the board
* @param height the height of the board
- *
* @return the new board, ready to be used
*/
- public static Board getSkyBoard(int width, int height) {
+ public static Board getSkyBoard(int width,
+ int height) {
Hex[] data = new Hex[width * height];
int index = 0;
for (int h = 0; h < height; h++) {
@@ -285,10 +295,10 @@ public static Board getSkyBoard(int width, int height) {
*
* @param width the width of the board
* @param height the height of the board
- *
* @return the new board, ready to be used
*/
- public static Board getSpaceBoard(int width, int height) {
+ public static Board getSpaceBoard(int width,
+ int height) {
Hex[] data = new Hex[width * height];
int index = 0;
for (int h = 0; h < height; h++) {
@@ -320,6 +330,36 @@ public Coords getCenter() {
return new Coords(getWidth() / 2, getHeight() / 2);
}
+ /**
+ * for a given deployment position, return the center point of it
+ *
+ * @param deploymentPosition Deployment zone
+ * @return a coordinate
+ */
+ public Coords getDeploymentCenter(int deploymentPosition) {
+ switch (deploymentPosition) {
+ case Board.START_W:
+ return new Coords(0, getHeight() / 2);
+ case Board.START_SW:
+ return new Coords(0, getHeight() - 1);
+ case Board.START_SE:
+ return new Coords(getWidth() - 1, getHeight() - 1);
+ case Board.START_E:
+ return new Coords(getWidth() - 1, getHeight() / 2);
+ case Board.START_NW:
+ return new Coords(0, 0);
+ case Board.START_NE:
+ return new Coords(getWidth() - 1, 0);
+ case Board.START_N:
+ return new Coords(getWidth() / 2, 0);
+ case Board.START_S:
+ return new Coords(getWidth() / 2, getHeight() - 1);
+ default:
+ // Any, Center, custom zones
+ return getCenter();
+ }
+ }
+
/**
* Creates a new data set for the board, with the specified dimensions and data; notifies listeners that a new data
* set has been created.
@@ -329,8 +369,10 @@ public Coords getCenter() {
* @param data new hex data appropriate for the board.
* @param errors A buffer for storing error messages, if any. This is allowed to be null.
*/
- public void newData(final int width, final int height, final Hex[] data,
- final @Nullable List errors) {
+ public void newData(final int width,
+ final int height,
+ final Hex[] data,
+ final @Nullable List errors) {
this.width = width;
this.height = height;
this.data = data;
@@ -344,20 +386,20 @@ public void newData(final int width, final int height, final Hex[] data,
*
* @param x the x Coords.
* @param y the y Coords.
- *
* @return the Hex, if this Board contains the (x, y) location; null otherwise.
*/
- public @Nullable Hex getHex(final int x, final int y) {
+ public @Nullable Hex getHex(final int x,
+ final int y) {
return contains(x, y) ? data[(y * width) + x] : null;
}
/**
* @param c starting coordinates
* @param dir direction
- *
* @return the hex in the specified direction from the specified starting coordinates.
*/
- public Hex getHexInDir(Coords c, int dir) {
+ public Hex getHexInDir(Coords c,
+ int dir) {
return getHex(c.xInDir(dir), c.yInDir(dir));
}
@@ -368,10 +410,11 @@ public Hex getHexInDir(Coords c, int dir) {
* @param x starting x coordinate
* @param y starting y coordinate
* @param dir direction
- *
* @return the hex in the specified direction from the specified starting coordinates.
*/
- public Hex getHexInDir(int x, int y, int dir) {
+ public Hex getHexInDir(int x,
+ int y,
+ int dir) {
return getHex(Coords.xInDir(x, y, dir), Coords.yInDir(x, y, dir));
}
@@ -399,7 +442,7 @@ protected void initializeAll(final @Nullable List errors) {
// Nope. Try to create an object for the new building.
try {
IBuilding bldg = new BuildingTerrain(coords, this, Terrains.BUILDING,
- BasementType.getType(curHex.terrainLevel(Terrains.BLDG_BASEMENT_TYPE)));
+ BasementType.getType(curHex.terrainLevel(Terrains.BLDG_BASEMENT_TYPE)));
addBuildingToBoard(bldg);
} catch (IllegalArgumentException exception) {
// Log the error and remove the building from the board.
@@ -471,7 +514,8 @@ protected void initializeAll(final @Nullable List errors) {
/**
* Initialize a hex and the hexes around it
*/
- public void initializeAround(int x, int y) {
+ public void initializeAround(int x,
+ int y) {
initializeHex(x, y);
for (int i = 0; i < 6; i++) {
initializeInDir(x, y, i);
@@ -481,7 +525,9 @@ public void initializeAround(int x, int y) {
/**
* Initializes a hex in a specific direction from an origin hex
*/
- private void initializeInDir(int x, int y, int dir) {
+ private void initializeInDir(int x,
+ int y,
+ int dir) {
initializeHex(Coords.xInDir(x, y, dir), Coords.yInDir(x, y, dir));
}
@@ -489,11 +535,14 @@ private void initializeInDir(int x, int y, int dir) {
* Initializes a hex in its surroundings. Currently, sets the connects parameter appropriately to the surrounding
* hexes. If a surrounding hex is off the board, it checks the hex opposite the missing hex.
*/
- public void initializeHex(int x, int y) {
+ public void initializeHex(int x,
+ int y) {
initializeHex(x, y, true);
}
- private void initializeHex(int x, int y, boolean event) {
+ private void initializeHex(int x,
+ int y,
+ boolean event) {
Hex hex = getHex(x, y);
if (hex == null) {
@@ -520,14 +569,17 @@ private void initializeHex(int x, int y, boolean event) {
}
}
- /** Adds the FOLIAGE_ELEV terrain when none is present. */
- private void initializeFoliageElev(int x, int y) {
+ /**
+ * Adds the FOLIAGE_ELEV terrain when none is present.
+ */
+ private void initializeFoliageElev(int x,
+ int y) {
Hex hex = getHex(x, y);
// If the foliage elevation is present or the hex doesn't even have foliage,
// nothing needs to be done
if (hex.containsTerrain(Terrains.FOLIAGE_ELEV) ||
- (!hex.containsTerrain(Terrains.WOODS) && !hex.containsTerrain(Terrains.JUNGLE))) {
+ (!hex.containsTerrain(Terrains.WOODS) && !hex.containsTerrain(Terrains.JUNGLE))) {
return;
}
@@ -547,7 +599,8 @@ private void initializeFoliageElev(int x, int y) {
* @param x The hex X-Coordinate.
* @param y The hex Y-Coordinate.
*/
- private void initializeAutomaticTerrain(int x, int y) {
+ private void initializeAutomaticTerrain(int x,
+ int y) {
Hex hex = getHex(x, y);
int origCliffTopExits = 0;
int correctedCliffTopExits = 0;
@@ -560,7 +613,7 @@ private void initializeAutomaticTerrain(int x, int y) {
// Get the currently set cliff-tops for correction. When exits
// are not specified, the cliff-tops are removed.
if (hex.containsTerrain(Terrains.CLIFF_TOP)
- && hex.getTerrain(Terrains.CLIFF_TOP).hasExitsSpecified()) {
+ && hex.getTerrain(Terrains.CLIFF_TOP).hasExitsSpecified()) {
origCliffTopExits = hex.getTerrain(Terrains.CLIFF_TOP).getExits();
}
@@ -585,23 +638,23 @@ private void initializeAutomaticTerrain(int x, int y) {
// Should there be an incline top?
if (((levelDiff == 1) || (levelDiff == 2))
- && !cliffTopExitInThisDir
- && !inWater
- && !towardsWater) {
+ && !cliffTopExitInThisDir
+ && !inWater
+ && !towardsWater) {
inclineTopExits += (1 << i);
}
if (towardsWater
- && !inWater
- && !cliffTopExitInThisDir
- && ((levelDiffToWaterSurface == 1) || levelDiffToWaterSurface == 2)) {
+ && !inWater
+ && !cliffTopExitInThisDir
+ && ((levelDiffToWaterSurface == 1) || levelDiffToWaterSurface == 2)) {
inclineTopExits += (1 << i);
}
// Should there be a high level cliff top?
if (levelDiff > 2
- && !inWater
- && (!towardsWater || levelDiffToWaterSurface > 2)) {
+ && !inWater
+ && (!towardsWater || levelDiffToWaterSurface > 2)) {
highInclineTopExits += (1 << i);
}
@@ -639,7 +692,9 @@ private void initializeAutomaticTerrain(int x, int y) {
/**
* Adds automatically handled terrain such as inclines when the given exits value is not 0, otherwise removes it.
*/
- private void addOrRemoveAutoTerrain(Hex hex, int terrainType, int exits) {
+ private void addOrRemoveAutoTerrain(Hex hex,
+ int terrainType,
+ int exits) {
if (exits > 0) {
hex.addTerrain(new Terrain(terrainType, 1, true, exits));
} else {
@@ -665,10 +720,10 @@ public void initializeAllAutomaticTerrain() {
*
* @param x the x Coords.
* @param y the y Coords.
- *
* @return true if the board contains the specified coords
*/
- public boolean contains(int x, int y) {
+ public boolean contains(int x,
+ int y) {
return (x >= 0) && (y >= 0) && (x < width) && (y < height);
}
@@ -676,7 +731,6 @@ public boolean contains(int x, int y) {
* Determines whether this Board "contains" the specified Coords.
*
* @param coords the Coords.
- *
* @return true if the board contains the specified coords
*/
public boolean contains(@Nullable Coords coords) {
@@ -688,7 +742,6 @@ public boolean contains(@Nullable Coords coords) {
* coords of the location are within the borders of the board.
*
* @param location the location to test
- *
* @return true if the board contains the specified location
*/
public boolean contains(@Nullable BoardLocation location) {
@@ -699,7 +752,6 @@ public boolean contains(@Nullable BoardLocation location) {
* Returns the Hex at the given Coords, both of which may be null.
*
* @param coords the Coords to look for the Hex
- *
* @return the Hex at the specified Coords, or null if there is not a hex there
*/
public @Nullable Hex getHex(final @Nullable Coords coords) {
@@ -711,7 +763,6 @@ public boolean contains(@Nullable BoardLocation location) {
* Coords collection. If the given Coords collection is null, the returned list will be empty.
*
* @param coords the Coords to query
- *
* @return the Hexes at the specified Coords
*/
public List getHexes(final @Nullable Collection coords) {
@@ -731,7 +782,9 @@ public List getHexes(final @Nullable Collection coords) {
* @param y the y Coords.
* @param hex the hex to be set into position.
*/
- public void setHex(int x, int y, Hex hex) {
+ public void setHex(int x,
+ int y,
+ Hex hex) {
Map changedHex = new HashMap<>();
changedHex.put(BoardLocation.of(new Coords(x, y), boardId), hex);
setHexes(changedHex);
@@ -785,7 +838,8 @@ public void setHexes(Map changedHexes) {
* @param c the Coords.
* @param hex the hex to be set into position.
*/
- public void setHex(Coords c, Hex hex) {
+ public void setHex(Coords c,
+ Hex hex) {
setHex(c.getX(), c.getY(), hex);
if (hex.getLevel() < minElevation && minElevation != UNDEFINED_MIN_ELEV) {
minElevation = hex.getLevel();
@@ -800,10 +854,10 @@ public void setHex(Coords c, Hex hex) {
*
* @param filepath The path to the board file.
* @param size The dimensions of the board to test.
- *
* @return {@code true} if the dimensions match.
*/
- public static boolean boardIsSize(final File filepath, final BoardDimensions size) {
+ public static boolean boardIsSize(final File filepath,
+ final BoardDimensions size) {
int boardX = 0;
int boardY = 0;
try (FileReader fr = new FileReader(filepath); BufferedReader br = new BufferedReader(fr)) {
@@ -815,7 +869,7 @@ public static boolean boardIsSize(final File filepath, final BoardDimensions siz
streamTokenizer.wordChars('_', '_');
while (streamTokenizer.nextToken() != StreamTokenizer.TT_EOF) {
if ((streamTokenizer.ttype == StreamTokenizer.TT_WORD)
- && streamTokenizer.sval.equalsIgnoreCase("size")) {
+ && streamTokenizer.sval.equalsIgnoreCase("size")) {
streamTokenizer.nextToken();
boardX = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
@@ -835,14 +889,13 @@ public static boolean boardIsSize(final File filepath, final BoardDimensions siz
* Inspect specified board file and return its dimensions.
*
* @param filepath The path to the board file.
- *
* @return A {@link BoardDimensions} object containing the dimension.
*/
public static BoardDimensions getSize(final File filepath) {
int boardX = 0;
int boardY = 0;
try (FileReader fileReader = new FileReader(filepath);
- BufferedReader bufferedReader = new BufferedReader(fileReader)) {
+ BufferedReader bufferedReader = new BufferedReader(fileReader)) {
// read board, looking for "size"
StreamTokenizer streamTokenizer = new StreamTokenizer(bufferedReader);
streamTokenizer.eolIsSignificant(true);
@@ -851,7 +904,7 @@ public static BoardDimensions getSize(final File filepath) {
streamTokenizer.wordChars('_', '_');
while (streamTokenizer.nextToken() != StreamTokenizer.TT_EOF) {
if ((streamTokenizer.ttype == StreamTokenizer.TT_WORD)
- && streamTokenizer.sval.equalsIgnoreCase("size")) {
+ && streamTokenizer.sval.equalsIgnoreCase("size")) {
streamTokenizer.nextToken();
boardX = (int) streamTokenizer.nval;
streamTokenizer.nextToken();
@@ -865,7 +918,9 @@ public static BoardDimensions getSize(final File filepath) {
return new BoardDimensions(boardX, boardY);
}
- /** Inspects the given board file and returns a set of its tags. */
+ /**
+ * Inspects the given board file and returns a set of its tags.
+ */
public static Set getTags(final File filepath) {
var result = new HashSet();
try (FileReader fr = new FileReader(filepath); BufferedReader br = new BufferedReader(fr)) {
@@ -911,29 +966,48 @@ public static boolean isValid(String board) {
/**
* Can the given player deploy at these coordinates?
*/
- public boolean isLegalDeployment(Coords c, Player p) {
+ public boolean isLegalDeployment(Coords c,
+ Player p) {
return isLegalDeployment(c, p.getStartingPos(), p.getStartWidth(), p.getStartOffset(), p.getStartingAnyNWx(),
- p.getStartingAnyNWy(), p.getStartingAnySEx(), p.getStartingAnySEy());
+ p.getStartingAnyNWy(), p.getStartingAnySEx(), p.getStartingAnySEy());
}
/**
* Can the given entity be deployed at these coordinates
*/
- public boolean isLegalDeployment(Coords c, Entity e) {
+ public boolean isLegalDeployment(Coords c,
+ Entity e) {
if (e == null) {
return false;
}
-
- return isLegalDeployment(c, e.getStartingPos(), e.getStartingWidth(), e.getStartingOffset(),
- e.getStartingAnyNWx(), e.getStartingAnyNWy(), e.getStartingAnySEx(), e.getStartingAnySEy());
+ int startingWidth = e.getGame().rulesManager.getRulesGame()
+ .getDeploymentWidth(e.getOwner(),
+ e.getStartingPos(), e.getStartingWidth());
+ if (e.isDropShip()) {
+ startingWidth = e.getStartingWidth();
+ }
+ return isLegalDeployment(c,
+ e.getStartingPos(),
+ startingWidth,
+ e.getStartingOffset(),
+ e.getStartingAnyNWx(),
+ e.getStartingAnyNWy(),
+ e.getStartingAnySEx(),
+ e.getStartingAnySEy());
}
/**
* Can an object be deployed at these coordinates, given a starting zone, width of starting zone and offset from
* edge of board?
*/
- public boolean isLegalDeployment(Coords c, int zoneType, int startingWidth, int startingOffset, int startingAnyNWx,
- int startingAnyNWy, int startingAnySEx, int startingAnySEy) {
+ public boolean isLegalDeployment(Coords c,
+ int zoneType,
+ int startingWidth,
+ int startingOffset,
+ int startingAnyNWx,
+ int startingAnyNWy,
+ int startingAnySEx,
+ int startingAnySEy) {
if ((c == null) || !contains(c)) {
return false;
}
@@ -943,46 +1017,46 @@ public boolean isLegalDeployment(Coords c, int zoneType, int startingWidth, int
return switch (zoneType) {
case START_ANY -> (((startingAnyNWx == Entity.STARTING_ANY_NONE) || (c.getX() >= startingAnyNWx))
- && ((startingAnySEx == Entity.STARTING_ANY_NONE) || (c.getX() <= startingAnySEx))
- && ((startingAnyNWy == Entity.STARTING_ANY_NONE) || (c.getY() >= startingAnyNWy))
- && ((startingAnySEy == Entity.STARTING_ANY_NONE) || (c.getY() <= startingAnySEy)));
+ && ((startingAnySEx == Entity.STARTING_ANY_NONE) || (c.getX() <= startingAnySEx))
+ && ((startingAnyNWy == Entity.STARTING_ANY_NONE) || (c.getY() >= startingAnyNWy))
+ && ((startingAnySEy == Entity.STARTING_ANY_NONE) || (c.getY() <= startingAnySEy)));
case START_NW -> ((c.getX() < (startingOffset + startingWidth)) && (c.getX() >= startingOffset) && (c.getY()
- >= startingOffset)
- && (c.getY() < (height / 2)))
- || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
- >= startingOffset)
- && (c.getX() < (width / 2)));
+ >= startingOffset)
+ && (c.getY() < (height / 2)))
+ || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
+ >= startingOffset)
+ && (c.getX() < (width / 2)));
case START_N -> (c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset);
case START_NE -> ((c.getX() >= (maxX - startingWidth)) && (c.getX() < maxX) && (c.getY() >= startingOffset)
- && (c.getY() < (height / 2)))
- || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
- < maxX)
- && (c.getX() > (width / 2)));
+ && (c.getY() < (height / 2)))
+ || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
+ < maxX)
+ && (c.getX() > (width / 2)));
case START_E -> (c.getX() >= (maxX - startingWidth)) && (c.getX() < maxX);
case START_SE -> ((c.getX() >= (maxX - startingWidth)) && (c.getX() < maxX) && (c.getY() < maxy)
- && (c.getY() > (height / 2)))
- || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() < maxX)
- && (c.getX() > (width / 2)));
+ && (c.getY() > (height / 2)))
+ || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() < maxX)
+ && (c.getX() > (width / 2)));
case START_S -> (c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy);
case START_SW -> ((c.getX() < (startingOffset + startingWidth)) && (c.getX() >= startingOffset) && (c.getY()
- < maxy)
- && (c.getY() > (height / 2)))
- || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() >= startingOffset)
- && (c.getX() < (width / 2)));
+ < maxy)
+ && (c.getY() > (height / 2)))
+ || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() >= startingOffset)
+ && (c.getX() < (width / 2)));
case START_W -> (c.getX() < (startingOffset + startingWidth)) && (c.getX() >= startingOffset);
case START_EDGE ->
- ((c.getX() < (startingOffset + startingWidth)) && (c.getX() >= startingOffset) && (c.getY()
- >= startingOffset) && (c.getY() < maxy))
- || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
- >= startingOffset)
+ ((c.getX() < (startingOffset + startingWidth)) && (c.getX() >= startingOffset) && (c.getY()
+ >= startingOffset) && (c.getY() < maxy))
+ || ((c.getY() < (startingOffset + startingWidth)) && (c.getY() >= startingOffset) && (c.getX()
+ >= startingOffset)
&& (c.getX() < maxX))
- || ((c.getX() >= (maxX - startingWidth)) && (c.getX() < maxX) && (c.getY() >= startingOffset)
+ || ((c.getX() >= (maxX - startingWidth)) && (c.getX() < maxX) && (c.getY() >= startingOffset)
&& (c.getY() < maxy))
- || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() >= startingOffset)
+ || ((c.getY() >= (maxy - startingWidth)) && (c.getY() < maxy) && (c.getX() >= startingOffset)
&& (c.getX() < maxX));
case START_CENTER ->
- (c.getX() >= (width / 3)) && (c.getX() <= ((2 * width) / 3)) && (c.getY() >= (height / 3))
- && (c.getY() <= ((2 * height) / 3));
+ (c.getX() >= (width / 3)) && (c.getX() <= ((2 * width) / 3)) && (c.getY() >= (height / 3))
+ && (c.getY() <= ((2 * height) / 3));
default -> {
Set customDeploymentZone = getCustomDeploymentZone(decodeCustomDeploymentZoneID(zoneType));
yield customDeploymentZone.contains(c);
@@ -995,7 +1069,6 @@ public boolean isLegalDeployment(Coords c, int zoneType, int startingWidth, int
* East)
*
* @param cardinalEdge The edge to return the opposite of
- *
* @return Constant representing the opposite edge
*/
public int getOppositeEdge(int cardinalEdge) {
@@ -1043,7 +1116,8 @@ public void load(InputStream is) {
load(is, null, false);
}
- public void load(String boardString, @Nullable List errors) {
+ public void load(String boardString,
+ @Nullable List errors) {
try (InputStream is = new ByteArrayInputStream(boardString.getBytes(StandardCharsets.UTF_8))) {
load(is, errors, false);
} catch (IOException ex) {
@@ -1052,7 +1126,9 @@ public void load(String boardString, @Nullable List errors) {
}
}
- public void load(InputStream is, @Nullable List errors, boolean continueLoadOnError) {
+ public void load(InputStream is,
+ @Nullable List errors,
+ boolean continueLoadOnError) {
int nw = 0, nh = 0, di = 0;
Hex[] nd = new Hex[0];
int index = 0;
@@ -1079,7 +1155,7 @@ public void load(InputStream is, @Nullable List errors, boolean continue
}
try (InputStreamReader isr = new InputStreamReader(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
- BufferedReader br = new BufferedReader(isr)) {
+ BufferedReader br = new BufferedReader(isr)) {
StreamTokenizer st = new StreamTokenizer(br);
st.eolIsSignificant(true);
st.commentChar('#');
@@ -1091,7 +1167,7 @@ public void load(InputStream is, @Nullable List errors, boolean continue
String[] args = { "0", "0" };
int i = 0;
while ((st.nextToken() == StreamTokenizer.TT_WORD) || (st.ttype == '"')
- || (st.ttype == StreamTokenizer.TT_NUMBER)) {
+ || (st.ttype == StreamTokenizer.TT_NUMBER)) {
args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int) st.nval + "" : st.sval;
}
nw = Integer.parseInt(args[0]);
@@ -1102,7 +1178,7 @@ public void load(InputStream is, @Nullable List errors, boolean continue
String[] args = { "", "" };
int i = 0;
while ((st.nextToken() == StreamTokenizer.TT_WORD) || (st.ttype == '"')
- || (st.ttype == StreamTokenizer.TT_NUMBER)) {
+ || (st.ttype == StreamTokenizer.TT_NUMBER)) {
args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int) st.nval + "" : st.sval;
}
// Only expect certain options.
@@ -1114,7 +1190,7 @@ public void load(InputStream is, @Nullable List errors, boolean continue
String[] args = { "", "0", "", "" };
int i = 0;
while ((st.nextToken() == StreamTokenizer.TT_WORD) || (st.ttype == '"')
- || (st.ttype == StreamTokenizer.TT_NUMBER)) {
+ || (st.ttype == StreamTokenizer.TT_NUMBER)) {
args[i++] = st.ttype == StreamTokenizer.TT_NUMBER ? (int) st.nval + "" : st.sval;
}
int elevation = Integer.parseInt(args[1]);
@@ -1191,7 +1267,10 @@ public boolean isValid(@Nullable List errors) {
return isValid(data, width, height, errors);
}
- private boolean isValid(Hex[] data, int width, int height, @Nullable List errors) {
+ private boolean isValid(Hex[] data,
+ int width,
+ int height,
+ @Nullable List errors) {
List newErrors = new ArrayList<>();
// Search for black-listed hexes
for (int x = 0; x < width; x++) {
@@ -1214,22 +1293,22 @@ private boolean isValid(Hex[] data, int width, int height, @Nullable ListCoords of the hit.
* @param round the kind of round that hit the hex.
* @param hits the int number of rounds that hit
- *
* @throws IllegalArgumentException if the hits number is negative
*/
- public void addInfernoTo(Coords coords, Inferno round, int hits) {
+ public void addInfernoTo(Coords coords,
+ Inferno round,
+ int hits) {
// Make sure the # of hits is valid.
if (hits < 0) {
throw new IllegalArgumentException("Board can't track negative hits. ");
@@ -1379,8 +1460,8 @@ public void removeInfernoFrom(Coords coords) {
}
/**
- * Record that a fire at the given coordinates was started by a fuel-fed flamer (TO:AuE p.153). Such fires are harder
- * for firefighting engineers to extinguish.
+ * Record that a fire at the given coordinates was started by a fuel-fed flamer (TO:AuE p.153). Such fires are
+ * harder for firefighting engineers to extinguish.
*
* @param coords the Coords of the flamer-started fire
*/
@@ -1406,7 +1487,6 @@ public void removeFlamerStartedFire(Coords coords) {
/**
* @param coords the Coords being checked
- *
* @return true if the fire at these coordinates was started by a fuel-fed flamer
*/
public boolean isFlamerStartedFire(Coords coords) {
@@ -1433,9 +1513,8 @@ public void clearBombIcons() {
* Determine if the given coordinates has a burning inferno.
*
* @param coords - the Coords being checked.
- *
* @return true if those coordinates have a burning inferno
- * round. false if no inferno has hit those coordinates or if it has burned out.
+ * round. false if no inferno has hit those coordinates or if it has burned out.
*/
public boolean isInfernoBurning(Coords coords) {
boolean result = false;
@@ -1490,9 +1569,8 @@ public Vector getBuildingsVector() {
* Get the building at the given coordinates.
*
* @param coords the Coords being examined.
- *
* @return a Building object, if there is one at the given coordinates, otherwise a
- * null will be returned.
+ * null will be returned.
*/
public @Nullable IBuilding getBuildingAt(Coords coords) {
return bldgByCoords.get(coords);
@@ -1504,9 +1582,8 @@ public Vector getBuildingsVector() {
*
* @param other - a Building object which may or may not be represented on this board. This value may
* be null .
- *
* @return The local Building object if we can find a match. If the other building is not on this
- * board, a null is returned instead.
+ * board, a null is returned instead.
*/
private IBuilding getLocalBuilding(IBuilding other) {
return buildings.stream().filter(building -> building.equals(other)).findFirst().orElse(null);
@@ -1656,7 +1733,7 @@ public void updateBuilding(IBuilding receivedBuilding) {
localBuilding.setPhaseCF(receivedBuilding.getPhaseCF(coords), coords);
localBuilding.setArmor(receivedBuilding.getArmor(coords), coords);
localBuilding.setBasement(coords,
- BasementType.getType(getHex(coords).terrainLevel(Terrains.BLDG_BASEMENT_TYPE)));
+ BasementType.getType(getHex(coords).terrainLevel(Terrains.BLDG_BASEMENT_TYPE)));
localBuilding.setBasementCollapsed(coords, receivedBuilding.getBasementCollapsed(coords));
localBuilding.setDemolitionCharges(receivedBuilding.getDemolitionCharges());
}
@@ -1666,8 +1743,8 @@ public void updateBuilding(IBuilding receivedBuilding) {
* Get the current value of the "road auto-exit" option.
*
* @return true if roads should automatically exit onto all
- * adjacent pavement hexes.
- * false otherwise.
+ * adjacent pavement hexes.
+ * false otherwise.
*/
public boolean getRoadsAutoExit() {
return roadsAutoExit;
@@ -1805,7 +1882,7 @@ public void setRandomBasementsOff() {
/**
* @return Special events that should be marked on hexes, such as artillery fire as well as notes players can leave
- * manually on hexes. Always returns at least an empty list, never null.
+ * manually on hexes. Always returns at least an empty list, never null.
*/
public Collection getSpecialHexDisplay(Coords coords) {
return specialHexes.getOrDefault(coords, Collections.emptyList());
@@ -1819,7 +1896,9 @@ public Collection getSpecialHexDisplay(Coords coords) {
* @param shd The SpecialHexDisplay to add
* @param fireEvent When true, a BoardEvent is fired for the affected coords
*/
- public void addSpecialHexDisplay(Coords coords, SpecialHexDisplay shd, boolean fireEvent) {
+ public void addSpecialHexDisplay(Coords coords,
+ SpecialHexDisplay shd,
+ boolean fireEvent) {
Collection col;
if (!specialHexes.containsKey(coords)) {
col = new LinkedList<>();
@@ -1845,7 +1924,8 @@ public void addSpecialHexDisplay(Coords coords, SpecialHexDisplay shd, boolean f
* @param coords The position of the SHD on this board
* @param shd The SpecialHexDisplay to add
*/
- public void addSpecialHexDisplay(Coords coords, SpecialHexDisplay shd) {
+ public void addSpecialHexDisplay(Coords coords,
+ SpecialHexDisplay shd) {
addSpecialHexDisplay(coords, shd, false);
}
@@ -1855,7 +1935,8 @@ public void addSpecialHexDisplay(Coords coords, SpecialHexDisplay shd) {
* @param coords The position of the SHD on this board
* @param shd The SpecialHexDisplay to remove
*/
- public void removeSpecialHexDisplay(Coords coords, SpecialHexDisplay shd) {
+ public void removeSpecialHexDisplay(Coords coords,
+ SpecialHexDisplay shd) {
removeSpecialHexDisplay(coords, shd, false);
}
@@ -1865,7 +1946,9 @@ public void removeSpecialHexDisplay(Coords coords, SpecialHexDisplay shd) {
* @param coords The position of the SHD on this board
* @param shd The SpecialHexDisplay to remove
*/
- public void removeSpecialHexDisplay(Coords coords, SpecialHexDisplay shd, boolean fireEvent) {
+ public void removeSpecialHexDisplay(Coords coords,
+ SpecialHexDisplay shd,
+ boolean fireEvent) {
Collection col = specialHexes.get(coords);
if (col != null) {
col.remove(shd);
@@ -1891,7 +1974,7 @@ public void setSpecialHexDisplayTable(Map>
specialHexes = shd;
toRedraw.addAll(shd.keySet());
toRedraw.forEach(coords ->
- processBoardEvent(new BoardEvent(this, coords, BoardEvent.BOARD_CHANGED_HEX)));
+ processBoardEvent(new BoardEvent(this, coords, BoardEvent.BOARD_CHANGED_HEX)));
//TODO: Add a BoardEvent for a set of coords to avoid many events
}
@@ -1994,7 +2077,6 @@ public Map> getAnnotations() {
* Gets the annotations associated with a hex.
*
* @param c Coordinates of the hex.
- *
* @return A collection of annotations for the hex.
*/
public Collection getAnnotations(Coords c) {
@@ -2007,7 +2089,8 @@ public Collection getAnnotations(Coords c) {
* @param c Coordinates of the hex to apply the annotations to.
* @param a A collection of annotations to assign to the hex. This may be null.
*/
- public void setAnnotations(Coords c, @Nullable Collection a) {
+ public void setAnnotations(Coords c,
+ @Nullable Collection a) {
if (null == a || a.isEmpty()) {
annotations.remove(c);
} else {
@@ -2037,10 +2120,11 @@ public void setTheme(final @Nullable String newTheme) {
*/
public boolean isOnBoardEdge(Coords coords) {
return (coords.getX() == 0) || (coords.getY() == 0) || (coords.getX() == (width - 1)) || (coords.getY() == (
- height - 1));
+ height - 1));
}
- public static Board createEmptyBoard(int width, int height) {
+ public static Board createEmptyBoard(int width,
+ int height) {
Hex[] hexes = new Hex[width * height];
for (int i = 0; i < width * height; i++) {
hexes[i] = new Hex();
@@ -2055,7 +2139,9 @@ public void addTag(String newTag) {
tags.add(newTag);
}
- /** Removes the given tag string from the board's tags list. */
+ /**
+ * Removes the given tag string from the board's tags list.
+ */
public void removeTag(String tag) {
tags.remove(tag);
@@ -2068,7 +2154,9 @@ public Set getTags() {
return Collections.unmodifiableSet(tags);
}
- /** @return The name of this map; this is meant to be displayed in the GUI. */
+ /**
+ * @return The name of this map; this is meant to be displayed in the GUI.
+ */
public String getBoardName() {
return mapName;
}
@@ -2079,7 +2167,7 @@ public void setMapName(String mapName) {
/**
* @return Given an "exits" value, returns it in a list form. (i.e. exits value of 4 returns {3}, exit value of 5
- * returns {1, 3}
+ * returns {1, 3}
*/
public static List exitsAsIntList(int exits) {
List results = new ArrayList<>();
@@ -2132,7 +2220,8 @@ private void initializeDeploymentZones() {
* Converts a custom deployment zone from the hex area definition to board hexes; also translates the ID. Note that
* the deploymentZones field must not be null.
*/
- private void convertDeploymentZone(int zoneId, HexArea hexArea) {
+ private void convertDeploymentZone(int zoneId,
+ HexArea hexArea) {
deploymentZones.put(zoneId - NUM_ZONES_X2, hexArea.getCoords(this));
}
@@ -2145,7 +2234,8 @@ private void convertDeploymentZone(int zoneId, HexArea hexArea) {
* @param zoneId The zone Id
* @param hexArea The hexes comprising this deployment zone
*/
- public void addDeploymentZone(int zoneId, HexArea hexArea) {
+ public void addDeploymentZone(int zoneId,
+ HexArea hexArea) {
areas.put(zoneId, hexArea);
}
@@ -2214,7 +2304,9 @@ public void setEnclosingBoard(int enclosingBoardId) {
enclosingBoard = enclosingBoardId;
}
- /** @return The ID of the enclosing board of this board, or -1 if it has no enclosing board. */
+ /**
+ * @return The ID of the enclosing board of this board, or -1 if it has no enclosing board.
+ */
public int getEnclosingBoardId() {
return enclosingBoard;
}
@@ -2225,10 +2317,10 @@ public int getEnclosingBoardId() {
*
* @param boardId The board ID to embed
* @param coords The location to place the given board
- *
* @throws IllegalArgumentException When this board does not contain the given coords
*/
- public void setEmbeddedBoard(int boardId, Coords coords) {
+ public void setEmbeddedBoard(int boardId,
+ Coords coords) {
if (contains(coords)) {
embeddedBoards.put(coords, boardId);
} else {
@@ -2263,7 +2355,7 @@ public boolean isGround() {
/**
* @return True if this board is a low altitude (a.k.a. atmospheric) board, either with terrain or without terrain
- * ("sky").
+ * ("sky").
*/
public boolean isLowAltitude() {
return boardType.isLowAltitude();
@@ -2278,7 +2370,7 @@ public boolean isSky() {
/**
* @return True if this board is a space board, either close to a planet with some atmospheric hexes ("high
- * altitude") or in deeper space.
+ * altitude") or in deeper space.
*/
public boolean isSpace() {
return boardType.isSpace();
@@ -2286,7 +2378,7 @@ public boolean isSpace() {
/**
* @return True if this board is a high altitude board, i.e. a space board close to a planet with some atmospheric
- * hexes.
+ * hexes.
*/
public boolean isHighAltitude() {
return boardType.isHighAltitude();
diff --git a/megamek/src/megamek/common/enums/MoveStepType.java b/megamek/src/megamek/common/enums/MoveStepType.java
index 08ab533d9f1..aa7783935a4 100644
--- a/megamek/src/megamek/common/enums/MoveStepType.java
+++ b/megamek/src/megamek/common/enums/MoveStepType.java
@@ -118,7 +118,8 @@ public enum MoveStepType {
CHAFF(false, "Chaff"),
PICKUP_CARGO(false, "Pickup Cargo"),
DROP_CARGO(false, "Drop Cargo"),
- CHANGE_BOARD(true, "Change Board");
+ CHANGE_BOARD(true, "Change Board"),
+ DEPLOY(false, "Deploy");
private final boolean entersNewHex;
private final String humanReadableLabel;
diff --git a/megamek/src/megamek/common/game/Game.java b/megamek/src/megamek/common/game/Game.java
index 579925dfc88..a249b015f46 100644
--- a/megamek/src/megamek/common/game/Game.java
+++ b/megamek/src/megamek/common/game/Game.java
@@ -120,7 +120,9 @@
* The game class is the root of all data about the game in progress. Both the Client and the Server should have one of
* these objects, and it is their job to keep it synced.
*/
-public final class Game extends AbstractGame implements Serializable, PlanetaryConditionsUsing {
+public final class Game extends AbstractGame implements Serializable,
+ PlanetaryConditionsUsing {
+
private static final MMLogger logger = MMLogger.create(Game.class);
@Serial
@@ -199,10 +201,14 @@ public final class Game extends AbstractGame implements Serializable, PlanetaryC
private final Vector vibraBombs = new Vector<>();
private final Vector empMines = new Vector<>();
- /** Tracks ongoing woods clearing operations for chainsaws and dual saws. Serialized with game saves. */
+ /**
+ * Tracks ongoing woods clearing operations for chainsaws and dual saws. Serialized with game saves.
+ */
private WoodsClearingTracker woodsClearingTracker = new WoodsClearingTracker();
- /** Hex locations being cleared by saws, mapped to turns remaining. For board view rendering. */
+ /**
+ * Hex locations being cleared by saws, mapped to turns remaining. For board view rendering.
+ */
private Map hexesBeingCut = new HashMap<>();
private Vector attacks = new Vector<>();
private Vector offboardArtilleryAttacks = new Vector<>();
@@ -314,7 +320,7 @@ public int getNbrMinefields(Coords coords) {
* Get the coordinates of all mined hexes in the game.
*
* @return an Enumeration of the Coords containing minefields. This will not be
- * null.
+ * null.
*/
public Enumeration getMinedCoords() {
return minefields.keys();
@@ -338,6 +344,13 @@ public WoodsClearingTracker getWoodsClearingTracker() {
public void initializeRulesManager(String system) {
if (system.equals(OptionsConstants.RULES_TW)) {
rulesManager = new TWRulesManager();
+
+ // Check for walk-on deployment here
+ if (getOptions().booleanOption(OptionsConstants.BASE_WALK_ON_DEPLOYMENT)) {
+ rulesManager.getRulesGame().setWalkOnDeployment(true);
+ } else {
+ rulesManager.getRulesGame().setWalkOnDeployment(false);
+ }
} else if (system.equals(OptionsConstants.RULES_CORE)) {
rulesManager = new CoreRulesManager();
}
@@ -463,7 +476,6 @@ public void removeVibrabomb(Minefield mf) {
* Checks if the game contains the specified Vibrabomb
*
* @param mf the Vibrabomb to check
- *
* @return true if the minefield contains a vibrabomb.
*/
public boolean containsVibrabomb(Minefield mf) {
@@ -486,7 +498,6 @@ public void removeEMPMine(Minefield mf) {
* Checks if the game contains the specified EMP mine
*
* @param mf the EMP mine to check
- *
* @return true if the minefield contains an EMP mine.
*/
public boolean containsEMPMine(Minefield mf) {
@@ -515,12 +526,18 @@ public void setOptions(final @Nullable GameOptions options) {
// Check Rules system and reapply as needed.
IOption rules_system = this.options.getOption(OptionsConstants.RULES_SYSTEM);
String loadedOption = (rulesManager instanceof CoreRulesManager) ?
- OptionsConstants.RULES_CORE : OptionsConstants.RULES_TW;
+ OptionsConstants.RULES_CORE : OptionsConstants.RULES_TW;
if (rules_system == null) {
initializeRulesManager(OptionsConstants.RULES_CORE);
} else if (!rules_system.stringValue().equals(loadedOption)) {
initializeRulesManager(rules_system.stringValue());
}
+ if (loadedOption.equals(OptionsConstants.RULES_TW)) {
+ boolean shouldWalkOn = this.options.booleanOption(OptionsConstants.BASE_WALK_ON_DEPLOYMENT);
+ if (shouldWalkOn != Game.rulesManager.getRulesGame().isWalkOnDeployment()) {
+ Game.rulesManager.getRulesGame().setWalkOnDeployment(shouldWalkOn);
+ }
+ }
processGameEvent(new GameSettingsChangeEvent(this));
}
}
@@ -533,8 +550,8 @@ public void setOptions(final @Nullable GameOptions options) {
*/
public boolean usesStandardGhostTargetMode() {
return getOptions().booleanOption(OptionsConstants.ADVANCED_TAC_OPS_GHOST_TARGET)
- && OptionsConstants.GHOST_TARGET_MODE_STANDARD.equals(
- getOptions().stringOption(OptionsConstants.ADVANCED_GHOST_TARGET_MODE));
+ && OptionsConstants.GHOST_TARGET_MODE_STANDARD.equals(
+ getOptions().stringOption(OptionsConstants.ADVANCED_GHOST_TARGET_MODE));
}
/**
@@ -604,7 +621,8 @@ public void setupTeams() {
}
@Override
- public void addPlayer(int id, Player player) {
+ public void addPlayer(int id,
+ Player player) {
player.setGame(this);
if ((player.isBot()) && (!player.getSingleBlind())) {
@@ -646,31 +664,31 @@ private boolean isOffboardPlayable() {
// per errata, TAG will spot for LRMs and such
if ((ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.LRM) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.LRM_IMP) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.MML) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.NLRM) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.MEK_MORTAR) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_5) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_10) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_15) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_20)) {
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.LRM_IMP) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.MML) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.NLRM) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.MEK_MORTAR) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_5) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_10) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_15) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.TBOLT_20)) {
return true;
}
if (((ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.ARROW_IV) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.LONG_TOM) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.SNIPER) ||
- (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.THUMPER)) &&
- (ammoType.getMunitionType().contains(AmmoType.Munitions.M_HOMING))) {
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.LONG_TOM) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.SNIPER) ||
+ (ammoType.getAmmoType() == AmmoType.AmmoTypeEnum.THUMPER)) &&
+ (ammoType.getMunitionType().contains(AmmoType.Munitions.M_HOMING))) {
return true;
}
}
if (entity.getBombs()
- .stream()
- .anyMatch(bomb -> !bomb.isDestroyed() &&
- (bomb.getUsableShotsLeft() > 0) &&
- (bomb.getType().getBombType() == BombTypeEnum.LG))) {
+ .stream()
+ .anyMatch(bomb -> !bomb.isDestroyed() &&
+ (bomb.getUsableShotsLeft() > 0) &&
+ (bomb.getType().getBombType() == BombTypeEnum.LG))) {
return true;
}
}
@@ -679,13 +697,14 @@ private boolean isOffboardPlayable() {
// prevents issues from aerospace homing artillery with the aerospace unit having left the field already, for
// example
return getAttacksVector().stream()
- .map(AttackHandler::getWeaponAttackAction)
- .filter(Objects::nonNull)
- .anyMatch(waa -> waa.getAmmoMunitionType().contains(AmmoType.Munitions.M_HOMING));
+ .map(AttackHandler::getWeaponAttackAction)
+ .filter(Objects::nonNull)
+ .anyMatch(waa -> waa.getAmmoMunitionType().contains(AmmoType.Munitions.M_HOMING));
}
@Override
- public void setPlayer(int id, Player player) {
+ public void setPlayer(int id,
+ Player player) {
player.setGame(this);
players.put(id, player);
setupTeams();
@@ -739,16 +758,16 @@ public int getLiveEntitiesOwnedBy(Player player) {
/**
* @return the number of non-destroyed entities owned by the player, including entities not yet deployed. Ignores
- * off board units and captured Mek pilots.
+ * off board units and captured Mek pilots.
*/
public int getLiveDeployedEntitiesOwnedBy(Player player) {
int count = 0;
for (Entity entity : inGameTWEntities()) {
if (entity.getOwner().equals(player) &&
- !entity.isDestroyed() &&
- !entity.isCarcass() &&
- !entity.isOffBoard() &&
- !entity.isCaptured()) {
+ !entity.isDestroyed() &&
+ !entity.isCarcass() &&
+ !entity.isOffBoard() &&
+ !entity.isCaptured()) {
count++;
}
}
@@ -757,17 +776,17 @@ public int getLiveDeployedEntitiesOwnedBy(Player player) {
/**
* @return the number of non-destroyed commander entities owned by the player. Ignores off board units and captured
- * Mek pilots.
+ * Mek pilots.
*/
public int getLiveCommandersOwnedBy(Player player) {
int count = 0;
for (Entity entity : inGameTWEntities()) {
if (entity.getOwner().equals(player) &&
- !entity.isDestroyed() &&
- !entity.isCarcass() &&
- entity.isCommander() &&
- !entity.isOffBoard() &&
- !entity.isCaptured()) {
+ !entity.isDestroyed() &&
+ !entity.isCarcass() &&
+ entity.isCommander() &&
+ !entity.isOffBoard() &&
+ !entity.isCaptured()) {
count++;
}
}
@@ -781,11 +800,11 @@ public boolean hasTacticalGenius(Player player) {
// Note: rules do not state that Tactical Genius cannot apply to deployment initiative roll (CamOps pg 80)
for (Entity entity : inGameTWEntities()) {
if (entity.hasAbility(OptionsConstants.MISC_TACTICAL_GENIUS) &&
- entity.getOwner().equals(player) &&
- !entity.isDestroyed() &&
- (entity.isDeployed() || (getPhase() == INITIATIVE_REPORT)) &&
- !entity.isCarcass() &&
- !entity.getCrew().isUnconscious()) {
+ entity.getOwner().equals(player) &&
+ !entity.isDestroyed() &&
+ (entity.isDeployed() || (getPhase() == INITIATIVE_REPORT)) &&
+ !entity.isCarcass() &&
+ !entity.getCrew().isUnconscious()) {
return true;
}
}
@@ -807,18 +826,17 @@ public boolean hasTacticalGenius(Player player) {
*
*
* @param player The player whose units will be checked.
- *
* @return {@code true} if the player has a valid unit with the "Combat Sense" ability, {@code false} otherwise.
*/
public boolean commanderHasCombatSense(Player player) {
for (Entity entity : inGameTWEntities()) {
if (entity.hasAbility(ATOW_COMBAT_SENSE) &&
- entity.isCommander() &&
- entity.getOwner().equals(player) &&
- !entity.isDestroyed() &&
- entity.isDeployed() &&
- !entity.isCarcass() &&
- !entity.getCrew().isUnconscious()) {
+ entity.isCommander() &&
+ entity.getOwner().equals(player) &&
+ !entity.isDestroyed() &&
+ entity.isDeployed() &&
+ !entity.isCarcass() &&
+ !entity.getCrew().isUnconscious()) {
return true;
}
}
@@ -840,19 +858,18 @@ public boolean commanderHasCombatSense(Player player) {
*
*
* @param player The player whose commander will be checked.
- *
* @return {@code true} if the player's commander has the "Combat Paralysis" special ability and meets all
- * conditions, {@code false} otherwise.
+ * conditions, {@code false} otherwise.
*/
public boolean commanderHasCombatParalysis(Player player) {
for (Entity entity : inGameTWEntities()) {
if (entity.hasAbility(ATOW_COMBAT_PARALYSIS) &&
- entity.isCommander() &&
- entity.getOwner().equals(player) &&
- !entity.isDestroyed() &&
- entity.isDeployed() &&
- !entity.isCarcass() &&
- !entity.getCrew().isUnconscious()) {
+ entity.isCommander() &&
+ entity.getOwner().equals(player) &&
+ !entity.isDestroyed() &&
+ entity.isDeployed() &&
+ !entity.isCarcass() &&
+ !entity.getCrew().isUnconscious()) {
return true;
}
}
@@ -871,12 +888,12 @@ public List getValidTargets(Entity entity) {
// Even if friendly fire is acceptable, do not shoot yourself
// Enemy units not on the board can not be shot.
if ((otherEntity.getPosition() != null) &&
- !otherEntity.isOffBoard() &&
- otherEntity.isTargetable() &&
- !otherEntity.isHidden() &&
- !otherEntity.isSensorReturn(entity.getOwner()) &&
- otherEntity.hasSeenEntity(entity.getOwner()) &&
- (entity.isEnemyOf(otherEntity) || (friendlyFire && (entity.getId() != otherEntity.getId())))) {
+ !otherEntity.isOffBoard() &&
+ otherEntity.isTargetable() &&
+ !otherEntity.isHidden() &&
+ !otherEntity.isSensorReturn(entity.getOwner()) &&
+ otherEntity.hasSeenEntity(entity.getOwner()) &&
+ (entity.isEnemyOf(otherEntity) || (friendlyFire && (entity.getId() != otherEntity.getId())))) {
// Air to Ground - target must be on flight path
if (Compute.isAirToGround(entity, otherEntity)) {
if (entity.getPassedThrough().contains(otherEntity.getPosition())) {
@@ -939,7 +956,8 @@ public void insertNextTurn(GameTurn turn) {
/**
* Inserts a turn after the specific index
*/
- public void insertTurnAfter(GameTurn turn, int index) {
+ public void insertTurnAfter(GameTurn turn,
+ int index) {
synchronized (turnVector) {
if ((index + 1) >= turnVector.size()) {
turnVector.add(turn);
@@ -952,7 +970,8 @@ public void insertTurnAfter(GameTurn turn, int index) {
/**
* Swaps the turn at index 1 with the turn at index 2.
*/
- public void swapTurnOrder(int index1, int index2) {
+ public void swapTurnOrder(int index1,
+ int index2) {
synchronized (turnVector) {
GameTurn turn1 = turnVector.get(index1);
GameTurn turn2 = turnVector.get(index2);
@@ -974,7 +993,8 @@ public Enumeration getTurns() {
* @param turnIndex The new turn index.
* @param prevPlayerId The ID of the player who triggered the turn index change.
*/
- public void setTurnIndex(int turnIndex, int prevPlayerId) {
+ public void setTurnIndex(int turnIndex,
+ int prevPlayerId) {
this.turnIndex = turnIndex;
GameTurn turn = getTurn();
@@ -1085,9 +1105,8 @@ public void setLastPhase(GamePhase lastPhase) {
/**
* @param current The Entity whose list position you wish to start from.
- *
* @return The previous Entity from the master list of entities. Will wrap around to the end of the
- * list if necessary, returning null if there are no entities.
+ * list if necessary, returning null if there are no entities.
*/
public @Nullable Entity getPreviousEntityFromList(final @Nullable Entity current) {
if ((current != null) && inGameTWEntities().contains(current)) {
@@ -1102,9 +1121,8 @@ public void setLastPhase(GamePhase lastPhase) {
/**
* @param current The Entity whose list position you wish to start from.
- *
* @return The next Entity from the master list of entities. Will wrap around to the beginning of the
- * list if necessary, returning null if there are no entities.
+ * list if necessary, returning null if there are no entities.
*/
public @Nullable Entity getNextEntityFromList(final @Nullable Entity current) {
if ((current != null) && inGameTWEntities().contains(current)) {
@@ -1142,7 +1160,6 @@ public Vector getOutOfGameEntitiesVector() {
*
* @param vOutOfGame - the new Vector of dead or fled units. This value should not be
* null.
- *
* @throws IllegalArgumentException if the new list is null.
*/
public void setOutOfGameEntitiesVector(final List vOutOfGame) {
@@ -1165,9 +1182,8 @@ public void setOutOfGameEntitiesVector(final List vOutOfGame) {
* Returns an out-of-game entity.
*
* @param id the int ID of the out-of-game entity.
- *
* @return the out-of-game Entity with that ID. If no out-of-game entity has that ID, returns a
- * null.
+ * null.
*/
public @Nullable Entity getOutOfGameEntity(int id) {
Entity match = null;
@@ -1189,11 +1205,9 @@ public void setOutOfGameEntitiesVector(final List vOutOfGame) {
*
* @param entity - the Entity whose C3 network co- members is required. This value may be
* null.
- *
* @return a Vector that will contain all other
- * Entitys that are in the same C3 network as the
- * passed-in unit. This Vector may be empty, but it will not be null.
- *
+ * Entitys that are in the same C3 network as the
+ * passed-in unit. This Vector may be empty, but it will not be null.
* @see #getC3SubNetworkMembers(Entity)
*/
public Vector getC3NetworkMembers(Entity entity) {
@@ -1222,20 +1236,18 @@ public Vector getC3NetworkMembers(Entity entity) {
*
* @param entity - the Entity whose C3 network sub-members is required. This value may be
* null.
- *
* @return a Vector that will contain all other
- * Entitys that are in the same C3 network under the
- * passed-in unit. This Vector may be empty, but it will not be null.
- *
+ * Entitys that are in the same C3 network under the
+ * passed-in unit. This Vector may be empty, but it will not be null.
* @see #getC3NetworkMembers(Entity)
*/
public Vector getC3SubNetworkMembers(Entity entity) {
// WOR. Handle null, C3i, NC3, and company commander units.
if ((entity == null) ||
- entity.hasC3i() ||
- entity.hasNavalC3() ||
- entity.hasActiveNovaCEWS() ||
- entity.C3MasterIs(entity)) {
+ entity.hasC3i() ||
+ entity.hasNavalC3() ||
+ entity.hasActiveNovaCEWS() ||
+ entity.C3MasterIs(entity)) {
return getC3NetworkMembers(entity);
}
@@ -1260,7 +1272,7 @@ public Vector getC3SubNetworkMembers(Entity entity) {
* getPositionMapMulti()
*
* @return a Hashtable that maps the Coords positions or each unit in the game to a Vector of Entity's at that
- * position.
+ * position.
*/
public Hashtable> getPositionMap() {
Hashtable> positionMap = new Hashtable<>();
@@ -1277,7 +1289,7 @@ public Hashtable> getPositionMap() {
/**
* @return a Map that maps the location of each unit in this game to a list of Entity's at the same location. Units
- * that have no position (e.g. loaded units) will not be in the map.
+ * that have no position (e.g. loaded units) will not be in the map.
*/
public Map> getPositionMapMulti() {
var positionMap = new HashMap>();
@@ -1293,7 +1305,7 @@ public Map> getPositionMapMulti() {
final BoardLocation secondaryLocation = new BoardLocation(coords, entity.getBoardId(), false);
if (hasBoardLocation(secondaryLocation)) {
List listForLocation = positionMap.computeIfAbsent(secondaryLocation,
- k -> new ArrayList<>());
+ k -> new ArrayList<>());
listForLocation.add(entity);
}
}
@@ -1310,7 +1322,7 @@ public Enumeration getGraveyardEntities() {
for (Entity entity : vOutOfGame) {
if ((entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_SALVAGEABLE) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_EJECTED)) {
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_EJECTED)) {
graveyard.addElement(entity);
}
}
@@ -1325,8 +1337,8 @@ public Enumeration getWreckedEntities() {
Vector wrecks = new Vector<>();
for (Entity entity : vOutOfGame) {
if ((entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_SALVAGEABLE) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_EJECTED) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_DEVASTATED)) {
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_EJECTED) ||
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_DEVASTATED)) {
wrecks.addElement(entity);
}
}
@@ -1343,8 +1355,8 @@ public Enumeration getRetreatedEntities() {
for (Entity entity : vOutOfGame) {
if ((entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_IN_RETREAT) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_CAPTURED) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_PUSHED)) {
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_CAPTURED) ||
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_PUSHED)) {
sanctuary.addElement(entity);
}
}
@@ -1392,7 +1404,8 @@ public int getNoOfEntities() {
/**
* Returns the appropriate target for this game given a type and id
*/
- public @Nullable Targetable getTarget(int targetType, int targetId) {
+ public @Nullable Targetable getTarget(int targetType,
+ int targetId) {
try {
return switch (targetType) {
case Targetable.TYPE_ENTITY -> getEntity(targetId);
@@ -1401,14 +1414,14 @@ public int getNoOfEntities() {
Targetable.TYPE_MINEFIELD_DELIVER, Targetable.TYPE_FLARE_DELIVER, Targetable.TYPE_HEX_EXTINGUISH,
Targetable.TYPE_HEX_ARTILLERY, Targetable.TYPE_HEX_SCREEN, Targetable.TYPE_HEX_AERO_BOMB,
Targetable.TYPE_SATURATION, Targetable.TYPE_HEX_TAG ->
- new HexTarget(HexTarget.idToLocation(targetId), targetType);
+ new HexTarget(HexTarget.idToLocation(targetId), targetType);
case Targetable.TYPE_FUEL_TANK, Targetable.TYPE_FUEL_TANK_IGNITE, Targetable.TYPE_BUILDING,
Targetable.TYPE_BLDG_IGNITE, Targetable.TYPE_BLDG_TAG -> {
final BoardLocation boardLocation = HexTarget.idToLocation(targetId);
yield getBuildingAt(boardLocation)
- .map(b -> new BuildingTarget(this, boardLocation, targetType))
- .orElse(null);
+ .map(b -> new BuildingTarget(this, boardLocation, targetType))
+ .orElse(null);
}
case Targetable.TYPE_MINEFIELD_CLEAR -> new MinefieldTarget(MinefieldTarget.idToCoords(targetId));
case Targetable.TYPE_I_NARC_POD -> INarcPod.idToInstance(targetId);
@@ -1420,7 +1433,9 @@ yield getBuildingAt(boardLocation)
}
}
- /** @return The entity with the given id number, if any. */
+ /**
+ * @return The entity with the given id number, if any.
+ */
public synchronized @Nullable Entity getEntity(final int id) {
InGameObject possibleEntity = inGameObjects.get(id);
return (possibleEntity instanceof Entity) ? (Entity) possibleEntity : null;
@@ -1432,7 +1447,6 @@ yield getBuildingAt(boardLocation)
* will cause a null pointer exception if the entity does not exist.
*
* @param id The id number of the entity to get.
- *
* @return The entity with the given id number or throw a no such element exception.
*/
public Entity getEntityOrThrow(final int id) {
@@ -1485,7 +1499,8 @@ public void addEntity(Entity entity) {
* @param entity The Entity to add.
* @param genEvent A flag that determines whether a GameEntityNewEvent is generated.
*/
- public synchronized void addEntity(Entity entity, boolean genEvent) {
+ public synchronized void addEntity(Entity entity,
+ boolean genEvent) {
entity.setGame(this);
entity.addIntrinsicTransporters();
@@ -1533,11 +1548,14 @@ private boolean isIdUsed(int id) {
return inGameObjects.containsKey(id) || isOutOfGame(id);
}
- public void setEntity(int id, Entity entity) {
+ public void setEntity(int id,
+ Entity entity) {
setEntity(id, entity, null);
}
- public synchronized void setEntity(int id, Entity entity, Vector movePath) {
+ public synchronized void setEntity(int id,
+ Entity entity,
+ Vector movePath) {
final Entity oldEntity = getEntity(id);
if (oldEntity == null) {
addEntity(entity);
@@ -1575,7 +1593,7 @@ public List getGraveyard() {
/**
* @return true if an entity with the specified id number exists in
- * this game.
+ * this game.
*/
public boolean hasEntity(int entityId) {
Optional possibleEntity = getInGameObject(entityId);
@@ -1585,7 +1603,8 @@ public boolean hasEntity(int entityId) {
/**
* Remove an entity from the master list. If we can't find that entity, (probably due to double-blind) ignore it.
*/
- public synchronized void removeEntity(int id, int condition) {
+ public synchronized void removeEntity(int id,
+ int condition) {
Entity toRemove = getEntity(id);
if (toRemove == null) {
return;
@@ -1607,7 +1626,8 @@ public synchronized void removeEntity(int id, int condition) {
processGameEvent(new GameEntityRemoveEvent(this, toRemove));
}
- public void removeEntities(List ids, int condition) {
+ public void removeEntities(List ids,
+ int condition) {
for (Integer id : ids) {
removeEntity(id, condition);
}
@@ -1695,7 +1715,8 @@ public Entity getFirstEntity(Coords c) {
* @param c the coordinates to search at
* @param currentEntity the entity that is firing
*/
- public Entity getFirstEnemyEntity(Coords c, Entity currentEntity) {
+ public Entity getFirstEnemyEntity(Coords c,
+ Entity currentEntity) {
for (Entity entity : inGameTWEntities()) {
if (c.equals(entity.getPosition()) && entity.isTargetable() && entity.isEnemyOf(currentEntity)) {
return entity;
@@ -1715,7 +1736,6 @@ public Iterator getEntities(Coords c) {
* Returns an Iterator for all entities in _all_ of the coordinates provided. Coords must not be null.
*
* @param coordList ArrayList of coordinates to check.
- *
* @return Iterator over the vector of entities. The vector must exist to get the iterator.
*/
public Iterator getEntities(ArrayList coordList) {
@@ -1731,7 +1751,8 @@ public Iterator getEntities(ArrayList coordList) {
/**
* Returns an Enumeration of the active entities at the given coordinates.
*/
- public Iterator getEntities(Coords c, boolean ignore) {
+ public Iterator getEntities(Coords c,
+ boolean ignore) {
return getEntitiesVector(c, ignore).iterator();
}
@@ -1739,7 +1760,6 @@ public Iterator getEntities(Coords c, boolean ignore) {
* Return an {@link Entity} List at {@link Coords} c, checking if they can be targeted.
*
* @param c The coordinates to check
- *
* @return the {@link Entity} List
*/
public synchronized List getEntitiesVector(Coords c) {
@@ -1751,10 +1771,10 @@ public synchronized List getEntitiesVector(Coords c) {
*
* @param c The coordinates to check
* @param ignore Flag that determines whether the ability to target is ignored
- *
* @return the {@link Entity} List
*/
- public synchronized List getEntitiesVector(Coords c, boolean ignore) {
+ public synchronized List getEntitiesVector(Coords c,
+ boolean ignore) {
// checkPositionCacheConsistency();
// Make sure the look-up is initialized
if (entityPosLookup.isEmpty() && !inGameTWEntities().isEmpty()) {
@@ -1789,7 +1809,8 @@ public synchronized List getEntitiesVector(Coords c, boolean ignore) {
return Collections.unmodifiableList(vector);
}
- public List getEntitiesVector(BoardLocation location, boolean ignoreTargetable) {
+ public List getEntitiesVector(BoardLocation location,
+ boolean ignoreTargetable) {
return getEntitiesVector(location.coords(), location.boardId(), ignoreTargetable);
}
@@ -1797,19 +1818,21 @@ public List getEntitiesVector(BoardLocation location) {
return getEntitiesVector(location.coords(), location.boardId(), true);
}
- public List getEntitiesVector(Coords coord, int boardId, boolean ignoreTargetable) {
+ public List getEntitiesVector(Coords coord,
+ int boardId,
+ boolean ignoreTargetable) {
return getEntitiesVector(coord, ignoreTargetable).stream()
- .filter(entity -> entity.isOnBoard(boardId))
- .toList();
+ .filter(entity -> entity.isOnBoard(boardId))
+ .toList();
}
- public List getEntitiesVector(Coords coord, int boardId) {
+ public List getEntitiesVector(Coords coord,
+ int boardId) {
return getEntitiesVector(coord, boardId, false);
}
/**
* @param player {@link Player} Object
- *
* @return a list of all off-board enemy entities.
*/
public synchronized List getAllOffboardEnemyEntities(Player player) {
@@ -1832,10 +1855,10 @@ public List getGunEmplacements(Coords c) {
* Return a Vector of gun emplacements at Coords c.
*
* @param c The coordinates to check
- *
* @return the {@link GunEmplacement} Vector
*/
- public List getGunEmplacements(Coords c, int boardId) {
+ public List getGunEmplacements(Coords c,
+ int boardId) {
List result = new ArrayList<>();
// Only build the list if the coords are on the board. // TODO Ensure this works w/ BuildingEntity
@@ -1855,7 +1878,8 @@ public List getGunEmplacements(Coords c, int boardId) {
*
* @param c The coordinates to check
*/
- public boolean hasRooftopGunEmplacement(Coords c, int boardId) {
+ public boolean hasRooftopGunEmplacement(Coords c,
+ int boardId) {
if (!hasBoardLocation(c, boardId)) {
return false;
} // TODO Ensure this works with BuildingEntity
@@ -1881,17 +1905,17 @@ public boolean hasRooftopGunEmplacement(Coords c, int boardId) {
*
* @param coords The Coords of the hex in which the accidental fall from above happens
* @param ignore The entity who is falling, so shouldn't be returned
- *
* @return The Entity that should be an AFFA target.
*/
- public @Nullable Entity getAFFATarget(Coords coords, Entity ignore) {
+ public @Nullable Entity getAFFATarget(Coords coords,
+ Entity ignore) {
List candidates = new ArrayList<>();
if (hasBoardLocation(coords, ignore.getBoardId())) {
Hex hex = getHex(coords, ignore.getBoardId());
for (Entity entity : getEntitiesVector(coords, ignore.getBoardId())) {
if (entity.isTargetable() && ((entity.getElevation() == 0) // Standing on hex surface
- || (entity.getElevation() == -hex.depth())) // Standing on hex floor
- && (entity.getAltitude() == 0) && !(entity instanceof Infantry) && (entity != ignore)) {
+ || (entity.getElevation() == -hex.depth())) // Standing on hex floor
+ && (entity.getAltitude() == 0) && !(entity instanceof Infantry) && (entity != ignore)) {
candidates.add(entity);
}
}
@@ -1908,14 +1932,14 @@ public boolean hasRooftopGunEmplacement(Coords c, int boardId) {
*
* @param coords the Coords of the hex being examined.
* @param currentEntity the Entity whose enemies are needed.
- *
* @return an Enumeration of Entitys at the given coordinates who are enemies of the given
- * unit.
+ * unit.
*/
- public Iterator getEnemyEntities(final Coords coords, final Entity currentEntity) {
+ public Iterator getEnemyEntities(final Coords coords,
+ final Entity currentEntity) {
return getSelectedEntities(entity -> coords.equals(entity.getPosition()) &&
- entity.isTargetable() &&
- entity.isEnemyOf(currentEntity));
+ entity.isTargetable() &&
+ entity.isEnemyOf(currentEntity));
}
/**
@@ -1923,24 +1947,24 @@ public Iterator getEnemyEntities(final Coords coords, final Entity curre
*
* @param coords the Coords of the hex being examined.
* @param currentEntity the Entity whose enemies are needed.
- *
* @return an Enumeration of Entitys at the given coordinates who are enemies of the given
- * unit.
+ * unit.
*/
- public List getEnemyEntities(final Coords coords, final int boardId, Entity currentEntity) {
+ public List getEnemyEntities(final Coords coords,
+ final int boardId,
+ Entity currentEntity) {
return getEntitiesVector(coords, boardId).stream()
- .filter(Entity::isTargetable)
- .filter(entity -> entity.isEnemyOf(currentEntity))
- .toList();
+ .filter(Entity::isTargetable)
+ .filter(entity -> entity.isEnemyOf(currentEntity))
+ .toList();
}
/**
* Returns an Enumeration of active enemy entities
*
* @param currentEntity the Entity whose enemies are needed.
- *
* @return an Enumeration of Entitys at the given coordinates who are enemies of the given
- * unit.
+ * unit.
*/
public Iterator getAllEnemyEntities(final Entity currentEntity) {
return getSelectedEntities(entity -> entity.isTargetable() && entity.isEnemyOf(currentEntity));
@@ -1955,14 +1979,14 @@ public Iterator getTeamEntities(final Team team) {
*
* @param coords the Coords of the hex being examined.
* @param currentEntity the Entity whose friends are needed.
- *
* @return an Enumeration of Entitys at the given coordinates who are friends of the given
- * unit.
+ * unit.
*/
- public Iterator getFriendlyEntities(final Coords coords, final Entity currentEntity) {
+ public Iterator getFriendlyEntities(final Coords coords,
+ final Entity currentEntity) {
return getSelectedEntities(entity -> coords.equals(entity.getPosition()) &&
- entity.isTargetable() &&
- !entity.isEnemyOf(currentEntity));
+ entity.isTargetable() &&
+ !entity.isEnemyOf(currentEntity));
}
/**
@@ -1976,9 +2000,8 @@ public void moveToGraveyard(int id) {
* See if the Entity with the given ID is out of the game.
*
* @param id - the ID of the Entity to be checked.
- *
* @return true if the Entity is in the graveyard,
- * false otherwise.
+ * false otherwise.
*/
public boolean isOutOfGame(int id) {
for (Entity entity : vOutOfGame) {
@@ -1994,9 +2017,8 @@ public boolean isOutOfGame(int id) {
* See if the Entity is out of the game.
*
* @param entity - the Entity to be checked.
- *
* @return true if the Entity is in the graveyard,
- * false otherwise.
+ * false otherwise.
*/
public boolean isOutOfGame(Entity entity) {
return isOutOfGame(entity.getId());
@@ -2011,7 +2033,6 @@ public boolean isOutOfGame(Entity entity) {
/**
* @param turn the current game turn, which may be null
- *
* @return the first entity that can act in the specified turn, or null if none can.
*/
public @Nullable Entity getFirstEntity(final @Nullable GameTurn turn) {
@@ -2027,7 +2048,6 @@ public int getFirstEntityNum() {
/**
* @param turn the current game turn, which may be null
- *
* @return the id of the first entity that can act in the specified turn, or -1 if none can.
*/
public int getFirstEntityNum(final @Nullable GameTurn turn) {
@@ -2046,7 +2066,6 @@ public int getFirstEntityNum(final @Nullable GameTurn turn) {
/**
* @param start the index number to start at (not an Entity ID)
- *
* @return the next selectable entity that can act this turn, or null if none can.
*/
public @Nullable Entity getNextEntity(int start) {
@@ -2061,10 +2080,10 @@ public int getFirstEntityNum(final @Nullable GameTurn turn) {
/**
* @param turn the turn to use, which may be null
* @param start the entity id to start at
- *
* @return the entity id of the next entity that can move during the specified turn
*/
- public int getNextEntityNum(final @Nullable GameTurn turn, int start) {
+ public int getNextEntityNum(final @Nullable GameTurn turn,
+ int start) {
List sortedEntities = inGameTWEntities();
sortedEntities.sort(Comparator.comparingInt(Entity::getId));
// If we don't have a turn, return ENTITY_NONE
@@ -2096,10 +2115,10 @@ public int getNextEntityNum(final @Nullable GameTurn turn, int start) {
/**
* @param turn the turn to use
* @param start the entity id to start at
- *
* @return the entity id of the previous entity that can move during the specified turn
*/
- public int getPrevEntityNum(GameTurn turn, int start) {
+ public int getPrevEntityNum(GameTurn turn,
+ int start) {
List sortedEntities = inGameTWEntities();
sortedEntities.sort(Comparator.comparingInt(Entity::getId));
boolean hasLooped = false;
@@ -2130,7 +2149,6 @@ public int getPrevEntityNum(GameTurn turn, int start) {
/**
* @param turn the current game turn, which may be null
- *
* @return the number of the first deployable entity that is valid for the specified turn
*/
public int getFirstDeployableEntityNum(final @Nullable GameTurn turn) {
@@ -2149,7 +2167,8 @@ public int getFirstDeployableEntityNum(final @Nullable GameTurn turn) {
/**
* @return the number of the next deployable entity that is valid for the specified turn
*/
- public int getNextDeployableEntityNum(GameTurn turn, int start) {
+ public int getNextDeployableEntityNum(GameTurn turn,
+ int start) {
if (start >= 0) {
for (int i = start; i < inGameTWEntities().size(); i++) {
final Entity entity = inGameTWEntities().get(i);
@@ -2163,7 +2182,6 @@ public int getNextDeployableEntityNum(GameTurn turn, int start) {
/**
* @param turn the current game turn, which may be null
- *
* @return the number of the first hidden entity that is valid for the specified turn
*/
@Deprecated(since = "0.51.0", forRemoval = true)
@@ -2189,7 +2207,8 @@ public int getFirstHiddenEntityNum(final @Nullable GameTurn turn) {
* @return the number of the next hidden entity that is valid for the specified turn
*/
@Deprecated(since = "0.51.0", forRemoval = true)
- public int getNextHiddenEntityNum(GameTurn turn, int start) {
+ public int getNextHiddenEntityNum(GameTurn turn,
+ int start) {
if (start >= 0) {
for (int i = start; i < inGameTWEntities().size(); i++) {
final Entity entity = inGameTWEntities().get(i);
@@ -2206,10 +2225,10 @@ public int getNextHiddenEntityNum(GameTurn turn, int start) {
*
* @param player - the Player whose entities are required.
* @param hide - should fighters loaded into squadrons be excluded?
- *
* @return a Vector of Entitys.
*/
- public ArrayList getPlayerEntities(Player player, boolean hide) {
+ public ArrayList getPlayerEntities(Player player,
+ boolean hide) {
ArrayList output = new ArrayList<>();
for (Entity entity : inGameTWEntities()) {
if (entity.isPartOfFighterSquadron() && hide) {
@@ -2227,11 +2246,11 @@ public ArrayList getPlayerEntities(Player player, boolean hide) {
*
* @param player - the Player whose entities are required.
* @param hide - should fighters loaded into squadrons be excluded from this list?
- *
* @return a Vector of Entitys.
*/
@Deprecated(since = "0.51.0", forRemoval = true)
- public ArrayList getPlayerEntityIds(Player player, boolean hide) {
+ public ArrayList getPlayerEntityIds(Player player,
+ boolean hide) {
ArrayList output = new ArrayList<>();
for (Entity entity : inGameTWEntities()) {
if (entity.isPartOfFighterSquadron() && hide) {
@@ -2248,16 +2267,15 @@ public ArrayList getPlayerEntityIds(Player player, boolean hide) {
* Get the entities for the player.
*
* @param player - the Player whose entities are required.
- *
* @return a Vector of Entity that have retreadeds.
*/
public ArrayList getPlayerRetreatedEntities(Player player) {
ArrayList output = new ArrayList<>();
for (Entity entity : vOutOfGame) {
if (player.equals(entity.getOwner()) &&
- ((entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_IN_RETREAT) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_CAPTURED) ||
- (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_PUSHED))) {
+ ((entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_IN_RETREAT) ||
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_CAPTURED) ||
+ (entity.getRemovalCondition() == IEntityRemovalConditions.REMOVE_PUSHED))) {
output.add(entity);
}
}
@@ -2270,9 +2288,8 @@ public ArrayList getPlayerRetreatedEntities(Player player) {
* According to Randall Bills, the "minimum move" rule allow stranded units to dismount at the start of the turn.
*
* @param entity the Entity that may be stranded
- *
* @return true if the entity is stranded false
- * otherwise.
+ * otherwise.
*/
public boolean isEntityStranded(Entity entity) {
@@ -2294,7 +2311,6 @@ public boolean isEntityStranded(Entity entity) {
/**
* @param playerId the player's ID
- *
* @return number of infantry playerId has not selected yet this turn
*/
public int getInfantryLeft(int playerId) {
@@ -2312,7 +2328,6 @@ public int getInfantryLeft(int playerId) {
/**
* @param playerId the player's ID
- *
* @return number of ProtoMeks playerId has not selected yet this turn
*/
public int getProtoMeksLeft(int playerId) {
@@ -2330,7 +2345,6 @@ public int getProtoMeksLeft(int playerId) {
/**
* @param playerId the player's ID
- *
* @return number of vehicles playerId has not selected yet this turn
*/
public int getVehiclesLeft(int playerId) {
@@ -2348,7 +2362,6 @@ public int getVehiclesLeft(int playerId) {
/**
* @param playerId the player's ID
- *
* @return number of 'Meks playerId has not selected yet this turn
*/
public int getMeksLeft(int playerId) {
@@ -2368,9 +2381,7 @@ public int getMeksLeft(int playerId) {
* Removes the first turn found that the specified entity can move in. Used when a turn is played out of order.
*
* @param entity the entity to remove a turn for
- *
* @return the removed GameTurn, or null if not found
- *
* @throws Exception if called during the movement phase
*/
public @Nullable GameTurn removeFirstTurnFor(final Entity entity) throws Exception {
@@ -2403,17 +2414,17 @@ public void removeTurnFor(Entity entity) {
// If the game option "move multiple infantry per mek" is selected, then we might not need to remove a turn
// at all. A turn only needs to be removed when going from 4 inf (2 turns) to 3 inf (1 turn)
if (getOptions().booleanOption(OptionsConstants.INIT_INF_MOVE_MULTI) &&
- (entity instanceof Infantry) &&
- getPhase().isMovement()) {
+ (entity instanceof Infantry) &&
+ getPhase().isMovement()) {
if ((getInfantryLeft(entity.getOwnerId()) %
- getOptions().intOption(OptionsConstants.INIT_INF_PROTO_MOVE_MULTI)) != 1) {
+ getOptions().intOption(OptionsConstants.INIT_INF_PROTO_MOVE_MULTI)) != 1) {
// exception, if the _next_ turn is an infantry turn, remove that contrived, but may come up e.g. one
// inf accidentally kills another
if (hasMoreTurns()) {
GameTurn nextTurn = turnVector.elementAt(turnIndex + 1);
if (nextTurn instanceof EntityClassTurn ect) {
if (ect.isValidClass(EntityClassTurn.CLASS_INFANTRY) &&
- !ect.isValidClass(~EntityClassTurn.CLASS_INFANTRY)) {
+ !ect.isValidClass(~EntityClassTurn.CLASS_INFANTRY)) {
turnVector.removeElementAt(turnIndex + 1);
}
}
@@ -2423,17 +2434,17 @@ public void removeTurnFor(Entity entity) {
}
// Same thing but for ProtoMeks
if (getOptions().booleanOption(OptionsConstants.INIT_PROTOMEKS_MOVE_MULTI) &&
- (entity instanceof ProtoMek) &&
- getPhase().isMovement()) {
+ (entity instanceof ProtoMek) &&
+ getPhase().isMovement()) {
if ((getProtoMeksLeft(entity.getOwnerId()) %
- getOptions().intOption(OptionsConstants.INIT_INF_PROTO_MOVE_MULTI)) != 1) {
+ getOptions().intOption(OptionsConstants.INIT_INF_PROTO_MOVE_MULTI)) != 1) {
// exception, if the _next_ turn is an ProtoMek turn, remove that contrived, but may come up e.g. one
// inf accidentally kills another
if (hasMoreTurns()) {
GameTurn nextTurn = turnVector.elementAt(turnIndex + 1);
if (nextTurn instanceof EntityClassTurn ect) {
if (ect.isValidClass(EntityClassTurn.CLASS_PROTOMEK) &&
- !ect.isValidClass(~EntityClassTurn.CLASS_PROTOMEK)) {
+ !ect.isValidClass(~EntityClassTurn.CLASS_PROTOMEK)) {
turnVector.removeElementAt(turnIndex + 1);
}
}
@@ -2444,18 +2455,18 @@ public void removeTurnFor(Entity entity) {
// Same thing but for vehicles
if (getOptions().booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_VEHICLE_LANCE_MOVEMENT) &&
- (entity instanceof Tank) &&
- getPhase().isMovement()) {
+ (entity instanceof Tank) &&
+ getPhase().isMovement()) {
if ((getVehiclesLeft(entity.getOwnerId()) %
- getOptions().intOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_VEHICLE_LANCE_MOVEMENT_NUMBER))
- != 1) {
+ getOptions().intOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_VEHICLE_LANCE_MOVEMENT_NUMBER))
+ != 1) {
// exception, if the _next_ turn is a tank turn, remove that contrived, but may come up e.g. one tank
// accidentally kills another
if (hasMoreTurns()) {
GameTurn nextTurn = turnVector.elementAt(turnIndex + 1);
if (nextTurn instanceof EntityClassTurn ect) {
if (ect.isValidClass(EntityClassTurn.CLASS_TANK) &&
- !ect.isValidClass(~EntityClassTurn.CLASS_TANK)) {
+ !ect.isValidClass(~EntityClassTurn.CLASS_TANK)) {
turnVector.removeElementAt(turnIndex + 1);
}
}
@@ -2466,18 +2477,18 @@ public void removeTurnFor(Entity entity) {
// Same thing but for meks
if (getOptions().booleanOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_MEK_LANCE_MOVEMENT) &&
- (entity instanceof Mek) &&
- getPhase().isMovement()) {
+ (entity instanceof Mek) &&
+ getPhase().isMovement()) {
if ((getMeksLeft(entity.getOwnerId()) %
- getOptions().intOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_MEK_LANCE_MOVEMENT_NUMBER))
- != 1) {
+ getOptions().intOption(OptionsConstants.ADVANCED_GROUND_MOVEMENT_MEK_LANCE_MOVEMENT_NUMBER))
+ != 1) {
// exception, if the _next_ turn is a mek turn, remove that contrived, but may come up e.g. one mek
// accidentally kills another
if (hasMoreTurns()) {
GameTurn nextTurn = turnVector.elementAt(turnIndex + 1);
if (nextTurn instanceof EntityClassTurn ect) {
if (ect.isValidClass(EntityClassTurn.CLASS_MEK) &&
- !ect.isValidClass(~EntityClassTurn.CLASS_MEK)) {
+ !ect.isValidClass(~EntityClassTurn.CLASS_MEK)) {
turnVector.removeElementAt(turnIndex + 1);
}
}
@@ -2489,9 +2500,9 @@ public void removeTurnFor(Entity entity) {
// If we have the "infantry move later" or "ProtoMeks move later" optional rules, then we may be removing an
// infantry unit that would be considered invalid unless we don't consider the extra validity checks.
boolean useInfantryMoveLaterCheck = (!getOptions().booleanOption(OptionsConstants.INIT_INF_MOVE_LATER) ||
- (!(entity instanceof Infantry))) &&
- (!getOptions().booleanOption(OptionsConstants.INIT_PROTOMEKS_MOVE_LATER) ||
- (!(entity instanceof ProtoMek)));
+ (!(entity instanceof Infantry))) &&
+ (!getOptions().booleanOption(OptionsConstants.INIT_PROTOMEKS_MOVE_LATER) ||
+ (!(entity instanceof ProtoMek)));
for (int i = turnVector.size() - 1; i >= turnIndex; i--) {
GameTurn turn = turnVector.elementAt(i);
@@ -2509,7 +2520,6 @@ public void removeTurnFor(Entity entity) {
* from the game to ensure any turns that only it can take are gone.
*
* @param entity the entity to remove turns for
- *
* @return The number of turns returned
*/
public int removeSpecificEntityTurnsFor(Entity entity) {
@@ -2578,7 +2588,7 @@ public void setEnemyArtilleryInbound(List inbound) {
/**
* @return The redacted enemy artillery-in-flight summaries (landing time only; target and munition withheld); never
- * {@code null} (empty when none, or after deserializing a saved game where this transient field is unset)
+ * {@code null} (empty when none, or after deserializing a saved game where this transient field is unset)
*/
public List getEnemyArtilleryInbound() {
return (enemyArtilleryInbound != null) ? enemyArtilleryInbound : new ArrayList<>();
@@ -2640,9 +2650,9 @@ public void rollInitAndResolveTies() {
}
TurnOrdered.rollInitAndResolveTies(teams,
- initiativeRerollRequests,
- getOptions().booleanOption(OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION),
- initiativeAptitude);
+ initiativeRerollRequests,
+ getOptions().booleanOption(OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION),
+ initiativeAptitude);
}
initiativeRerollRequests.removeAllElements();
@@ -2651,7 +2661,7 @@ public void rollInitAndResolveTies() {
public void handleInitiativeCompensation() {
if (getOptions().booleanOption(OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION)) {
TurnOrdered.resetInitiativeCompensation(teams,
- getOptions().booleanOption(OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION));
+ getOptions().booleanOption(OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION));
}
}
@@ -2742,7 +2752,9 @@ public void initializeAfterLoad() {
// Reverse traverse the pendingDisplacementAttacks, otherwise when we remove things, it causes problems
for (int attack = (pendingDisplacementAttacks.size() - 1); attack >= 0; attack--) {
AttackAction pendingAttack = pendingDisplacementAttacks.get(attack);
- if (pendingAttack == null) {continue;}
+ if (pendingAttack == null) {
+ continue;
+ }
if (pendingAttack instanceof RamAttackAction) {
addRam(pendingAttack);
pendingDisplacementAttacks.remove(attack);
@@ -2791,7 +2803,6 @@ public List getTeleMissileAttacksVector() {
* Adds a pending PSR to the list for this phase.
*
* @param psr Pending PSR.
- *
* @see PilotingRollData
*/
public void addPSR(PilotingRollData psr) {
@@ -3010,7 +3021,6 @@ public void addReports(List v) {
/**
* @param r Round number
- *
* @return a vector of reports for the given round.
*/
public List getReports(int r) {
@@ -3038,7 +3048,8 @@ public void clearAllReports() {
gameReports.clear();
}
- public void end(int winner, int winnerTeam) {
+ public void end(int winner,
+ int winnerTeam) {
setVictoryPlayerId(winner);
setVictoryTeam(winnerTeam);
processGameEvent(new GameEndEvent(this));
@@ -3083,7 +3094,7 @@ public void setVictoryTeam(int victoryTeam) {
/**
* @return true if the specified player is either the victor, or is on the winning team. Best to call during
- * GamePhase.VICTORY.
+ * GamePhase.VICTORY.
*/
@Deprecated(since = "0.51.0", forRemoval = true)
public boolean isPlayerVictor(Player player) {
@@ -3095,9 +3106,9 @@ public boolean isPlayerVictor(Player player) {
/**
* @return the currently active context-object for VictoryCondition checking. This should be a mutable object, and
- * it will be modified by the victory condition checkers. Whoever saves the game state when doing saves is
- * also responsible for saving this state. At the start of the game this should be initialized to an empty
- * HashMap
+ * it will be modified by the victory condition checkers. Whoever saves the game state when doing saves is
+ * also responsible for saving this state. At the start of the game this should be initialized to an empty
+ * HashMap
*/
public HashMap getVictoryContext() {
return victoryContext;
@@ -3131,9 +3142,8 @@ public void setVictoryPointLevels(List victoryPointLevels) {
* This value may be
* null (in which case all entities in the game
* will be returned).
- *
* @return an Enumeration of all entities that the selector accepts. This value will not be
- * null but it may be empty.
+ * null but it may be empty.
*/
public Iterator getSelectedEntities(@Nullable EntitySelector selector) {
Iterator retVal;
@@ -3202,9 +3212,8 @@ public void remove() {
* This value may be
* null (in which case the count of all entities in
* the game will be returned).
- *
* @return the int count of all entities that the selector accepts. This value will not be
- * null but it may be empty.
+ * null but it may be empty.
*/
public int getSelectedEntityCount(EntitySelector selector) {
int retVal = 0;
@@ -3235,9 +3244,8 @@ public int getSelectedEntityCount(EntitySelector selector) {
* This value may be
* null (in which case all entities in the game
* will be returned).
- *
* @return an Enumeration of all entities that the selector accepts. This value will not be
- * null but it may be empty.
+ * null but it may be empty.
*/
public Enumeration getSelectedOutOfGameEntities(EntitySelector selector) {
Enumeration retVal;
@@ -3301,9 +3309,8 @@ public Entity nextElement() {
* This value may be
* null (in which case the count of all out-of-game
* entities will be returned).
- *
* @return the int count of all entities that the selector accepts. This value will not be
- * null but it may be empty.
+ * null but it may be empty.
*/
public int getSelectedOutOfGameEntityCount(EntitySelector selector) {
int retVal = 0;
@@ -3339,7 +3346,7 @@ public boolean checkForValidNonInfantryAndOrProtoMeks(int playerId) {
if ((entity instanceof Infantry) && getOptions().booleanOption(OptionsConstants.INIT_INF_MOVE_LATER)) {
excluded = true;
} else if ((entity instanceof ProtoMek) &&
- getOptions().booleanOption(OptionsConstants.INIT_PROTOMEKS_MOVE_LATER)) {
+ getOptions().booleanOption(OptionsConstants.INIT_PROTOMEKS_MOVE_LATER)) {
excluded = true;
}
@@ -3355,11 +3362,11 @@ public boolean checkForValidNonInfantryAndOrProtoMeks(int playerId) {
*
* @param attacker The attacking Entity.
* @param target The Coords of the original target.
- *
* @return an Enumeration of entities that have nemesis pods attached, are located between attacker and
- * target, and are friendly with the attacker.
+ * target, and are friendly with the attacker.
*/
- public Enumeration getNemesisTargets(Entity attacker, Coords target) {
+ public Enumeration getNemesisTargets(Entity attacker,
+ Coords target) {
final Coords attackerPos = attacker.getPosition();
final ArrayList in = Coords.intervening(attackerPos, target);
Vector nemesisTargets = new Vector<>();
@@ -3482,7 +3489,7 @@ public Vector ageFlares() {
if (!planetaryConditions.getWind().isCalm()) {
WindDirection dir = planetaryConditions.getWindDirection();
flare.position = flare.position.translated(dir.ordinal(),
- (wind.ordinal() > 1) ? (wind.ordinal() - 1) : wind.ordinal());
+ (wind.ordinal() > 1) ? (wind.ordinal() - 1) : wind.ordinal());
if (getBoard().contains(flare.position)) {
r = new Report(5236);
r.add(flare.position.getBoardNum());
@@ -3519,7 +3526,7 @@ public Vector ageFlares() {
public boolean gameTimerIsExpired() {
return getOptions().booleanOption(OptionsConstants.VICTORY_USE_GAME_TURN_LIMIT) &&
- (getRoundCount() == getOptions().intOption(OptionsConstants.VICTORY_GAME_TURN_LIMIT));
+ (getRoundCount() == getOptions().intOption(OptionsConstants.VICTORY_GAME_TURN_LIMIT));
}
/**
@@ -3539,7 +3546,7 @@ public VictoryResult getVictoryResult() {
// applicable
public boolean useVectorMove() {
return getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_ADVANCED_MOVEMENT)
- && getBoard().isSpace();
+ && getBoard().isSpace();
}
/**
@@ -3611,8 +3618,9 @@ public boolean checkForValidDropShips(int playerId) {
@Deprecated(since = "0.51.0", forRemoval = true)
public boolean checkForValidSmallCraft(int playerId) {
return getPlayerEntities(getPlayer(playerId), false).stream()
- .anyMatch(e -> (e instanceof SmallCraft) &&
- Objects.requireNonNull(getTurn()).isValidEntity(e, this));
+ .anyMatch(e -> (e instanceof SmallCraft) &&
+ Objects.requireNonNull(getTurn())
+ .isValidEntity(e, this));
}
@Override
@@ -3668,7 +3676,6 @@ public void addIndustrialElevator(IndustrialElevator elevator) {
* Gets an industrial elevator at the specified location.
*
* @param location The board location to check
- *
* @return The elevator at this location, or {@code null} if none exists
*/
public @Nullable IndustrialElevator getIndustrialElevator(BoardLocation location) {
@@ -3680,10 +3687,10 @@ public void addIndustrialElevator(IndustrialElevator elevator) {
*
* @param coords The coordinates to check
* @param boardId The board ID
- *
* @return The elevator at this location, or {@code null} if none exists
*/
- public @Nullable IndustrialElevator getIndustrialElevator(Coords coords, int boardId) {
+ public @Nullable IndustrialElevator getIndustrialElevator(Coords coords,
+ int boardId) {
return getIndustrialElevator(BoardLocation.of(coords, boardId));
}
@@ -3700,7 +3707,6 @@ public Collection getIndustrialElevators() {
* Checks if there is an industrial elevator at the specified location.
*
* @param location The board location to check
- *
* @return {@code true} if an elevator exists at this location
*/
public boolean hasIndustrialElevator(BoardLocation location) {
@@ -3711,7 +3717,6 @@ public boolean hasIndustrialElevator(BoardLocation location) {
* Removes an industrial elevator from the game.
*
* @param location The location of the elevator to remove
- *
* @return The removed elevator, or {@code null} if none was found
*/
public @Nullable IndustrialElevator removeIndustrialElevator(BoardLocation location) {
@@ -3771,7 +3776,8 @@ public void setTemporaryECMFields(List fields) {
* @param currentRound The current game round
* @param currentPhase The current game phase
*/
- public void removeExpiredECMFields(int currentRound, GamePhase currentPhase) {
+ public void removeExpiredECMFields(int currentRound,
+ GamePhase currentPhase) {
temporaryECMFields.removeIf(field -> field.isExpired(currentRound, currentPhase));
}
@@ -3782,9 +3788,7 @@ public void removeExpiredECMFields(int currentRound, GamePhase currentPhase) {
* usually unnecessary.
*
* @param entity Entity we want to get the cached old positions of
- *
* @return cached coords that contain this entity
- *
* @see Dropship#setPosition(Coords)
*/
public synchronized HashSet getEntityPositions(Entity entity) {
@@ -3804,7 +3808,8 @@ public synchronized HashSet getEntityPositions(Entity entity) {
/**
* Updates the map that maps a position to the list of Entity's in that position.
*/
- public synchronized void updateEntityPositionLookup(Entity e, HashSet oldPositions) {
+ public synchronized void updateEntityPositionLookup(Entity e,
+ HashSet oldPositions) {
HashSet newPositions = e.getOccupiedCoords();
// Check to see that the position has actually changed
if (newPositions.equals(oldPositions)) {
@@ -3880,14 +3885,14 @@ private void checkPositionCacheConsistency() {
Collections.sort(entitiesInCache);
Collections.sort(entitiesInVector);
if ((entitiesInCacheCount != entityVectorSize) &&
- !getPhase().isDeployment() &&
- !getPhase().isExchange() &&
- !getPhase().isLounge() &&
- !getPhase().isInitiativeReport() &&
- !getPhase().isInitiative()) {
+ !getPhase().isDeployment() &&
+ !getPhase().isExchange() &&
+ !getPhase().isLounge() &&
+ !getPhase().isInitiativeReport() &&
+ !getPhase().isInitiative()) {
logger.warn("Entities vector has {} but pos lookup cache has {} entities!",
- inGameTWEntities().size(),
- entitiesInCache.size());
+ inGameTWEntities().size(),
+ entitiesInCache.size());
List missingIds = new ArrayList<>();
for (Integer id : entitiesInVector) {
if (!entitiesInCache.contains(id)) {
@@ -3902,8 +3907,8 @@ private void checkPositionCacheConsistency() {
HashSet entityIDs = entityPosLookup.get(coords);
if ((entityIDs != null) && !entityIDs.contains(entity.getId())) {
logger.warn("Entity {} is in {} however the position cache does not have it in that position!",
- entity.getId(),
- entity.getPosition());
+ entity.getId(),
+ entity.getPosition());
}
}
}
@@ -3916,9 +3921,9 @@ private void checkPositionCacheConsistency() {
HashSet positions = e.getOccupiedCoords();
if (!positions.contains(c)) {
logger.warn("Entity Position Cache thinks Entity {} is in {} but the Entity thinks it's in {}",
- eId,
- c,
- e.getPosition());
+ eId,
+ c,
+ e.getPosition());
}
}
}
@@ -3950,7 +3955,8 @@ public void setBotSettings(Map botSettings) {
* @param botPlayerId the reporting bot's player ID
* @param dishonoredPlayerIds the player IDs that bot considers dishonored
*/
- public void setDishonoredPlayers(int botPlayerId, Collection dishonoredPlayerIds) {
+ public void setDishonoredPlayers(int botPlayerId,
+ Collection dishonoredPlayerIds) {
ensureDishonoredPlayers().put(botPlayerId, new HashSet<>(dishonoredPlayerIds));
}
@@ -3964,7 +3970,8 @@ public void setDishonoredPlayers(int botPlayerId, Collection dishonored
* @param botPlayerId the bot player that now holds a grudge
* @param playerId the player it now considers dishonored
*/
- public void addDishonoredPlayer(int botPlayerId, int playerId) {
+ public void addDishonoredPlayer(int botPlayerId,
+ int playerId) {
Map> byBot = ensureDishonoredPlayers();
Set current = byBot.get(botPlayerId);
Set updated = (current == null) ? new HashSet<>() : new HashSet<>(current);
@@ -3975,12 +3982,12 @@ public void addDishonoredPlayer(int botPlayerId, int playerId) {
/**
* @param botPlayerId the bot player whose honor opinion is being queried
* @param playerId the player who may be dishonored
- *
* @return true if the bot with player ID {@code botPlayerId} currently considers {@code playerId} dishonored, as
- * last reported via {@link megamek.common.net.enums.PacketCommand#PRINCESS_DISHONORED}. False if that bot has
- * not reported (e.g. it is not a Princess bot, or the report has not arrived yet).
+ * last reported via {@link megamek.common.net.enums.PacketCommand#PRINCESS_DISHONORED}. False if that bot has
+ * not reported (e.g. it is not a Princess bot, or the report has not arrived yet).
*/
- public boolean isPlayerDishonoredBy(int botPlayerId, int playerId) {
+ public boolean isPlayerDishonoredBy(int botPlayerId,
+ int playerId) {
Set dishonored = ensureDishonoredPlayers().get(botPlayerId);
return (dishonored != null) && dishonored.contains(playerId);
}
@@ -3995,8 +4002,8 @@ private Map> ensureDishonoredPlayers() {
/**
* @return which AI implementation the most recent bot connected under each player name was, as an unmodifiable
- * view; never {@code null} - games saved before the types were recorded read as an empty map. Record entries
- * through {@link #recordBotType(String, AIType)}.
+ * view; never {@code null} - games saved before the types were recorded read as an empty map. Record entries
+ * through {@link #recordBotType(String, AIType)}.
*/
public Map getBotTypes() {
return Collections.unmodifiableMap(ensureBotTypes());
@@ -4008,7 +4015,8 @@ public Map getBotTypes() {
* @param playerName the bot player's name
* @param aiType the AI implementation it reported
*/
- public void recordBotType(String playerName, AIType aiType) {
+ public void recordBotType(String playerName,
+ AIType aiType) {
ensureBotTypes().put(playerName, aiType);
}
@@ -4027,7 +4035,8 @@ private Map ensureBotTypes() {
/**
* Get a list of all objects on the ground at the given coordinates that can be picked up by the given entity
*/
- public List getGroundObjects(Coords coords, Entity entity) {
+ public List getGroundObjects(Coords coords,
+ Entity entity) {
if (!getGroundObjects().containsKey(coords)) {
return new ArrayList<>();
}
@@ -4079,7 +4088,9 @@ public void setMapSettings(MapSettings mapSettings) {
this.mapSettings = mapSettings;
}
- /** @return The TW Units (Entity) currently in the game. */
+ /**
+ * @return The TW Units (Entity) currently in the game.
+ */
public List inGameTWEntities() {
return filterToEntity(inGameObjects.values());
}
@@ -4095,7 +4106,6 @@ public ReportEntry getNewReport(int messageId) {
/**
* @param playerName The name of the Player to find.
- *
* @return The ID of the Player with the given name, if there is such a Player.
*/
public Optional idForPlayerName(String playerName) {
@@ -4104,7 +4114,6 @@ public Optional idForPlayerName(String playerName) {
/**
* @param playerName The name of the Player to find.
- *
* @return The ID of the Player with the given name, if there is such a Player.
*/
public Optional playerForPlayerName(String playerName) {
@@ -4115,7 +4124,6 @@ public Optional playerForPlayerName(String playerName) {
* Returns the Building at the given location, if any. Shortcut to Board.getBuildingAt().
*
* @param boardLocation The location to check
- *
* @return The building at the location, if any
*/
public Optional getBuildingAt(@Nullable BoardLocation boardLocation) {
@@ -4127,10 +4135,10 @@ public Optional getBuildingAt(@Nullable BoardLocation boardLocation)
*
* @param boardId The board ID
* @param coords The position on the board
- *
* @return The building at the location, if any
*/
- public Optional