From a924386cf2062e931f07d45dfae1dd2ffb4e2f23 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Thu, 8 Jun 2023 08:26:41 -0400 Subject: [PATCH 01/21] Add Black Ice terrain modification --- megamek/src/megamek/common/Terrain.java | 6 ++ megamek/src/megamek/common/Terrains.java | 107 ++++++++++++----------- 2 files changed, 61 insertions(+), 52 deletions(-) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index 0ab72533016..39b2409549e 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -358,6 +358,11 @@ public void pilotingModifier(EntityMovementMode moveMode, PilotingRollData roll, roll.addModifier(4, "Ice"); } break; + case Terrains.BLACK_ICE: + if ((moveMode != EntityMovementMode.HOVER) && (moveMode != EntityMovementMode.WIGE)) { + roll.addModifier(4, "Black Ice"); + } + break; case Terrains.INDUSTRIAL: roll.addModifier(1, "Industrial Zone"); break; @@ -498,6 +503,7 @@ public int movementCost(Entity e) { } return Math.max(0, mp); case Terrains.ICE: + case Terrains.BLACK_ICE: if ((moveMode == EntityMovementMode.HOVER) || (moveMode == EntityMovementMode.WIGE)) { return 0; } diff --git a/megamek/src/megamek/common/Terrains.java b/megamek/src/megamek/common/Terrains.java index c3d0fd11020..04efc7f2921 100644 --- a/megamek/src/megamek/common/Terrains.java +++ b/megamek/src/megamek/common/Terrains.java @@ -48,15 +48,15 @@ public class Terrains implements Serializable { public static final int MUD = 15; public static final int RAPIDS = 16; // 1: rapids 2: torrent public static final int ICE = 17; - public static final int SNOW = 18; // 1: thin 2: deep - public static final int FIRE = 19; // 1: normal, fire 2: inferno fire, 3: + public static final int BLACK_ICE = 18; + public static final int SNOW = 19; // 1: thin 2: deep + public static final int FIRE = 20; // 1: normal, fire 2: inferno fire, 3: // inferno bombs, 4: inferno IV /** The SMOKE terrain type includes laser-inhibiting smoke and chaff from chaff pods (TO:AUE p111). */ - public static final int SMOKE = 20; // 1: light smoke 2: heavy smoke 3:light + public static final int SMOKE = 21; // 1: light smoke 2: heavy smoke 3:light // LI smoke 4: Heavy LI smoke - public static final int GEYSER = 21; // 1: dormant 2: active 3: magma vent + public static final int GEYSER = 22; // 1: dormant 2: active 3: magma vent // unimplemented - // Black Ice // Bug Storm // Extreme Depths // Hazardous Liquid Pools @@ -70,78 +70,78 @@ public class Terrains implements Serializable { public static final int FIRE_LVL_INFERNO_IV = 4; // Building stuff - public static final int BUILDING = 22; // 1: light 2: medium 3: heavy 4: + public static final int BUILDING = 23; // 1: light 2: medium 3: heavy 4: // hardened [5: wall not implemented] - public static final int BLDG_CF = 23; - public static final int BLDG_ELEV = 24; - public static final int BLDG_BASEMENT_TYPE = 25; // level equals + public static final int BLDG_CF = 24; + public static final int BLDG_ELEV = 25; + public static final int BLDG_BASEMENT_TYPE = 26; // level equals // BasemenType, one of the // values of the // BasementType enum - public static final int BLDG_CLASS = 26; // 1: hangars 2: fortresses 3: gun + public static final int BLDG_CLASS = 27; // 1: hangars 2: fortresses 3: gun // emplacements - public static final int BLDG_ARMOR = 27; + public static final int BLDG_ARMOR = 28; // leaving this empty will be interpreted as standard - public static final int BRIDGE = 28; - public static final int BRIDGE_CF = 29; - public static final int BRIDGE_ELEV = 30; - public static final int FUEL_TANK = 31; - public static final int FUEL_TANK_CF = 32; - public static final int FUEL_TANK_ELEV = 33; - public static final int FUEL_TANK_MAGN = 34; + public static final int BRIDGE = 29; + public static final int BRIDGE_CF = 30; + public static final int BRIDGE_ELEV = 31; + public static final int FUEL_TANK = 32; + public static final int FUEL_TANK_CF = 33; + public static final int FUEL_TANK_ELEV = 34; + public static final int FUEL_TANK_MAGN = 35; // special types - public static final int IMPASSABLE = 35; - public static final int ELEVATOR = 36; // level = elevation it moves to, exits = d6 rolls it moves on - public static final int FORTIFIED = 37; + public static final int IMPASSABLE = 36; + public static final int ELEVATOR = 37; // level = elevation it moves to, exits = d6 rolls it moves on + public static final int FORTIFIED = 38; /** The SCREEN terrain type stands for chaff hexes generated by screen launchers in space. */ - public static final int SCREEN = 38; + public static final int SCREEN = 39; // fluff - public static final int FLUFF = 39; - public static final int ARMS = 40; // blown off arms for use as clubs, level + public static final int FLUFF = 40; + public static final int ARMS = 41; // blown off arms for use as clubs, level // = number of arms in that hex - public static final int LEGS = 41; // blown off legs for use as clubs, level + public static final int LEGS = 42; // blown off legs for use as clubs, level // = number of legs in that hex - public static final int METAL_CONTENT = 42; // Is there metal content that + public static final int METAL_CONTENT = 43; // Is there metal content that // will block magscan sensors? - public static final int BLDG_BASE_COLLAPSED = 43; // 1 means collapsed - + public static final int BLDG_BASE_COLLAPSED = 44; // 1 means collapsed + // Additional fluff types so that stacking of special images is possible - public static final int BLDG_FLUFF = 44; // Ideally used to denote special bldg images - public static final int ROAD_FLUFF = 45; // Ideally used to denote special road images - public static final int GROUND_FLUFF = 46; // Ideally used to denote special ground images + public static final int BLDG_FLUFF = 45; // Ideally used to denote special bldg images + public static final int ROAD_FLUFF = 46; // Ideally used to denote special road images + public static final int GROUND_FLUFF = 47; // Ideally used to denote special ground images // these should be supers, not bases, as base image - // matching is not exact while super is - public static final int WATER_FLUFF = 47; // Ideally used to denote special water images + // matching is not exact while super is + public static final int WATER_FLUFF = 48; // Ideally used to denote special water images // Cliffs, use with exits to denote cliffsides; only valid when there's // actually a level drop/rise in the specified direction - public static final int CLIFF_TOP = 48; - public static final int CLIFF_BOTTOM = 49; - - // Terrain for the incline at a hex edge towards a higher or lower + public static final int CLIFF_TOP = 49; + public static final int CLIFF_BOTTOM = 50; + + // Terrain for the incline at a hex edge towards a higher or lower // neighboring hex. Used to add highlighting/images to hex sides // This is added to hexes automatically by MegaMek, not for // manual use in the Editor - public static final int INCLINE_TOP = 50; - public static final int INCLINE_BOTTOM = 51; - - // Hex level differences of at least 3 levels, used with exits to + public static final int INCLINE_TOP = 51; + public static final int INCLINE_BOTTOM = 52; + + // Hex level differences of at least 3 levels, used with exits to // denote the hex side. Used to add highlighting/images to hex sides // This is added to hexes automatically by MegaMek, not for // manual use in the Editor - public static final int INCLINE_HIGH_TOP = 52; - public static final int INCLINE_HIGH_BOTTOM = 53; - + public static final int INCLINE_HIGH_TOP = 53; + public static final int INCLINE_HIGH_BOTTOM = 54; + // Helper terrain that gives the elevation for foliage (woods and jungle). // Allowed values are 1 for L/H/U, 2 for L/H and 3 for U foliage. // This terrain is meaningless when alone but must be present in any // hex that has either woods or jungle. It is added by the board loader // when it's not present in the board file. - public static final int FOLIAGE_ELEV = 54; - + public static final int FOLIAGE_ELEV = 55; + /** * Keeps track of the different type of terrains that can have exits. */ @@ -149,12 +149,12 @@ public class Terrains implements Serializable { private static final String[] names = { "none", "woods", "water", "rough", "rubble", "jungle", "sand", "tundra", "magma", "planted_fields", "heavy_industrial", "space", "pavement", "road", "swamp", "mud", "rapids", "ice", - "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", + "black ice", "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", "bldg_armor", "bridge", "bridge_cf", "bridge_elev", "fuel_tank", "fuel_tank_cf", "fuel_tank_elev", "fuel_tank_magn", "impassable", "elevator", "fortified", "screen", "fluff", "arms", "legs", "metal_deposit", - "bldg_base_collapsed", "bldg_fluff", "road_fluff", "ground_fluff", "water_fluff", "cliff_top", "cliff_bottom", + "bldg_base_collapsed", "bldg_fluff", "road_fluff", "ground_fluff", "water_fluff", "cliff_top", "cliff_bottom", "incline_top", "incline_bottom", "incline_high_top", "incline_high_bottom", "foliage_elev" }; - + /** Terrains in this set are hidden in the Editor, not saved to board files and handled internally. */ public static final HashSet AUTOMATIC = new HashSet<>(Arrays.asList( INCLINE_TOP, INCLINE_BOTTOM, INCLINE_HIGH_TOP, INCLINE_HIGH_BOTTOM, CLIFF_BOTTOM)); @@ -165,7 +165,7 @@ public class Terrains implements Serializable { /** * Checks to see if the given terrain type can have exits. - * + * * @param terrType The terrain type to test * @return True if the input terrain type can have exits, else false. */ @@ -207,7 +207,7 @@ public static String getEditorTooltip(int type) { } /** - * Returns a name to be displayed in tooltips. + * Returns a name to be displayed in tooltips. * Intentionally returns null for terrains that should be treated * separately such as buildings and for terrains that should not be listed * such as cliff-tops. @@ -301,6 +301,8 @@ public static String getDisplayName(int type, int level) { } case ICE: return "Ice"; + case BLACK_ICE: + return "Black Ice"; case FORTIFIED: return "Improved position"; case GEYSER: @@ -439,6 +441,7 @@ public static int getTerrainFactor(int type, int level) { case ROAD: return 150; case ICE: + case BLACK_ICE: return 40; case MAGMA: if (level == 1) { @@ -468,7 +471,7 @@ public static int getTerrainFactor(int type, int level) { /** * Returns the number of elevations or altitudes above the hex level a given * terrainType rises. - * + * * @param terrainType this specifies the type of terrain to get the information for * @param inAtmosphere * Flag that determines whether elevations or altitudes should be From 2fba4ac33ff5cee2260c2c5cb965e92e9d8e2b41 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Thu, 8 Jun 2023 08:37:46 -0400 Subject: [PATCH 02/21] Create option to use Black Ice outside Ice Storms when temp is less than -30C --- .../common/options/messages.properties | 2 + .../megamek/common/options/GameOptions.java | 375 +++++++++--------- .../common/options/OptionsConstants.java | 1 + 3 files changed, 191 insertions(+), 187 deletions(-) diff --git a/megamek/i18n/megamek/common/options/messages.properties b/megamek/i18n/megamek/common/options/messages.properties index 764bf2adc72..8df2052e823 100644 --- a/megamek/i18n/megamek/common/options/messages.properties +++ b/megamek/i18n/megamek/common/options/messages.properties @@ -125,6 +125,8 @@ GameOptionsInfo.option.minefields.displayableName=TacOps Minefields / BMM Minefi GameOptionsInfo.option.minefields.description=If checked, minefields can be used.\nChecked by default. GameOptionsInfo.option.hidden_units.displayableName=Hidden Units GameOptionsInfo.option.hidden_units.description=If checked, players may deploy units hidden. +GameOptionsInfo.option.black_ice.displayableName=Black Ice +GameOptionsInfo.option.black_ice.description=If checked, Black Ice may form on pavement if temperatures are below -30C. TO:AR p38\nDoes not affect Black Ice forming do to Ice Storms. TO:AR p58 GameOptionsInfo.option.double_blind.displayableName=TacOps Double blind GameOptionsInfo.option.single_blind_bots.displayableName=(Unofficial) Default bots to single blind, when using TacOps Double blind GameOptionsInfo.option.double_blind.description=If checked, enemy units will only be visible if they are in line of sight of one or more of your units, or within sensor range. \nUnchecked by default. diff --git a/megamek/src/megamek/common/options/GameOptions.java b/megamek/src/megamek/common/options/GameOptions.java index 7ba3fe3425b..505cf50cdc0 100755 --- a/megamek/src/megamek/common/options/GameOptions.java +++ b/megamek/src/megamek/common/options/GameOptions.java @@ -39,7 +39,7 @@ */ public class GameOptions extends AbstractOptions { private static final long serialVersionUID = 4916321960852747706L; - private static final String GAME_OPTIONS_FILE_NAME = "mmconf/gameoptions.xml"; + private static final String GAME_OPTIONS_FILE_NAME = "mmconf/gameoptions.xml"; public GameOptions() { super(); @@ -47,108 +47,109 @@ public GameOptions() { @Override public synchronized void initialize() { - IBasicOptionGroup base = addGroup("basic"); - addOption(base, OptionsConstants.BASE_FRIENDLY_FIRE, false); - addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_MOVEMENT, false); - addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_FIRING, false); - addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_PHYSICAL, true); - addOption(base, OptionsConstants.BASE_PUSH_OFF_BOARD, true); - addOption(base, OptionsConstants.BASE_TEAM_INITIATIVE, true); - addOption(base, OptionsConstants.BASE_AUTOSAVE_MSG, true); - addOption(base, OptionsConstants.BASE_PARANOID_AUTOSAVE, false); + IBasicOptionGroup base = addGroup("basic"); + addOption(base, OptionsConstants.BASE_FRIENDLY_FIRE, false); + addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_MOVEMENT, false); + addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_FIRING, false); + addOption(base, OptionsConstants.BASE_SKIP_INELIGABLE_PHYSICAL, true); + addOption(base, OptionsConstants.BASE_PUSH_OFF_BOARD, true); + addOption(base, OptionsConstants.BASE_TEAM_INITIATIVE, true); + addOption(base, OptionsConstants.BASE_AUTOSAVE_MSG, true); + addOption(base, OptionsConstants.BASE_PARANOID_AUTOSAVE, false); addOption(base, OptionsConstants.BASE_EXCLUSIVE_DB_DEPLOYMENT, true); - addOption(base, OptionsConstants.BASE_BLIND_DROP, false); - addOption(base, OptionsConstants.BASE_REAL_BLIND_DROP, false); - addOption(base, OptionsConstants.BASE_LOBBY_AMMO_DUMP, false); - addOption(base, OptionsConstants.BASE_DUMPING_FROM_ROUND, 1); - addOption(base, OptionsConstants.BASE_SET_ARTY_PLAYER_HOMEEDGE, false); - addOption(base, OptionsConstants.BASE_RESTRICT_GAME_COMMANDS, false); - addOption(base, OptionsConstants.BASE_DISABLE_LOCAL_SAVE, false); - addOption(base, OptionsConstants.BASE_BRIDGECF, 0); - addOption(base, OptionsConstants.BASE_SHOW_BAY_DETAIL, false); - addOption(base, OptionsConstants.BASE_RNG_TYPE, 1); - addOption(base, OptionsConstants.BASE_RNG_LOG, false); - addOption(base, OptionsConstants.BASE_FLAMER_HEAT, false); - addOption(base, OptionsConstants.BASE_INDIRECT_FIRE, true); - addOption(base, OptionsConstants.BASE_BREEZE, false); - addOption(base, OptionsConstants.BASE_RANDOM_BASEMENTS, true); - addOption(base, OptionsConstants.BASE_AUTO_AMS, true); + addOption(base, OptionsConstants.BASE_BLIND_DROP, false); + addOption(base, OptionsConstants.BASE_REAL_BLIND_DROP, false); + addOption(base, OptionsConstants.BASE_LOBBY_AMMO_DUMP, false); + addOption(base, OptionsConstants.BASE_DUMPING_FROM_ROUND, 1); + addOption(base, OptionsConstants.BASE_SET_ARTY_PLAYER_HOMEEDGE, false); + addOption(base, OptionsConstants.BASE_RESTRICT_GAME_COMMANDS, false); + addOption(base, OptionsConstants.BASE_DISABLE_LOCAL_SAVE, false); + addOption(base, OptionsConstants.BASE_BRIDGECF, 0); + addOption(base, OptionsConstants.BASE_SHOW_BAY_DETAIL, false); + addOption(base, OptionsConstants.BASE_RNG_TYPE, 1); + addOption(base, OptionsConstants.BASE_RNG_LOG, false); + addOption(base, OptionsConstants.BASE_FLAMER_HEAT, false); + addOption(base, OptionsConstants.BASE_INDIRECT_FIRE, true); + addOption(base, OptionsConstants.BASE_BREEZE, false); + addOption(base, OptionsConstants.BASE_RANDOM_BASEMENTS, true); + addOption(base, OptionsConstants.BASE_AUTO_AMS, true); addOption(base, OptionsConstants.BASE_TURN_TIMER, 0); addOption(base, OptionsConstants.BASE_HIDE_UNOFFICIAL, false); addOption(base, OptionsConstants.BASE_HIDE_LEGACY, false); - IBasicOptionGroup victory = addGroup("victory"); - addOption(victory, OptionsConstants.VICTORY_SKIP_FORCED_VICTORY, false); - addOption(victory, OptionsConstants.VICTORY_CHECK_VICTORY, true); - addOption(victory, OptionsConstants.VICTORY_ACHIEVE_CONDITIONS, 1); - addOption(victory, OptionsConstants.VICTORY_USE_BV_DESTROYED, false); - addOption(victory, OptionsConstants.VICTORY_BV_DESTROYED_PERCENT, 100); - addOption(victory, OptionsConstants.VICTORY_USE_BV_RATIO, false); - addOption(victory, OptionsConstants.VICTORY_BV_RATIO_PERCENT, 300); - addOption(victory, OptionsConstants.VICTORY_USE_GAME_TURN_LIMIT, false); - addOption(victory, OptionsConstants.VICTORY_GAME_TURN_LIMIT, 10); - addOption(victory, OptionsConstants.VICTORY_USE_KILL_COUNT, false); - addOption(victory, OptionsConstants.VICTORY_GAME_KILL_COUNT, 4); - addOption(victory, OptionsConstants.VICTORY_COMMANDER_KILLED, false); - - IBasicOptionGroup allowed = addGroup("allowedUnits"); - addOption(allowed, OptionsConstants.ALLOWED_CANON_ONLY, false); - addOption(allowed, OptionsConstants.ALLOWED_YEAR, 3150); + IBasicOptionGroup victory = addGroup("victory"); + addOption(victory, OptionsConstants.VICTORY_SKIP_FORCED_VICTORY, false); + addOption(victory, OptionsConstants.VICTORY_CHECK_VICTORY, true); + addOption(victory, OptionsConstants.VICTORY_ACHIEVE_CONDITIONS, 1); + addOption(victory, OptionsConstants.VICTORY_USE_BV_DESTROYED, false); + addOption(victory, OptionsConstants.VICTORY_BV_DESTROYED_PERCENT, 100); + addOption(victory, OptionsConstants.VICTORY_USE_BV_RATIO, false); + addOption(victory, OptionsConstants.VICTORY_BV_RATIO_PERCENT, 300); + addOption(victory, OptionsConstants.VICTORY_USE_GAME_TURN_LIMIT, false); + addOption(victory, OptionsConstants.VICTORY_GAME_TURN_LIMIT, 10); + addOption(victory, OptionsConstants.VICTORY_USE_KILL_COUNT, false); + addOption(victory, OptionsConstants.VICTORY_GAME_KILL_COUNT, 4); + addOption(victory, OptionsConstants.VICTORY_COMMANDER_KILLED, false); + + IBasicOptionGroup allowed = addGroup("allowedUnits"); + addOption(allowed, OptionsConstants.ALLOWED_CANON_ONLY, false); + addOption(allowed, OptionsConstants.ALLOWED_YEAR, 3150); addOption(allowed, OptionsConstants.ALLOWED_TECHLEVEL, IOption.CHOICE, TechConstants.T_SIMPLE_NAMES[TechConstants.T_SIMPLE_STANDARD]); addOption(allowed, OptionsConstants.ALLOWED_ERA_BASED, false); - addOption(allowed, OptionsConstants.ALLOWED_ALLOW_ILLEGAL_UNITS, false); - addOption(allowed, OptionsConstants.ALLOWED_CLAN_IGNORE_EQ_LIMITS, false); - addOption(allowed, OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL, false); - addOption(allowed, OptionsConstants.ALLOWED_ALLOW_NUKES, false); - addOption(allowed, OptionsConstants.ALLOWED_REALLY_ALLOW_NUKES, false); - - IBasicOptionGroup advancedRules = addGroup("advancedRules"); - addOption(advancedRules, OptionsConstants.ADVANCED_MINEFIELDS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_HIDDEN_UNITS, true); + addOption(allowed, OptionsConstants.ALLOWED_ALLOW_ILLEGAL_UNITS, false); + addOption(allowed, OptionsConstants.ALLOWED_CLAN_IGNORE_EQ_LIMITS, false); + addOption(allowed, OptionsConstants.ALLOWED_NO_CLAN_PHYSICAL, false); + addOption(allowed, OptionsConstants.ALLOWED_ALLOW_NUKES, false); + addOption(allowed, OptionsConstants.ALLOWED_REALLY_ALLOW_NUKES, false); + + IBasicOptionGroup advancedRules = addGroup("advancedRules"); + addOption(advancedRules, OptionsConstants.ADVANCED_MINEFIELDS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_HIDDEN_UNITS, true); + addOption(advancedRules, OptionsConstants.ADVANCED_BLACK_ICE, false); addOption(advancedRules, OptionsConstants.ADVANCED_DOUBLE_BLIND, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SENSORS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_SUPRESS_ALL_DB_MESSAGES, false); - addOption(advancedRules, OptionsConstants.ADVANCED_SUPPRESS_DB_BV, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TEAM_VISION, true); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BAP, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_ECCM, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_GHOST_TARGET, false); - addOption(advancedRules, OptionsConstants.ADVANCED_GHOST_TARGET_MAX, 5); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_DIG_IN, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SENSORS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_SUPRESS_ALL_DB_MESSAGES, false); + addOption(advancedRules, OptionsConstants.ADVANCED_SUPPRESS_DB_BV, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TEAM_VISION, true); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BAP, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_ECCM, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_GHOST_TARGET, false); + addOption(advancedRules, OptionsConstants.ADVANCED_GHOST_TARGET_MAX, 5); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_DIG_IN, false); addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BA_WEIGHT, false); addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_TAKE_COVER, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_ANGEL_ECM, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BATTLE_WRECK, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SKIN_OF_THE_TEETH_EJECTION, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_MOBILE_HQS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_FATIGUE, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_FUMBLES, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SELF_DESTRUCT, false); - addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_TANK_CREWS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_STRATOPS_QUIRKS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_STRATOPS_PARTIALREPAIRS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_ASSAULT_DROP, false); - addOption(advancedRules, OptionsConstants.ADVANCED_PARATROOPERS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_INCLUSIVE_SENSOR_RANGE, false); - addOption(advancedRules, OptionsConstants.ADVANCED_SENSORS_DETECT_ALL, false); - addOption(advancedRules, OptionsConstants.ADVANCED_MAGSCAN_NOHILLS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_WOODS_BURN_DOWN, false); - addOption(advancedRules, OptionsConstants.ADVANCED_WOODS_BURN_DOWN_AMOUNT, 5); - addOption(advancedRules, OptionsConstants.ADVANCED_NO_IGNITE_CLEAR, false); - addOption(advancedRules, OptionsConstants.ADVANCED_ALL_HAVE_EI_COCKPIT, false); - addOption(advancedRules, OptionsConstants.ADVANCED_EXTREME_TEMPERATURE_SURVIVAL, false); - addOption(advancedRules, OptionsConstants.ADVANCED_ARMED_MECHWARRIORS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_PILOTS_VISUAL_RANGE_ONE, false); - addOption(advancedRules, OptionsConstants.ADVANCED_PILOTS_CANNOT_SPOT, false); - addOption(advancedRules, OptionsConstants.ADVANCED_METAL_CONTENT, false); - addOption(advancedRules, OptionsConstants.ADVANCED_BA_GRAB_BARS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_MAXTECH_MOVEMENT_MODS, false); - addOption(advancedRules, OptionsConstants.ADVANCED_ALTERNATE_MASC, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_ANGEL_ECM, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_BATTLE_WRECK, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SKIN_OF_THE_TEETH_EJECTION, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_MOBILE_HQS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_FATIGUE, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_FUMBLES, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_SELF_DESTRUCT, false); + addOption(advancedRules, OptionsConstants.ADVANCED_TACOPS_TANK_CREWS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_STRATOPS_QUIRKS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_STRATOPS_PARTIALREPAIRS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_ASSAULT_DROP, false); + addOption(advancedRules, OptionsConstants.ADVANCED_PARATROOPERS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_INCLUSIVE_SENSOR_RANGE, false); + addOption(advancedRules, OptionsConstants.ADVANCED_SENSORS_DETECT_ALL, false); + addOption(advancedRules, OptionsConstants.ADVANCED_MAGSCAN_NOHILLS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_WOODS_BURN_DOWN, false); + addOption(advancedRules, OptionsConstants.ADVANCED_WOODS_BURN_DOWN_AMOUNT, 5); + addOption(advancedRules, OptionsConstants.ADVANCED_NO_IGNITE_CLEAR, false); + addOption(advancedRules, OptionsConstants.ADVANCED_ALL_HAVE_EI_COCKPIT, false); + addOption(advancedRules, OptionsConstants.ADVANCED_EXTREME_TEMPERATURE_SURVIVAL, false); + addOption(advancedRules, OptionsConstants.ADVANCED_ARMED_MECHWARRIORS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_PILOTS_VISUAL_RANGE_ONE, false); + addOption(advancedRules, OptionsConstants.ADVANCED_PILOTS_CANNOT_SPOT, false); + addOption(advancedRules, OptionsConstants.ADVANCED_METAL_CONTENT, false); + addOption(advancedRules, OptionsConstants.ADVANCED_BA_GRAB_BARS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_MAXTECH_MOVEMENT_MODS, false); + addOption(advancedRules, OptionsConstants.ADVANCED_ALTERNATE_MASC, false); addOption(advancedRules, OptionsConstants.ADVANCED_ALTERNATE_MASC_ENHANCED, false); addOption(advancedRules, OptionsConstants.ADVANCED_SINGLE_BLIND_BOTS, false); - IBasicOptionGroup advancedCombat = addGroup("advancedCombat"); + IBasicOptionGroup advancedCombat = addGroup("advancedCombat"); addOption(advancedCombat, OptionsConstants.ADVCOMBAT_TACOPS_AMS, false); addOption(advancedCombat, OptionsConstants.ADVCOMBAT_TACOPS_MANUAL_AMS, false); addOption(advancedCombat, OptionsConstants.ADVCOMBAT_FLOATING_CRITS, false); @@ -211,105 +212,105 @@ public synchronized void initialize() { addOption(advancedCombat, OptionsConstants.ADVCOMBAT_FOREST_FIRES_NO_SMOKE, false); addOption(advancedCombat, OptionsConstants.ADVCOMBAT_HOTLOAD_IN_GAME, false); addOption(advancedCombat, OptionsConstants.ADVCOMBAT_MULTI_USE_AMS, false); - - IBasicOptionGroup advancedGroundMovement = addGroup("advancedGroundMovement"); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_SPRINT, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_STANDING_STILL, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_EVADE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_SKILLED_EVASION, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_LEAPING, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_PHYSICAL_PSR, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_PHYSICAL_ATTACK_PSR, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_TAKING_DAMAGE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_LEG_DAMAGE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_WALK_BACKWARDS, false); + + IBasicOptionGroup advancedGroundMovement = addGroup("advancedGroundMovement"); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_SPRINT, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_STANDING_STILL, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_EVADE, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_SKILLED_EVASION, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_LEAPING, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_PHYSICAL_PSR, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_PHYSICAL_ATTACK_PSR, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_TAKING_DAMAGE, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_LEG_DAMAGE, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_WALK_BACKWARDS, false); addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE, false); addOption(advancedGroundMovement, OptionsConstants.ADVANCED_TACOPS_INF_PAVE_BONUS, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT_NUMBER, 4); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_ACCELERATION, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_REVERSE_GEAR, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TURN_MODE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_ADVANCED_MANEUVERS, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_HULL_DOWN, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_FALLING_EXPANDED, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_ATTEMPTING_STAND, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_CAREFUL_STAND, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_ZIPLINES, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT_NUMBER, 4); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_IMMOBILE_VEHICLES, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_LANCE_MOVEMENT_NUMBER, 4); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_ACCELERATION, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_REVERSE_GEAR, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TURN_MODE, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLE_ADVANCED_MANEUVERS, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_HULL_DOWN, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_FALLING_EXPANDED, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_ATTEMPTING_STAND, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_CAREFUL_STAND, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_TACOPS_ZIPLINES, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_MEK_LANCE_MOVEMENT_NUMBER, 4); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_IMMOBILE_VEHICLES, false); addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_VEHICLES_CAN_EJECT, false); addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_EJECTED_PILOTS_FLEE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_AUTO_ABANDON_UNIT, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_HOVER_CHARGE, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_PREMOVE_VIBRA, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_FALLS_END_MOVEMENT, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_AUTO_ABANDON_UNIT, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_HOVER_CHARGE, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_PREMOVE_VIBRA, false); + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_FALLS_END_MOVEMENT, false); addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_PSR_JUMP_HEAVY_WOODS, false); - addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_NIGHT_MOVE_PEN, false); - - IBasicOptionGroup advAeroRules = addGroup("advancedAeroRules"); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_GROUND_MOVE, true); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_CAPITAL_FIGHTER, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_FUEL_CONSUMPTION, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_CONV_FUSION_BONUS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_HARJEL, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_GRAV_EFFECTS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_ADVANCED_MOVEMENT, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_HEAT_BY_BAY, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_ATMOSPHERIC_CONTROL, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AMMO_EXPLOSIONS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AAA_LASER, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ADV_POINTDEF, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BRACKET_FIRE, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ECM, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_SENSOR_SHADOW, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_OVER_PENETRATE, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_SPACE_BOMB, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BEARINGS_ONLY_LAUNCH, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BEARINGS_ONLY_VELOCITY, 50); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_WAYPOINT_LAUNCH, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ADVANCED_SENSORS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_VARIABLE_DAMAGE_THRESH, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_AT2_NUKES, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_SANITY, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_RETURN_FLYOVER, true); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AA_FIRE, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_AA_MOVE_MOD, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_ALLOW_LARGE_SQUADRONS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_SINGLE_NO_CAP, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_ARTILLERY_MUNITIONS, false); - addOption(advAeroRules, OptionsConstants.ADVAERORULES_EXPANDED_KF_DRIVE_DAMAGE, false); - - IBasicOptionGroup initiative = addGroup("initiative"); - addOption(initiative, OptionsConstants.INIT_INF_MOVE_EVEN, false); - addOption(initiative, OptionsConstants.INIT_INF_DEPLOY_EVEN, false); - addOption(initiative, OptionsConstants.INIT_INF_MOVE_LATER, false); - addOption(initiative, OptionsConstants.INIT_INF_MOVE_MULTI, false); - addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_EVEN, false); - addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_EVEN, false); - addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_LATER, false); - addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_MULTI, false); - addOption(initiative, OptionsConstants.INIT_INF_PROTO_MOVE_MULTI, 3); - addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_DEPLOYMENT, false); - addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_MOVEMENT, false); - addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_TARGETING, false); - addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_FIRING, false); - addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_PHYSICAL, false); - addOption(initiative, OptionsConstants.INIT_FRONT_LOAD_INITIATIVE, false); - addOption(initiative, OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION, false); - + addOption(advancedGroundMovement, OptionsConstants.ADVGRNDMOV_NO_NIGHT_MOVE_PEN, false); + + IBasicOptionGroup advAeroRules = addGroup("advancedAeroRules"); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_GROUND_MOVE, true); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_CAPITAL_FIGHTER, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_FUEL_CONSUMPTION, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_CONV_FUSION_BONUS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_HARJEL, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_GRAV_EFFECTS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_ADVANCED_MOVEMENT, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_HEAT_BY_BAY, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_ATMOSPHERIC_CONTROL, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AMMO_EXPLOSIONS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AAA_LASER, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ADV_POINTDEF, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BRACKET_FIRE, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ECM, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_SENSOR_SHADOW, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_OVER_PENETRATE, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_SPACE_BOMB, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BEARINGS_ONLY_LAUNCH, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_BEARINGS_ONLY_VELOCITY, 50); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_WAYPOINT_LAUNCH, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_ADVANCED_SENSORS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_VARIABLE_DAMAGE_THRESH, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_AT2_NUKES, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_SANITY, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_RETURN_FLYOVER, true); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_STRATOPS_AA_FIRE, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_AA_MOVE_MOD, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_ALLOW_LARGE_SQUADRONS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_SINGLE_NO_CAP, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_AERO_ARTILLERY_MUNITIONS, false); + addOption(advAeroRules, OptionsConstants.ADVAERORULES_EXPANDED_KF_DRIVE_DAMAGE, false); + + IBasicOptionGroup initiative = addGroup("initiative"); + addOption(initiative, OptionsConstants.INIT_INF_MOVE_EVEN, false); + addOption(initiative, OptionsConstants.INIT_INF_DEPLOY_EVEN, false); + addOption(initiative, OptionsConstants.INIT_INF_MOVE_LATER, false); + addOption(initiative, OptionsConstants.INIT_INF_MOVE_MULTI, false); + addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_EVEN, false); + addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_EVEN, false); + addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_LATER, false); + addOption(initiative, OptionsConstants.INIT_PROTOS_MOVE_MULTI, false); + addOption(initiative, OptionsConstants.INIT_INF_PROTO_MOVE_MULTI, 3); + addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_DEPLOYMENT, false); + addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_MOVEMENT, false); + addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_TARGETING, false); + addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_FIRING, false); + addOption(initiative, OptionsConstants.INIT_SIMULTANEOUS_PHYSICAL, false); + addOption(initiative, OptionsConstants.INIT_FRONT_LOAD_INITIATIVE, false); + addOption(initiative, OptionsConstants.INIT_INITIATIVE_STREAK_COMPENSATION, false); + IBasicOptionGroup rpg = addGroup("rpg"); - addOption(rpg, OptionsConstants.RPG_PILOT_ADVANTAGES, false); - addOption(rpg, OptionsConstants.EDGE, false); - addOption(rpg, OptionsConstants.RPG_MANEI_DOMINI, false); - addOption(rpg, OptionsConstants.RPG_INDIVIDUAL_INITIATIVE, false); - addOption(rpg, OptionsConstants.RPG_COMMAND_INIT, false); - addOption(rpg, OptionsConstants.RPG_RPG_GUNNERY, false); - addOption(rpg, OptionsConstants.RPG_ARTILLERY_SKILL, false); - addOption(rpg, OptionsConstants.RPG_TOUGHNESS, false); - addOption(rpg, OptionsConstants.RPG_CONDITIONAL_EJECTION, false); - addOption(rpg, OptionsConstants.RPG_MANUAL_SHUTDOWN, false); + addOption(rpg, OptionsConstants.RPG_PILOT_ADVANTAGES, false); + addOption(rpg, OptionsConstants.EDGE, false); + addOption(rpg, OptionsConstants.RPG_MANEI_DOMINI, false); + addOption(rpg, OptionsConstants.RPG_INDIVIDUAL_INITIATIVE, false); + addOption(rpg, OptionsConstants.RPG_COMMAND_INIT, false); + addOption(rpg, OptionsConstants.RPG_RPG_GUNNERY, false); + addOption(rpg, OptionsConstants.RPG_ARTILLERY_SKILL, false); + addOption(rpg, OptionsConstants.RPG_TOUGHNESS, false); + addOption(rpg, OptionsConstants.RPG_CONDITIONAL_EJECTION, false); + addOption(rpg, OptionsConstants.RPG_MANUAL_SHUTDOWN, false); addOption(rpg, OptionsConstants.RPG_BEGIN_SHUTDOWN, false); } @@ -323,10 +324,10 @@ public synchronized Vector loadOptions(File file, boolean print) { if (!file.exists()) { return changedOptions; } - + try { JAXBContext jc = JAXBContext.newInstance(GameOptionsXML.class, Option.class, BasicOption.class); - + Unmarshaller um = jc.createUnmarshaller(); InputStream is = new FileInputStream(file); GameOptionsXML opts = (GameOptionsXML) um.unmarshal(MMXMLUtility.createSafeXmlSource(is)); @@ -437,7 +438,7 @@ public static AbstractOptionsInfo getInstance() { return instance; } } - + /** * A helper class for the XML binding. */ @@ -446,11 +447,11 @@ public static AbstractOptionsInfo getInstance() { private static class GameOptionsXML { @XmlElement(name = "gameoption", type = BasicOption.class) private Vector options; - + GameOptionsXML(final Vector options) { this.options = options; } - + /** * Required for JAXB. */ diff --git a/megamek/src/megamek/common/options/OptionsConstants.java b/megamek/src/megamek/common/options/OptionsConstants.java index db3acf2ffb1..a50a576b49e 100644 --- a/megamek/src/megamek/common/options/OptionsConstants.java +++ b/megamek/src/megamek/common/options/OptionsConstants.java @@ -318,6 +318,7 @@ public class OptionsConstants { public static final String ALLOWED_REALLY_ALLOW_NUKES = "really_allow_nukes"; public static final String ADVANCED_MINEFIELDS = "minefields"; public static final String ADVANCED_HIDDEN_UNITS = "hidden_units"; + public static final String ADVANCED_BLACK_ICE= "black_ice"; public static final String ADVANCED_DOUBLE_BLIND = "double_blind"; public static final String ADVANCED_SINGLE_BLIND_BOTS = "single_blind_bots"; public static final String ADVANCED_TACOPS_SENSORS = "tacops_sensors"; From d8350496d8cbe56d217a4f646cf0d08c3be2628f Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Thu, 8 Jun 2023 19:31:17 -0400 Subject: [PATCH 03/21] Added check for valid terrain and if PSR needed for terrain --- megamek/src/megamek/common/Compute.java | 8 ++++++++ megamek/src/megamek/common/Terrain.java | 2 ++ 2 files changed, 10 insertions(+) diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index 5b13c7f0e41..b50992f0684 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -576,6 +576,14 @@ public static boolean isPilotingSkillNeeded(Game game, int entityId, return true; } + // Check for black ice on pavement + if (destHex.containsTerrain(Terrains.BLACK_ICE) + && !(entity.getElevation() > destHex.getLevel()) + && isPavementStep + && (movementType != EntityMovementType.MOVE_JUMP)) { + return true; + } + // Check for water unless we're a hovercraft or naval or using a bridge // or flying or QuadVee in vehicle mode. if ((movementType != EntityMovementType.MOVE_JUMP) diff --git a/megamek/src/megamek/common/Terrain.java b/megamek/src/megamek/common/Terrain.java index 39b2409549e..985d78194cb 100644 --- a/megamek/src/megamek/common/Terrain.java +++ b/megamek/src/megamek/common/Terrain.java @@ -670,6 +670,8 @@ public boolean isValid(StringBuffer errBuff) { rv = false; } else if (type == Terrains.ICE && level != 1) { rv = false; + } else if (type == Terrains.BLACK_ICE && level != 1) { + rv = false; } else if (type == Terrains.GEYSER && (level < 1 || level > 3)) { rv = false; } else if (type == Terrains.FORTIFIED && level != 1) { From 2223158ff86550b2772d997741b5ee46cd3ca465 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Thu, 8 Jun 2023 19:37:08 -0400 Subject: [PATCH 04/21] Added PSR modifier for reckless movement on Black Ice --- megamek/src/megamek/common/Entity.java | 194 +++++++++++++------------ 1 file changed, 98 insertions(+), 96 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 1ef187d5ae9..d41c8e78dd0 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -214,7 +214,7 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta * The pilot of the entity. Even infantry has a 'pilot'. */ private Crew crew; - + // Crew and passenger numbers protected int nCrew; protected int nPassenger; @@ -258,8 +258,8 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta protected boolean selfDestructInitiated = false; protected boolean selfDestructedThisTurn = false; - /** - * True when the entity has an undestroyed searchlight that is neither a + /** + * True when the entity has an undestroyed searchlight that is neither a * Quirk searchlight nor a mounted (0.5t / 1slot) searchlight. */ protected boolean hasExternalSearchlight = false; @@ -668,7 +668,7 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta private boolean isCommander = false; protected boolean isCarefulStanding = false; - + private boolean turnWasInterrupted = false; /** @@ -785,15 +785,15 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta * Set of team IDs that have observed this entity making attacks from off-board */ private Set offBoardShotObservers; - + private String forceString = ""; private int forceId = Force.NO_FORCE; - + /** * The current target of the Blood Stalker SPA. */ private int bloodStalkerTarget = Entity.NONE; - + /** * The location the unit is bracing as per TacOps:AR page 82 */ @@ -895,11 +895,11 @@ public void restore() { for (Mounted mounted : equipmentList) { mounted.restore(); } - + // in some situations, an entity's facing winds up having an illegal value // this will correct it as best as possible facing = FireControl.correctFacing(getFacing()); - + // set game options, we derive some equipment's modes from this setGameOptions(); } @@ -1262,7 +1262,7 @@ public void recalculateTechAdvancement() { public static TechAdvancement getOmniAdvancement() { return getOmniAdvancement(null); } - + public static TechAdvancement getOmniAdvancement(Entity en) { if (en instanceof Tank) { return new TechAdvancement(TA_OMNIVEHICLE); @@ -1378,7 +1378,7 @@ public boolean isClanArmor(int loc) { if (loc >= locations()) { return false; } - + if (getArmorTechLevel(loc) == TechConstants.T_TECH_UNKNOWN) { return isClan(); } @@ -1473,8 +1473,8 @@ public int getBodyLocation() { public Player getOwner() { // Replaced 24 NOV 2020 // Server and other central classes already used game.getplayer(entity.getownerID()) - // instead of entity.getowner() and it is noted that getOwner is not reliable. - // The entity owner object would have to be replaced whenever a player is updated + // instead of entity.getowner() and it is noted that getOwner is not reliable. + // The entity owner object would have to be replaced whenever a player is updated // which does not happen. The player ID on the other hand stays the same and the game // object is not usually replaced. I expect entity.game to be up to date much more than owner. // Unfortunately, entities freshly created may not have the game set. Therefore, fall @@ -1522,7 +1522,7 @@ public Crew getCrew() { public void setCrew(Crew crew) { this.crew = crew; } - + /** * @return The total number of crew available to supplement marines on boarding actions. * Includes officers, enlisted, and bay personnel, but not marines/ba or passengers. @@ -1530,10 +1530,10 @@ public void setCrew(Crew crew) { public int getNCrew() { return nCrew; } - + public void setNCrew(int crew) { } - + /** * Returns the number of passengers on this unit * Intended for spacecraft, where we want to get the crews of transported units @@ -1543,17 +1543,17 @@ public void setNCrew(int crew) { public int getNPassenger() { return nPassenger; } - + public void setNPassenger(int pass) { } - + /** * @return The number conventional marines available to vessels for boarding actions. */ public int getNMarines() { return nMarines; } - + /** * Updates the number of marines aboard * @param marines The number of marines to add/subtract @@ -1846,7 +1846,7 @@ public void setFindingClub(boolean findingClub) { public void setArmsFlipped(boolean armsFlipped) { setArmsFlipped(armsFlipped, true); } - + /** * Set whether or not the mech's arms are flipped to the rear. * Does not fire the game event, useful for when it's called repeatedly @@ -1854,7 +1854,7 @@ public void setArmsFlipped(boolean armsFlipped) { */ public void setArmsFlipped(boolean armsFlipped, boolean fireEvent) { this.armsFlipped = armsFlipped; - + if (fireEvent) { game.processGameEvent(new GameEntityChangeEvent(this, this)); } @@ -2237,7 +2237,7 @@ public boolean canGoUp(int assumedElevation, Coords assumedPos) { // "- 1" to correct that height() reports one less than the rules (TW p.99) say if (hex.containsTerrain(Terrains.BRIDGE_ELEV) && assumedElevation < hex.terrainLevel(Terrains.BRIDGE_ELEV)) { - maxAlt = hex.terrainLevel(Terrains.BRIDGE_ELEV) - height() - 1; + maxAlt = hex.terrainLevel(Terrains.BRIDGE_ELEV) - height() - 1; } break; case AERODYNE: @@ -2294,16 +2294,16 @@ public boolean isElevationValid(int assumedElevation, Hex hex) { if (getMovementMode() == EntityMovementMode.VTOL) { if ((this instanceof Infantry) && (hex.containsTerrain(Terrains.BUILDING) - || hex.containsTerrain(Terrains.WOODS) + || hex.containsTerrain(Terrains.WOODS) || hex.containsTerrain(Terrains.JUNGLE))) { // VTOL BA (sylph) can move as ground unit as well return ((assumedElevation <= 50) && (assumedAlt >= hex.floor())); } else { // VTOLs can be anywhere on or above ground and fly beneath bridges, - // land on buildings and ignore planted fields and industrial zone + // land on buildings and ignore planted fields and industrial zone // but cannot land on water or trees // As always, height() reports one less than the rules (TW p.99) say - // Units may move under a bridge if their top is + // Units may move under a bridge if their top is // lower than or equal to the bridge height (TW p.62) boolean allowed = (assumedElevation <= 50) && (assumedElevation >= 0); if (hex.containsTerrain(Terrains.BRIDGE_ELEV)) { @@ -2564,7 +2564,7 @@ public int getFacing() { if (transporter == null) { transporter = game.getOutOfGameEntity(conveyance); } - + if (transporter != null) { return transporter.getFacing(); } @@ -2611,9 +2611,9 @@ public int getSecondaryFacing() { public void setSecondaryFacing(int sec_facing) { setSecondaryFacing(sec_facing, true); } - + /** - * Sets the secondary facing. + * Sets the secondary facing. * Optionally does not fire a game change event (useful for bot evaluation) */ public void setSecondaryFacing(int sec_facing, boolean fireEvent) { @@ -2622,7 +2622,7 @@ public void setSecondaryFacing(int sec_facing, boolean fireEvent) { game.processGameEvent(new GameEntityChangeEvent(this, this)); } } - + /** * Utility function that handles situations where a facing change * imparts some kind of permanent effect to the entity. @@ -3817,7 +3817,7 @@ public int getTotalAmmoOfType(EquipmentType et) { */ public int getTotalMunitionsOfType(Mounted weapon) { int totalShotsLeft = 0; - + // specifically don't count caseless munitions as being of the same type as non-caseless for (Mounted amounted : getAmmo()) { boolean canSwitchToAmmo = AmmoType.canSwitchToAmmo(weapon, (AmmoType) amounted.getType()); @@ -3850,7 +3850,7 @@ public Iterator getWeapons() { return weaponList.iterator(); } - + public ArrayList getIndividualWeaponList() { return weaponList; } @@ -4006,10 +4006,10 @@ public void loadWeapon(Mounted mounted) { /** * Tries to load the specified weapon with the first available ammo of the * same munition type as currently in use. If this fails, use first ammo. - * + * * If this is a weapon bay, try to load the weapon with ammo in the same bay, * and if it fails, load with compatible ammo in the same location. - * + * * If this unit is part of a train, also check the vehicles directly connected * to it for compatible ammo */ @@ -5313,7 +5313,7 @@ public int getECMRange() { public boolean hasBAP() { return hasBAP(true); } - + /** * Does a unit on the same C3 network have a BAP? * Used to share BAP targeting bonuses against targets in woods @@ -5322,7 +5322,7 @@ public boolean hasBAP() { public boolean hasNetworkBAP() { return networkBAP; } - + public void setNetworkBAP(boolean BAP) { networkBAP = BAP; } @@ -5701,12 +5701,12 @@ && hasAbility(OptionsConstants.MD_BOOST_COMM_IMPLANT)) { } return false; } - + /** Returns true if the unit has a nonhierarchic C3 system (C3i, NC3 or Nova CEWS). */ public boolean hasNhC3() { return hasC3i() || hasNavalC3() || hasNovaCEWS(); } - + /** Returns true if the unit has a standard C3M/S, a Naval C3 or C3i or a Nova CEWS. */ public boolean hasAnyC3System() { return hasC3() || hasNhC3(); @@ -6396,7 +6396,7 @@ public void newRound(int roundNumber) { setSelfDestructedThisTurn(false); setClimbMode(GUIP.getMoveDefaultClimbMode()); - + setTurnInterrupted(false); } @@ -6641,12 +6641,12 @@ public void removeAllINarcPods() { public boolean hasINarcPodsAttached() { return !iNarcPods.isEmpty(); } - + /** Returns true if any Narc pods are attached to this unit. (Ignores iNarc) */ public boolean hasNarcPodsAttached() { return !narcPods.isEmpty(); } - + /** Returns true if any Narc or iNarc pods are attached to this unit. */ public boolean hasAnyTypeNarcPodsAttached() { return hasINarcPodsAttached() || hasNarcPodsAttached(); @@ -7282,6 +7282,8 @@ else if ((isFoggy || isDark) // ice conditions } else if (curHex.containsTerrain(Terrains.ICE)) { roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); + } else if (curHex.containsTerrain(Terrains.BLACK_ICE)) { + roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); } else { roll.addModifier(TargetRoll.CHECK_FALSE, "not moving recklessly"); } @@ -7555,24 +7557,24 @@ public PilotingRollData checkBogDown(MoveStep step, this instanceof LargeSupportTank); // we check for bog down on entering a new hex or changing altitude - // but not if we're jumping, above the "ground" (meaning the bottom of the lake), + // but not if we're jumping, above the "ground" (meaning the bottom of the lake), // not susceptible to bog down as per getBogDownModifier, // and not on pavement if ((!lastPos.equals(curPos) || (step.getElevation() != lastElev)) && (bgMod != TargetRoll.AUTOMATIC_SUCCESS) && (moveType != EntityMovementType.MOVE_JUMP) && (step.getElevation() == -curHex.depth()) && !isPavementStep) { - + roll.append(new PilotingRollData(getId(), bgMod, "avoid bogging down")); - + if ((this instanceof Mech) && ((Mech) this).isSuperHeavy()) { roll.addModifier(1, "superheavy mech avoiding bogging down"); } - + if (hasAbility(OptionsConstants.PILOT_TM_SWAMP_BEAST)) { roll.addModifier(-1, "Swamp Beast"); } - + addPilotingModifierForTerrain(roll, curPos, false); adjustDifficultTerrainPSRModifier(roll); } else { @@ -7765,7 +7767,7 @@ public PilotingRollData rollMovementInBuilding(Building bldg, int distance, if ((this instanceof Mech) && ((Mech) this).isSuperHeavy()) { roll.addModifier(4, "superheavy mech moving in building"); } - + if (this.hasQuirk(OptionsConstants.QUIRK_NEG_OVERSIZED)) { roll.addModifier(1, "oversized unit"); } @@ -8364,9 +8366,9 @@ public Vector getBayLoadedUnits() { // Return the list. return result; } - + /** - * Generate a list of the Ids of entities stored in bays. + * Generate a list of the Ids of entities stored in bays. * Used by MHQ in cases where we can't get the entities via Game * * @return @@ -8417,7 +8419,7 @@ public Bay getBayById(int bayNumber) { } return null; } - + /** * Returns the DockingCollar with the given ID or null if this unit doesn't have such a * Docking Collar. @@ -9295,7 +9297,7 @@ public void setSpotting(boolean spotting) { * @return true, if the entity is eligible to spot */ public boolean canSpot() { - return isActive() && !isOffBoard() && + return isActive() && !isOffBoard() && (moved != EntityMovementType.MOVE_SPRINT) && (moved != EntityMovementType.MOVE_VTOL_SPRINT); } @@ -9441,7 +9443,7 @@ public void setNeverDeployed(boolean neverDeployed) { * Returns true if the entity should be deployed */ public boolean shouldDeploy(int round) { - return !isDeployed() + return !isDeployed() && (getDeployRound() <= round) && !isOffBoard(); } @@ -9453,8 +9455,8 @@ public boolean shouldDeploy(int round) { * round, otherwise false. */ public boolean shouldOffBoardDeploy(int round) { - return isOffBoard() - && !isDeployed() + return isOffBoard() + && !isDeployed() && (getDeployRound() <= round); } @@ -9925,7 +9927,7 @@ public boolean isAttackingThisTurn() { public boolean isEligibleForPhysical() { boolean canHit = false; boolean friendlyFire = game.getOptions().booleanOption(OptionsConstants.BASE_FRIENDLY_FIRE); - + if ((this instanceof Infantry) && hasWorkingMisc(MiscType.F_TOOLS, MiscType.S_DEMOLITION_CHARGE)) { @@ -11248,7 +11250,7 @@ public int getMotiveSideMod(int side) { public void setHidden(boolean inVal) { isHidden = inVal; } - + public void setMadePointblankShot(boolean inVal) { madePointblankShot = inVal; } @@ -11332,7 +11334,7 @@ public void destroyLocation(int loc, boolean blownOff) { } // all critical slots set as missing - // while we're here, if something is mounted in those crits, set it as hit, + // while we're here, if something is mounted in those crits, set it as hit, // instead of looping through all equipment in the unit for (int i = 0; i < getNumberOfCriticals(loc); i++) { final CriticalSlot cs = getCritical(loc, i); @@ -11343,35 +11345,35 @@ public void destroyLocation(int loc, boolean blownOff) { && !cs.isDamaged()) { engineHitsThisPhase++; } - + final boolean mountOneIsHittable = (cs.getMount() != null) && cs.getMount().getType().isHittable(); final boolean mountTwoIsHittable = (cs.getMount2() != null) && cs.getMount2().getType().isHittable(); - + if (blownOff) { cs.setMissing(true); - + if (mountOneIsHittable) { cs.getMount().setMissing(true); } - + if (mountTwoIsHittable) { cs.getMount2().setMissing(true); } - + } else { cs.setHit(true); - + if (mountOneIsHittable) { cs.getMount().setHit(true); } - + if (mountTwoIsHittable) { cs.getMount2().setHit(true); } } } } - + // some equipment is not present in critical slots // but is present in the location, so we'll need to look at it as well for (Mounted mounted : getEquipment()) { @@ -11386,7 +11388,7 @@ public void destroyLocation(int loc, boolean blownOff) { } } } - + // dependent locations destroyed, unless they are already destroyed if ((getDependentLocation(loc) != Entity.LOC_NONE) && !(getInternal(getDependentLocation(loc)) < 0)) { @@ -13858,11 +13860,11 @@ public int getFreeNC3UUID() { } return pos; } - + public boolean isC3CompanyCommander() { return getC3MasterId() == id; } - + public boolean isC3IndependentMaster() { return !isC3CompanyCommander(); } @@ -13943,14 +13945,14 @@ public Camouflage getCamouflageOrElse(final Camouflage camouflage) { public Camouflage getCamouflageOrElse(final Camouflage camouflage, final boolean checkForces) { // if we're checking forces and the game exists, then initialize the force. Leave it as null otherwise. - final Force force = checkForces && (game != null) ? + final Force force = checkForces && (game != null) ? game.getForces().getForce(this) : null; - + // if the camouflage is default and the force is null, return the current entity-specific camouflage // if the force is not null, return the force specific camouflage // if the camouflage is not default, just return the current entity-specific camouflage return getCamouflage().hasDefaultCategory() - ? ((force == null) ? camouflage : force.getCamouflageOrElse(game, camouflage)) + ? ((force == null) ? camouflage : force.getCamouflageOrElse(game, camouflage)) : getCamouflage(); } @@ -14399,7 +14401,7 @@ public int getAllowedPhysicalAttacks() { public int getMaxWeaponRange() { return getMaxWeaponRange(false); } - + /** * The max weapons range of this entity, taking into account whether * we're on an air/space map, using extreme range, and whether the target is @@ -14429,18 +14431,18 @@ public int getMaxWeaponRange(boolean targetIsAirborne) { WeaponType type = (WeaponType) weapon.getType(); int range; - + if (isAirborne()) { int rangeMultiplier = type.isCapital() ? 2 : 1; rangeMultiplier *= isAirborneAeroOnGroundMap() ? 8 : 1; - + range = WeaponType.AIRBORNE_WEAPON_RANGES[type.getMaxRange(weapon)] * rangeMultiplier; } else { range = (game.getOptions().booleanOption( OptionsConstants.ADVCOMBAT_TACOPS_RANGE) ? type.getExtremeRange() : type.getLongRange()); } - + if (range > maxRange) { maxRange = range; } @@ -15257,7 +15259,7 @@ public int modifyPhysicalDamageForMeleeSpecialist() { public Set getSensorContacts() { return sensorContacts; } - + /** * Checks the sensorContacts set for a specific target's ID number * @param targetId the ID number of the target entity to check for @@ -15266,7 +15268,7 @@ public Set getSensorContacts() { public boolean hasSensorContactFor(int targetId) { return sensorContacts.contains(targetId); } - + /** * Adds the specified target entity's ID to this entity's sensorContacts * @param targetId the ID number of the target entity to add @@ -15274,7 +15276,7 @@ public boolean hasSensorContactFor(int targetId) { public void addSensorContact(int targetId) { sensorContacts.add(targetId); } - + /** * Removes the specified target entity's ID from this entity's sensorContacts * @param targetIds the ID number of the target entity to remove @@ -15282,7 +15284,7 @@ public void addSensorContact(int targetId) { public void removeSensorContact(Collection targetIds) { sensorContacts.removeAll(targetIds); } - + /** * Empties this entity's sensorContacts * Used when it dies or moves offboard @@ -15290,7 +15292,7 @@ public void removeSensorContact(Collection targetIds) { public void clearSensorContacts() { sensorContacts.clear(); } - + /** * Retrieves the IDs of all entities that this entity has established firing solutions on * @return the contents of this entity's firingSolutions set @@ -15298,7 +15300,7 @@ public void clearSensorContacts() { public Set getFiringSolutions() { return firingSolutions; } - + /** * Checks the firingSolutions set for a specific target's ID number * @param targetId the ID number of the target entity to check for @@ -15307,7 +15309,7 @@ public Set getFiringSolutions() { public boolean hasFiringSolutionFor(int targetId) { return firingSolutions.contains(targetId); } - + /** * Adds the specified target entity's ID to this entity's firingSolutions * @param targetId the ID number of the target entity to add @@ -15315,7 +15317,7 @@ public boolean hasFiringSolutionFor(int targetId) { public void addFiringSolution(int targetId) { firingSolutions.add(targetId); } - + /** * Removes the specified target entity's ID from this entity's firingSolutions * @param targetIds the ID number of the target entity to remove @@ -15323,7 +15325,7 @@ public void addFiringSolution(int targetId) { public void removeFiringSolution(Collection targetIds) { firingSolutions.removeAll(targetIds); } - + /** * Empties this entity's firingSolutions * Used when it dies or moves offboard @@ -15331,14 +15333,14 @@ public void removeFiringSolution(Collection targetIds) { public void clearFiringSolutions() { firingSolutions.clear(); } - + /** * Indicate that an off-board artillery attack by this entity has been observed by a particular team */ public void addOffBoardObserver(int teamID) { offBoardShotObservers.add(teamID); } - + /** * Has the given team observed an off-board artillery attack by this entity? */ @@ -15369,18 +15371,18 @@ public void setForceId(int newId) { public void setBloodStalkerTarget(int value) { bloodStalkerTarget = value; } - + public int getStartingOffset() { return getStartingOffset(true); } - + public int getStartingOffset(boolean inheritFromOwner) { // if we are given permission to use the owner's settings // and have specified entity-specific settings, use the owner's settings if (inheritFromOwner && (startingPos == Board.START_NONE)) { return getOwner().getStartOffset(); } - + return startingOffset; } @@ -15391,14 +15393,14 @@ public void setStartingOffset(int startingOffset) { public int getStartingWidth() { return getStartingWidth(true); } - + public int getStartingWidth(boolean inheritFromOwner) { // if we are given permission to use the owner's settings // and have specified entity-specific settings, use the owner's settings if (inheritFromOwner && (startingPos == Board.START_NONE)) { return getOwner().getStartWidth(); } - + return startingWidth; } @@ -15409,7 +15411,7 @@ public void setStartingWidth(int startingWidth) { public int getBloodStalkerTarget() { return bloodStalkerTarget; } - + /** * Whether this entity can activate the "blood stalker" ability */ @@ -15417,24 +15419,24 @@ public boolean canActivateBloodStalker() { return hasAbility(OptionsConstants.GUNNERY_BLOOD_STALKER) && (getBloodStalkerTarget() == Entity.NONE); } - + public int braceLocation() { return braceLocation; } - + public void setBraceLocation(int location) { braceLocation = location; } - + @Override public boolean isBracing() { return braceLocation != Entity.LOC_NONE; } - + public boolean canBrace() { return false; } - + public int getBraceMPCost() { return Entity.LOC_NONE; } From e4f35567310053d0f00f53547b4e683502ca3fdf Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Fri, 9 Jun 2023 08:03:22 -0400 Subject: [PATCH 05/21] Add helper function for checking if isPavementStep contains black ice. --- megamek/src/megamek/server/ServerHelper.java | 104 +++++++++++-------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/megamek/src/megamek/server/ServerHelper.java b/megamek/src/megamek/server/ServerHelper.java index 896b7a2555b..745f0b07fb4 100644 --- a/megamek/src/megamek/server/ServerHelper.java +++ b/megamek/src/megamek/server/ServerHelper.java @@ -26,12 +26,12 @@ /** * This class contains computations carried out by the Server class. - * Methods put in here should be static and self-contained. + * Methods put in here should be static and self-contained. * @author NickAragua */ public class ServerHelper { /** - * Determines if the given entity is an infantry unit in the given hex is "in the open" + * Determines if the given entity is an infantry unit in the given hex is "in the open" * (and thus subject to double damage from attacks) * @param te Target entity. * @param te_hex Hex where target entity is located. @@ -41,9 +41,9 @@ public class ServerHelper { * @param ignoreInfantryDoubleDamage Whether we should ignore double damage to infantry. * @return Whether the infantry unit can be considered to be "in the open" */ - public static boolean infantryInOpen(Entity te, Hex te_hex, Game game, + public static boolean infantryInOpen(Entity te, Hex te_hex, Game game, boolean isPlatoon, boolean ammoExplosion, boolean ignoreInfantryDoubleDamage) { - + if (isPlatoon && !te.isDestroyed() && !te.isDoomed() && !ignoreInfantryDoubleDamage && (((Infantry) te).getDugIn() != Infantry.DUG_IN_COMPLETE)) { @@ -61,17 +61,17 @@ public static boolean infantryInOpen(Entity te, Hex te_hex, Game game, return true; } } - + return false; } - + /** * Worker function that handles heat as applied to aerospace fighter */ - public static void resolveAeroHeat(Game game, Entity entity, Vector vPhaseReport, Vector rhsReports, + public static void resolveAeroHeat(Game game, Entity entity, Vector vPhaseReport, Vector rhsReports, int radicalHSBonus, int hotDogMod, GameManager s) { Report r; - + // If this aero is part of a squadron, we will deal with its // heat with the fighter squadron if (game.getEntity(entity.getTransportId()) instanceof FighterSquadron) { @@ -354,10 +354,10 @@ else if ((entity.heat >= 14) && !entity.isShutDown()) { r.subject = entity.getId(); r.addDesc(entity); r.add(boom); - + int roll = Compute.d6(2); r.add(roll); - + if (roll >= boom) { // no ammo explosion r.choose(true); @@ -448,15 +448,15 @@ public static void sinkToBottom(Entity entity) { if ((entity == null) || !entity.getGame().getBoard().contains(entity.getPosition())) { return; } - + Hex fallHex = entity.getGame().getBoard().getHex(entity.getPosition()); int waterDepth = 0; - + // we're going hull down, we still sink to the bottom if appropriate if (fallHex.containsTerrain(Terrains.WATER)) { boolean hexHasBridge = fallHex.containsTerrain(Terrains.BRIDGE_CF); boolean entityOnTopOfBridge = hexHasBridge && (entity.getElevation() == fallHex.ceiling()); - + if (!entityOnTopOfBridge) { // *Only* use this if there actually is water in the hex, otherwise // we get Terrain.LEVEL_NONE, i.e. Integer.minValue... @@ -465,22 +465,22 @@ public static void sinkToBottom(Entity entity) { } } } - + public static void checkAndApplyMagmaCrust(Hex hex, int elevation, Entity entity, Coords curPos, boolean jumpLanding, Vector vPhaseReport, GameManager gameManager) { - + if ((hex.terrainLevel(Terrains.MAGMA) == 1) && (elevation == 0) && (entity.getMovementMode() != EntityMovementMode.HOVER)) { int reportID = jumpLanding ? 2396 : 2395; - + int roll = Compute.d6(); Report r = new Report(reportID); r.addDesc(entity); r.add(roll); r.subject = entity.getId(); vPhaseReport.add(r); - + int rollTarget = jumpLanding ? 4 : 6; - + if (roll >= rollTarget) { hex.removeTerrain(Terrains.MAGMA); hex.addTerrain(new Terrain(Terrains.MAGMA, 2)); @@ -504,12 +504,32 @@ public static void checkEnteringMagma(Hex hex, int elevation, Entity entity, Gam } } + /** + * Check for black ice when moving into pavement hex. + */ + public static boolean checkEnteringBlackIce(GameManager gameManager, Coords curPos, Hex curHex, boolean useBlackIce, boolean goodTemp, boolean isIceStorm) { + boolean isPavement = curHex.hasPavement(); + if (isPavement && ((useBlackIce && goodTemp) || isIceStorm)) { + if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { + int blackIceChance = Compute.d6(1); + if (blackIceChance > 1) { + curHex.addTerrain(new Terrain(Terrains.BLACK_ICE, 1)); + gameManager.sendChangedHex(curPos); + return true; + } + } else { + return true; + } + } + return false; + } + /** * Loops through all active entities in the game and performs mine detection */ public static void detectMinefields(Game game, Vector vPhaseReport, GameManager gameManager) { boolean tacOpsBap = game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_BAP); - + // if the entity is on the board // and it either a) hasn't moved or b) we're not using TacOps BAP rules // if we are not using the TacOps BAP rules, that means we only check the entity's final hex @@ -522,67 +542,67 @@ public static void detectMinefields(Game game, Vector vPhaseReport, Game } } } - + /** * Checks for minefields within the entity's active probe range. * @return True if any minefields have been detected. */ - public static boolean detectMinefields(Game game, Entity entity, Coords coords, + public static boolean detectMinefields(Game game, Entity entity, Coords coords, Vector vPhaseReport, GameManager gameManager) { if (!game.getOptions().booleanOption(OptionsConstants.ADVANCED_MINEFIELDS)) { return false; } - + // can't detect minefields if the coordinates are invalid if (coords == null) { return false; } - + // can't detect minefields if there aren't any to detect if (!game.getMinedCoords().hasMoreElements()) { return false; } - + // can't detect minefields if we have no probe int probeRange = entity.getBAPRange(); if (probeRange <= 0) { return false; } - + boolean minefieldDetected = false; - + for (int distance = 1; distance <= probeRange; distance++) { for (Coords potentialMineCoords : coords.allAtDistance(distance)) { if (!game.getBoard().contains(potentialMineCoords)) { continue; } - + for (Minefield minefield : game.getMinefields(potentialMineCoords)) { // no need to roll for already revealed minefields if (entity.getOwner().containsMinefield(minefield)) { continue; } - + int roll = Compute.d6(2); - + if (roll >= minefield.getBAPDetectionTarget()) { minefieldDetected = true; - + Report r = new Report(2163); r.subject = entity.getId(); r.add(entity.getShortName(), true); r.add(potentialMineCoords.toFriendlyString()); vPhaseReport.add(r); - + gameManager.revealMinefield(entity.getOwner(), minefield); } } } } - + return minefieldDetected; } - + /** * Checks to see if any units can detected hidden units. */ @@ -592,20 +612,20 @@ public static boolean detectHiddenUnits(Game game, Entity detector, Coords detec if (!game.getOptions().booleanOption(OptionsConstants.ADVANCED_HIDDEN_UNITS)) { return false; } - + // Units without a position won't be able to detect // check for this before calculating BAP range, as that's expensive if ((detector.getPosition() == null) || (detectorCoords == null)) { return false; } - + int probeRange = detector.getBAPRange(); - + // if no probe, save ourselves a few loops if (probeRange <= 0) { return false; } - + // Get all hidden units in probe range List hiddenUnits = new ArrayList<>(); for (Coords coords : detectorCoords.allAtDistanceOrLess(probeRange)) { @@ -625,8 +645,8 @@ public static boolean detectHiddenUnits(Game game, Entity detector, Coords detec boolean detectorHasBloodhound = detector.hasWorkingMisc(MiscType.F_BLOODHOUND); boolean hiddenUnitFound = false; - - for (Entity detected : hiddenUnits) { + + for (Entity detected : hiddenUnits) { // Can only detect units within the probes range int dist = detector.getPosition().distance(detected.getPosition()); boolean beyondPointBlankRange = dist > 1; @@ -670,7 +690,7 @@ public static boolean detectHiddenUnits(Game game, Entity detector, Coords detec Report.addNewline(vPhaseReport); reportPlayers.add(detector.getOwnerId()); reportPlayers.add(detected.getOwnerId()); - + hiddenUnitFound = true; } } @@ -681,10 +701,10 @@ public static boolean detectHiddenUnits(Game game, Entity detector, Coords detec gameManager.send(playerId, gameManager.createSpecialReportPacket()); } } - + return hiddenUnitFound; } - + /** * Loop through the game and clear 'blood stalker' flag for * any entities that have the given unit as the blood stalker target. From 0d107c7b0d5452b78a85f62c26bfeb35bdc51921 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Sat, 10 Jun 2023 00:02:17 -0400 Subject: [PATCH 06/21] Remove Black Ice if hex has been on fire for multiple turns. --- .../src/megamek/server/WeatherProcessor.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/megamek/src/megamek/server/WeatherProcessor.java b/megamek/src/megamek/server/WeatherProcessor.java index 85a601a3363..6bf10cf0c97 100644 --- a/megamek/src/megamek/server/WeatherProcessor.java +++ b/megamek/src/megamek/server/WeatherProcessor.java @@ -135,14 +135,14 @@ private void resolveWeather() { gameManager.removeFire(currentCoords, "weather conditions"); } // Downgrade Inferno fires so they can burn out - } else if (currentHex.terrainLevel(Terrains.FIRE) + } else if (currentHex.terrainLevel(Terrains.FIRE) == Terrains.FIRE_LVL_INFERNO) { //inferno fires should become regular fires currentHex.removeTerrain(Terrains.FIRE); currentHex.addTerrain(new Terrain(Terrains.FIRE, 1)); gameManager.getHexUpdateSet().add(currentCoords); // Check Inferno Bombs - } else if (currentHex.terrainLevel(Terrains.FIRE) + } else if (currentHex.terrainLevel(Terrains.FIRE) == Terrains.FIRE_LVL_INFERNO_BOMB) { if (currentHex.getFireTurn() > 30) { gameManager.removeFire(currentCoords, @@ -160,7 +160,7 @@ private void resolveWeather() { if (lightSnow && !currentHex.containsTerrain(Terrains.SNOW) - && !(currentHex.containsTerrain(Terrains.WATER) + && !(currentHex.containsTerrain(Terrains.WATER) && !currentHex.containsTerrain(Terrains.ICE)) && !currentHex.containsTerrain(Terrains.MAGMA)) { currentHex.addTerrain(new Terrain(Terrains.SNOW, 1)); @@ -168,7 +168,7 @@ private void resolveWeather() { } if (deepSnow && !(currentHex.terrainLevel(Terrains.SNOW) > 1) - && !(currentHex.containsTerrain(Terrains.WATER) + && !(currentHex.containsTerrain(Terrains.WATER) && !currentHex.containsTerrain(Terrains.ICE)) && !currentHex.containsTerrain(Terrains.MAGMA)) { currentHex.addTerrain(new Terrain(Terrains.SNOW, 2)); @@ -177,7 +177,7 @@ private void resolveWeather() { // check for the melting of any snow or ice if (currentHex.terrainLevel(Terrains.SNOW) > 1 - && currentHex.containsTerrain(Terrains.FIRE) + && currentHex.containsTerrain(Terrains.FIRE) && currentHex.getFireTurn() == 3) { currentHex.removeTerrain(Terrains.SNOW); if (!currentHex.containsTerrain(Terrains.MUD) @@ -187,7 +187,7 @@ private void resolveWeather() { } if (currentHex.terrainLevel(Terrains.SNOW) == 1 - && currentHex.containsTerrain(Terrains.FIRE) + && currentHex.containsTerrain(Terrains.FIRE) && currentHex.getFireTurn() == 1) { currentHex.removeTerrain(Terrains.SNOW); if (!currentHex.containsTerrain(Terrains.MUD) @@ -197,7 +197,7 @@ private void resolveWeather() { } if (currentHex.containsTerrain(Terrains.ICE) - && currentHex.containsTerrain(Terrains.FIRE) + && currentHex.containsTerrain(Terrains.FIRE) && currentHex.getFireTurn() == 2) { currentHex.removeTerrain(Terrains.ICE); if (!currentHex.containsTerrain(Terrains.MUD) @@ -206,10 +206,16 @@ private void resolveWeather() { } } + if (currentHex.containsTerrain(Terrains.BLACK_ICE) + && currentHex.containsTerrain(Terrains.FIRE) + && currentHex.getFireTurn() == 2) { + currentHex.removeTerrain(Terrains.BLACK_ICE); + } + // check for rapids/torrents created by wind // FIXME: This doesn't seem to be doing anything if (conditions.getWindStrength() > PlanetaryConditions.WI_MOD_GALE - && currentHex.containsTerrain(Terrains.WATER) + && currentHex.containsTerrain(Terrains.WATER) && currentHex.depth(true) > 0) { if (conditions.getWindStrength() > PlanetaryConditions.WI_STORM) { From 8674575d0200bd72e4ee3f602843b1cb83a65eb9 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Sat, 10 Jun 2023 06:35:47 -0400 Subject: [PATCH 07/21] PSR check for jumping onto possible black ice hex. --- megamek/src/megamek/common/Entity.java | 20 ++++++++++++++++++++ megamek/src/megamek/server/GameManager.java | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index d41c8e78dd0..d9bc9796d8d 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7383,6 +7383,26 @@ public PilotingRollData checkLandingOnIce( return roll; } + /** + * Checks if the entity is landing (from a jump) on black ice. + */ + public PilotingRollData checkLandingOnBlackIce( + EntityMovementType overallMoveType, Hex curHex) { + PilotingRollData roll = getBasePilotingRoll(overallMoveType); + + if (curHex.containsTerrain(Terrains.BLACK_ICE)) { + roll.append(new PilotingRollData(getId(), 0, + "landing on black ice")); + addPilotingModifierForTerrain(roll); + adjustDifficultTerrainPSRModifier(roll); + } else { + roll.addModifier(TargetRoll.CHECK_FALSE, + "hex is not covered by black ice"); + } + + return roll; + } + /** * return a PilotingRollData checking for whether this Entity * moved too fast due to low gravity diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index 89a4286da74..cfacc39b31a 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -8580,16 +8580,19 @@ else if ((step.getElevation() + entity.height()) == 0) { // but the danger isn't over yet! landing from a jump can be risky! if ((overallMoveType == EntityMovementType.MOVE_JUMP) && !entity.isMakingDfa()) { final Hex curHex = game.getBoard().getHex(curPos); + // check for damaged criticals rollTarget = entity.checkLandingWithDamage(overallMoveType); if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { doSkillCheckInPlace(entity, rollTarget); } + // check for prototype JJs rollTarget = entity.checkLandingWithPrototypeJJ(overallMoveType); if (rollTarget.getValue() != TargetRoll.CHECK_FALSE) { doSkillCheckInPlace(entity, rollTarget); } + // check for jumping into heavy woods if (game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_PSR_JUMP_HEAVY_WOODS)) { rollTarget = entity.checkLandingInHeavyWoods(overallMoveType, curHex); @@ -8597,6 +8600,7 @@ else if ((step.getElevation() + entity.height()) == 0) { doSkillCheckInPlace(entity, rollTarget); } } + // Mechanical jump boosters fall damage if (md.shouldMechanicalJumpCauseFallDamage()) { vPhaseReport.addAll(doEntityFallsInto(entity, @@ -8604,6 +8608,7 @@ else if ((step.getElevation() + entity.height()) == 0) { curPos, entity.getBasePilotingRoll(overallMoveType), false, entity.getJumpMP())); } + // jumped into water? int waterLevel = curHex.terrainLevel(Terrains.WATER); if (curHex.containsTerrain(Terrains.ICE) && (waterLevel > 0)) { @@ -8660,6 +8665,20 @@ else if ((step.getElevation() + entity.height()) == 0) { } } + // check for black ice + // FIXME Check weather and optional rule for black ice. + boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + if ((useBlackIce && goodTemp) || goodWeather) { + if (ServerHelper.checkEnteringBlackIce(this, curPos, curHex, useBlackIce, goodTemp, goodWeather)) { + rollTarget = entity.checkLandingOnBlackIce(overallMoveType, curHex); + if (!doSkillCheckInPlace(entity, rollTarget)) { + entity.applyDamage(); + } + } + } + // check for building collapse Building bldg = game.getBoard().getBuildingAt(curPos); if (bldg != null) { @@ -8703,6 +8722,7 @@ else if ((step.getElevation() + entity.height()) == 0) { } } } + // If the entity is being swarmed, jumping may dislodge the fleas. if (Entity.NONE != swarmerId) { final Entity swarmer = game.getEntity(swarmerId); From 8b740ee08a3e4d3a6e7366ac7b5ef749e564845b Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 12 Jun 2023 03:30:32 -0400 Subject: [PATCH 08/21] Adding reckless movement on pavement PSR check when Black Ice is in play. --- megamek/src/megamek/common/Entity.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index d9bc9796d8d..93247922d9f 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7258,6 +7258,15 @@ public PilotingRollData checkRecklessMove(MoveStep step, // move path has ice boolean isFoggy = game.getPlanetaryConditions().getFog() != PlanetaryConditions.FOG_NONE; boolean isDark = game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DUSK; + boolean isBlackIce; + + if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) + || (game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE) + && game.getPlanetaryConditions().getTemperature() <= -30)) { + isBlackIce = true; + } else { + isBlackIce = false; + } // if we are jumping, then no worries if (moveType == EntityMovementType.MOVE_JUMP) { @@ -7284,6 +7293,8 @@ else if ((isFoggy || isDark) roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); } else if (curHex.containsTerrain(Terrains.BLACK_ICE)) { roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); + } else if (curHex.hasPavement() && isBlackIce) { + roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); } else { roll.addModifier(TargetRoll.CHECK_FALSE, "not moving recklessly"); } From df2e4c81b424776116c7d76c264f04822e63adad Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 12 Jun 2023 03:31:17 -0400 Subject: [PATCH 09/21] Careful movement penalties apply to pavement when using Black Ice --- megamek/src/megamek/common/MoveStep.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/megamek/src/megamek/common/MoveStep.java b/megamek/src/megamek/common/MoveStep.java index 22c32bd634c..1155cf36056 100644 --- a/megamek/src/megamek/common/MoveStep.java +++ b/megamek/src/megamek/common/MoveStep.java @@ -3018,6 +3018,25 @@ && getEntity().getPosition().equals(prev) return; } + // Be careful on pavement during cold weather, there may be black ice. + boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + + if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { + if (destHex.containsTerrain(Terrains.BLACK_ICE) + && !isCareful() + && (nDestEl == destHex.getLevel())) { + mp--; + } + if (isPavementStep + && !destHex.containsTerrain(Terrains.BLACK_ICE) + && isCareful()) { + mp++; + } + + } + // Account for terrain, unless we're moving along a road. if (!isPavementStep()) { From 5ffe7b357c5bb80b0df4f85642b9c0e1b53c65a6 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 12 Jun 2023 04:27:15 -0400 Subject: [PATCH 10/21] Add check for Black Ice on pavement in processMovement. --- megamek/src/megamek/server/GameManager.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index cfacc39b31a..26358eb12dd 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -7808,6 +7808,20 @@ else if ((step.getElevation() + entity.height()) == 0) { } } + // Check for black ice + boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { + if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { + int blackIceChance = Compute.d6(1); + if (blackIceChance > 1) { + curHex.addTerrain(new Terrain(Terrains.BLACK_ICE, 1)); + sendChangedHex(curPos); + } + } + } + // Handle loading units. if (step.getType() == MovePath.MoveStepType.LOAD) { From da482627d038eed71220739a7eb10618d96d4ecf Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 12 Jun 2023 20:30:22 -0400 Subject: [PATCH 11/21] Changed temp comparison structure. --- megamek/src/megamek/common/Entity.java | 3 ++- megamek/src/megamek/common/MoveStep.java | 3 ++- megamek/src/megamek/server/GameManager.java | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 93247922d9f..0b73029e77a 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7256,13 +7256,14 @@ public PilotingRollData checkRecklessMove(MoveStep step, // this only applies in fog, night conditions, or if a hex along the // move path has ice + int minTemp = -30; boolean isFoggy = game.getPlanetaryConditions().getFog() != PlanetaryConditions.FOG_NONE; boolean isDark = game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DUSK; boolean isBlackIce; if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) || (game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE) - && game.getPlanetaryConditions().getTemperature() <= -30)) { + && game.getPlanetaryConditions().getTemperature() <= minTemp)) { isBlackIce = true; } else { isBlackIce = false; diff --git a/megamek/src/megamek/common/MoveStep.java b/megamek/src/megamek/common/MoveStep.java index 1155cf36056..56412e14092 100644 --- a/megamek/src/megamek/common/MoveStep.java +++ b/megamek/src/megamek/common/MoveStep.java @@ -3019,8 +3019,9 @@ && getEntity().getPosition().equals(prev) } // Be careful on pavement during cold weather, there may be black ice. + int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); - boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index 26358eb12dd..b55fd310016 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -7809,8 +7809,9 @@ else if ((step.getElevation() + entity.height()) == 0) { } // Check for black ice + int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); - boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { @@ -8680,9 +8681,9 @@ else if ((step.getElevation() + entity.height()) == 0) { } // check for black ice - // FIXME Check weather and optional rule for black ice. + int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); - boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= -30; + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if ((useBlackIce && goodTemp) || goodWeather) { if (ServerHelper.checkEnteringBlackIce(this, curPos, curHex, useBlackIce, goodTemp, goodWeather)) { From 04ff8c1b90d6f2a28871fced00f08b5ed14737a0 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Thu, 15 Jun 2023 23:16:17 -0400 Subject: [PATCH 12/21] Added entry for the Map Editor dropdown tile selector. --- megamek/i18n/megamek/common/messages.properties | 2 ++ megamek/src/megamek/common/Terrains.java | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index ee9de6ae3e8..edff0dbd51c 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -424,6 +424,7 @@ Terrains.editorName.swamp=Swamp Terrains.editorName.mud=Mud Terrains.editorName.rapids=Rapids Terrains.editorName.ice=Ice +Terrains.editorName.black_ice=Black Ice Terrains.editorName.snow=Snow Terrains.editorName.fire=Fire Terrains.editorName.smoke=Smoke @@ -474,6 +475,7 @@ Terrains.editorTooltip.swamp=Swamp Terrains.editorTooltip.mud=Mud Terrains.editorTooltip.rapids=Rapids Terrains.editorTooltip.ice=Ice +Terrains.editorTooltip.black_ice=Black Ice Terrains.editorTooltip.snow=Snow Terrains.editorTooltip.fire=Fire Terrains.editorTooltip.smoke=Smoke diff --git a/megamek/src/megamek/common/Terrains.java b/megamek/src/megamek/common/Terrains.java index 04efc7f2921..33dca3aec57 100644 --- a/megamek/src/megamek/common/Terrains.java +++ b/megamek/src/megamek/common/Terrains.java @@ -149,7 +149,7 @@ public class Terrains implements Serializable { private static final String[] names = { "none", "woods", "water", "rough", "rubble", "jungle", "sand", "tundra", "magma", "planted_fields", "heavy_industrial", "space", "pavement", "road", "swamp", "mud", "rapids", "ice", - "black ice", "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", + "black_ice", "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", "bldg_armor", "bridge", "bridge_cf", "bridge_elev", "fuel_tank", "fuel_tank_cf", "fuel_tank_elev", "fuel_tank_magn", "impassable", "elevator", "fortified", "screen", "fluff", "arms", "legs", "metal_deposit", "bldg_base_collapsed", "bldg_fluff", "road_fluff", "ground_fluff", "water_fluff", "cliff_top", "cliff_bottom", From 85d544faaa05ca523d61829f8a29ba8af6d0e9e9 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Fri, 30 Jun 2023 01:04:36 -0400 Subject: [PATCH 13/21] Add check for Black Ice in skid check. --- megamek/src/megamek/common/Entity.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 0b73029e77a..4395a440299 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7469,6 +7469,7 @@ public PilotingRollData checkSkid(EntityMovementType moveType, Hex prevHex, PilotingRollData roll = getBasePilotingRoll(overallMoveType); // If we aren't traveling along a road, apply terrain modifiers + // Unless said pavement has black ice if (!((prevStep == null || prevStep.isPavementStep()) && currStep.isPavementStep())) { addPilotingModifierForTerrain(roll, lastPos); } @@ -7521,9 +7522,17 @@ public PilotingRollData checkSkid(EntityMovementType moveType, Hex prevHex, || (game.getPlanetaryConditions() .getWindStrength() >= PlanetaryConditions.WI_STORM)))) && (prevFacing != curFacing) && !lastPos.equals(curPos)) { - roll.append(new PilotingRollData(getId(), - getMovementBeforeSkidPSRModifier(distance), - "turning on ice")); + roll.append(new PilotingRollData(getId(), getMovementBeforeSkidPSRModifier(distance), "turning on ice")); + adjustDifficultTerrainPSRModifier(roll); + return roll; + } else if (prevHex.containsTerrain(Terrains.BLACK_ICE) + && (((movementMode != EntityMovementMode.HOVER) && (movementMode != EntityMovementMode.WIGE)) + || (((movementMode == EntityMovementMode.HOVER) || (movementMode == EntityMovementMode.WIGE)) + && ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) + || (game.getPlanetaryConditions().getWindStrength() >= PlanetaryConditions.WI_STORM)))) + && (prevFacing != curFacing) && !lastPos.equals(curPos)) { + addPilotingModifierForTerrain(roll, lastPos); + roll.append(new PilotingRollData(getId(), getMovementBeforeSkidPSRModifier(distance), "turning on black ice")); adjustDifficultTerrainPSRModifier(roll); return roll; } else if ((prevStepPavement From d23c893aad50e72f71c8e160a4170ff9fbfade53 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 3 Jul 2023 08:16:28 -0400 Subject: [PATCH 14/21] Fixed issue where careful movement was not being applied. --- megamek/src/megamek/common/MoveStep.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/megamek/src/megamek/common/MoveStep.java b/megamek/src/megamek/common/MoveStep.java index 56412e14092..2de4e80d83a 100644 --- a/megamek/src/megamek/common/MoveStep.java +++ b/megamek/src/megamek/common/MoveStep.java @@ -3025,6 +3025,9 @@ && getEntity().getPosition().equals(prev) boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { + if (destHex.containsTerrain(Terrains.BLACK_ICE)){ + mp ++; + } if (destHex.containsTerrain(Terrains.BLACK_ICE) && !isCareful() && (nDestEl == destHex.getLevel())) { From 66027bfd764b4089275c61a378b4365f6b038f72 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 3 Jul 2023 19:56:20 -0400 Subject: [PATCH 15/21] Make sure black ice gets a melt check. --- megamek/src/megamek/server/GameManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index b55fd310016..e040131a13f 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -14461,12 +14461,14 @@ public boolean tryIgniteHex(Coords c, int entityId, boolean bHotGun, // if there is snow on the ground and this a hotgun or inferno, it may // melt the snow instead if ((hex.containsTerrain(Terrains.SNOW) || hex - .containsTerrain(Terrains.ICE)) && (bHotGun || bInferno)) { + .containsTerrain(Terrains.ICE) + || hex.containsTerrain(Terrains.BLACK_ICE)) && (bHotGun || bInferno)) { boolean melted = false; int meltCheck = Compute.d6(2); if ((hex.terrainLevel(Terrains.SNOW) > 1) && (meltCheck == 12)) { melted = true; - } else if (hex.containsTerrain(Terrains.ICE) && (meltCheck > 9)) { + } else if ((hex.containsTerrain(Terrains.ICE) + || hex.containsTerrain(Terrains.BLACK_ICE)) && (meltCheck > 9)) { melted = true; } else if (hex.containsTerrain(Terrains.SNOW) && (meltCheck > 7)) { melted = true; From c89384352f9519a6ed0dd05ab259d2e986f795d4 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Mon, 3 Jul 2023 20:09:39 -0400 Subject: [PATCH 16/21] Update roll target from testing value --- megamek/src/megamek/server/GameManager.java | 2 +- megamek/src/megamek/server/ServerHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index e040131a13f..24cd7de5cbc 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -7816,7 +7816,7 @@ else if ((step.getElevation() + entity.height()) == 0) { if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { int blackIceChance = Compute.d6(1); - if (blackIceChance > 1) { + if (blackIceChance > 4) { curHex.addTerrain(new Terrain(Terrains.BLACK_ICE, 1)); sendChangedHex(curPos); } diff --git a/megamek/src/megamek/server/ServerHelper.java b/megamek/src/megamek/server/ServerHelper.java index 745f0b07fb4..3fd4b12e230 100644 --- a/megamek/src/megamek/server/ServerHelper.java +++ b/megamek/src/megamek/server/ServerHelper.java @@ -512,7 +512,7 @@ public static boolean checkEnteringBlackIce(GameManager gameManager, Coords curP if (isPavement && ((useBlackIce && goodTemp) || isIceStorm)) { if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { int blackIceChance = Compute.d6(1); - if (blackIceChance > 1) { + if (blackIceChance > 4) { curHex.addTerrain(new Terrain(Terrains.BLACK_ICE, 1)); gameManager.sendChangedHex(curPos); return true; From e61c9651c2ab6aa11fc95f853887436d8d9a9cec Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Sat, 8 Jul 2023 21:28:40 -0400 Subject: [PATCH 17/21] Update megamek/i18n/megamek/common/options/messages.properties Co-authored-by: Christopher Watford --- megamek/i18n/megamek/common/options/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/i18n/megamek/common/options/messages.properties b/megamek/i18n/megamek/common/options/messages.properties index 8df2052e823..bd1161e1946 100644 --- a/megamek/i18n/megamek/common/options/messages.properties +++ b/megamek/i18n/megamek/common/options/messages.properties @@ -126,7 +126,7 @@ GameOptionsInfo.option.minefields.description=If checked, minefields can be used GameOptionsInfo.option.hidden_units.displayableName=Hidden Units GameOptionsInfo.option.hidden_units.description=If checked, players may deploy units hidden. GameOptionsInfo.option.black_ice.displayableName=Black Ice -GameOptionsInfo.option.black_ice.description=If checked, Black Ice may form on pavement if temperatures are below -30C. TO:AR p38\nDoes not affect Black Ice forming do to Ice Storms. TO:AR p58 +GameOptionsInfo.option.black_ice.description=If checked, Black Ice may form on pavement if temperatures are below -30C. TO:AR p38\nDoes not affect Black Ice forming due to Ice Storms. TO:AR p58 GameOptionsInfo.option.double_blind.displayableName=TacOps Double blind GameOptionsInfo.option.single_blind_bots.displayableName=(Unofficial) Default bots to single blind, when using TacOps Double blind GameOptionsInfo.option.double_blind.description=If checked, enemy units will only be visible if they are in line of sight of one or more of your units, or within sensor range. \nUnchecked by default. From 681ba3ddbc0eba77aaf0475bb40b829b6a6087e8 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 12 Jul 2023 02:24:36 -0400 Subject: [PATCH 18/21] Add temp constant for black ice to planetary conditions --- megamek/src/megamek/common/Entity.java | 3 +-- megamek/src/megamek/common/PlanetaryConditions.java | 11 ++++++----- megamek/src/megamek/server/GameManager.java | 7 +++---- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index dbc668191b7..09e53455450 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7256,14 +7256,13 @@ public PilotingRollData checkRecklessMove(MoveStep step, // this only applies in fog, night conditions, or if a hex along the // move path has ice - int minTemp = -30; boolean isFoggy = game.getPlanetaryConditions().getFog() != PlanetaryConditions.FOG_NONE; boolean isDark = game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DUSK; boolean isBlackIce; if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) || (game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE) - && game.getPlanetaryConditions().getTemperature() <= minTemp)) { + && game.getPlanetaryConditions().getTemperature() <= PlanetaryConditions.BLACK_ICE_TEMP)) { isBlackIce = true; } else { isBlackIce = false; diff --git a/megamek/src/megamek/common/PlanetaryConditions.java b/megamek/src/megamek/common/PlanetaryConditions.java index e6c35145a10..5fe3850da42 100644 --- a/megamek/src/megamek/common/PlanetaryConditions.java +++ b/megamek/src/megamek/common/PlanetaryConditions.java @@ -67,6 +67,7 @@ public class PlanetaryConditions implements Serializable { public static final int WE_HEAVY_HAIL = 13;// NYI public static final int WE_LIGHTNING_STORM = 14;// NYI // public static final int WE_BLIZZARD = 11; does not exist anymore + public static final int BLACK_ICE_TEMP = -30; private static final String MSG_NAME_WEATHER_CLEAR = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Clear"); private static final String MSG_NAME_WEATHER_LIGHTRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Light Rain"); private static final String MSG_NAME_WEATHER_MODRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Moderate Rain"); @@ -373,8 +374,8 @@ public int getLightHitPenalty(boolean isWeapon) { return penalty; } - - /** + + /** * Returns true when the light conditions give a hit penalty and * the hit penalty can be offset by a searchlight, i.e. in full moon, * moonless and pitch black night. @@ -397,11 +398,11 @@ public boolean isIlluminationEffective() { public static boolean requiresLowTemp(int weather) { return weather == WE_LIGHT_HAIL || weather == WE_HEAVY_HAIL || - weather == WE_LIGHT_SNOW || + weather == WE_LIGHT_SNOW || weather == WE_SLEET || weather == WE_SNOW_FLURRIES || weather == WE_HEAVY_SNOW || - weather == WE_ICE_STORM || + weather == WE_ICE_STORM || weather == WE_MOD_SNOW; } @@ -775,7 +776,7 @@ public int getVisualRange(Entity en, boolean targetIlluminated) { isAero = (en.isAero()) && !isLargeCraft; } // anything else is infantry - + // Beyond altitude 9, Aeros can't see. No need to repeat this test. if (isAero && (en.getAltitude() > 9)) { return 0; diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index 0d76b14402a..2a5ec9831a0 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -8424,7 +8424,7 @@ else if ((step.getElevation() + entity.height()) == 0) { && game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_FUEL_CONSUMPTION)) || (entity instanceof TeleMissile)) { int fuelUsed = ((IAero) entity).getFuelUsed(thrust); - + // if we're a gas hog, aerospace fighter and going faster than walking, then use 2x fuel if (((overallMoveType == EntityMovementType.MOVE_RUN) || (overallMoveType == EntityMovementType.MOVE_SPRINT) || @@ -8432,7 +8432,7 @@ else if ((step.getElevation() + entity.height()) == 0) { entity.hasQuirk(OptionsConstants.QUIRK_NEG_GAS_HOG)) { fuelUsed *= 2; } - + a.useFuel(fuelUsed); } @@ -8712,9 +8712,8 @@ else if ((step.getElevation() + entity.height()) == 0) { } // check for black ice - int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); - boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= PlanetaryConditions.BLACK_ICE_TEMP; boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if ((useBlackIce && goodTemp) || goodWeather) { if (ServerHelper.checkEnteringBlackIce(this, curPos, curHex, useBlackIce, goodTemp, goodWeather)) { From 9bbd484f9d5bc288df25be12487bf331b6b70b73 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 12 Jul 2023 02:25:44 -0400 Subject: [PATCH 19/21] Added missing null check --- megamek/src/megamek/common/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 09e53455450..05be5e58db3 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -7524,7 +7524,7 @@ public PilotingRollData checkSkid(EntityMovementType moveType, Hex prevHex, roll.append(new PilotingRollData(getId(), getMovementBeforeSkidPSRModifier(distance), "turning on ice")); adjustDifficultTerrainPSRModifier(roll); return roll; - } else if (prevHex.containsTerrain(Terrains.BLACK_ICE) + } else if ((prevHex != null) && prevHex.containsTerrain(Terrains.BLACK_ICE) && (((movementMode != EntityMovementMode.HOVER) && (movementMode != EntityMovementMode.WIGE)) || (((movementMode == EntityMovementMode.HOVER) || (movementMode == EntityMovementMode.WIGE)) && ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) From 85244c205fa46f04a9b8ceba32fd33bc531250c0 Mon Sep 17 00:00:00 2001 From: pheonixstorm Date: Wed, 12 Jul 2023 02:28:26 -0400 Subject: [PATCH 20/21] Removed minTemp for constant check. --- megamek/src/megamek/common/MoveStep.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/MoveStep.java b/megamek/src/megamek/common/MoveStep.java index 2de4e80d83a..c66f4b2ea01 100644 --- a/megamek/src/megamek/common/MoveStep.java +++ b/megamek/src/megamek/common/MoveStep.java @@ -3019,9 +3019,8 @@ && getEntity().getPosition().equals(prev) } // Be careful on pavement during cold weather, there may be black ice. - int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); - boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; + boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= PlanetaryConditions.BLACK_ICE_TEMP; boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { From 1e5a9507a19686c771c6706a6d1790459e63a9bf Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 15 Feb 2024 10:51:29 +0100 Subject: [PATCH 21/21] Restore terrains numbering --- megamek/src/megamek/common/Terrains.java | 107 ++++++++++++----------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/megamek/src/megamek/common/Terrains.java b/megamek/src/megamek/common/Terrains.java index 1defe912d73..1d986468048 100644 --- a/megamek/src/megamek/common/Terrains.java +++ b/megamek/src/megamek/common/Terrains.java @@ -48,15 +48,16 @@ public class Terrains implements Serializable { public static final int MUD = 15; public static final int RAPIDS = 16; // 1: rapids 2: torrent public static final int ICE = 17; - public static final int BLACK_ICE = 18; - public static final int SNOW = 19; // 1: thin 2: deep - public static final int FIRE = 20; // 1: normal, fire 2: inferno fire, 3: - // inferno bombs, 4: inferno IV + + public static final int SNOW = 18; // 1: thin 2: deep + public static final int FIRE = 19; // 1: normal, fire 2: inferno fire, 3: + // inferno bombs, 4: inferno IV /** The SMOKE terrain type includes laser-inhibiting smoke and chaff from chaff pods (TO:AUE p111). */ - public static final int SMOKE = 21; // 1: light smoke 2: heavy smoke 3:light - // LI smoke 4: Heavy LI smoke - public static final int GEYSER = 22; // 1: dormant 2: active 3: magma vent + public static final int SMOKE = 20; // 1: light smoke 2: heavy smoke 3:light + // LI smoke 4: Heavy LI smoke + public static final int GEYSER = 21; // 1: dormant 2: active 3: magma vent // unimplemented + // Black Ice // Bug Storm // Extreme Depths // Hazardous Liquid Pools @@ -70,77 +71,79 @@ public class Terrains implements Serializable { public static final int FIRE_LVL_INFERNO_IV = 4; // Building stuff - public static final int BUILDING = 23; // 1: light 2: medium 3: heavy 4: - // hardened [5: wall not implemented] - public static final int BLDG_CF = 24; - public static final int BLDG_ELEV = 25; - public static final int BLDG_BASEMENT_TYPE = 26; // level equals - // BasemenType, one of the - // values of the - // BasementType enum - public static final int BLDG_CLASS = 27; // 1: hangars 2: fortresses 3: gun - // emplacements - public static final int BLDG_ARMOR = 28; + public static final int BUILDING = 22; // 1: light 2: medium 3: heavy 4: + // hardened [5: wall not implemented] + public static final int BLDG_CF = 23; + public static final int BLDG_ELEV = 24; + public static final int BLDG_BASEMENT_TYPE = 25; // level equals + // BasemenType, one of the + // values of the + // BasementType enum + public static final int BLDG_CLASS = 26; // 1: hangars 2: fortresses 3: gun + // emplacements + public static final int BLDG_ARMOR = 27; // leaving this empty will be interpreted as standard - public static final int BRIDGE = 29; - public static final int BRIDGE_CF = 30; - public static final int BRIDGE_ELEV = 31; - public static final int FUEL_TANK = 32; - public static final int FUEL_TANK_CF = 33; - public static final int FUEL_TANK_ELEV = 34; - public static final int FUEL_TANK_MAGN = 35; + public static final int BRIDGE = 28; + public static final int BRIDGE_CF = 29; + public static final int BRIDGE_ELEV = 30; + public static final int FUEL_TANK = 31; + public static final int FUEL_TANK_CF = 32; + public static final int FUEL_TANK_ELEV = 33; + public static final int FUEL_TANK_MAGN = 34; // special types - public static final int IMPASSABLE = 36; - public static final int ELEVATOR = 37; // level = elevation it moves to, exits = d6 rolls it moves on - public static final int FORTIFIED = 38; + public static final int IMPASSABLE = 35; + public static final int ELEVATOR = 36; // level = elevation it moves to, exits = d6 rolls it moves on + public static final int FORTIFIED = 37; /** The SCREEN terrain type stands for chaff hexes generated by screen launchers in space. */ - public static final int SCREEN = 39; + public static final int SCREEN = 38; // fluff - public static final int FLUFF = 40; - public static final int ARMS = 41; // blown off arms for use as clubs, level - // = number of arms in that hex - public static final int LEGS = 42; // blown off legs for use as clubs, level - // = number of legs in that hex + public static final int FLUFF = 39; + public static final int ARMS = 40; // blown off arms for use as clubs, level + // = number of arms in that hex + public static final int LEGS = 41; // blown off legs for use as clubs, level + // = number of legs in that hex - public static final int METAL_CONTENT = 43; // Is there metal content that - // will block magscan sensors? - public static final int BLDG_BASE_COLLAPSED = 44; // 1 means collapsed + public static final int METAL_CONTENT = 42; // Is there metal content that + // will block magscan sensors? + public static final int BLDG_BASE_COLLAPSED = 43; // 1 means collapsed // Additional fluff types so that stacking of special images is possible - public static final int BLDG_FLUFF = 45; // Ideally used to denote special bldg images - public static final int ROAD_FLUFF = 46; // Ideally used to denote special road images - public static final int GROUND_FLUFF = 47; // Ideally used to denote special ground images - // these should be supers, not bases, as base image - // matching is not exact while super is - public static final int WATER_FLUFF = 48; // Ideally used to denote special water images + public static final int BLDG_FLUFF = 44; // Ideally used to denote special bldg images + public static final int ROAD_FLUFF = 45; // Ideally used to denote special road images + public static final int GROUND_FLUFF = 46; // Ideally used to denote special ground images + // these should be supers, not bases, as base image + // matching is not exact while super is + public static final int WATER_FLUFF = 47; // Ideally used to denote special water images // Cliffs, use with exits to denote cliffsides; only valid when there's // actually a level drop/rise in the specified direction - public static final int CLIFF_TOP = 49; - public static final int CLIFF_BOTTOM = 50; + public static final int CLIFF_TOP = 48; + public static final int CLIFF_BOTTOM = 49; // Terrain for the incline at a hex edge towards a higher or lower // neighboring hex. Used to add highlighting/images to hex sides // This is added to hexes automatically by MegaMek, not for // manual use in the Editor - public static final int INCLINE_TOP = 51; - public static final int INCLINE_BOTTOM = 52; + public static final int INCLINE_TOP = 50; + public static final int INCLINE_BOTTOM = 51; // Hex level differences of at least 3 levels, used with exits to // denote the hex side. Used to add highlighting/images to hex sides // This is added to hexes automatically by MegaMek, not for // manual use in the Editor - public static final int INCLINE_HIGH_TOP = 53; - public static final int INCLINE_HIGH_BOTTOM = 54; + public static final int INCLINE_HIGH_TOP = 52; + public static final int INCLINE_HIGH_BOTTOM = 53; // Helper terrain that gives the elevation for foliage (woods and jungle). // Allowed values are 1 for L/H/U, 2 for L/H and 3 for U foliage. // This terrain is meaningless when alone but must be present in any // hex that has either woods or jungle. It is added by the board loader // when it's not present in the board file. - public static final int FOLIAGE_ELEV = 55; + public static final int FOLIAGE_ELEV = 54; + + public static final int BLACK_ICE = 55; /** * Keeps track of the different type of terrains that can have exits. @@ -149,11 +152,11 @@ public class Terrains implements Serializable { private static final String[] names = { "none", "woods", "water", "rough", "rubble", "jungle", "sand", "tundra", "magma", "planted_fields", "heavy_industrial", "space", "pavement", "road", "swamp", "mud", "rapids", "ice", - "black_ice", "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", + "snow", "fire", "smoke", "geyser", "building", "bldg_cf", "bldg_elev", "bldg_basement_type", "bldg_class", "bldg_armor", "bridge", "bridge_cf", "bridge_elev", "fuel_tank", "fuel_tank_cf", "fuel_tank_elev", "fuel_tank_magn", "impassable", "elevator", "fortified", "screen", "fluff", "arms", "legs", "metal_deposit", "bldg_base_collapsed", "bldg_fluff", "road_fluff", "ground_fluff", "water_fluff", "cliff_top", "cliff_bottom", - "incline_top", "incline_bottom", "incline_high_top", "incline_high_bottom", "foliage_elev" }; + "incline_top", "incline_bottom", "incline_high_top", "incline_high_bottom", "foliage_elev", "black_ice" }; /** Terrains in this set are hidden in the Editor, not saved to board files and handled internally. */ public static final HashSet AUTOMATIC = new HashSet<>(Arrays.asList(