From 8fdd24afb42ae7ad9b04ba3f142740ce58400d62 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 6 Oct 2024 10:00:13 +0200 Subject: [PATCH] restore altitude behavior for Princess deploying Aero --- .../megamek/client/bot/princess/Princess.java | 31 +++++++++++++++---- .../common/AllowedDeploymentHelper.java | 30 ++++++++++++++---- .../src/megamek/common/ElevationOption.java | 8 ++--- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/megamek/src/megamek/client/bot/princess/Princess.java b/megamek/src/megamek/client/bot/princess/Princess.java index 8654a01c24..a556e0498f 100644 --- a/megamek/src/megamek/client/bot/princess/Princess.java +++ b/megamek/src/megamek/client/bot/princess/Princess.java @@ -523,13 +523,32 @@ protected void calculateDeployment() { decentFacing = deployCoords.direction(center); } - final Entity deployEntity = game.getEntity(entityNum); + final Entity deployEntity = getEntity(entityNum); final Hex deployHex = game.getBoard().getHex(deployCoords); - - int deployElevation = getDeployElevation(deployEntity, deployHex); - - // Compensate for hex elevation where != 0... - deployElevation -= deployHex.getLevel(); + int deployElevation = deployEntity.getElevation(); + + if (deployEntity.isAero()) { + if (game.getBoard().onGround()) { + // keep the altitude set in the lobby, possibly starting grounded + deployElevation = deployEntity.getAltitude(); + } else if (game.getBoard().inAtmosphere()) { + // try to keep the altitude set in the lobby, but stay above the terrain + var deploymentHelper = new AllowedDeploymentHelper(deployEntity, deployCoords, game.getBoard(), deployHex, game); + List allowedDeployment = deploymentHelper.findAllowedElevations(DeploymentElevationType.ALTITUDE); + if (allowedDeployment.isEmpty()) { + // that's bad, cannot deploy at all + logger.error("Cannot find viable altitude to deploy to"); + sendDeleteEntity(entityNum); + return; + } else { + deployElevation = Math.max(deployEntity.getAltitude(), Collections.min(allowedDeployment).elevation()); + } + } + } else { + deployElevation = getDeployElevation(deployEntity, deployHex); + // Compensate for hex elevation where != 0... + deployElevation -= deployHex.getLevel(); + } deploy(entityNum, deployCoords, decentFacing, deployElevation); } diff --git a/megamek/src/megamek/common/AllowedDeploymentHelper.java b/megamek/src/megamek/common/AllowedDeploymentHelper.java index c9b6f1d188..0259a594c6 100644 --- a/megamek/src/megamek/common/AllowedDeploymentHelper.java +++ b/megamek/src/megamek/common/AllowedDeploymentHelper.java @@ -18,6 +18,8 @@ */ package megamek.common; +import megamek.common.annotations.Nullable; + import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -27,16 +29,28 @@ public record AllowedDeploymentHelper(Entity entity, Coords coords, Board board, Hex hex, Game game) { /** - * Returns a list of elevations/altitudes that the given entity can deploy to at the given coords. This - * can be anything from the seafloor, swimming, ice, water surface, ground, up to elevations and - * altitudes. For VTOLs, elevations up to 10 are always included individually if available. Above that - * and above all terrain features of the hex, only a single elevation is reported using the - * ELEVATIONS_ABOVE marker, meaning that any elevation above the reported value is also available. - * Altitudes are always reported individually (0 to 10). + * Returns a list of elevations/altitudes that the given entity can deploy to at the given coords. This can be anything from the + * seafloor, swimming, ice, water surface, ground, up to elevations and altitudes. For VTOLs, elevations up to 10 are always included + * individually if available. Above that and above all terrain features of the hex, only a single elevation is reported using the + * ELEVATIONS_ABOVE marker, meaning that any elevation above the reported value is also available. Altitudes are always reported + * individually (0 to 10). * * @return All legal deployment elevations/altitudes */ public List findAllowedElevations() { + return findAllowedElevations(null); + } + + /** + * Returns a list of elevations/altitudes that the given entity can deploy to at the given coords that are of the given type. This can + * be anything from the seafloor, swimming, ice, water surface, ground, up to elevations and altitudes. For VTOLs, elevations up to 10 + * are always included individually if available. Above that and above all terrain features of the hex, only a single elevation is + * reported using the ELEVATIONS_ABOVE marker, meaning that any elevation above the reported value is also available. Altitudes are + * always reported individually (0 to 10). + * + * @return All legal deployment elevations/altitudes of the given type + */ + public List findAllowedElevations(@Nullable DeploymentElevationType limitToType) { if (board.inSpace()) { throw new IllegalStateException("Cannot find allowed deployment elevations in space!"); } @@ -54,6 +68,10 @@ public List findAllowedElevations() { addAirborneWigeOptions(result); } + if (limitToType != null) { + result.removeIf(o -> o.type() != limitToType); + } + Collections.sort(result); return result; } diff --git a/megamek/src/megamek/common/ElevationOption.java b/megamek/src/megamek/common/ElevationOption.java index 8b70cb5479..2139bd79d8 100644 --- a/megamek/src/megamek/common/ElevationOption.java +++ b/megamek/src/megamek/common/ElevationOption.java @@ -21,12 +21,12 @@ import java.util.Objects; /** - * This is a data record for a possible deployment elevation together with a DeploymentElevationType that - * signals if the elevation is, e.g., on the ground, on a bridge or submerged. Note that two such records are - * equal when their elevation and type are equal. + * This is a data record for a possible deployment elevation together with a DeploymentElevationType that signals if the elevation is, e.g., + * on the ground, on a bridge or submerged. Note that two such records are equal when their elevation and type are equal. ElevationOptions + * are comparable, with the natural ordering being by their elevation only. * * @param elevation The elevation or altitude in the hex - * @param type the DeploymentElevationType (on the ground, on a bridge, ...) + * @param type the DeploymentElevationType (on the ground, on a bridge, ...) */ public record ElevationOption(int elevation, DeploymentElevationType type) implements Comparable {