From 62f1b04f4c50cf74ab1945fba678fa55e5a00f5c Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 16 Jan 2023 19:59:37 -0500 Subject: [PATCH 1/5] SPA Cross-Country --- .../common/options/messages.properties | 2 + megamek/src/megamek/common/Tank.java | 21 +++++++++ megamek/src/megamek/common/Terrain.java | 44 +++++++++++++++++++ .../common/options/OptionsConstants.java | 5 +-- .../megamek/common/options/PilotOptions.java | 2 +- 5 files changed, 70 insertions(+), 4 deletions(-) diff --git a/megamek/i18n/megamek/common/options/messages.properties b/megamek/i18n/megamek/common/options/messages.properties index 9f614ddb2fb..fcfffa5a3e1 100644 --- a/megamek/i18n/megamek/common/options/messages.properties +++ b/megamek/i18n/megamek/common/options/messages.properties @@ -533,6 +533,8 @@ PilotOptionsInfo.option.animal_mimic.displayableName=Animal Mimicry (CamOps) PilotOptionsInfo.option.animal_mimic.description=Allows a Quad Mek or ProtoMek, or a bipedal Mek or ProtoMek with the animalistic quirk, the following benefits.\n-1 MP per hex of Woods and Jungle terrain.\n In addition quads gain a -1 to any quad related PSR check.\nNOTE: The quirk should be used only on bipedal units that have an animal like appearance. PilotOptionsInfo.option.blood_stalker.displayableName=Blood Stalker (CamOps) PilotOptionsInfo.option.blood_stalker.description=Unit has -1 bonus against designated target, +2 penalty against all others; lasts until target retreats, can only be used once per battle. +PilotOptionsInfo.option.cross_country.displayableName=Cross-Country (CamOps) +PilotOptionsInfo.option.cross_country.description=Allows a unit to use terrain normally restricted to said unit at the cost of increased MP. PilotOptionsInfo.option.dodge_maneuver.displayableName= Dodge (MaxTech) PilotOptionsInfo.option.dodge_maneuver.description=Enables the unit to make a dodge maneuver instead of a physical attack.\nThis maneuver adds +2 to the BTH to physical attacks against the unit.\nNOTE: The dodge maneuver is declared during the weapons phase.\nNote: This ability is only used for BattleMeks. PilotOptionsInfo.option.eagle_eyes.displayableName= Eagle's Eyes (CamOps) diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index d8a13a03b71..a639ad573fb 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -584,10 +584,18 @@ public boolean isLocationProhibited(Coords c, int currElevation) { boolean isAmphibious = hasWorkingMisc(MiscType.F_FULLY_AMPHIBIOUS); boolean hexHasRoad = hex.containsTerrain(Terrains.ROAD); boolean scoutBikeIntoLightWoods = (hex.terrainLevel(Terrains.WOODS) == 1) && hasQuirk(OptionsConstants.QUIRK_POS_SCOUT_BIKE); + boolean isCrossCountry = hasAbility(OptionsConstants.PILOT_CROSS_COUNTRY); // roads allow movement through hexes that you normally couldn't go through switch (movementMode) { case TRACKED: + if (isCrossCountry && !isSuperHeavy()) { + return ((hex.terrainLevel(Terrains.WATER) > 0) + && !hex.containsTerrain(Terrains.ICE) + && !hasFlotationHull && !isAmphibious) + || (hex.terrainLevel(Terrains.MAGMA) > 1); + } + if (!isSuperHeavy()) { return ((hex.terrainLevel(Terrains.WOODS) > 1) && !hexHasRoad) || ((hex.terrainLevel(Terrains.WATER) > 0) @@ -606,6 +614,15 @@ public boolean isLocationProhibited(Coords c, int currElevation) { || (hex.terrainLevel(Terrains.MAGMA) > 1); } case WHEELED: + if (isCrossCountry && !isSuperHeavy()) { + return ((hex.terrainLevel(Terrains.WATER) > 0) + && !hex.containsTerrain(Terrains.ICE) + && !hasFlotationHull && !isAmphibious) + || hex.containsTerrain(Terrains.MAGMA) + || ((hex.terrainLevel(Terrains.SNOW) > 1) && !hexHasRoad) + || (hex.terrainLevel(Terrains.GEYSER) == 2); + } + if (!isSuperHeavy()) { return (hex.containsTerrain(Terrains.WOODS) && !hexHasRoad && !scoutBikeIntoLightWoods) || (hex.containsTerrain(Terrains.ROUGH) && !hexHasRoad) @@ -629,6 +646,10 @@ public boolean isLocationProhibited(Coords c, int currElevation) { || (hex.terrainLevel(Terrains.GEYSER) == 2); } case HOVER: + if (isCrossCountry && !isSuperHeavy()) { + return (hex.terrainLevel(Terrains.MAGMA) > 1); + } + if (!isSuperHeavy()) { return (hex.containsTerrain(Terrains.WOODS) && !hexHasRoad && !scoutBikeIntoLightWoods) || (hex.containsTerrain(Terrains.JUNGLE) && !hexHasRoad) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index dd278d848b9..b59f1d98f8e 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -372,6 +372,8 @@ public void pilotingModifier(EntityMovementMode moveMode, PilotingRollData roll, public int movementCost(Entity e) { EntityMovementMode moveMode = e.getMovementMode(); int mp; + boolean isCrossCountry = e.hasAbility(OptionsConstants.PILOT_CROSS_COUNTRY); + switch (type) { case Terrains.MAGMA: return level - 1; @@ -386,12 +388,24 @@ public int movementCost(Entity e) { } else { mp = 1; } + + if (isCrossCountry) { + if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) + && (level == 6)) { + mp *= 2; + } else if ((moveMode == EntityMovementMode.WHEELED)) { + mp *= 2; + } + } + if ((e instanceof Mech) && e.isSuperHeavy()) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_TM_MOUNTAINEER)) { mp -= 1; } + if ((e.hasAbility(OptionsConstants.INFANTRY_FOOT_CAV) && (moveMode == EntityMovementMode.INF_LEG))) { mp -= 1; @@ -399,16 +413,27 @@ public int movementCost(Entity e) { return Math.max(0, mp); case Terrains.WOODS: mp = level; + if (isCrossCountry) { + if ((level == 1) && ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WHEELED))) { + mp *= 2; + } else { + mp *= 2; + } + } + if ((e instanceof Mech) && e.isSuperHeavy()) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_TM_FOREST_RANGER)) { mp -= 1; } + if ((e.hasAbility(OptionsConstants.INFANTRY_FOOT_CAV) && (moveMode == EntityMovementMode.INF_LEG))) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_ANIMAL_MIMIC)) { if ((e.entityIsQuad()) || ((moveMode == EntityMovementMode.BIPED) && e.hasQuirk("animalistic"))) { mp -= 1; @@ -417,16 +442,23 @@ public int movementCost(Entity e) { return Math.max(0, mp); case Terrains.JUNGLE: mp = level +1; + if (isCrossCountry) { + mp *= 2; + } + if ((e instanceof Mech) && e.isSuperHeavy()) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_TM_FOREST_RANGER)) { mp -= 1; } + if ((e.hasAbility(OptionsConstants.INFANTRY_FOOT_CAV) && (moveMode == EntityMovementMode.INF_LEG))) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_ANIMAL_MIMIC)) { if ((e.entityIsQuad()) || ((moveMode == EntityMovementMode.BIPED) && e.hasQuirk("animalistic"))) { mp -= 1; @@ -494,12 +526,24 @@ public int movementCost(Entity e) { } else { mp = 1; } + + if (isCrossCountry) { + if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) + && (level == 2)) { + mp *= 2; + } else if ((moveMode == EntityMovementMode.WHEELED)) { + mp *= 2; + } + } + if ((e instanceof Mech) && e.isSuperHeavy()) { mp -= 1; } + if (e.hasAbility(OptionsConstants.PILOT_TM_MOUNTAINEER)) { mp -= 1; } + if ((e.hasAbility(OptionsConstants.INFANTRY_FOOT_CAV) && (moveMode == EntityMovementMode.INF_LEG))) { mp -= 1; diff --git a/megamek/src/megamek/common/options/OptionsConstants.java b/megamek/src/megamek/common/options/OptionsConstants.java index 05de66207bd..8e179a55bb8 100644 --- a/megamek/src/megamek/common/options/OptionsConstants.java +++ b/megamek/src/megamek/common/options/OptionsConstants.java @@ -144,9 +144,8 @@ public class OptionsConstants { public static final String PILOT_APTITUDE_GUNNERY = "aptitude_gunnery"; public static final String PILOT_APTITUDE_PILOTING = "aptitude_piloting"; public static final String PILOT_ANIMAL_MIMIC= "animal_mimic"; - // public static final String PILOT_CROSS_COUNTRY= "cross_country"; - // - public static final String PILOT_DODGE_MANEUVER = "dodge_maneuver"; + public static final String PILOT_CROSS_COUNTRY= "cross_country"; + public static final String PILOT_DODGE_MANEUVER = "dodge_maneuver"; // public static final String PILOT_DUST_OFF= "dust_off"; // public static final String PILOT_HVY_LIFTER= "hvy_lifter"; // public static final String PILOT_HOPPER= "hopper"; diff --git a/megamek/src/megamek/common/options/PilotOptions.java b/megamek/src/megamek/common/options/PilotOptions.java index 1fe81e61551..9f8035477e2 100755 --- a/megamek/src/megamek/common/options/PilotOptions.java +++ b/megamek/src/megamek/common/options/PilotOptions.java @@ -36,7 +36,7 @@ public void initialize() { IBasicOptionGroup adv = addGroup("adv", LVL3_ADVANTAGES); addOption(adv, OptionsConstants.PILOT_ANIMAL_MIMIC, false); - // addOption(adv, OptionsConstants.PILOT_CROSS_COUNTRY, false); + addOption(adv, OptionsConstants.PILOT_CROSS_COUNTRY, false); addOption(adv, OptionsConstants.PILOT_DODGE_MANEUVER, false); // addOption(adv, OptionsConstants.PILOT_DUST_OFF, false); // addOption(adv, OptionsConstants.PILOT_HVY_LIFTER, false); From a485ec964a271e8adeea2a8dc4a904075639772a Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Sun, 29 Jan 2023 19:43:08 -0500 Subject: [PATCH 2/5] Fixed an issue that caused tracked vehicles to pay double mp in light woods --- megamek/src/megamek/common/Terrain.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index b59f1d98f8e..27ea8ab90c6 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -416,7 +416,7 @@ public int movementCost(Entity e) { if (isCrossCountry) { if ((level == 1) && ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WHEELED))) { mp *= 2; - } else { + } else if (level > 1){ mp *= 2; } } From 07817686ceb6cc89707aa96c181143460112a9bd Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 15 Feb 2023 18:00:36 -0500 Subject: [PATCH 3/5] Only ground combat vehicles should be able to use Cross Country. This should keep QuadVees from getting lumped into this. --- megamek/src/megamek/common/Terrain.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index 27ea8ab90c6..6b6ebad8b08 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -389,7 +389,7 @@ public int movementCost(Entity e) { mp = 1; } - if (isCrossCountry) { + if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) && (level == 6)) { mp *= 2; @@ -413,7 +413,7 @@ public int movementCost(Entity e) { return Math.max(0, mp); case Terrains.WOODS: mp = level; - if (isCrossCountry) { + if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { if ((level == 1) && ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WHEELED))) { mp *= 2; } else if (level > 1){ @@ -442,7 +442,7 @@ public int movementCost(Entity e) { return Math.max(0, mp); case Terrains.JUNGLE: mp = level +1; - if (isCrossCountry) { + if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { mp *= 2; } @@ -527,7 +527,7 @@ public int movementCost(Entity e) { mp = 1; } - if (isCrossCountry) { + if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) && (level == 2)) { mp *= 2; From 7ca5b59e9406eb5f88158f4ae36a37b94cabbc77 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 15 Feb 2023 19:38:18 -0500 Subject: [PATCH 4/5] Condensed rubble and rough if statements --- megamek/src/megamek/common/Terrain.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index 6b6ebad8b08..f2b56f24434 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -383,6 +383,8 @@ public int movementCost(Entity e) { } return 0; case Terrains.RUBBLE: + boolean allowRubbleHoverTracked = ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) && (level == 6); + if (level == 6) { mp = 2; } else { @@ -390,10 +392,7 @@ public int movementCost(Entity e) { } if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { - if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) - && (level == 6)) { - mp *= 2; - } else if ((moveMode == EntityMovementMode.WHEELED)) { + if (allowRubbleHoverTracked || (moveMode == EntityMovementMode.WHEELED)) { mp *= 2; } } @@ -521,6 +520,8 @@ public int movementCost(Entity e) { } return Math.max(0, mp); case Terrains.ROUGH: + boolean allowRoughHoverTracked = ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) && (level == 2); + if (level == 2) { mp = 2; } else { @@ -528,10 +529,7 @@ public int movementCost(Entity e) { } if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { - if (((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.TRACKED)) - && (level == 2)) { - mp *= 2; - } else if ((moveMode == EntityMovementMode.WHEELED)) { + if ( allowRoughHoverTracked || (moveMode == EntityMovementMode.WHEELED)) { mp *= 2; } } From 8b3e7dd67fdf0a590f90c32b6d5a96566638de23 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 15 Feb 2023 21:04:05 -0500 Subject: [PATCH 5/5] Condensed woods if statement --- megamek/src/megamek/common/Terrain.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index f2b56f24434..0ab72533016 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -413,9 +413,8 @@ public int movementCost(Entity e) { case Terrains.WOODS: mp = level; if (isCrossCountry && e.isGround() && e.isCombatVehicle()) { - if ((level == 1) && ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WHEELED))) { - mp *= 2; - } else if (level > 1){ + if (((level == 1) && ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WHEELED))) + || (level > 1)) { mp *= 2; } }