diff --git a/megamek/i18n/megamek/common/messages.properties b/megamek/i18n/megamek/common/messages.properties index 5c3fb4f58af..237898c8e81 100644 --- a/megamek/i18n/megamek/common/messages.properties +++ b/megamek/i18n/megamek/common/messages.properties @@ -214,31 +214,31 @@ HexTarget.Screen=\ (Screen) HexTarget.Tag=\ (Tag) PlanetaryConditions.DisplayableName.Light.Daylight=Daylight PlanetaryConditions.DisplayableName.Light.Dusk=Dusk/Dawn -PlanetaryConditions.DisplayableName.Light.Full\ Moon\ Night=Full Moon Night -PlanetaryConditions.DisplayableName.Light.Moonless\ Night=Moonless Night -PlanetaryConditions.DisplayableName.Light.Pitch\ Black=Pitch Black +PlanetaryConditions.DisplayableName.Light.FullMoonNight=Full Moon Night +PlanetaryConditions.DisplayableName.Light.MoonlessNight=Moonless Night +PlanetaryConditions.DisplayableName.Light.PitchBlack=Pitch Black PlanetaryConditions.DisplayableName.Weather.Clear=Clear -PlanetaryConditions.DisplayableName.Weather.Light\ Rain=Light Rain -PlanetaryConditions.DisplayableName.Weather.Moderate\ Rain=Moderate Rain -PlanetaryConditions.DisplayableName.Weather.Heavy\ Rain=Heavy Rain -PlanetaryConditions.DisplayableName.Weather.Gusting\ Rain=Gusting Rain -PlanetaryConditions.DisplayableName.Weather.Torrential\ Downpour=Torrential Downpour -PlanetaryConditions.DisplayableName.Weather.Light\ Snowfall=Light Snowfall -PlanetaryConditions.DisplayableName.Weather.Moderate\ Snowfall=Moderate Snowfall -PlanetaryConditions.DisplayableName.Weather.Heavy\ Snowfall=Heavy Snowfall +PlanetaryConditions.DisplayableName.Weather.LightRain=Light Rain +PlanetaryConditions.DisplayableName.Weather.ModerateRain=Moderate Rain +PlanetaryConditions.DisplayableName.Weather.HeavyRain=Heavy Rain +PlanetaryConditions.DisplayableName.Weather.GustingRain=Gusting Rain +PlanetaryConditions.DisplayableName.Weather.TorrentialDownpour=Torrential Downpour +PlanetaryConditions.DisplayableName.Weather.LightSnowfall=Light Snowfall +PlanetaryConditions.DisplayableName.Weather.ModerateSnowfall=Moderate Snowfall +PlanetaryConditions.DisplayableName.Weather.HeavySnowfall=Heavy Snowfall PlanetaryConditions.DisplayableName.Weather.Sleet=Sleet -PlanetaryConditions.DisplayableName.Weather.Snow\ Flurries=Snow Flurries -PlanetaryConditions.DisplayableName.Weather.Blizzard=Blizzard -PlanetaryConditions.DisplayableName.Weather.Ice\ Storm=Ice Storm -PlanetaryConditions.DisplayableName.Weather.Light\ Hail=Light Hail -PlanetaryConditions.DisplayableName.Weather.Heavy\ Hail=Heavy Hail +PlanetaryConditions.DisplayableName.Weather.SnowFlurries=Snow Flurries +PlanetaryConditions.DisplayableName.Weather.IceStorm=Ice Storm +PlanetaryConditions.DisplayableName.Weather.LightHail=Light Hail +PlanetaryConditions.DisplayableName.Weather.HeavyHail=Heavy Hail +PlanetaryConditions.DisplayableName.Weather.LightningStorm=Lightning Storm PlanetaryConditions.DisplayableName.WindStrength.Calm=Calm -PlanetaryConditions.DisplayableName.WindStrength.Light\ Gale=Light Gale -PlanetaryConditions.DisplayableName.WindStrength.Moderate\ Gale=Moderate Gale -PlanetaryConditions.DisplayableName.WindStrength.Strong\ Gale=Strong Gale +PlanetaryConditions.DisplayableName.WindStrength.LightGale=Light Gale +PlanetaryConditions.DisplayableName.WindStrength.ModerateGale=Moderate Gale +PlanetaryConditions.DisplayableName.WindStrength.StrongGale=Strong Gale PlanetaryConditions.DisplayableName.WindStrength.Storm=Storm -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F1-F3=Tornado F1-F3 -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F4=Tornado F4 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF1-F3=Tornado F1-F3 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF4=Tornado F4 PlanetaryConditions.DisplayableName.WindDirection.RandomWindDirection=Random PlanetaryConditions.DisplayableName.WindDirection.North=North PlanetaryConditions.DisplayableName.WindDirection.Northeast=Northeast @@ -251,66 +251,16 @@ PlanetaryConditions.DisplayableName.Atmosphere.Trace=Trace PlanetaryConditions.DisplayableName.Atmosphere.Thin=Thin PlanetaryConditions.DisplayableName.Atmosphere.Standard=Standard PlanetaryConditions.DisplayableName.Atmosphere.High=High -PlanetaryConditions.DisplayableName.Atmosphere.Very\ High=Very High +PlanetaryConditions.DisplayableName.Atmosphere.VeryHigh=Very High PlanetaryConditions.DisplayableName.Fog.None=None -PlanetaryConditions.DisplayableName.Fog.Light\ Fog=Light Fog +PlanetaryConditions.DisplayableName.Fog.LightFog=Light Fog PlanetaryConditions.DisplayableName.SandBlowing.true=Yes PlanetaryConditions.DisplayableName.SandBlowing.false=No -PlanetaryConditions.DisplayableName.Fog.Heavy\ Fog=Heavy Fog +PlanetaryConditions.DisplayableName.Fog.HeavyFog=Heavy Fog PlanetaryConditions.DisplayableName.Temperature.ExtremeCold=Extreme Cold PlanetaryConditions.DisplayableName.Temperature.ExtremeHeat=Extreme Heat PlanetaryConditions.DisplayableName.EMI.true=Yes PlanetaryConditions.DisplayableName.EMI.false=No -PlanetaryConditions.Indicator.Light.Day=\u2600 -PlanetaryConditions.Indicator.Light.Dusk=\u263D \u263C -PlanetaryConditions.Indicator.Light.FullMoon=\u26AB -PlanetaryConditions.Indicator.Light.Moonless=\u26AA -PlanetaryConditions.Indicator.Light.PitchBlack=\u2588 -PlanetaryConditions.Indicator.Fog.None=\uD83D\uDC41 -PlanetaryConditions.Indicator.Fog.Light=\u2588 \u2022 -PlanetaryConditions.Indicator.Fog.Heavy=\u2588 \u2588 -PlanetaryConditions.Indicator.WindStrength.Calm=\u2690 -PlanetaryConditions.Indicator.WindStrength.LightGale=\u21F6 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.WindStrength.ModGale=\u21F6 \u21F6 \u2022 \u2022 -PlanetaryConditions.Indicator.WindStrength.StrongGale=\u21F6 \u21F6 \u21F6 \u2022 -PlanetaryConditions.Indicator.WindStrength.Storm=\u21F6 \u21F6 \u21F6 \u21F6 -PlanetaryConditions.Indicator.WindStrength.TornadoF13=\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \u2022 -PlanetaryConditions.Indicator.WindStrength.TornadoF4=\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A -PlanetaryConditions.Indicator.WindDirection.North=\u2193 -PlanetaryConditions.Indicator.WindDirection.Northeast=\u2B0B -PlanetaryConditions.Indicator.WindDirection.Southeast=\u2B09 -PlanetaryConditions.Indicator.WindDirection.South=\u2191 -PlanetaryConditions.Indicator.WindDirection.Southwest=\u2B08 -PlanetaryConditions.Indicator.WindDirection.Northwest=\u2B0A -PlanetaryConditions.Indicator.WindDirection.RandomWindDirection= -PlanetaryConditions.Indicator.Weather.None=\u239A -PlanetaryConditions.Indicator.Weather.LightRain=\u2601 \u2022 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.ModRain=\u2601 \u2601 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.HeavyRain=\u2601 \u2601 \u2601 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.GustingRain=\u2601 \u2601 \u2601 \u2601 \u2022 -PlanetaryConditions.Indicator.Weather.Downpour=\u2601 \u2601 \u2601 \u2601 \u2601 -PlanetaryConditions.Indicator.Weather.LightSnow=\u2744 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.ModSnow=\u2744 \u2744 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.SnowFlurries=\u2744 \u2744 \u2744 \u2022 -PlanetaryConditions.Indicator.Weather.HeavySnow=\u2744 \u2744 \u2744 \u2744 -PlanetaryConditions.Indicator.Weather.Sleet=\u26C6 \u2022 -PlanetaryConditions.Indicator.Weather.IceStorm=\u26C6 \u26C6 -PlanetaryConditions.Indicator.Atmosphere.Vacuum=\u2726 \u2727 \u2727 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Trace=\u2726 \u2726 \u2727 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Thin=\u2726 \u2726 \u2726 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Standard=\u2726 \u2726 \u2726 \u25AE \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.High=\u2726 \u2726 \u2726 \u25AE \u2726 \u2727 -PlanetaryConditions.Indicator.Atmosphere.VHigh=\u2726 \u2726 \u2726 \u25AE \u2726 \u2726 -PlanetaryConditions.Indicator.SandBlowing.true=\uD83C\uDF2C -PlanetaryConditions.Indicator.SandBlowing.false=\uD83D\uDC41 -PlanetaryConditions.Indicator.Temperature.ExtremeCold=\u2744 -PlanetaryConditions.Indicator.Temperature.Normal=\uD83C\uDF21 -PlanetaryConditions.Indicator.Temperature.ExtremeHeat=\uD83D\uDD25 -PlanetaryConditions.Indicator.Gravity.Low=\u2B71 -PlanetaryConditions.Indicator.Gravity.Normal=\u23AF -PlanetaryConditions.Indicator.Gravity.High=\u2B73 -PlanetaryConditions.Indicator.EMI.true=\u2301 -PlanetaryConditions.Indicator.EMI.false=\u2312 UnitType.Aero=Aerospace UnitType.AeroSpaceFighter=Aerospace Fighter UnitType.BattleArmor=Battle Armor diff --git a/megamek/i18n/megamek/common/messages_es.properties b/megamek/i18n/megamek/common/messages_es.properties index 0b0f6ba4210..bedb69e0a63 100644 --- a/megamek/i18n/megamek/common/messages_es.properties +++ b/megamek/i18n/megamek/common/messages_es.properties @@ -208,31 +208,30 @@ HexTarget.Screen=\ (Pantalla) HexTarget.Tag=\ (Etiqueta) PlanetaryConditions.DisplayableName.Light.Daylight=Luz Natural PlanetaryConditions.DisplayableName.Light.Dusk=Anochecer/Amanecer -PlanetaryConditions.DisplayableName.Light.Full\ Moon\ Night=Noche de Luna Llena -PlanetaryConditions.DisplayableName.Light.Moonless\ Night=Noche sin Luna -PlanetaryConditions.DisplayableName.Light.Pitch\ Black=Oscuro +PlanetaryConditions.DisplayableName.Light.FullMoonNight=Noche de Luna Llena +PlanetaryConditions.DisplayableName.Light.MoonlessNight=Noche sin Luna +PlanetaryConditions.DisplayableName.Light.PitchBlack=Oscuro PlanetaryConditions.DisplayableName.Weather.Clear=Claro -PlanetaryConditions.DisplayableName.Weather.Light\ Rain= Lluvia Ligera -PlanetaryConditions.DisplayableName.Weather.Moderate\ Rain=Lluvia Moderada -PlanetaryConditions.DisplayableName.Weather.Heavy\ Rain=Lluvia Intensa -PlanetaryConditions.DisplayableName.Weather.Gusting\ Rain=Rachas de Lluvia -PlanetaryConditions.DisplayableName.Weather.Torrential\ Downpour=Aguacero Torrencial -PlanetaryConditions.DisplayableName.Weather.Light\ Snowfall=Nevada Ligera -PlanetaryConditions.DisplayableName.Weather.Moderate\ Snowfall=Nevada Moderada -PlanetaryConditions.DisplayableName.Weather.Heavy\ Snowfall=Nevada Fuerte +PlanetaryConditions.DisplayableName.Weather.LightRain= Lluvia Ligera +PlanetaryConditions.DisplayableName.Weather.ModerateRain=Lluvia Moderada +PlanetaryConditions.DisplayableName.Weather.HeavyRain=Lluvia Intensa +PlanetaryConditions.DisplayableName.Weather.GustingRain=Rachas de Lluvia +PlanetaryConditions.DisplayableName.Weather.TorrentialDownpour=Aguacero Torrencial +PlanetaryConditions.DisplayableName.Weather.LightSnowfall=Nevada Ligera +PlanetaryConditions.DisplayableName.Weather.ModerateSnowfall=Nevada Moderada +PlanetaryConditions.DisplayableName.Weather.HeavySnowfall=Nevada Fuerte PlanetaryConditions.DisplayableName.Weather.Sleet=Aguanieve -PlanetaryConditions.DisplayableName.Weather.Snow\ Flurries=Rafagas de Nieve -PlanetaryConditions.DisplayableName.Weather.Blizzard=Ventisca -PlanetaryConditions.DisplayableName.Weather.Ice\ Storm=Tormenta de Hielo -PlanetaryConditions.DisplayableName.Weather.Light\ Hail=Granizo Ligero -PlanetaryConditions.DisplayableName.Weather.Heavy\ Hail=Granizo Intenso +PlanetaryConditions.DisplayableName.Weather.SnowFlurries=Rafagas de Nieve +PlanetaryConditions.DisplayableName.Weather.IceStorm=Tormenta de Hielo +PlanetaryConditions.DisplayableName.Weather.LightHail=Granizo Ligero +PlanetaryConditions.DisplayableName.Weather.HeavyHail=Granizo Intenso PlanetaryConditions.DisplayableName.WindStrength.Calm=Calma -PlanetaryConditions.DisplayableName.WindStrength.Light\ Gale=Vendaval Ligero -PlanetaryConditions.DisplayableName.WindStrength.Moderate\ Gale=Vendaval Moderado -PlanetaryConditions.DisplayableName.WindStrength.Strong\ Gale=Vendaval Fuerte +PlanetaryConditions.DisplayableName.WindStrength.LightGale=Vendaval Ligero +PlanetaryConditions.DisplayableName.WindStrength.ModerateGale=Vendaval Moderado +PlanetaryConditions.DisplayableName.WindStrength.StrongGale=Vendaval Fuerte PlanetaryConditions.DisplayableName.WindStrength.Storm=Tormenta -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F1-F3=Tornado F1-F3 -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F4=Tornado F4 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF1-F3=Tornado F1-F3 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF4=Tornado F4 PlanetaryConditions.DisplayableName.WindDirection.RandomWindDirection=Aleatorio PlanetaryConditions.DisplayableName.WindDirection.North=Norte PlanetaryConditions.DisplayableName.WindDirection.Northeast=Noreste @@ -245,66 +244,16 @@ PlanetaryConditions.DisplayableName.Atmosphere.Trace=Traza PlanetaryConditions.DisplayableName.Atmosphere.Thin=Ligera PlanetaryConditions.DisplayableName.Atmosphere.Standard=Estándar PlanetaryConditions.DisplayableName.Atmosphere.High=Alta -PlanetaryConditions.DisplayableName.Atmosphere.Very\ High=Muy Alta +PlanetaryConditions.DisplayableName.Atmosphere.VeryHigh=Muy Alta PlanetaryConditions.DisplayableName.Fog.None=Ninguno -PlanetaryConditions.DisplayableName.Fog.Light\ Fog=Niebla Ligera +PlanetaryConditions.DisplayableName.Fog.LightFog=Niebla Ligera PlanetaryConditions.DisplayableName.SandBlowing.true=Si PlanetaryConditions.DisplayableName.SandBlowing.false=No -PlanetaryConditions.DisplayableName.Fog.Heavy\ Fog=Niebla Densa +PlanetaryConditions.DisplayableName.Fog.HeavyFog=Niebla Densa PlanetaryConditions.DisplayableName.Temperature.ExtremeCold=Frio Extremo PlanetaryConditions.DisplayableName.Temperature.ExtremeHeat=Calor Extremo PlanetaryConditions.DisplayableName.EMI.true=Si PlanetaryConditions.DisplayableName.EMI.false=No -PlanetaryConditions.Indicator.Light.Day=\u2600 -PlanetaryConditions.Indicator.Light.Dusk=\u263D \u263C -PlanetaryConditions.Indicator.Light.FullMoon=\u26AB -PlanetaryConditions.Indicator.Light.Moonless=\u26AA -PlanetaryConditions.Indicator.Light.PitchBlack=\u2588 -PlanetaryConditions.Indicator.Fog.None=\uD83D\uDC41 -PlanetaryConditions.Indicator.Fog.Light=\u2588 \u2022 -PlanetaryConditions.Indicator.Fog.Heavy=\u2588 \u2588 -PlanetaryConditions.Indicator.WindStrength.Calm=\u2690 -PlanetaryConditions.Indicator.WindStrength.LightGale=\u21F6 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.WindStrength.ModGale=\u21F6 \u21F6 \u2022 \u2022 -PlanetaryConditions.Indicator.WindStrength.StrongGale=\u21F6 \u21F6 \u21F6 \u2022 -PlanetaryConditions.Indicator.WindStrength.Storm=\u21F6 \u21F6 \u21F6 \u21F6 -PlanetaryConditions.Indicator.WindStrength.TornadoF13=\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \u2022 -PlanetaryConditions.Indicator.WindStrength.TornadoF4=\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A -PlanetaryConditions.Indicator.WindDirection.North=\u2193 -PlanetaryConditions.Indicator.WindDirection.Northeast=\u2B0B -PlanetaryConditions.Indicator.WindDirection.Southeast=\u2B09 -PlanetaryConditions.Indicator.WindDirection.South=\u2191 -PlanetaryConditions.Indicator.WindDirection.Southwest=\u2B08 -PlanetaryConditions.Indicator.WindDirection.Northwest=\u2B0A -PlanetaryConditions.Indicator.WindDirection.RandomWindDirection= -PlanetaryConditions.Indicator.Weather.None=\u239A -PlanetaryConditions.Indicator.Weather.LightRain=\u2601 \u2022 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.ModRain=\u2601 \u2601 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.HeavyRain=\u2601 \u2601 \u2601 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.GustingRain=\u2601 \u2601 \u2601 \u2601 \u2022 -PlanetaryConditions.Indicator.Weather.Downpour=\u2601 \u2601 \u2601 \u2601 \u2601 -PlanetaryConditions.Indicator.Weather.LightSnow=\u2744 \u2022 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.ModSnow=\u2744 \u2744 \u2022 \u2022 -PlanetaryConditions.Indicator.Weather.SnowFlurries=\u2744 \u2744 \u2744 \u2022 -PlanetaryConditions.Indicator.Weather.HeavySnow=\u2744 \u2744 \u2744 \u2744 -PlanetaryConditions.Indicator.Weather.Sleet=\u26C6 \u2022 -PlanetaryConditions.Indicator.Weather.IceStorm=\u26C6 \u26C6 -PlanetaryConditions.Indicator.Atmosphere.Vacuum=\u2726 \u2727 \u2727 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Trace=\u2726 \u2726 \u2727 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Thin=\u2726 \u2726 \u2726 \u25AF \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.Standard=\u2726 \u2726 \u2726 \u25AE \u2727 \u2727 -PlanetaryConditions.Indicator.Atmosphere.High=\u2726 \u2726 \u2726 \u25AE \u2726 \u2727 -PlanetaryConditions.Indicator.Atmosphere.VHigh=\u2726 \u2726 \u2726 \u25AE \u2726 \u2726 -PlanetaryConditions.Indicator.SandBlowing.true=\uD83C\uDF2C -PlanetaryConditions.Indicator.SandBlowing.false=\uD83D\uDC41 -PlanetaryConditions.Indicator.Temperature.ExtremeCold=\u2744 -PlanetaryConditions.Indicator.Temperature.Normal=\uD83C\uDF21 -PlanetaryConditions.Indicator.Temperature.ExtremeHeat=\uD83D\uDD25 -PlanetaryConditions.Indicator.Gravity.Low=\u2B71 -PlanetaryConditions.Indicator.Gravity.Normal=\u23AF -PlanetaryConditions.Indicator.Gravity.High=\u2B73 -PlanetaryConditions.Indicator.EMI.true=\u2301 -PlanetaryConditions.Indicator.EMI.false=\u2312 UnitType.Aero=Caza Aeroespacial UnitType.BattleArmor=Armadura de Combate UnitType.Conventional\ Fighter=Caza Convencional diff --git a/megamek/i18n/megamek/common/messages_ru.properties b/megamek/i18n/megamek/common/messages_ru.properties index 8c909ad29f5..6f490329710 100644 --- a/megamek/i18n/megamek/common/messages_ru.properties +++ b/megamek/i18n/megamek/common/messages_ru.properties @@ -45,28 +45,28 @@ HexTarget.Screen=\ (Завеса) HexTarget.Tag=\ (Пометить) PlanetaryConditions.DisplayableName.Light.Daylight=Дневной свет PlanetaryConditions.DisplayableName.Light.Dusk=Закат/Рассвет -PlanetaryConditions.DisplayableName.Light.Full\ Moon\ Night=Ночь в полнолуние -PlanetaryConditions.DisplayableName.Light.Moonless\ Night=Безлунная ночь -PlanetaryConditions.DisplayableName.Light.Pitch\ Black=Полная темнота +PlanetaryConditions.DisplayableName.Light.FullMoonNight=Ночь в полнолуние +PlanetaryConditions.DisplayableName.Light.MoonlessNight=Безлунная ночь +PlanetaryConditions.DisplayableName.Light.PitchBlack=Полная темнота PlanetaryConditions.DisplayableName.Weather.Clear=Ясно -PlanetaryConditions.DisplayableName.Weather.Light\ Rain=Легкий дождь -PlanetaryConditions.DisplayableName.Weather.Moderate\ Rain=Дождь -PlanetaryConditions.DisplayableName.Weather.Heavy\ Rain=Сильный дождь -PlanetaryConditions.DisplayableName.Weather.Torrential\ Downpour=Ливень потоками -PlanetaryConditions.DisplayableName.Weather.Light\ Snowfall=Легкий снегопад -PlanetaryConditions.DisplayableName.Weather.Moderate\ Snowfall=Снегопад -PlanetaryConditions.DisplayableName.Weather.Heavy\ Snowfall=Сильный снегопад +PlanetaryConditions.DisplayableName.Weather.LightRain=Легкий дождь +PlanetaryConditions.DisplayableName.Weather.ModerateRain=Дождь +PlanetaryConditions.DisplayableName.Weather.HeavyRain=Сильный дождь +PlanetaryConditions.DisplayableName.Weather.TorrentialDownpour=Ливень потоками +PlanetaryConditions.DisplayableName.Weather.LightSnowfall=Легкий снегопад +PlanetaryConditions.DisplayableName.Weather.ModerateSnowfall=Снегопад +PlanetaryConditions.DisplayableName.Weather.HeavySnowfall=Сильный снегопад PlanetaryConditions.DisplayableName.Weather.Sleet=Мокрый снег -PlanetaryConditions.DisplayableName.Weather.Ice\ Storm=Снежная буря -PlanetaryConditions.DisplayableName.Weather.Light\ Hail=Легкий град -PlanetaryConditions.DisplayableName.Weather.Heavy\ Hail=Сильный град +PlanetaryConditions.DisplayableName.Weather.IceStorm=Снежная буря +PlanetaryConditions.DisplayableName.Weather.LightHail=Легкий град +PlanetaryConditions.DisplayableName.Weather.HeavyHail=Сильный град PlanetaryConditions.DisplayableName.WindStrength.Calm=Штиль -PlanetaryConditions.DisplayableName.WindStrength.Light\ Gale=Легкий ветер -PlanetaryConditions.DisplayableName.WindStrength.Moderate\ Gale=Умеренный ветер -PlanetaryConditions.DisplayableName.WindStrength.Strong\ Gale=Сильный ветер +PlanetaryConditions.DisplayableName.WindStrength.LightGale=Легкий ветер +PlanetaryConditions.DisplayableName.WindStrength.ModerateGale=Умеренный ветер +PlanetaryConditions.DisplayableName.WindStrength.StrongGale=Сильный ветер PlanetaryConditions.DisplayableName.WindStrength.Storm=Шторм -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F1-F3=Торнадо F1-F3 -PlanetaryConditions.DisplayableName.WindStrength.Tornado\ F4=Торнадо F4 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF1-F3=Торнадо F1-F3 +PlanetaryConditions.DisplayableName.WindStrength.TornadoF4=Торнадо F4 PlanetaryConditions.DisplayableName.WindDirection.North=К северу PlanetaryConditions.DisplayableName.WindDirection.Northeast=К северо-востоку PlanetaryConditions.DisplayableName.WindDirection.Southeast=К юго-востоку @@ -78,10 +78,10 @@ PlanetaryConditions.DisplayableName.Atmosphere.Trace=Остаточная PlanetaryConditions.DisplayableName.Atmosphere.Thin=Тонкая PlanetaryConditions.DisplayableName.Atmosphere.Standard=Стандартная PlanetaryConditions.DisplayableName.Atmosphere.High=Высокая -PlanetaryConditions.DisplayableName.Atmosphere.Very\ High=Очень высокая +PlanetaryConditions.DisplayableName.Atmosphere.VeryHigh=Очень высокая PlanetaryConditions.DisplayableName.Fog.None=Никакой -PlanetaryConditions.DisplayableName.Fog.Light\ Fog=Легкий туман -PlanetaryConditions.DisplayableName.Fog.Heavy\ Fog=Сильный туман +PlanetaryConditions.DisplayableName.Fog.LightFog=Легкий туман +PlanetaryConditions.DisplayableName.Fog.HeavyFog=Сильный туман UnitType.Aero=Аэрокосмический истребитель UnitType.BattleArmor=Бронепехота UnitType.Conventional\ Fighter=Обычный истребитель diff --git a/megamek/src/megamek/client/Client.java b/megamek/src/megamek/client/Client.java index 7f6aa62d804..424dfa2cab9 100644 --- a/megamek/src/megamek/client/Client.java +++ b/megamek/src/megamek/client/Client.java @@ -46,6 +46,7 @@ import megamek.common.options.GameOptions; import megamek.common.options.IBasicOption; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; import megamek.common.util.ImageUtil; import megamek.common.util.SerializationHelper; diff --git a/megamek/src/megamek/client/bot/princess/FireControl.java b/megamek/src/megamek/client/bot/princess/FireControl.java index a8f93ba77e9..dabe31d38f5 100644 --- a/megamek/src/megamek/client/bot/princess/FireControl.java +++ b/megamek/src/megamek/client/bot/princess/FireControl.java @@ -17,9 +17,9 @@ import megamek.common.actions.*; import megamek.common.annotations.Nullable; import megamek.common.annotations.StaticWrapper; -import megamek.common.enums.IlluminationLevel; import megamek.common.options.OptionsConstants; import megamek.common.pathfinder.AeroGroundPathFinder; +import megamek.common.planetaryconditions.IlluminationLevel; import megamek.common.weapons.StopSwarmAttack; import megamek.common.weapons.Weapon; import megamek.common.weapons.infantry.InfantryWeapon; diff --git a/megamek/src/megamek/client/bot/princess/Precognition.java b/megamek/src/megamek/client/bot/princess/Precognition.java index 03b7c9e6e04..d6606cce030 100644 --- a/megamek/src/megamek/client/bot/princess/Precognition.java +++ b/megamek/src/megamek/client/bot/princess/Precognition.java @@ -23,6 +23,7 @@ import megamek.common.net.packets.Packet; import megamek.common.net.enums.PacketCommand; import megamek.common.options.GameOptions; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.SmokeCloud; import org.apache.logging.log4j.LogManager; diff --git a/megamek/src/megamek/client/bot/princess/Princess.java b/megamek/src/megamek/client/bot/princess/Princess.java index eb12240b300..97ead530ea9 100644 --- a/megamek/src/megamek/client/bot/princess/Princess.java +++ b/megamek/src/megamek/client/bot/princess/Princess.java @@ -36,6 +36,7 @@ import megamek.common.options.OptionsConstants; import megamek.common.pathfinder.BoardClusterTracker; import megamek.common.pathfinder.PathDecorator; +import megamek.common.planetaryconditions.Light; import megamek.common.util.BoardUtilities; import megamek.common.util.StringUtil; import megamek.common.weapons.AmmoWeapon; @@ -2031,10 +2032,10 @@ private void evadeIfNotFiring(MovePath path, boolean possibleToInflictDamage) { */ private void turnOnSearchLight(MovePath path, boolean possibleToInflictDamage) { Entity pathEntity = path.getEntity(); - if (possibleToInflictDamage && - pathEntity.hasSearchlight() && - !pathEntity.isUsingSearchlight() && - (path.getGame().getPlanetaryConditions().getLight() >= PlanetaryConditions.L_FULL_MOON)) { + if (possibleToInflictDamage + && pathEntity.hasSearchlight() + && !pathEntity.isUsingSearchlight() + && path.getGame().getPlanetaryConditions().getLight().isDarkerThan(Light.DUSK)) { path.addStep(MoveStepType.SEARCHLIGHT); } } diff --git a/megamek/src/megamek/client/ratgenerator/SubforcesNode.java b/megamek/src/megamek/client/ratgenerator/SubforcesNode.java index 47bc2670189..9dbfa50ff38 100644 --- a/megamek/src/megamek/client/ratgenerator/SubforcesNode.java +++ b/megamek/src/megamek/client/ratgenerator/SubforcesNode.java @@ -93,7 +93,7 @@ public ArrayList generateSubforces(ForceDescriptor fd, } else if (vn.getContent().endsWith("-")) { sub.setSizeMod(ForceDescriptor.UNDERSTRENGTH); sub.setEschelon(Integer.parseInt(vn.getContent().replace("-", ""))); - } else { + } else { sub.setEschelon(Integer.parseInt(vn.getContent())); } apply(sub, i); diff --git a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java index d6a514da2da..b4f5b6915a1 100644 --- a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java +++ b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java @@ -19,6 +19,7 @@ import megamek.common.*; import megamek.common.options.AbstractOptions; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Light; import megamek.common.util.fileUtils.MegaMekFile; import megamek.common.verifier.EntityVerifier; import megamek.common.verifier.TestBattleArmor; @@ -262,7 +263,7 @@ public EquipChoicePanel(Entity entity, ClientGUI clientgui, Client client) { // Set up searchlight if (!entity.getsAutoExternalSearchlight() - && (client.getGame().getPlanetaryConditions().getLight() > PlanetaryConditions.L_DUSK)) { + && client.getGame().getPlanetaryConditions().getLight().isDarkerThan(Light.DUSK)) { add(labSearchlight, GBC.std()); add(chSearchlight, GBC.eol()); chSearchlight.setSelected(entity.hasSearchlight() diff --git a/megamek/src/megamek/client/ui/swing/MovementDisplay.java b/megamek/src/megamek/client/ui/swing/MovementDisplay.java index f16a3fec1af..05a3ec6088a 100644 --- a/megamek/src/megamek/client/ui/swing/MovementDisplay.java +++ b/megamek/src/megamek/client/ui/swing/MovementDisplay.java @@ -43,6 +43,9 @@ import megamek.common.pathfinder.AbstractPathFinder; import megamek.common.pathfinder.LongestPathFinder; import megamek.common.pathfinder.ShortestPathFinder; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; import org.apache.logging.log4j.LogManager; @@ -1096,8 +1099,10 @@ private void updateAeroButtons() { setEvadeAeroEnabled(cmd != null && !cmd.contains(MoveStepType.EVADE)); setEjectEnabled(true); // no turning for spheroids in atmosphere - if ((((IAero) ce()).isSpheroid() || clientgui.getClient().getGame() - .getPlanetaryConditions().isVacuum()) + PlanetaryConditions conditions = clientgui.getClient().getGame().getPlanetaryConditions(); + boolean spheroidOrLessThanThin = ((IAero) ce()).isSpheroid() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); + if (spheroidOrLessThanThin && !clientgui.getClient().getGame().getBoard().inSpace()) { setTurnEnabled(false); } @@ -2342,7 +2347,7 @@ private void updateSearchlightButton() { if (ce == null) { return; } - boolean isNight = clientgui.getClient().getGame().getPlanetaryConditions().isIlluminationEffective(); + boolean isNight = clientgui.getClient().getGame().getPlanetaryConditions().getLight().isDarkerThan(Light.DAY); setSearchlightEnabled(isNight && ce.hasSearchlight() && !cmd.contains(MoveStepType.SEARCHLIGHT), ce.isUsingSearchlight()); } @@ -4200,8 +4205,9 @@ private void checkAtmosphere() { IAero a = (IAero) ce; if (!clientgui.getClient().getGame().getBoard().inSpace()) { + PlanetaryConditions conditions = clientgui.getClient().getGame().getPlanetaryConditions(); if (a.isSpheroid() - || clientgui.getClient().getGame().getPlanetaryConditions().isVacuum()) { + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN)) { getBtn(MoveCommand.MOVE_ACC).setEnabled(false); getBtn(MoveCommand.MOVE_DEC).setEnabled(false); getBtn(MoveCommand.MOVE_ACCN).setEnabled(false); @@ -5016,12 +5022,14 @@ public synchronized void actionPerformed(ActionEvent ev) { } else if (actionCmd.equals(MoveCommand.MOVE_RAISE_ELEVATION.getCmd())) { addStepToMovePath(MoveStepType.UP); } else if (actionCmd.equals(MoveCommand.MOVE_LOWER_ELEVATION.getCmd())) { + PlanetaryConditions conditions = clientgui.getClient().getGame().getPlanetaryConditions(); + boolean spheroidOrLessThanThin = ((IAero) ce).isSpheroid() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); if (ce.isAero() && (null != cmd.getLastStep()) && (cmd.getLastStep().getNDown() == 1) && (cmd.getLastStep().getVelocity() < 12) - && !(((IAero) ce).isSpheroid() || clientgui.getClient() - .getGame().getPlanetaryConditions().isVacuum())) { + && !spheroidOrLessThanThin) { addStepToMovePath(MoveStepType.ACC, true); computeAeroMovementEnvelope(ce); } diff --git a/megamek/src/megamek/client/ui/swing/PlanetaryConditionsDialog.java b/megamek/src/megamek/client/ui/swing/PlanetaryConditionsDialog.java index 0731c5bfdb5..2aedae8c32d 100644 --- a/megamek/src/megamek/client/ui/swing/PlanetaryConditionsDialog.java +++ b/megamek/src/megamek/client/ui/swing/PlanetaryConditionsDialog.java @@ -33,12 +33,12 @@ import megamek.client.ui.Messages; import megamek.client.ui.swing.dialog.DialogButton; import megamek.common.Configuration; -import megamek.common.PlanetaryConditions; +import megamek.common.planetaryconditions.*; import megamek.common.util.ImageUtil; +import megamek.common.util.StringUtil; import megamek.common.util.fileUtils.MegaMekFile; import static megamek.client.ui.swing.util.UIUtil.*; -import static megamek.common.PlanetaryConditions.*; /** * A dialog that allows for customization of planetary conditions @@ -89,25 +89,23 @@ public void update(PlanetaryConditions planetConditions) { private ClientGUI client; private PlanetaryConditions conditions; - - private static final int TOOLTIP_WIDTH = 300; private static final String PCD = "PlanetaryConditionsDialog."; private JLabel labLight = new JLabel(Messages.getString(PCD + "labLight"), SwingConstants.RIGHT); - private JComboBox comLight = new JComboBox<>(); + private JComboBox comLight = new JComboBox<>(); private JLabel labWeather = new TipLabel(Messages.getString(PCD + "labWeather"), SwingConstants.RIGHT); - private JComboBox comWeather = new JComboBox<>(); + private JComboBox comWeather = new JComboBox<>(); private JLabel labWind = new TipLabel(Messages.getString(PCD + "labWind"), SwingConstants.RIGHT); - private JComboBox comWind = new JComboBox<>(); + private JComboBox comWind = new JComboBox<>(); private JLabel labMinWind = new JLabel(Messages.getString(PCD + "labMinWind"), SwingConstants.RIGHT); - private JComboBox comWindFrom = new JComboBox<>(); - private JLabel labMaxWind = new JLabel(Messages.getString(PCD + "labMaxWind"), SwingConstants.RIGHT); - private JComboBox comWindDirection = new JComboBox<>(); + private JComboBox comWindFrom = new JComboBox<>(); + private JLabel labMaxWind = new JLabel(Messages.getString(PCD + "labMaxWind"), SwingConstants.RIGHT); + private JComboBox comWindTo = new JComboBox<>(); private JLabel labWindDirection = new JLabel(Messages.getString(PCD + "labWindDirection"), SwingConstants.RIGHT); - private JComboBox comWindTo = new JComboBox<>(); + private JComboBox comWindDirection = new JComboBox<>(); private JLabel labAtmosphere = new TipLabel(Messages.getString(PCD + "labAtmosphere"), SwingConstants.RIGHT); - private JComboBox comFog = new JComboBox<>(); + private JComboBox comAtmosphere = new JComboBox<>(); private JLabel labFog = new TipLabel(Messages.getString(PCD + "labFog"), SwingConstants.RIGHT); - private JComboBox comAtmosphere = new JComboBox<>(); + private JComboBox comFog = new JComboBox<>(); private JLabel labBlowingSands = new TipLabel(Messages.getString(PCD + "BlowingSands"), SwingConstants.RIGHT); private JCheckBox chkBlowingSands = new JCheckBox(); private JLabel labShiftWindDir = new JLabel(Messages.getString(PCD + "shiftWindDir"), SwingConstants.RIGHT); @@ -224,25 +222,25 @@ private JPanel buttonPanel() { /** Fills the dialog comboboxes. */ private void setupCombos() { - for (int i = 0; i < PlanetaryConditions.L_SIZE; i++) { - comLight.addItem(PlanetaryConditions.getLightDisplayableName(i)); + for (Light condition : Light.values()) { + comLight.addItem(condition); } - for (int i = 0; i < PlanetaryConditions.WE_SIZE; i++) { - comWeather.addItem(PlanetaryConditions.getWeatherDisplayableName(i)); + for (Weather condition : Weather.values()) { + comWeather.addItem(condition); } - for (int i = 0; i < PlanetaryConditions.WI_SIZE; i++) { - comWind.addItem(PlanetaryConditions.getWindDisplayableName(i)); - comWindFrom.addItem(PlanetaryConditions.getWindDisplayableName(i)); - comWindTo.addItem(PlanetaryConditions.getWindDisplayableName(i)); + for (Wind condition : Wind.values()) { + comWind.addItem(condition); + comWindFrom.addItem(condition); + comWindTo.addItem(condition); } - for (int i = 0; i < PlanetaryConditions.DIR_SIZE; i++) { - comWindDirection.addItem(PlanetaryConditions.getWindDirDisplayableName(i)); + for (WindDirection condition : WindDirection.values()) { + comWindDirection.addItem(condition); } - for (int i = 0; i < PlanetaryConditions.ATMO_SIZE; i++) { - comAtmosphere.addItem(PlanetaryConditions.getAtmosphereDisplayableName(i)); + for (Atmosphere condition : Atmosphere.values()) { + comAtmosphere.addItem(condition); } - for (int i = 0; i < PlanetaryConditions.FOG_SIZE; i++) { - comFog.addItem(PlanetaryConditions.getFogDisplayableName(i)); + for (Fog condition : Fog.values()) { + comFog.addItem(condition); } } @@ -281,20 +279,20 @@ private void removeListeners() { /** Updates the dialog fields with values from the stored conditions. */ private void refreshValues() { removeListeners(); - comLight.setSelectedIndex(conditions.getLight()); - comWeather.setSelectedIndex(conditions.getWeather()); - comWind.setSelectedIndex(conditions.getWindStrength()); - comWindFrom.setSelectedIndex(conditions.getMinWindStrength()); - comWindTo.setSelectedIndex(conditions.getMaxWindStrength()); - comWindDirection.setSelectedIndex(conditions.getWindDirection()); - comAtmosphere.setSelectedIndex(conditions.getAtmosphere()); - comFog.setSelectedIndex(conditions.getFog()); - chkBlowingSands.setSelected(conditions.isSandBlowing()); + comLight.setSelectedItem(conditions.getLight()); + comWeather.setSelectedItem(conditions.getWeather()); + comWind.setSelectedItem(conditions.getWind()); + comWindFrom.setSelectedItem(conditions.getWindMin()); + comWindTo.setSelectedItem(conditions.getWindMax()); + comWindDirection.setSelectedItem(conditions.getWindDirection()); + comAtmosphere.setSelectedItem(conditions.getAtmosphere()); + comFog.setSelectedItem(conditions.getFog()); + chkBlowingSands.setSelected(conditions.isBlowingSand()); chkShiftWindDir.setSelected(conditions.shiftingWindDirection()); chkShiftWindStr.setSelected(conditions.shiftingWindStrength()); fldTemp.setText(Integer.toString(conditions.getTemperature())); fldGrav.setText(Float.toString(conditions.getGravity())); - chkEMI.setSelected(conditions.hasEMI()); + chkEMI.setSelected(conditions.getEMI().isEMI()); chkTerrainAffected.setSelected(conditions.isTerrainAffected()); addListeners(); refreshWindShift(); @@ -305,19 +303,21 @@ private void refreshValues() { */ private void setConditions() { // make the changes to the planetary conditions - conditions.setLight(comLight.getSelectedIndex()); - conditions.setWeather(comWeather.getSelectedIndex()); - conditions.setWindStrength(comWind.getSelectedIndex()); - conditions.setWindDirection(comWindDirection.getSelectedIndex()); + conditions.setLight(comLight.getItemAt(comLight.getSelectedIndex())); + conditions.setWeather(comWeather.getItemAt(comWeather.getSelectedIndex())); + conditions.setWind(comWind.getItemAt(comWind.getSelectedIndex())); + conditions.setWindDirection(comWindDirection.getItemAt(comWindDirection.getSelectedIndex())); refreshWindRange(); - conditions.setAtmosphere(comAtmosphere.getSelectedIndex()); - conditions.setFog(comFog.getSelectedIndex()); - conditions.setBlowingSand(chkBlowingSands.isSelected()); + conditions.setAtmosphere(comAtmosphere.getItemAt(comAtmosphere.getSelectedIndex())); + conditions.setFog(comFog.getItemAt(comFog.getSelectedIndex())); + BlowingSand blowingSand = chkBlowingSands.isSelected() ? BlowingSand.BLOWING_SAND : BlowingSand.BLOWING_SAND_NONE; + conditions.setBlowingSand(blowingSand); conditions.setShiftingWindDirection(chkShiftWindDir.isSelected()); conditions.setShiftingWindStrength(chkShiftWindStr.isSelected()); - conditions.setTemperature(Integer.parseInt(fldTemp.getText())); - conditions.setGravity(Float.parseFloat(fldGrav.getText())); - conditions.setEMI(chkEMI.isSelected()); + conditions.setTemperature(StringUtil.toInt(fldTemp.getText(), 25)); + conditions.setGravity(StringUtil.toFloat(fldGrav.getText(), 1.0f)); + EMI emi = chkEMI.isSelected() ? EMI.EMI : EMI.EMI_NONE; + conditions.setEMI(emi); conditions.setTerrainAffected(chkTerrainAffected.isSelected()); } @@ -332,7 +332,7 @@ private boolean validateEntries() { StringBuilder windTip = new StringBuilder(); StringBuilder atmoTip = new StringBuilder(); StringBuilder sandTip = new StringBuilder(); - int weather = comWeather.getSelectedIndex(); + Weather weather = comWeather.getItemAt(comWeather.getSelectedIndex()); int temp = 0; float grav = (float) 1.0; try { @@ -367,45 +367,47 @@ private boolean validateEntries() { gravTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.gravRange")); } - int wind = comWind.getSelectedIndex(); - int atmo = comAtmosphere.getSelectedIndex(); - - if ((chkBlowingSands.isSelected()) && (wind < WI_MOD_GALE) - && (!chkShiftWindStr.isSelected() - || (conditions.getMinWindStrength() > WI_MOD_GALE) - || (conditions.getMaxWindStrength() < WI_MOD_GALE))) { + Wind wind = comWind.getItemAt(comWind.getSelectedIndex()); + Atmosphere atmo = comAtmosphere.getItemAt(comAtmosphere.getSelectedIndex()); + + boolean blowingSandsLessThanModerateGale = chkBlowingSands.isSelected() + && wind.isWeakerThan(Wind.MOD_GALE); + boolean shiftWindsLessThanModerateGale = chkShiftWindStr.isSelected() + && conditions.getWindMax().isWeakerThan(Wind.MOD_GALE); + if (blowingSandsLessThanModerateGale + || shiftWindsLessThanModerateGale) { windTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.sandsLost")); sandTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.sandsLost")); } - if ((atmo == ATMO_TRACE) && (wind == WI_LIGHT_GALE)) { + if (atmo.isTrace() + && wind.isLightGale()) { atmoTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.traceLightGale")); windTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.traceLightGale")); } // The following temperature checks are not exactly what the rules demand, but see the comment above. - if (((weather == WE_LIGHT_SNOW) || (weather == WE_SLEET) - || (weather == WE_LIGHT_HAIL) || (weather == WE_HEAVY_HAIL)) + if (weather.isLightSnowOrSleetOrLightHailOrHeavyHail() && (temp > -40)) { tempTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.lightSnowTemp")); wthrTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.lightSnowTemp")); } - - if (((weather == WE_HEAVY_SNOW) || (weather == WE_MOD_SNOW) - || (weather == WE_SNOW_FLURRIES)) + + if (weather.isModerateSnowOrHeavySnowOrSnowFlurries() && (temp > -50)) { tempTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.modSnowTemp")); wthrTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.modSnowTemp")); } - if ((weather == WE_ICE_STORM) && (temp > -60)) { + if (weather.isIceStorm() + && (temp > -60)) { tempTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.iceStormTemp")); wthrTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.iceStormTemp")); } if (chkShiftWindStr.isSelected()) { - if ((comWind.getSelectedIndex() < conditions.getMinWindStrength()) - || (comWind.getSelectedIndex() > conditions.getMaxWindStrength())) { + if (comWind.getItemAt(comWind.getSelectedIndex()).isWeakerThan(conditions.getWindMin()) + || comWind.getItemAt(comWind.getSelectedIndex()).isStrongerThan(conditions.getWindMax())) { windTip.append(Messages.getString("PlanetaryConditionsDialog.invalid.windRange")); } } @@ -441,38 +443,36 @@ private void refreshWarning(JLabel label, StringBuilder text) { * weather to none. */ private void adaptToWeatherAtmo() { - boolean isVacuum = comAtmosphere.getSelectedIndex() == ATMO_VACUUM; - boolean isTraceThin = comAtmosphere.getSelectedIndex() == ATMO_THIN - | comAtmosphere.getSelectedIndex() == ATMO_TRACE; - boolean isDense = !isVacuum && !isTraceThin; - int weather = comWeather.getSelectedIndex(); - boolean specificWind = (weather == WE_SNOW_FLURRIES) || (weather == WE_ICE_STORM) - || (weather == WE_GUSTING_RAIN) || (weather == WE_LIGHTNING_STORM); + boolean isVacuum = comAtmosphere.getItemAt(comAtmosphere.getSelectedIndex()).isVacuum(); + boolean isTraceOrThin = comAtmosphere.getItemAt(comAtmosphere.getSelectedIndex()).isTraceOrThin(); + boolean isDense = !isVacuum && !isTraceOrThin; + Weather weather = comWeather.getItemAt(comWeather.getSelectedIndex()); removeListeners(); - if (isTraceThin) { - comWeather.setSelectedIndex(PlanetaryConditions.WE_NONE); - comFog.setSelectedIndex(PlanetaryConditions.FOG_NONE); + if (isTraceOrThin) { + comWeather.setSelectedItem(Weather.CLEAR); + comFog.setSelectedItem(Fog.FOG_NONE); } if (isVacuum) { - comWind.setSelectedIndex(PlanetaryConditions.WI_NONE); + comWind.setSelectedItem(Wind.CALM); chkBlowingSands.setSelected(false); chkShiftWindDir.setSelected(false); chkShiftWindStr.setSelected(false); - comWind.setSelectedIndex(WI_NONE); - comWeather.setSelectedIndex(WE_NONE); - comFog.setSelectedIndex(FOG_NONE); + comWind.setSelectedItem(Wind.CALM); + comWeather.setSelectedItem(Weather.CLEAR); + comFog.setSelectedItem(Fog.FOG_NONE); } - if (specificWind) { + if (weather.isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm()) { chkShiftWindStr.setSelected(false); switch (weather) { - case WE_LIGHTNING_STORM: - case WE_SNOW_FLURRIES: - case WE_ICE_STORM: - comWind.setSelectedIndex(WI_MOD_GALE); + case LIGHTNING_STORM: + case SNOW_FLURRIES: + case ICE_STORM: + comWind.setSelectedItem(Wind.MOD_GALE); break; - case WE_GUSTING_RAIN: - comWind.setSelectedIndex(WI_STRONG_GALE); + case GUSTING_RAIN: + comWind.setSelectedItem(Wind.STRONG_GALE); + default: } } addListeners(); @@ -480,14 +480,14 @@ private void adaptToWeatherAtmo() { comWeather.setEnabled(isDense); labFog.setEnabled(isDense); comFog.setEnabled(isDense); - labWind.setEnabled(!isVacuum && !specificWind); - comWind.setEnabled(!isVacuum && !specificWind); + labWind.setEnabled(!isVacuum && !weather.isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm()); + comWind.setEnabled(!isVacuum && !weather.isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm()); labBlowingSands.setEnabled(!isVacuum); chkBlowingSands.setEnabled(!isVacuum); labShiftWindDir.setEnabled(!isVacuum); chkShiftWindDir.setEnabled(!isVacuum); - labShiftWindStr.setEnabled(!isVacuum && !specificWind); - chkShiftWindStr.setEnabled(!isVacuum && !specificWind); + labShiftWindStr.setEnabled(!isVacuum && !weather.isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm()); + chkShiftWindStr.setEnabled(!isVacuum && !weather.isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm()); comWindDirection.setEnabled(!isVacuum); labWindDirection.setEnabled(!isVacuum); refreshWindShift(); @@ -495,21 +495,21 @@ private void adaptToWeatherAtmo() { /** Sets the temperature to at most -40, -50 or -60 for snow conditions. */ private void adaptTemperature() { - int weather = comWeather.getSelectedIndex(); + Weather weather = comWeather.getItemAt(comWeather.getSelectedIndex()); int maxTemp = 200; switch (weather) { - case WE_LIGHT_SNOW: - case WE_SLEET: - case WE_LIGHT_HAIL: - case WE_HEAVY_HAIL: + case LIGHT_SNOW: + case SLEET: + case LIGHT_HAIL: + case HEAVY_HAIL: maxTemp = -40; break; - case WE_HEAVY_SNOW: - case WE_MOD_SNOW: - case WE_SNOW_FLURRIES: + case HEAVY_SNOW: + case MOD_SNOW: + case SNOW_FLURRIES: maxTemp = -50; break; - case WE_ICE_STORM: + case ICE_STORM: maxTemp = -60; } setMaximumTemperature(maxTemp); @@ -518,7 +518,7 @@ private void adaptTemperature() { /** Sets the wind to at least moderate gale if Blowing Sands is activated. */ private void adaptWindToBlowingSands() { if (chkBlowingSands.isSelected()) { - setMinimumWind(WI_MOD_GALE); + setMinimumWind(Wind.MOD_GALE); } } @@ -531,10 +531,10 @@ private void refreshWindShift() { } /** Sets wind strength to Moderate Gale if it is less than that. */ - private void setMinimumWind(int minWind) { - if (comWind.getSelectedIndex() < minWind) { + private void setMinimumWind(Wind minWind) { + if (comWind.getItemAt(comWind.getSelectedIndex()).isWeakerThan(minWind)) { removeListeners(); - comWind.setSelectedIndex(minWind); + comWind.setSelectedItem(minWind); addListeners(); } } @@ -567,7 +567,7 @@ public void actionPerformed(ActionEvent e) { setVisible(false); } else if ((e.getSource() instanceof JComboBox) - || (e.getSource() instanceof JCheckBox)) { + || (e.getSource() instanceof JCheckBox)) { if (e.getSource() == chkBlowingSands) { adaptWindToBlowingSands(); } @@ -595,16 +595,16 @@ public void actionPerformed(ActionEvent e) { * closer border of that range. */ private void refreshWindRange() { - int min = Math.min(comWindFrom.getSelectedIndex(), comWindTo.getSelectedIndex()); - int max = Math.max(comWindFrom.getSelectedIndex(), comWindTo.getSelectedIndex()); - conditions.setMinWindStrength(min); - conditions.setMaxWindStrength(max); + Wind min = Wind.getWind(Math.min(comWindFrom.getSelectedIndex(), comWindTo.getSelectedIndex())); + Wind max = Wind.getWind(Math.max(comWindFrom.getSelectedIndex(), comWindTo.getSelectedIndex())); + conditions.setWindMin(min); + conditions.setWindMax(max); removeListeners(); - if (comWind.getSelectedIndex() < min) { - comWind.setSelectedIndex(min); + if (comWind.getItemAt(comWind.getSelectedIndex()).isWeakerThan(min)) { + comWind.setSelectedItem(min); } - if (comWind.getSelectedIndex() > max) { - comWind.setSelectedIndex(max); + if (comWind.getItemAt(comWind.getSelectedIndex()).isStrongerThan(max)) { + comWind.setSelectedItem(max); } addListeners(); } @@ -620,5 +620,4 @@ public void focusLost(FocusEvent e) { @Override public void focusGained(FocusEvent e) { } }; - } diff --git a/megamek/src/megamek/client/ui/swing/boardview/BoardView.java b/megamek/src/megamek/client/ui/swing/boardview/BoardView.java index 3f904c884b6..5ceb7c9a9ef 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/BoardView.java +++ b/megamek/src/megamek/client/ui/swing/boardview/BoardView.java @@ -40,12 +40,14 @@ import megamek.common.MovePath.MoveStepType; import megamek.common.actions.*; import megamek.common.annotations.Nullable; -import megamek.common.enums.IlluminationLevel; import megamek.common.event.*; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.pathfinder.BoardClusterTracker; import megamek.common.pathfinder.BoardClusterTracker.BoardCluster; +import megamek.common.planetaryconditions.IlluminationLevel; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.ClientPreferences; import megamek.common.preference.IPreferenceChangeListener; import megamek.common.preference.PreferenceChangeEvent; @@ -1396,7 +1398,8 @@ private Image createBlurredShadow(Image orig) { g.dispose(); mask = createShadowMask(mask); mask = blurOp.filter(mask, null); - if (game.getPlanetaryConditions().getLight() != PlanetaryConditions.L_DAY) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (!conditions.getLight().isDay()) { mask = blurOp.filter(mask, null); } shadowImageCache.put(orig.hashCode(), mask); @@ -1439,6 +1442,7 @@ private void updateShadowMap() { return; } + PlanetaryConditions conditions = game.getPlanetaryConditions(); long stT = System.nanoTime(); // 1) create or get the hex shadow @@ -1464,10 +1468,9 @@ private void updateShadowMap() { // Compute shadow angle based on planentary conditions. double[] lightDirection = {-19, 7}; - if ((game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_MOONLESS) || - (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_PITCH_BLACK)) { + if (conditions.getLight().isDarkerThan(Light.FULL_MOON)) { lightDirection = new double[]{0, 0}; - } else if (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DUSK) { + } else if (conditions.getLight().isDusk()) { // TODO: replace when made user controlled lightDirection = new double[]{-38, 14}; } else { @@ -2402,6 +2405,7 @@ private void drawHex(Coords c, Graphics boardGraph, boolean saveBoardImage) { final Hex hex = game.getBoard().getHex(c); final Point hexLoc = getHexLocation(c); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // Check the cache to see if we already have the image HexImageCacheEntry cacheEntry = hexImageCache.get(c); @@ -2554,7 +2558,7 @@ private void drawHex(Coords c, Graphics boardGraph, boolean saveBoardImage) { Point p2DST = new Point(hex_size.width, hex_size.height); Composite svComp = g.getComposite(); - if (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DAY) { + if (conditions.getLight().isDay()) { g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.55f)); } else { g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.45f)); @@ -2659,7 +2663,7 @@ private void drawHex(Coords c, Graphics boardGraph, boolean saveBoardImage) { // Darken the hex for nighttime, if applicable if (GUIP.getDarkenMapAtNight() && IlluminationLevel.determineIlluminationLevel(game, c).isNone() - && (game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DAY)) { + && conditions.getLight().isDarkerThan(Light.DAY)) { for (int x = 0; x < hexImage.getWidth(); ++x) { for (int y = 0; y < hexImage.getHeight(); ++y) { hexImage.setRGB(x, y, getNightDarkenedColor(hexImage.getRGB(x, y))); @@ -2872,9 +2876,10 @@ private void drawOrthograph(Coords c, Graphics boardGraph) { BufferedImage scaledImage = ImageUtil.createAcceleratedImage(getScaledImage(image, true)); // Darken the hex for nighttime, if applicable + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (GUIP.getDarkenMapAtNight() && IlluminationLevel.determineIlluminationLevel(game, c).isNone() - && (game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DAY)) { + && conditions.getLight().isDarkerThan(Light.DAY)) { for (int x = 0; x < scaledImage.getWidth(null); ++x) { for (int y = 0; y < scaledImage.getHeight(); ++y) { scaledImage.setRGB(x, y, getNightDarkenedColor(scaledImage.getRGB(x, y))); @@ -3036,13 +3041,13 @@ public int getNightDarkenedColor(int rgb) { int al = (rgb >> 24); switch (game.getPlanetaryConditions().getLight()) { - case PlanetaryConditions.L_FULL_MOON: - case PlanetaryConditions.L_MOONLESS: + case FULL_MOON: + case MOONLESS: rd = rd / 4; // 1/4 red gr = gr / 4; // 1/4 green bl = bl / 2; // half blue break; - case PlanetaryConditions.L_PITCH_BLACK: + case PITCH_BLACK: int gy = (rd + gr + bl) / 16; if (Math.random() < 0.3) { gy = gy * 4 / 5; @@ -3054,7 +3059,7 @@ public int getNightDarkenedColor(int rgb) { gr = gy + gr / 5; bl = gy + bl / 5; break; - case PlanetaryConditions.L_DUSK: + case DUSK: bl = bl * 3 / 4; break; default: @@ -6560,7 +6565,7 @@ public void setSensorRange(Entity entity, Coords c) { minSensorRange = 0; - if (game.getPlanetaryConditions().isIlluminationEffective()) { + if (game.getPlanetaryConditions().getLight().isDarkerThan(Light.DAY)) { maxSensorRange = Compute.getMaxVisualRange(entity, true); } else { maxSensorRange = 0; diff --git a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java index 0f2ce9227ee..cf98ac678c5 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java +++ b/megamek/src/megamek/client/ui/swing/boardview/FovHighlightingAndDarkening.java @@ -3,11 +3,11 @@ import megamek.client.ui.swing.GUIPreferences; import megamek.common.*; import megamek.common.annotations.Nullable; -import megamek.common.enums.IlluminationLevel; import megamek.common.event.GameListener; import megamek.common.event.GameListenerAdapter; import megamek.common.event.GameTurnChangeEvent; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.IlluminationLevel; import megamek.common.preference.IPreferenceChangeListener; import org.apache.logging.log4j.LogManager; diff --git a/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java b/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java index ea4eff3efbd..468245b5b7f 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java +++ b/megamek/src/megamek/client/ui/swing/boardview/PlanetaryConditionsOverlay.java @@ -16,7 +16,7 @@ import megamek.client.ui.Messages; import megamek.client.ui.swing.GUIPreferences; import megamek.client.ui.swing.util.KeyCommandBind; -import megamek.common.PlanetaryConditions; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceChangeEvent; import java.awt.*; @@ -64,11 +64,12 @@ protected List assembleTextLines() { // In a game, not the Board Editor String tempColor = ""; - int temp = currentGame.getPlanetaryConditions().getTemperature(); + PlanetaryConditions conditions = currentGame.getPlanetaryConditions(); + int temp = conditions.getTemperature(); - if (currentGame.getPlanetaryConditions().isExtremeTemperatureHeat()) { + if (conditions.isExtremeTemperatureHeat()) { tempColor = colorToHex(colorHot); - } else if (currentGame.getPlanetaryConditions().isExtremeTemperatureCold()) { + } else if (conditions.isExtremeTemperatureCold()) { tempColor = colorToHex(colorCold); } @@ -80,71 +81,71 @@ protected List assembleTextLines() { String tmpStr; - if (showDefaultConditions || (currentGame.getPlanetaryConditions().isExtremeTemperature())) { + if (showDefaultConditions || (conditions.isExtremeTemperature())) { tmpStr = (showLabel ? MSG_TEMPERATURE + " " : ""); tmpStr = tmpStr + (showValue ? temp + "\u00B0C " : ""); - tmpStr = tmpStr + (showIndicator ? (!showValue ? temp + "\u00B0C " : "" ) + currentGame.getPlanetaryConditions().getTemperatureIndicator() : ""); + tmpStr = tmpStr + (showIndicator ? (!showValue ? temp + "\u00B0C " : "" ) + conditions.getTemperatureIndicator() : ""); result.add(tempColor + tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getGravity() != 1.0)) { - float grav = currentGame.getPlanetaryConditions().getGravity(); + if (showDefaultConditions || (conditions.getGravity() != 1.0)) { + float grav = conditions.getGravity(); tmpStr = (showLabel ? MSG_GRAVITY + " " : ""); tmpStr = tmpStr + (showValue ? grav + "g " : ""); - tmpStr = tmpStr + (showIndicator ? (!showValue ? grav + "g " : "") + currentGame.getPlanetaryConditions().getGravityIndicator() : ""); + tmpStr = tmpStr + (showIndicator ? (!showValue ? grav + "g " : "") + conditions.getGravityIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getLight() != PlanetaryConditions.L_DAY)) { + if (showDefaultConditions || !conditions.getLight().isDay()) { tmpStr = (showLabel ? MSG_LIGHT + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getLightDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getLightIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getLight().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getLight().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getAtmosphere() != PlanetaryConditions.ATMO_STANDARD)) { + if (showDefaultConditions || !conditions.getAtmosphere().isStandard()) { tmpStr = (showLabel ? MSG_ATMOSPHERICPREASSURE + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getAtmosphereDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getAtmosphereIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getAtmosphere().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getAtmosphere().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().hasEMI())) { + if (showDefaultConditions || conditions.isEMI()) { tmpStr = (showLabel ? MSG_EMI + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getEMIDisplayableValue() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getEMIIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getEMI().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getEMI().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getWeather() != PlanetaryConditions.WE_NONE)) { + if (showDefaultConditions || !conditions.getWeather().isClear()) { tmpStr = (showLabel ? MSG_WEATHER + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWeatherDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWeatherIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getWeather().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getWeather().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getWindStrength() != PlanetaryConditions.WI_NONE)) { + if (showDefaultConditions || !conditions.getWind().isCalm()) { tmpStr = (showLabel ? MSG_WIND + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWindDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWindStrengthIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getWind().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getWind().getIndicator() : ""); result.add(tmpStr); tmpStr = (showLabel ? MSG_DIRECTION + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getWindDirDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getWindDirectionIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getWindDirection().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getWindDirection().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().getFog() != PlanetaryConditions.FOG_NONE)) { + if (showDefaultConditions || conditions.isFog()) { tmpStr = (showLabel ? MSG_FOG + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getFogDisplayableName() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getFogIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getFog().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getFog().getIndicator() : ""); result.add(tmpStr); } - if (showDefaultConditions || (currentGame.getPlanetaryConditions().isSandBlowing())) { + if (showDefaultConditions || conditions.isBlowingSand()) { tmpStr = (showLabel ? MSG_BLOWINGSAND + " " : ""); - tmpStr = tmpStr + (showValue ? currentGame.getPlanetaryConditions().getSandBlowingDisplayableValue() + " " : ""); - tmpStr = tmpStr + (showIndicator ? currentGame.getPlanetaryConditions().getSandBlowingIndicator() : ""); + tmpStr = tmpStr + (showValue ? conditions.getBlowingSand().toString() + " " : ""); + tmpStr = tmpStr + (showIndicator ? conditions.getBlowingSand().getIndicator() : ""); result.add(tmpStr); } } diff --git a/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java b/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java index bdc3b8a6055..6225db178c4 100644 --- a/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java +++ b/megamek/src/megamek/client/ui/swing/tooltip/HexTooltip.java @@ -20,7 +20,7 @@ import megamek.common.*; import megamek.common.annotations.Nullable; import megamek.common.enums.BasementType; -import megamek.common.enums.IlluminationLevel; +import megamek.common.planetaryconditions.IlluminationLevel; import java.util.Vector; @@ -188,10 +188,10 @@ public static String getOneLineSummary(BuildingTarget target, Board board) { return result; } - public static String getTerrainTip(Hex mhex, GUIPreferences GUIP, Game game) - { + public static String getTerrainTip(Hex mhex, GUIPreferences GUIP, Game game) { Coords mcoords = mhex.getCoords(); - String illuminated = IlluminationLevel.getIlluminationLevelIndicator(game, mcoords, GUIP); + String indicator = IlluminationLevel.determineIlluminationLevel(game, mcoords).getIndicator(); + String illuminated = DOT_SPACER + guiScaledFontHTML(GUIP.getCautionColor()) + " " + indicator + ""; String result = ""; StringBuilder sTerrain = new StringBuilder(Messages.getString("BoardView1.Tooltip.Hex", mcoords.getBoardNum(), mhex.getLevel()) + illuminated + "
"); diff --git a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java index 0a50fc4b90a..85742602723 100644 --- a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java +++ b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java @@ -22,6 +22,8 @@ import megamek.common.annotations.Nullable; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; import megamek.common.templates.TROView; import megamek.common.weapons.LegAttack; @@ -1242,6 +1244,7 @@ private static StringBuilder inGameValues(Entity entity, Player localPlayer, boo boolean showBV, boolean showSensors, boolean showSeenBy) { Game game = entity.getGame(); GameOptions gameOptions = game.getOptions(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); boolean isGunEmplacement = entity instanceof GunEmplacement; String result = ""; @@ -1501,13 +1504,13 @@ private static StringBuilder inGameValues(Entity entity, Player localPlayer, boo if (gameOptions.booleanOption(OptionsConstants.ADVANCED_TACOPS_SENSORS) || (gameOptions.booleanOption(OptionsConstants.ADVAERORULES_STRATOPS_ADVANCED_SENSORS)) && entity.isSpaceborne()) { String visualRange = Compute.getMaxVisualRange(entity, false) + ""; - if (game.getPlanetaryConditions().isIlluminationEffective()) { + if (conditions.getLight().isDarkerThan(Light.DAY)) { visualRange += " (" + Compute.getMaxVisualRange(entity, true) + ")"; } result += addToTT("Sensors", BR, getSensorDesc(entity), visualRange); } else { String visualRange = Compute.getMaxVisualRange(entity, false) + ""; - if (game.getPlanetaryConditions().isIlluminationEffective()) { + if (conditions.getLight().isDarkerThan(Light.DAY)) { visualRange += " (" + Compute.getMaxVisualRange(entity, true) + ")"; } result += addToTT("Visual", BR, visualRange); diff --git a/megamek/src/megamek/common/Aero.java b/megamek/src/megamek/common/Aero.java index 2af76f4a593..2cec6aebb00 100644 --- a/megamek/src/megamek/common/Aero.java +++ b/megamek/src/megamek/common/Aero.java @@ -17,6 +17,8 @@ import megamek.common.cost.AeroCostCalculator; import megamek.common.enums.AimingMode; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; import java.text.NumberFormat; @@ -345,11 +347,12 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if ((null != game) && !mpCalculationSetting.ignoreWeather) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE)) { + && conditions.getWind().isTornadoF1ToF3() + && conditions.getWeather().isClear()) { mp += 1; } } @@ -1418,9 +1421,12 @@ public PilotingRollData addEntityBonuses(PilotingRollData prd) { prd.addModifier(vmod, "Velocity greater than 2x safe thrust"); } - int atmoCond = game.getPlanetaryConditions().getAtmosphere(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // add in atmospheric effects later - if (!(game.getBoard().inSpace() || (atmoCond == PlanetaryConditions.ATMO_VACUUM)) && isAirborne()) { + boolean spaceOrVacuum = game.getBoard().inSpace() + || conditions.getAtmosphere().isVacuum(); + if (!spaceOrVacuum + && isAirborne()) { prd.addModifier(+2, "Atmospheric operations"); // check type @@ -2684,11 +2690,13 @@ public boolean canSpot() { // per a recent ruling on the official forums, aero units can't spot // for indirect LRM fire, unless they have a recon cam, an infrared or // hyperspec imager, or a high-res imager and it's not night - return !isAirborne() || hasWorkingMisc(MiscType.F_RECON_CAMERA) || hasWorkingMisc(MiscType.F_INFRARED_IMAGER) + boolean hiresLighted = hasWorkingMisc(MiscType.F_HIRES_IMAGER) + && game.getPlanetaryConditions().getLight().isLighterThan(Light.FULL_MOON); + return !isAirborne() + || hasWorkingMisc(MiscType.F_RECON_CAMERA) + || hasWorkingMisc(MiscType.F_INFRARED_IMAGER) || hasWorkingMisc(MiscType.F_HYPERSPECTRAL_IMAGER) - || (hasWorkingMisc(MiscType.F_HIRES_IMAGER) - && ((game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DAY) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DUSK))); + || hiresLighted; } // Damage a fighter that was part of a squadron when splitting it. Per diff --git a/megamek/src/megamek/common/BattleArmor.java b/megamek/src/megamek/common/BattleArmor.java index d880daa4405..ab81e73ce57 100644 --- a/megamek/src/megamek/common/BattleArmor.java +++ b/megamek/src/megamek/common/BattleArmor.java @@ -18,6 +18,9 @@ import megamek.common.cost.BattleArmorCostCalculator; import megamek.common.enums.AimingMode; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import megamek.common.weapons.InfantryAttack; import megamek.common.weapons.infantry.InfantryWeapon; import org.apache.logging.log4j.LogManager; @@ -440,18 +443,18 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if ((!mpCalculationSetting.ignoreWeather) && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_GUSTING_RAIN) + if (conditions.getWeather().isGustingRain() && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_RAIN)) { mp += 1; } if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && ((game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_STRONG_GALE) - || (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_STORM))) { + && conditions.getWeather().isClear() + && conditions.getWind().isStrongGaleOrStorm()) { mp += 1; } } @@ -495,13 +498,16 @@ public int getJumpMP(MPCalculationSetting mpCalculationSetting) { return 0; } - if (!mpCalculationSetting.ignoreWeather && (null != game) - && (game.getPlanetaryConditions().getWindStrength() >= PlanetaryConditions.WI_STORM)) { - return 0; + if (null != game) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (!mpCalculationSetting.ignoreWeather + && conditions.getWind().isStrongerThan(Wind.STRONG_GALE)){ + return 0; + } } int mp = 0; - if (getMovementMode() != EntityMovementMode.INF_UMU) { + if (!getMovementMode().isUMUInfantry()) { mp = getOriginalJumpMP(); } // if we have no normal jump jets, we get 1 jump MP from mechanical jump @@ -510,13 +516,19 @@ public int getJumpMP(MPCalculationSetting mpCalculationSetting) { mp++; } - if ((mp > 0) - && hasWorkingMisc(MiscType.F_PARTIAL_WING) - && (mpCalculationSetting.ignoreWeather || (game == null) || !game.getPlanetaryConditions().isVacuum())) { - mp++; + if ((game != null)) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + boolean ignoreGameLessThanThin = mpCalculationSetting.ignoreWeather + || !conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); + if ((mp > 0) + && hasWorkingMisc(MiscType.F_PARTIAL_WING) + && ignoreGameLessThanThin) { + mp++; + } } - if ((mp > 0) && hasWorkingMisc(MiscType.F_JUMP_BOOSTER)) { + if ((mp > 0) + && hasWorkingMisc(MiscType.F_JUMP_BOOSTER)) { mp++; } diff --git a/megamek/src/megamek/common/BipedMech.java b/megamek/src/megamek/common/BipedMech.java index 32f1de74457..3fc9674b50f 100644 --- a/megamek/src/megamek/common/BipedMech.java +++ b/megamek/src/megamek/common/BipedMech.java @@ -20,6 +20,7 @@ import java.util.List; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; public class BipedMech extends Mech { private static final long serialVersionUID = 4166375446709772785L; @@ -92,7 +93,7 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { int actuatorHits = 0; //A Mech using tracks has its movement reduced by 50% per leg or track destroyed; - if (getMovementMode() == EntityMovementMode.TRACKED) { + if (getMovementMode().isTracked()) { for (Mounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_TRACKS)) { if (m.isHit() || isLocationBad(m.getLocation())) { @@ -179,12 +180,13 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { mp += 1; } } diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index cd5b922443b..63e4728bff6 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -18,10 +18,12 @@ import megamek.common.MovePath.MoveStepType; import megamek.common.actions.*; import megamek.common.annotations.Nullable; -import megamek.common.enums.AimingMode; -import megamek.common.enums.BasementType; -import megamek.common.enums.IlluminationLevel; +import megamek.common.enums.*; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.IlluminationLevel; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.weapons.DiveBombAttack; import megamek.common.weapons.InfantryAttack; import megamek.common.weapons.Weapon; @@ -2586,8 +2588,7 @@ public static void modifyPhysicalBTHForAdvantages(final Entity attacker, final E if (attacker.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_LIGHT) && !target.isIlluminated() - && ((game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_MOONLESS) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_PITCH_BLACK))) { + && game.getPlanetaryConditions().getLight().isDarkerThan(Light.FULL_MOON)) { toHit.addModifier(-1, "light specialist"); } @@ -7416,8 +7417,9 @@ public static boolean useSpheroidAtmosphere(Game game, Entity en) { return false; } // aerodyne's will operate like spheroids in vacuum + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (!((IAero) en).isSpheroid() - && !game.getPlanetaryConditions().isVacuum()) { + && !conditions.getAtmosphere().isLighterThan(Atmosphere.THIN)) { return false; } // are we in atmosphere? diff --git a/megamek/src/megamek/common/Dropship.java b/megamek/src/megamek/common/Dropship.java index 62412655b36..11b5c27f85f 100644 --- a/megamek/src/megamek/common/Dropship.java +++ b/megamek/src/megamek/common/Dropship.java @@ -14,6 +14,8 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.DropShipCostCalculator; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.PlanetaryConditions; import java.util.HashMap; import java.util.HashSet; @@ -741,7 +743,9 @@ public void postProcessFacingChange() { */ @Override public boolean canLandVertically() { - return isSpheroid() || game.getPlanetaryConditions().isVacuum(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + return isSpheroid() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); } /** @@ -750,6 +754,9 @@ public boolean canLandVertically() { */ @Override public boolean canTakeOffVertically() { - return (isSpheroid() || game.getPlanetaryConditions().isVacuum()) && (getCurrentThrust() > 2); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + boolean spheroidOrLessThanThin = isSpheroid() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); + return spheroidOrLessThanThin && (getCurrentThrust() > 2); } } diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index d27b18c0c24..8f9e249b4c2 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -31,6 +31,9 @@ import megamek.common.force.Force; import megamek.common.icons.Camouflage; import megamek.common.options.*; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import megamek.common.preference.PreferenceManager; import megamek.common.weapons.*; import megamek.common.weapons.bayweapons.AR10BayWeapon; @@ -2436,13 +2439,13 @@ public int relHeight() { * Convenience method to determine whether this entity is on a ground map with an atmosphere */ public boolean isOnAtmosphericGroundMap() { - return ((getGame().getPlanetaryConditions().getAtmosphere() != PlanetaryConditions.ATMO_VACUUM) || - (getGame().getPlanetaryConditions().getAtmosphere() != PlanetaryConditions.ATMO_TRACE)) && - - (getGame().getBoard().onGround() || + boolean onGroundOrinAtmosphere = getGame().getBoard().onGround() || // doesn't make sense in english, but "atmospheric" map actually // covers maps that are within a planet's gravity well - getGame().getBoard().inAtmosphere()); + getGame().getBoard().inAtmosphere(); + PlanetaryConditions conditions = getGame().getPlanetaryConditions(); + return conditions.getAtmosphere().isDenserThan(Atmosphere.TRACE) + && onGroundOrinAtmosphere; } /** @@ -5419,7 +5422,8 @@ public int getECMRange() { if (type.hasFlag(MiscType.F_EW_EQUIPMENT)) { toReturn = 3; } - if (game.getPlanetaryConditions().hasEMI()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { return toReturn * 2; } return toReturn; @@ -5438,10 +5442,16 @@ public boolean hasBAP() { } public boolean hasBAP(boolean checkECM) { - if (((game != null) && game.getPlanetaryConditions().hasEMI()) - || isShutDown()) { + if (game != null) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { + return false; + } + } + if (isShutDown()) { return false; } + for (Mounted m : getMisc()) { EquipmentType type = m.getType(); if ((type instanceof MiscType) && type.hasFlag(MiscType.F_BAP)) { @@ -5453,7 +5463,8 @@ public boolean hasBAP(boolean checkECM) { || !checkECM || !ComputeECM.isAffectedByAngelECM(this, getPosition(), getPosition()); } - return !checkECM || (game == null) + return !checkECM + || (game == null) || !ComputeECM.isAffectedByECM(this, getPosition(), getPosition()); } } @@ -5488,7 +5499,9 @@ && isConventionalInfantry()) * Entity.NONE if no BAP is active. */ public int getBAPRange() { - if (game.getPlanetaryConditions().hasEMI() || isShutDown()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI() + || isShutDown()) { return Entity.NONE; } // check for Manei Domini implants @@ -7112,77 +7125,82 @@ TargetRoll.AUTOMATIC_FAIL, getCrew().getPiloting() */ public PilotingRollData addConditionBonuses(PilotingRollData roll, EntityMovementType moveType) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (moveType == EntityMovementType.MOVE_SPRINT || moveType == EntityMovementType.MOVE_VTOL_SPRINT) { roll.addModifier(2, "Sprinting"); } - - PlanetaryConditions conditions = game.getPlanetaryConditions(); // check weather conditions for all entities int weatherMod = conditions.getWeatherPilotPenalty(); - if ((weatherMod != 0) && !game.getBoard().inSpace() - && ((null == crew) || !hasAbility(OptionsConstants.UNOFF_ALLWEATHER))) { - roll.addModifier(weatherMod, conditions.getWeatherDisplayableName()); + boolean hasAllWeather = (null == crew) || !hasAbility(OptionsConstants.UNOFF_ALLWEATHER); + if ((weatherMod != 0) + && !game.getBoard().inSpace() + && hasAllWeather) { + roll.addModifier(weatherMod, conditions.getWeather().toString()); } // check wind conditions for all entities int windMod = conditions.getWindPilotPenalty(this); - if ((windMod != 0) && !game.getBoard().inSpace() - && ((null == crew) || !hasAbility(OptionsConstants.UNOFF_ALLWEATHER))) { - roll.addModifier(windMod, conditions.getWindDisplayableName()); + if ((windMod != 0) + && !game.getBoard().inSpace() + && hasAllWeather) { + roll.addModifier(windMod, conditions.getWind().toString()); } if (!hasAbility(OptionsConstants.UNOFF_ALLWEATHER) && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_RAIN)) { - if (conditions.getWeather() == PlanetaryConditions.WE_GUSTING_RAIN) { - if ((this instanceof Mech) || isAirborne() - || (getMovementMode() == EntityMovementMode.WHEELED) - || (getMovementMode() == EntityMovementMode.TRACKED)) { + if (conditions.getWeather().isGustingRain()) { + if ((this instanceof Mech) + || isAirborne() + || getMovementMode().isTrackedOrWheeled()) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.RainSpec")); } - if (isAirborneVTOLorWIGE() || (getMovementMode() == EntityMovementMode.HOVER)) { + if (isAirborneVTOLorWIGE() || getMovementMode().isHover()) { roll.addModifier(-2, Messages.getString("PilotingSPA.EnvSpec.RainSpec")); } } - if ((conditions.getWeather() == PlanetaryConditions.WE_DOWNPOUR) - ||(conditions.getWeather() == PlanetaryConditions.WE_HEAVY_RAIN)) { + if (conditions.getWeather().isHeavyRainOrDownpour()) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.RainSpec")); } } if (!hasAbility(OptionsConstants.UNOFF_ALLWEATHER) && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if (conditions.getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) { + if (conditions.getWeather().isHeavySnow()) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.SnowSpec")); } - if (((conditions.getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES) - || (conditions.getWeather() == PlanetaryConditions.WE_SLEET) - || (conditions.getWeather() == PlanetaryConditions.WE_ICE_STORM)) - && (isAirborneVTOLorWIGE() || isAirborne())) { + boolean airborne = isAirborneVTOLorWIGE() + || isAirborne(); + if (conditions.getWeather().isSnowFlurriesOrSleetOrIceStorm() + && airborne) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.SnowSpec")); } } - if (!hasAbility(OptionsConstants.UNOFF_ALLWEATHER) && (conditions.getWeather() == PlanetaryConditions.WE_NONE) + if (!hasAbility(OptionsConstants.UNOFF_ALLWEATHER) + && conditions.getWeather().isClear() && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND)) { - if ((conditions.getWindStrength() == PlanetaryConditions.WI_MOD_GALE) && isAirborneVTOLorWIGE()) { + if ((conditions.getWind().isModerateGale()) && isAirborneVTOLorWIGE()) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.WindSpec")); } - if (conditions.getWindStrength() == PlanetaryConditions.WI_STRONG_GALE) { - if ((this instanceof Mech) || isAirborne() - || isAirborneVTOLorWIGE() || (getMovementMode() == EntityMovementMode.HOVER)) { + if (conditions.getWind().isStrongGale()) { + if ((this instanceof Mech) + || isAirborne() + || isAirborneVTOLorWIGE() + || getMovementMode().isHover()) { roll.addModifier(-1, Messages.getString("PilotingSPA.EnvSpec.WindSpec")); } } - if (conditions.getWindStrength() == PlanetaryConditions.WI_STORM) { - if ((this instanceof Mech) || isAirborneVTOLorWIGE() - || (getMovementMode() == EntityMovementMode.HOVER)) { + if (conditions.getWind().isStorm()) { + if ((this instanceof Mech) + || isAirborneVTOLorWIGE() + || getMovementMode().isHover()) { roll.addModifier(-2, Messages.getString("PilotingSPA.EnvSpec.WindSpec")); } @@ -7191,11 +7209,11 @@ && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equ } } - if (conditions.getWindStrength() == PlanetaryConditions.WI_TORNADO_F13) { + if (conditions.getWind().isTornadoF1ToF3()) { roll.addModifier(-2, Messages.getString("PilotingSPA.EnvSpec.WindSpec")); } - if (conditions.getWindStrength() == PlanetaryConditions.WI_TORNADO_F4) { + if (conditions.getWind().isTornadoF4()) { roll.addModifier(-3, Messages.getString("PilotingSPA.EnvSpec.WindSpec")); } } @@ -7373,6 +7391,7 @@ public PilotingRollData checkGunningIt (EntityMovementType overallMoveType) { public PilotingRollData checkRecklessMove(MoveStep step, EntityMovementType moveType, Hex curHex, Coords lastPos, Coords curPos, Hex prevHex) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); PilotingRollData roll = getBasePilotingRoll(moveType); // no need to go further if movement is careful if (step.isCareful()) { @@ -7382,13 +7401,12 @@ public PilotingRollData checkRecklessMove(MoveStep step, // this only applies in fog, night conditions, or if a hex along the // 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() <= PlanetaryConditions.BLACK_ICE_TEMP)) { + boolean blackIceCheck = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE) + && conditions.getTemperature() <= PlanetaryConditions.BLACK_ICE_TEMP; + if (conditions.getWeather().isIceStorm() + || blackIceCheck) { isBlackIce = true; } else { isBlackIce = false; @@ -7402,17 +7420,20 @@ public PilotingRollData checkRecklessMove(MoveStep step, // we need to make this check on the first move forward and anytime the // hex is not clear or is a level change - if ((isFoggy || isDark) && !lastPos.equals(curPos) - && lastPos.equals(step.getEntity().getPosition())) { + boolean levelChange = (null != prevHex) + && (prevHex.getLevel() != curHex.getLevel()); + boolean moved = (curHex.movementCost(this) > 0) + || levelChange; + if (conditions.isRecklessConditions() + && !lastPos.equals(curPos) + && lastPos.equals(step.getEntity().getPosition())) { roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); } // FIXME: no perfect solution in the current code to determine if hex is // clear. I will use movement costs - else if ((isFoggy || isDark) - && !lastPos.equals(curPos) - && ((curHex.movementCost(this) > 0) || ((null != prevHex) && (prevHex - .getLevel() != curHex - .getLevel())))) { + else if (conditions.isRecklessConditions() + && !lastPos.equals(curPos) + && moved) { roll.append(new PilotingRollData(getId(), 0, "moving recklessly")); // ice conditions } else if (curHex.containsTerrain(Terrains.ICE)) { @@ -7591,6 +7612,7 @@ public PilotingRollData checkSkid(EntityMovementType moveType, Hex prevHex, EntityMovementType overallMoveType, MoveStep prevStep, MoveStep currStep, int prevFacing, int curFacing, Coords lastPos, Coords curPos, boolean isInfantry, int distance) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); PilotingRollData roll = getBasePilotingRoll(overallMoveType); // If we aren't traveling along a road, apply terrain modifiers @@ -7637,35 +7659,31 @@ public PilotingRollData checkSkid(EntityMovementType moveType, Hex prevHex, // TODO: add check for elevation of pavement, road, // or bridge matches entity elevation. - if ((prevHex != null) && prevHex.containsTerrain(Terrains.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)) { + boolean hoverOrWigeStrongGale = movementMode.isHoverOrWiGE() && conditions.getWind().isStrongerThan(Wind.STRONG_GALE); + boolean iceCheck = !movementMode.isHoverOrWiGE() || hoverOrWigeStrongGale; + boolean runOrSprint = (overallMoveType == EntityMovementType.MOVE_RUN) || (overallMoveType == EntityMovementType.MOVE_SPRINT); + if ((prevHex != null) + && prevHex.containsTerrain(Terrains.ICE) + && iceCheck + && (prevFacing != curFacing) + && !lastPos.equals(curPos)) { roll.append(new PilotingRollData(getId(), getMovementBeforeSkidPSRModifier(distance), "turning on ice")); adjustDifficultTerrainPSRModifier(roll); return roll; - } 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) - || (game.getPlanetaryConditions().getWindStrength() >= PlanetaryConditions.WI_STORM)))) - && (prevFacing != curFacing) && !lastPos.equals(curPos)) { + } else if ((prevHex != null) + && prevHex.containsTerrain(Terrains.BLACK_ICE) + && iceCheck + && (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 - && ((overallMoveType == EntityMovementType.MOVE_RUN) - || (overallMoveType == EntityMovementType.MOVE_SPRINT)) - && (movementMode != EntityMovementMode.HOVER) - && (movementMode != EntityMovementMode.WIGE)) - && (prevFacing != curFacing) && !lastPos.equals(curPos)) { + } else if (prevStepPavement + && runOrSprint + && !movementMode.isHoverOrWiGE() + && (prevFacing != curFacing) + && !lastPos.equals(curPos)) { if (this instanceof Mech) { roll.append(new PilotingRollData(getId(), getMovementBeforeSkidPSRModifier(distance), @@ -8039,6 +8057,7 @@ public boolean usesTurnMode() { */ public PilotingRollData checkTurnModeFailure(EntityMovementType overallMoveType, int straightLineHexes, int mpUsed, Coords currPos) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); PilotingRollData roll = getBasePilotingRoll(overallMoveType); //Turn mode @@ -8073,14 +8092,12 @@ public PilotingRollData checkTurnModeFailure(EntityMovementType overallMoveType, if (currHex.containsTerrain(Terrains.ICE)) { roll.addModifier(movementMode == EntityMovementMode.TRACKED? 1 : 2, "ice"); } - if (game.getPlanetaryConditions().isSleeting() - || game.getPlanetaryConditions().getFog() == PlanetaryConditions.FOG_HEAVY - || game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_RAIN - || game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_GUSTING_RAIN - || game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_DOWNPOUR) { + if (conditions.isSleeting() + || conditions.getFog().isFogHeavy() + || conditions.getWeather().isHeavyRainOrGustingRainOrDownpour()) { roll.addModifier(+1, "fog/rain"); } - if (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) { + if (conditions.getWeather().isHeavySnow()) { roll.addModifier(movementMode == EntityMovementMode.TRACKED? 1 : 2, "snow"); } } diff --git a/megamek/src/megamek/common/EntityMovementMode.java b/megamek/src/megamek/common/EntityMovementMode.java index bdc2ad19c44..29602ef0674 100644 --- a/megamek/src/megamek/common/EntityMovementMode.java +++ b/megamek/src/megamek/common/EntityMovementMode.java @@ -208,6 +208,10 @@ public boolean isTrain() { return isRail() || isMaglev(); } + public boolean isJumpOrLegInfantry() { + return isLegInfantry() || isJumpInfantry(); + } + /** * Whether this movement mode is capable of detonating minefields. */ diff --git a/megamek/src/megamek/common/FighterSquadron.java b/megamek/src/megamek/common/FighterSquadron.java index 201617236a4..de9df11ee0f 100644 --- a/megamek/src/megamek/common/FighterSquadron.java +++ b/megamek/src/megamek/common/FighterSquadron.java @@ -23,6 +23,7 @@ import megamek.common.cost.CostCalculator; import megamek.common.enums.AimingMode; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; import java.util.*; @@ -199,8 +200,9 @@ public PilotingRollData addEntityBonuses(PilotingRollData prd) { } // add in atmospheric effects later - int atmoCond = game.getPlanetaryConditions().getAtmosphere(); - if (!(game.getBoard().inSpace() || atmoCond == PlanetaryConditions.ATMO_VACUUM)) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (!(game.getBoard().inSpace() + || conditions.getAtmosphere().isVacuum())) { prd.addModifier(+2, "Atmospheric operations"); prd.addModifier(-1, "fighter/ small craft"); } diff --git a/megamek/src/megamek/common/Game.java b/megamek/src/megamek/common/Game.java index 60f3f577eb5..df2f4797ae5 100644 --- a/megamek/src/megamek/common/Game.java +++ b/megamek/src/megamek/common/Game.java @@ -28,6 +28,9 @@ import megamek.common.force.Forces; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; +import megamek.common.planetaryconditions.WindDirection; import megamek.common.weapons.AttackHandler; import megamek.server.SmokeCloud; import megamek.server.victory.Victory; @@ -3103,10 +3106,10 @@ public Vector ageFlares() { if (flare.isIgnited()) { flare.turnsToBurn--; if (flare.isDrifting()) { - int str = planetaryConditions.getWindStrength(); - if (str > 0) { - int dir = planetaryConditions.getWindDirection(); - flare.position = flare.position.translated(dir, (str > 1) ? (str - 1) : str); + Wind wind = planetaryConditions.getWind(); + if (!planetaryConditions.getWind().isCalm()) { + WindDirection dir = planetaryConditions.getWindDirection(); + flare.position = flare.position.translated(dir.ordinal(), (wind.ordinal() > 1) ? (wind.ordinal() - 1) : wind.ordinal()); if (getBoard().contains(flare.position)) { r = new Report(5236); r.add(flare.position.getBoardNum()); diff --git a/megamek/src/megamek/common/Infantry.java b/megamek/src/megamek/common/Infantry.java index 3895f938754..e5b1dc45c63 100644 --- a/megamek/src/megamek/common/Infantry.java +++ b/megamek/src/megamek/common/Infantry.java @@ -26,6 +26,8 @@ import megamek.common.enums.AimingMode; import megamek.common.enums.GamePhase; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import megamek.common.verifier.TestInfantry; import megamek.common.weapons.infantry.InfantryWeapon; import org.apache.logging.log4j.LogManager; @@ -375,7 +377,7 @@ && isConventionalInfantry()) { } if ((null != getCrew()) && hasAbility(OptionsConstants.INFANTRY_FOOT_CAV) - && ((getMovementMode().isLegInfantry()) || (getMovementMode().isJumpInfantry()))) { + && getMovementMode().isJumpOrLegInfantry()) { mp += 1; } @@ -385,10 +387,11 @@ && isConventionalInfantry()) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_GUSTING_RAIN) + if (conditions.getWeather().isGustingRain() && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_RAIN)) { if ((mp !=0) || getMovementMode().isMotorizedInfantry()) { mp += 1; @@ -396,20 +399,19 @@ && getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equ } if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if (((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM)) + if (conditions.getWeather().isSnowFlurriesOrIceStorm() && (getOriginalWalkMP() != 0)) { mp += 1; } } if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE)) { - if (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_MOD_GALE) { + && conditions.getWeather().isClear()) { + if (conditions.getWind().isModerateGale()) { mp += 1; } - if ((game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_STRONG_GALE) + if (conditions.getWind().isStrongGale() && ((mp != 0) || getMovementMode().isMotorizedInfantry())) { mp += 1; } @@ -454,17 +456,17 @@ public int getJumpMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int windCond = game.getPlanetaryConditions().getWindStrength(); - if (windCond >= PlanetaryConditions.WI_STRONG_GALE) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getWind().isStrongerThan(Wind.MOD_GALE)) { return 0; - } else if ((windCond == PlanetaryConditions.WI_MOD_GALE) + } else if (conditions.getWind().isModerateGale() && !getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND)) { mp--; } if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM)) { + if (conditions.getWeather().isSnowFlurries() + && conditions.getWeather().isIceStorm()) { mp += 1; } } diff --git a/megamek/src/megamek/common/LandAirMech.java b/megamek/src/megamek/common/LandAirMech.java index 5ce443a2755..d327c15a61b 100644 --- a/megamek/src/megamek/common/LandAirMech.java +++ b/megamek/src/megamek/common/LandAirMech.java @@ -15,6 +15,8 @@ import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; import java.util.*; @@ -349,14 +351,15 @@ public int getCurrentThrust() { } int j = getJumpMP(); if (null != game) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); if (weatherMod != 0) { j = Math.max(j + weatherMod, 0); } if(getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { j += 1; } } @@ -370,12 +373,13 @@ public int getCurrentThrust(MPCalculationSetting mpCalculationSetting) { } int j = getJumpMP(); if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); j = Math.max(j + weatherMod, 0); if(getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { j += 1; } } @@ -726,9 +730,12 @@ public PilotingRollData addEntityBonuses(PilotingRollData roll) { roll.addModifier(vmod, "Velocity greater than 2x safe thrust"); } - int atmoCond = game.getPlanetaryConditions().getAtmosphere(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // add in atmospheric effects later - if (!(game.getBoard().inSpace() || (atmoCond == PlanetaryConditions.ATMO_VACUUM)) && isAirborne()) { + boolean spaceOrVacuum = game.getBoard().inSpace() + || conditions.getAtmosphere().isVacuum(); + if (!spaceOrVacuum + && isAirborne()) { roll.addModifier(+1, "Atmospheric operations"); } @@ -2084,11 +2091,13 @@ public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted) t @Override public boolean canSpot() { if (getConversionMode() == CONV_MODE_FIGHTER) { - return !isAirborne() || hasWorkingMisc(MiscType.F_RECON_CAMERA) - || hasWorkingMisc(MiscType.F_INFRARED_IMAGER) || hasWorkingMisc(MiscType.F_HYPERSPECTRAL_IMAGER) - || (hasWorkingMisc(MiscType.F_HIRES_IMAGER) - && ((game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DAY) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DUSK))); + boolean hiresLighted = hasWorkingMisc(MiscType.F_HIRES_IMAGER) + && game.getPlanetaryConditions().getLight().isLighterThan(Light.FULL_MOON); + return !isAirborne() + || hasWorkingMisc(MiscType.F_RECON_CAMERA) + || hasWorkingMisc(MiscType.F_INFRARED_IMAGER) + || hasWorkingMisc(MiscType.F_HYPERSPECTRAL_IMAGER) + || hiresLighted; } else { return super.canSpot(); } diff --git a/megamek/src/megamek/common/Mech.java b/megamek/src/megamek/common/Mech.java index 745948a9951..db84983c0a5 100644 --- a/megamek/src/megamek/common/Mech.java +++ b/megamek/src/megamek/common/Mech.java @@ -1125,34 +1125,34 @@ public int getPartialWingJumpAtmoBonus(MPCalculationSetting mpCalculationSetting if (!mpCalculationSetting.ignoreWeather && (game != null)) { if ((getWeightClass() <= EntityWeightClass.WEIGHT_MEDIUM)) { switch (game.getPlanetaryConditions().getAtmosphere()) { - case PlanetaryConditions.ATMO_VACUUM: - case PlanetaryConditions.ATMO_TRACE: + case VACUUM: + case TRACE: bonus = 0; break; - case PlanetaryConditions.ATMO_THIN: + case THIN: bonus = 1; break; - case PlanetaryConditions.ATMO_VHIGH: + case VERY_HIGH: bonus = 3; break; - case PlanetaryConditions.ATMO_STANDARD: - case PlanetaryConditions.ATMO_HIGH: + case STANDARD: + case HIGH: default: bonus = 2; break; } } else { switch (game.getPlanetaryConditions().getAtmosphere()) { - case PlanetaryConditions.ATMO_VACUUM: - case PlanetaryConditions.ATMO_TRACE: - case PlanetaryConditions.ATMO_THIN: + case VACUUM: + case TRACE: + case THIN: bonus = 0; break; - case PlanetaryConditions.ATMO_HIGH: - case PlanetaryConditions.ATMO_VHIGH: + case HIGH: + case VERY_HIGH: bonus = 2; break; - case PlanetaryConditions.ATMO_STANDARD: + case STANDARD: default: bonus = 1; } @@ -1191,18 +1191,18 @@ private int getPartialWingHeatBonus() { int bonus; if (game != null) { switch (game.getPlanetaryConditions().getAtmosphere()) { - case PlanetaryConditions.ATMO_VACUUM: + case VACUUM: bonus = 0; break; - case PlanetaryConditions.ATMO_TRACE: + case TRACE: bonus = 1; break; - case PlanetaryConditions.ATMO_THIN: + case THIN: bonus = 2; break; - case PlanetaryConditions.ATMO_STANDARD: - case PlanetaryConditions.ATMO_HIGH: - case PlanetaryConditions.ATMO_VHIGH: + case STANDARD: + case HIGH: + case VERY_HIGH: default: bonus = 3; break; diff --git a/megamek/src/megamek/common/MoveStep.java b/megamek/src/megamek/common/MoveStep.java index 46824cb830e..37356aaf715 100644 --- a/megamek/src/megamek/common/MoveStep.java +++ b/megamek/src/megamek/common/MoveStep.java @@ -22,6 +22,9 @@ import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; import megamek.common.pathfinder.CachedEntityState; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; import java.io.Serializable; @@ -2876,7 +2879,8 @@ && isHullDown()) { } // only walking speed in Tornados - if (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F4) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getWind().isTornadoF4()) { if (getMpUsed() > tmpWalkMP) { movementType = EntityMovementType.MOVE_ILLEGAL; return; @@ -2963,10 +2967,10 @@ protected void calcMovementCostFor(Game game, MoveStep prevStep, CachedEntitySta final boolean isLightSpecialist = en.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_LIGHT); int nSrcEl = srcHex.getLevel() + prevEl; int nDestEl = destHex.getLevel() + elevation; + PlanetaryConditions conditions = game.getPlanetaryConditions(); mp = 1; - // 0 MP infantry units can move 1 hex if (isInfantry && (cachedEntityState.getWalkMP() == 0) @@ -2979,7 +2983,6 @@ && getEntity().getPosition().equals(prev) return; } - boolean applyNightPen = !game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_NO_NIGHT_MOVE_PEN); boolean carefulExempt = @@ -2989,30 +2992,31 @@ && getEntity().getPosition().equals(prev) if (!game.getBoard().inSpace() && isCareful() && applyNightPen && !carefulExempt) { // Fog - switch (game.getPlanetaryConditions().getFog()) { - case PlanetaryConditions.FOG_LIGHT: + switch (conditions.getFog()) { + case FOG_LIGHT: if (!isFogSpecialist) { mp += 1; } break; - case PlanetaryConditions.FOG_HEAVY: + case FOG_HEAVY: if (!isFogSpecialist) { mp += 2; } else { mp += 1; } break; + default: } // Light if (!entity.isNightwalker()) { - switch (game.getPlanetaryConditions().getLight()) { - case PlanetaryConditions.L_FULL_MOON: + switch (conditions.getLight()) { + case FULL_MOON: if (!isLightSpecialist && !en.isUsingSearchlight()) { mp += 1; } break; - case PlanetaryConditions.L_MOONLESS: + case MOONLESS: if (en.isUsingSearchlight()) { break; } @@ -3023,20 +3027,20 @@ && getEntity().getPosition().equals(prev) mp += 1; } break; - case PlanetaryConditions.L_PITCH_BLACK: + case PITCH_BLACK: if (!isLightSpecialist) { mp += 3; } else { mp += 1; } break; + default: } - } else if (game.getPlanetaryConditions().getLight() > PlanetaryConditions.L_DUSK) { + } else if (conditions.getLight().isDarkerThan(Light.DUSK)) { setRunProhibited(true); } } - // VTOLs pay 1 for everything if (moveMode == EntityMovementMode.VTOL) { return; @@ -3049,8 +3053,8 @@ && getEntity().getPosition().equals(prev) // 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() <= PlanetaryConditions.BLACK_ICE_TEMP; - boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + boolean goodTemp = conditions.getTemperature() <= PlanetaryConditions.BLACK_ICE_TEMP; + boolean goodWeather = conditions.getWeather().isIceStorm(); if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { if (destHex.containsTerrain(Terrains.BLACK_ICE)){ @@ -4099,7 +4103,9 @@ boolean useAeroAtmosphere(Game game, Entity en) { return false; } // are we airborne in non-vacuum? - return en.isAirborne() && !game.getPlanetaryConditions().isVacuum(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + return en.isAirborne() + && !conditions.getAtmosphere().isLighterThan(Atmosphere.THIN); } /** diff --git a/megamek/src/megamek/common/PlanetaryConditions.java b/megamek/src/megamek/common/PlanetaryConditions.java deleted file mode 100644 index 3426b8b163e..00000000000 --- a/megamek/src/megamek/common/PlanetaryConditions.java +++ /dev/null @@ -1,1323 +0,0 @@ -/* -* MegaMek - -* Copyright (C) 2005 Ben Mazur (bmazur@sev.org) -* Copyright (C) 2018 The MegaMek Team -* -* This program is free software; you can redistribute it and/or modify it under -* the terms of the GNU General Public License as published by the Free Software -* Foundation; either version 2 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT -* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -* details. -*/ - -package megamek.common; - -import java.io.Serializable; - -import org.apache.logging.log4j.LogManager; - -/** - * This class will hold all the information on planetary conditions and a variety of helper functions - * for those conditions - */ -public class PlanetaryConditions implements Serializable { - - private static final long serialVersionUID = 6838624193286089781L; - - // light - public static final int L_DAY = 0; - public static final int L_DUSK = 1; - public static final int L_FULL_MOON = 2; - public static final int L_MOONLESS = 3; - public static final int L_PITCH_BLACK = 4; - private static final String MSG_NAME_LIGHT_DAYLIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Daylight"); - private static final String MSG_NAME_LIGHT_DUSK = Messages.getString("PlanetaryConditions.DisplayableName.Light.Dusk"); - private static final String MSG_NAME_LIGHT_FULLMOONNIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Full Moon Night"); - private static final String MSG_NAME_LIGHT_MOONLESSNIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Light.Moonless Night"); - private static final String MSG_NAME_LIGHT_PITCHBLACK = Messages.getString("PlanetaryConditions.DisplayableName.Light.Pitch Black"); - private static String[] lightNames = { MSG_NAME_LIGHT_DAYLIGHT, MSG_NAME_LIGHT_DUSK, MSG_NAME_LIGHT_FULLMOONNIGHT, - MSG_NAME_LIGHT_MOONLESSNIGHT, MSG_NAME_LIGHT_PITCHBLACK }; - public static final int L_SIZE = lightNames.length; - private static final String MSG_INDICATOR_LIGHT_DAY = Messages.getString("PlanetaryConditions.Indicator.Light.Day"); - private static final String MSG_INDICATOR_LIGHT_DUSK = Messages.getString("PlanetaryConditions.Indicator.Light.Dusk"); - private static final String MSG_INDICATOR_LIGHT_FULL_MOON = Messages.getString("PlanetaryConditions.Indicator.Light.FullMoon"); - private static final String MSG_INDICATOR_LIGHT_MOONLESS = Messages.getString("PlanetaryConditions.Indicator.Light.Moonless"); - private static final String MSG_INDICATOR_LIGHT_PITCH_BLACK = Messages.getString("PlanetaryConditions.Indicator.Light.PitchBlack"); - private static String[] lightIndicators = { MSG_INDICATOR_LIGHT_DAY, MSG_INDICATOR_LIGHT_DUSK, MSG_INDICATOR_LIGHT_FULL_MOON, - MSG_INDICATOR_LIGHT_MOONLESS, MSG_INDICATOR_LIGHT_PITCH_BLACK }; - - // Weather - public static final int WE_NONE = 0; - public static final int WE_LIGHT_RAIN = 1; - public static final int WE_MOD_RAIN = 2; - public static final int WE_HEAVY_RAIN = 3; - public static final int WE_GUSTING_RAIN = 4; - public static final int WE_DOWNPOUR = 5; - public static final int WE_LIGHT_SNOW = 6; - public static final int WE_MOD_SNOW = 7; - public static final int WE_SNOW_FLURRIES = 8; - public static final int WE_HEAVY_SNOW = 9; - public static final int WE_SLEET = 10; - public static final int WE_ICE_STORM = 11; - public static final int WE_LIGHT_HAIL = 12;// NYI - 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"); - private static final String MSG_NAME_WEATHER_HEAVYGRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Heavy Rain"); - private static final String MSG_NAME_WEATHER_GUSTINGRAIN = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Gusting Rain"); - private static final String MSG_NAME_WEATHER_TORRDOWNPOUR = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Torrential Downpour"); - private static final String MSG_NAME_WEATHER_LIGHTSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Light Snowfall"); - private static final String MSG_NAME_WEATHER_MODSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Moderate Snowfall"); - private static final String MSG_NAME_WEATHER_SNOWFLUFFIES = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Snow Flurries"); - private static final String MSG_NAME_WEATHER_HEAVYSNOWFALL = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Heavy Snowfall"); - private static final String MSG_NAME_WEATHER_SLEET = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Sleet"); - private static final String MSG_NAME_WEATHER_ICESTORM = Messages.getString("PlanetaryConditions.DisplayableName.Weather.Ice Storm"); - private static String[] weatherNames = { MSG_NAME_WEATHER_CLEAR, MSG_NAME_WEATHER_LIGHTRAIN, MSG_NAME_WEATHER_MODRAIN, - MSG_NAME_WEATHER_HEAVYGRAIN, MSG_NAME_WEATHER_GUSTINGRAIN, MSG_NAME_WEATHER_TORRDOWNPOUR, - MSG_NAME_WEATHER_LIGHTSNOWFALL, MSG_NAME_WEATHER_MODSNOWFALL, MSG_NAME_WEATHER_SNOWFLUFFIES, - MSG_NAME_WEATHER_HEAVYSNOWFALL, MSG_NAME_WEATHER_SLEET, MSG_NAME_WEATHER_ICESTORM };//, "Light Hail", "Heavy Hail", "Lightning Storm" }; - public static final int WE_SIZE = weatherNames.length; - private static final String MSG_INDICATOR_WEATHER_NONE = Messages.getString("PlanetaryConditions.Indicator.Weather.None"); - private static final String MSG_INDICATOR_WEATHER_LIGHT_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.LightRain"); - private static final String MSG_INDICATOR_WEATHER_MOD_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.ModRain"); - private static final String MSG_INDICATOR_WEATHER_HEAVY_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.HeavyRain"); - private static final String MSG_INDICATOR_WEATHER_GUSTING_RAIN = Messages.getString("PlanetaryConditions.Indicator.Weather.GustingRain"); - private static final String MSG_INDICATOR_WEATHER_DOWNPOUR = Messages.getString("PlanetaryConditions.Indicator.Weather.Downpour"); - private static final String MSG_INDICATOR_WEATHER_LIGHT_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.LightSnow"); - private static final String MSG_INDICATOR_WEATHER_MOD_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.ModSnow"); - private static final String MSG_INDICATOR_WEATHER_SNOW_FLURRIES = Messages.getString("PlanetaryConditions.Indicator.Weather.SnowFlurries"); - private static final String MSG_INDICATOR_WEATHER_HEAVY_SNOW = Messages.getString("PlanetaryConditions.Indicator.Weather.HeavySnow"); - private static final String MSG_INDICATOR_WEATHER_SLEET = Messages.getString("PlanetaryConditions.Indicator.Weather.Sleet"); - private static final String MSG_INDICATOR_WEATHER_ICE_STORM = Messages.getString("PlanetaryConditions.Indicator.Weather.IceStorm"); - private static String[] weatherIndicators = { MSG_INDICATOR_WEATHER_NONE, MSG_INDICATOR_WEATHER_LIGHT_RAIN, MSG_INDICATOR_WEATHER_MOD_RAIN, - MSG_INDICATOR_WEATHER_HEAVY_RAIN, MSG_INDICATOR_WEATHER_GUSTING_RAIN, MSG_INDICATOR_WEATHER_DOWNPOUR, - MSG_INDICATOR_WEATHER_LIGHT_SNOW, MSG_INDICATOR_WEATHER_MOD_SNOW, MSG_INDICATOR_WEATHER_SNOW_FLURRIES, - MSG_INDICATOR_WEATHER_HEAVY_SNOW, MSG_INDICATOR_WEATHER_SLEET, MSG_INDICATOR_WEATHER_ICE_STORM}; - - // Wind - public static final int WI_NONE = 0; - public static final int WI_LIGHT_GALE = 1; - public static final int WI_MOD_GALE = 2; - public static final int WI_STRONG_GALE = 3; - public static final int WI_STORM = 4; - public static final int WI_TORNADO_F13 = 5; - public static final int WI_TORNADO_F4 = 6; - private static final String MSG_NAME_WINDSTRENGTH_LIGHT_CALM = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Calm"); - private static final String MSG_NAME_WINDSTRENGTH_LIGHT_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Light Gale"); - private static final String MSG_NAME_WINDSTRENGTH_MOD_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Moderate Gale"); - private static final String MSG_NAME_WINDSTRENGTH_STRONG_GALE = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Strong Gale"); - private static final String MSG_NAME_WINDSTRENGTH_STORM = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Storm"); - private static final String MSG_NAME_WINDSTRENGTH_TORNADO_F13 = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Tornado F1-F3"); - private static final String MSG_NAME_WINDSTRENGTH_TORNADO_F4 = Messages.getString("PlanetaryConditions.DisplayableName.WindStrength.Tornado F4"); - private static String[] windNames = { MSG_NAME_WINDSTRENGTH_LIGHT_CALM, MSG_NAME_WINDSTRENGTH_LIGHT_GALE, - MSG_NAME_WINDSTRENGTH_MOD_GALE, MSG_NAME_WINDSTRENGTH_STRONG_GALE, - MSG_NAME_WINDSTRENGTH_STORM, MSG_NAME_WINDSTRENGTH_TORNADO_F13, - MSG_NAME_WINDSTRENGTH_TORNADO_F4 }; - public static final int WI_SIZE = windNames.length; - private static final String MSG_INDICATOR_WINDSTRENGTH_LIGHT_CALM = Messages.getString("PlanetaryConditions.Indicator.WindStrength.Calm"); - private static final String MSG_INDICATOR_WINDSTRENGTH_LIGHT_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.LightGale"); - private static final String MSG_INDICATOR_WINDSTRENGTH_MOD_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.ModGale"); - private static final String MSG_INDICATOR_WINDSTRENGTH_STRONG_GALE = Messages.getString("PlanetaryConditions.Indicator.WindStrength.StrongGale"); - private static final String MSG_INDICATOR_WINDSTRENGTH_STORM = Messages.getString("PlanetaryConditions.Indicator.WindStrength.Storm"); - private static final String MSG_INDICATOR_WINDSTRENGTH_TORNADO_F13 = Messages.getString("PlanetaryConditions.Indicator.WindStrength.TornadoF13"); - private static final String MSG_INDICATOR_WINDSTRENGTH_TORNADO_F4 = Messages.getString("PlanetaryConditions.Indicator.WindStrength.TornadoF4"); - private static String[] windStrengthIndicators = { MSG_INDICATOR_WINDSTRENGTH_LIGHT_CALM, MSG_INDICATOR_WINDSTRENGTH_LIGHT_GALE, - MSG_INDICATOR_WINDSTRENGTH_MOD_GALE, MSG_INDICATOR_WINDSTRENGTH_STRONG_GALE, - MSG_INDICATOR_WINDSTRENGTH_STORM, MSG_INDICATOR_WINDSTRENGTH_TORNADO_F13, - MSG_INDICATOR_WINDSTRENGTH_TORNADO_F4 }; - - // wind direction - private static final String MSG_NAME_WINDDIRECTION_NORTH = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.North"); - private static final String MSG_NAME_WINDDIRECTION_NORTHEAST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Northeast"); - private static final String MSG_NAME_WINDDIRECTION_SOUTHEAST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Southeast"); - private static final String MSG_NAME_WINDDIRECTION_SOUTH = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.South"); - private static final String MSG_NAME_WINDDIRECTION_SOUTHWEST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Southwest"); - private static final String MSG_NAME_WINDDIRECTION_NORTHWEST = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.Northwest"); - private static final String MSG_NAME_WINDDIRECTION_RANDOM = Messages.getString("PlanetaryConditions.DisplayableName.WindDirection.RandomWindDirection"); - // no east and west, because the map uses 6 side hex tiles. east and west are skipped. - private static String[] dirNames = { MSG_NAME_WINDDIRECTION_SOUTH, MSG_NAME_WINDDIRECTION_SOUTHWEST, - MSG_NAME_WINDDIRECTION_NORTHWEST, MSG_NAME_WINDDIRECTION_NORTH, MSG_NAME_WINDDIRECTION_NORTHEAST, - MSG_NAME_WINDDIRECTION_SOUTHEAST, MSG_NAME_WINDDIRECTION_RANDOM }; - public static final int DIR_SIZE = dirNames.length; - public static final int DIR_RANDOM = 6; - private static final String MSG_INDICATOR_WINDDIRECTION_NORTH = Messages.getString("PlanetaryConditions.Indicator.WindDirection.North"); - private static final String MSG_INDICATOR_WINDDIRECTION_NORTHEAST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Northeast"); - private static final String MSG_INDICATOR_WINDDIRECTION_SOUTHEAST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Southeast"); - private static final String MSG_INDICATOR_WINDDIRECTION_SOUTH = Messages.getString("PlanetaryConditions.Indicator.WindDirection.South"); - private static final String MSG_INDICATOR_WINDDIRECTION_SOUTHWEST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Southwest"); - private static final String MSG_INDICATOR_WINDDIRECTION_NORTHWEST = Messages.getString("PlanetaryConditions.Indicator.WindDirection.Northwest"); - private static final String MSG_INDICATOR_WINDDIRECTION_RANDOM = Messages.getString("PlanetaryConditions.Indicator.WindDirection.RandomWindDirection"); - // no east and west, because the map uses 6 side hex tiles. east and west are skipped. - private static String[] windDirectionIndicators = { MSG_INDICATOR_WINDDIRECTION_SOUTH, MSG_INDICATOR_WINDDIRECTION_SOUTHWEST, - MSG_INDICATOR_WINDDIRECTION_NORTHWEST, MSG_INDICATOR_WINDDIRECTION_NORTH, MSG_INDICATOR_WINDDIRECTION_NORTHEAST, - MSG_INDICATOR_WINDDIRECTION_SOUTHEAST, MSG_INDICATOR_WINDDIRECTION_RANDOM }; - - // atmospheric pressure - public static final int ATMO_VACUUM = 0; - public static final int ATMO_TRACE = 1; - public static final int ATMO_THIN = 2; - public static final int ATMO_STANDARD = 3; - public static final int ATMO_HIGH = 4; - public static final int ATMO_VHIGH = 5; - private static final String MSG_NAME_ATMOSPHERE_VACUUM = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Vacuum"); - private static final String MSG_NAME_ATMOSPHERE_TRACE = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Trace"); - private static final String MSG_NAME_ATMOSPHERE_THIN = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Thin"); - private static final String MSG_NAME_ATMOSPHERE_STANDARD = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Standard"); - private static final String MSG_NAME_ATMOSPHERE_HIGH = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.High"); - private static final String MSG_NAME_ATMOSPHERE_VHIGH = Messages.getString("PlanetaryConditions.DisplayableName.Atmosphere.Very High"); - public static String[] atmoNames = { MSG_NAME_ATMOSPHERE_VACUUM, MSG_NAME_ATMOSPHERE_TRACE, MSG_NAME_ATMOSPHERE_THIN, - MSG_NAME_ATMOSPHERE_STANDARD, MSG_NAME_ATMOSPHERE_HIGH, MSG_NAME_ATMOSPHERE_VHIGH }; - public static final int ATMO_SIZE = atmoNames.length; - private static final String MSG_INDICATOR_ATMOSPHERE_VACUUM = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Vacuum"); - private static final String MSG_INDICATOR_ATMOSPHERE_TRACE = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Trace"); - private static final String MSG_INDICATOR_ATMOSPHERE_THIN = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Thin"); - private static final String MSG_INDICATOR_ATMOSPHERE_STANDARD = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.Standard"); - private static final String MSG_INDICATOR_ATMOSPHERE_HIGH = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.High"); - private static final String MSG_INDICATOR_ATMOSPHERE_VHIGH = Messages.getString("PlanetaryConditions.Indicator.Atmosphere.VHigh"); - private static String[] atmosphereIndicators = { MSG_INDICATOR_ATMOSPHERE_VACUUM, MSG_INDICATOR_ATMOSPHERE_TRACE, MSG_INDICATOR_ATMOSPHERE_THIN, - MSG_INDICATOR_ATMOSPHERE_STANDARD ,MSG_INDICATOR_ATMOSPHERE_HIGH ,MSG_INDICATOR_ATMOSPHERE_VHIGH }; - - // fog - public static final int FOG_NONE = 0; - public static final int FOG_LIGHT = 1; - public static final int FOG_HEAVY = 2; - private static final String MSG_NAME_FOG_NONE = Messages.getString("PlanetaryConditions.DisplayableName.Fog.None"); - private static final String MSG_NAME_FOG_LIGHT = Messages.getString("PlanetaryConditions.DisplayableName.Fog.Light Fog"); - private static final String MSG_NAME_FOG_HEAVY = Messages.getString("PlanetaryConditions.DisplayableName.Fog.Heavy Fog"); - private static String[] fogNames = { MSG_NAME_FOG_NONE, MSG_NAME_FOG_LIGHT, MSG_NAME_FOG_HEAVY }; - public static final int FOG_SIZE = fogNames.length; - private static final String MSG_INDICATOR_FOG_NONE = Messages.getString("PlanetaryConditions.Indicator.Fog.None"); - private static final String MSG_INDICATOR_FOG_LIGHT = Messages.getString("PlanetaryConditions.Indicator.Fog.Light"); - private static final String MSG_INDICATOR_FOG_HEAVY = Messages.getString("PlanetaryConditions.Indicator.Fog.Heavy"); - private static String[] fogIndicators = { MSG_INDICATOR_FOG_NONE, MSG_INDICATOR_FOG_LIGHT, MSG_INDICATOR_FOG_HEAVY }; - - // misc - private boolean blowingSand = false; - private static final String MSG_NAME_BLOWINGSAND_TRUE = Messages.getString("PlanetaryConditions.DisplayableName.SandBlowing.true"); - private static final String MSG_NAME_BLOWINGSAND_FALSE = Messages.getString("PlanetaryConditions.DisplayableName.SandBlowing.false"); - private static final String MSG_INDICATOR_BLOWINGSAND_TRUE = Messages.getString("PlanetaryConditions.Indicator.SandBlowing.true"); - private static final String MSG_INDICATOR_BLOWINGSAND_FALSE = Messages.getString("PlanetaryConditions.Indicator.SandBlowing.false"); - - private boolean sandStorm = false; - private boolean runOnce = false; - - // set up the specific conditions - private int lightConditions = L_DAY; - private int weatherConditions = WE_NONE; - private int oldWeatherConditions = WE_NONE; - private int windStrength = WI_NONE; - private int windDirection = DIR_RANDOM; - private boolean shiftWindDirection = false; - private boolean shiftWindStrength = false; - private boolean isSleeting = false; - private int atmosphere = ATMO_STANDARD; - private int fog = FOG_NONE; - private int temperature = 25; - private int oldTemperature = 25; - private static final String MSG_NAME_TEMPERATURE_COLD = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeCold"); - private static final String MSG_NAME_TEMPERATURE_HEAT = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeHeat"); - private static final String MSG_INDICATOR_TEMPERATURE_COLD = Messages.getString("PlanetaryConditions.Indicator.Temperature.ExtremeCold"); - private static final String MSG_INDICATOR_TEMPERATURE_HEAT= Messages.getString("PlanetaryConditions.Indicator.Temperature.ExtremeHeat"); - private static final String MSG_INDICATOR_TEMPERATURE_NORMAL = Messages.getString("PlanetaryConditions.Indicator.Temperature.Normal"); - private float gravity = (float) 1.0; - private static final String MSG_INDICATOR_GRAVITY_LOW= Messages.getString("PlanetaryConditions.Indicator.Gravity.Low"); - private static final String MSG_INDICATOR_GRAVITY_NORMAL = Messages.getString("PlanetaryConditions.Indicator.Gravity.Normal"); - private static final String MSG_INDICATOR_GRAVITY_HIGH = Messages.getString("PlanetaryConditions.Indicator.Gravity.High"); - private boolean emi = false; - private static final String MSG_NAME_EMI_TRUE = Messages.getString("PlanetaryConditions.DisplayableName.EMI.true"); - private static final String MSG_NAME_EMI_FALSE = Messages.getString("PlanetaryConditions.DisplayableName.EMI.false"); - private static final String MSG_INDICATOR_EMI_TRUE = Messages.getString("PlanetaryConditions.Indicator.EMI.true"); - private static final String MSG_INDICATOR_EMI_FALSE = Messages.getString("PlanetaryConditions.Indicator.EMI.false"); - private boolean terrainAffected = true; - private int maxWindStrength = PlanetaryConditions.WI_TORNADO_F4; - private int minWindStrength = PlanetaryConditions.WI_NONE; - - /** - * Constructor - */ - public PlanetaryConditions() { - - } - - /** Creates new PlanetaryConditions that is a duplicate of another */ - public PlanetaryConditions(PlanetaryConditions other) { - lightConditions = other.lightConditions; - weatherConditions = other.weatherConditions; - windStrength = other.windStrength; - windDirection = other.windDirection; - shiftWindDirection = other.shiftWindDirection; - shiftWindStrength = other.shiftWindStrength; - minWindStrength = other.minWindStrength; - maxWindStrength = other.maxWindStrength; - atmosphere = other.atmosphere; - temperature = other.temperature; - gravity = other.gravity; - emi = other.emi; - fog = other.fog; - terrainAffected = other.terrainAffected; - blowingSand = other.blowingSand; - runOnce = other.runOnce; - } - - /** clone! */ - @Override - public Object clone() { - return new PlanetaryConditions(this); - } - - public static String getLightDisplayableName(int type) { - if ((type >= 0) && (type < L_SIZE)) { - return lightNames[type]; - } - throw new IllegalArgumentException("Unknown light condition"); - } - - public static String getWeatherDisplayableName(int type) { - if ((type >= 0) && (type < WE_SIZE)) { - return weatherNames[type]; - } - throw new IllegalArgumentException("Unknown weather condition"); - } - - public static String getTemperatureDisplayableName(int temp) { - if (isExtremeTemperature(temp) && (temp > 0)) { - return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_HEAT); - } else if (isExtremeTemperature(temp) && (temp <= 0)) { - return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_COLD); - } else { - return String.valueOf(temp); - } - } - - public static String getWindDirDisplayableName(int type) { - if ((type >= 0) && (type < DIR_SIZE)) { - return dirNames[type]; - } - throw new IllegalArgumentException("Unknown wind direction"); - } - - public static String getWindDisplayableName(int type) { - if ((type >= 0) && (type < WI_SIZE)) { - return windNames[type]; - } - throw new IllegalArgumentException("Unknown wind condition"); - } - - public static String getAtmosphereDisplayableName(int type) { - if ((type >= 0) && (type < ATMO_SIZE)) { - return atmoNames[type]; - } - throw new IllegalArgumentException("Unknown atmospheric pressure condition"); - } - - public static String getFogDisplayableName(int type) { - if ((type >= 0) && (type < FOG_SIZE)) { - return fogNames[type]; - } - throw new IllegalArgumentException("Unknown fog condition"); - } - - public String getWindDirDisplayableName() { - return getWindDirDisplayableName(windDirection); - } - - public String getLightDisplayableName() { - return getLightDisplayableName(lightConditions); - } - - public String getWeatherDisplayableName() { - return getWeatherDisplayableName(weatherConditions); - } - - public String getWindDisplayableName() { - return getWindDisplayableName(windStrength); - } - - public String getAtmosphereDisplayableName() { - return getAtmosphereDisplayableName(atmosphere); - } - - public String getFogDisplayableName() { - return getFogDisplayableName(fog); - } - - /** - * to-hit penalty for light - */ - public int getLightHitPenalty(boolean isWeapon) { - int penalty = 0; - if (isWeapon) { - if (lightConditions == L_DUSK) { - penalty = 1; - } else if (lightConditions == L_FULL_MOON) { - penalty = 2; - } else if (lightConditions == L_MOONLESS) { - penalty = 3; - } else if (lightConditions == L_PITCH_BLACK) { - penalty = 4; - } - } else { - if (lightConditions == L_MOONLESS) { - penalty = 1; - } else if (lightConditions == L_PITCH_BLACK) { - penalty = 2; - } - } - - 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. - */ - public boolean isSearchlightEffective() { - return (lightConditions == L_FULL_MOON) || (lightConditions == L_MOONLESS) - || (lightConditions == L_PITCH_BLACK); - } - - /** - * Returns true when visual range is increased by a illumination - * in the light condition, i.e. in dusk/dawn, full moon, - * moonless and pitch black night. - */ - public boolean isIlluminationEffective() { - return (lightConditions > L_DAY); - } - - /** Returns true when the given weather is prohibited for temperatures of 30 degC and more. */ - public static boolean requiresLowTemp(int weather) { - return weather == WE_LIGHT_HAIL || - weather == WE_HEAVY_HAIL || - weather == WE_LIGHT_SNOW || - weather == WE_SLEET || - weather == WE_SNOW_FLURRIES || - weather == WE_HEAVY_SNOW || - weather == WE_ICE_STORM || - weather == WE_MOD_SNOW; - } - - /** - * heat bonus to hit for being overheated in darkness - */ - public int getLightHeatBonus(int heat) { - double divisor = 10000.0; - if (lightConditions == L_DUSK) { - divisor = 25.0; - } else if (lightConditions == L_FULL_MOON) { - divisor = 20.0; - } else if (lightConditions == L_MOONLESS) { - divisor = 15.0; - } else if (lightConditions == L_PITCH_BLACK) { - divisor = 10.0; - } - - return (-1 * (int) Math.floor(heat / divisor)); - } - - /** - * to-hit penalty for weather - */ - public int getWeatherHitPenalty(Entity en) { - if (((weatherConditions == WE_LIGHT_RAIN) || (weatherConditions == WE_LIGHT_SNOW)) - && en.isConventionalInfantry()) { - return 1; - } else if ((weatherConditions == WE_MOD_RAIN) || (weatherConditions == WE_HEAVY_RAIN) - || (weatherConditions == WE_MOD_SNOW) || (weatherConditions == WE_HEAVY_SNOW) - || (weatherConditions == WE_SLEET) || (weatherConditions == WE_GUSTING_RAIN) - || (weatherConditions == WE_SNOW_FLURRIES)) { - return 1; - } else if (weatherConditions == WE_DOWNPOUR) { - return 2; - } else { - return 0; - } - } - - /** - * piloting penalty for weather - */ - public int getWeatherPilotPenalty() { - if ((weatherConditions == WE_HEAVY_RAIN) || (weatherConditions == WE_HEAVY_SNOW) - || (weatherConditions == WE_GUSTING_RAIN)) { - return 1; - } else if (weatherConditions == WE_DOWNPOUR) { - return 2; - } else { - return 0; - } - } - - /** - * gravity penalties to PSRs - * According to email from TPTB, you apply a penalty for every 0.5 gravities above or below 1 (rounding up) - */ - public int getGravityPilotPenalty() { - return (int) Math.floor(Math.abs(gravity - 1.0) / 0.5); - } - - /** - * piloting penalty for wind - */ - public int getWindPilotPenalty(Entity en) { - int penalty = 0; - - switch (windStrength) { - case WI_MOD_GALE: - if ((en instanceof VTOL) || (en.getMovementMode() == EntityMovementMode.WIGE)) { - penalty = 1; - } - break; - case WI_STRONG_GALE: - if ((en instanceof VTOL) || (en.getMovementMode() == EntityMovementMode.WIGE) - || (en.getMovementMode() == EntityMovementMode.HOVER)) { - penalty = 2; - } else if ((en instanceof Mech) || (en.isAirborne())) { - penalty = 1; - } - break; - case WI_STORM: - if ((en instanceof VTOL) || (en instanceof Mech) || (en.getMovementMode() == EntityMovementMode.WIGE) - || (en.getMovementMode() == EntityMovementMode.HOVER)) { - penalty = 3; - } else if (en.isAirborne()) { - penalty = 2; - } - break; - case WI_TORNADO_F13: - penalty = 3; - break; - case WI_TORNADO_F4: - penalty = 5; - break; - default: - break; - } - return penalty; - } - - public void determineWind() { - if (windDirection == DIR_RANDOM) { - // Initial wind direction. If using level 2 rules, this - // will be the wind direction for the whole battle. - windDirection = Compute.d6(1) - 1; - } else if (shiftWindDirection) { - // Wind direction changes on a roll of 1 or 6 - switch (Compute.d6()) { - case 1: // rotate clockwise - windDirection = (windDirection + 1) % 6; - break; - case 6: // rotate counter-clockwise - windDirection = (windDirection + 5) % 6; - } - } - if (shiftWindStrength) { - // Wind strength changes on a roll of 1 or 6 - switch (Compute.d6()) { - case 1: // weaker - windStrength = Math.max(minWindStrength, --windStrength); - doSleetCheck(); - doSandStormCheck(); - break; - case 6: // stronger - windStrength = Math.min(maxWindStrength, ++windStrength); - doSleetCheck(); - doSandStormCheck(); - break; - } - } - - // atmospheric pressure may limit wind strength - if ((atmosphere == ATMO_TRACE) && (windStrength > WI_STORM)) { - windStrength = WI_STORM; - } - - if ((atmosphere ==ATMO_THIN) && (windStrength > WI_TORNADO_F13)) { - windStrength = WI_TORNADO_F13; - } - } - - /** - * modifiers for fire ignition - */ - public int getIgniteModifiers() { - int mod = 0; - - if ((weatherConditions == WE_LIGHT_RAIN) || (weatherConditions == WE_MOD_RAIN)) { - mod += 1; - } - - if ((weatherConditions == WE_HEAVY_RAIN) || (weatherConditions == WE_DOWNPOUR) - || (weatherConditions == WE_LIGHT_SNOW) || (weatherConditions == WE_MOD_SNOW) - || (weatherConditions == WE_GUSTING_RAIN) || (weatherConditions == WE_SNOW_FLURRIES)) { - mod += 2; - } - - if ((weatherConditions == WE_HEAVY_SNOW) - || (weatherConditions == WE_LIGHT_HAIL) || (weatherConditions == WE_HEAVY_HAIL)) { - mod += 3; - } - - if ((windStrength == WI_LIGHT_GALE) || (windStrength == WI_MOD_GALE)) { - mod += 2; - } - - if ((windStrength == WI_STRONG_GALE) || (windStrength == WI_STORM) || (weatherConditions == WE_ICE_STORM)) { - mod += 4; - } - - if (getTemperature() > 30) { - mod -= getTemperatureDifference(30,-30); - } else if (getTemperature() < 30) { - mod += getTemperatureDifference(30, -30); - } - - return mod; - } - - /** - * Do a roll for these weather conditions putting out fire - * return boolean - */ - public boolean putOutFire() { - int roll = Compute.d6(2); - switch (weatherConditions) { - case WE_LIGHT_HAIL: - case WE_LIGHT_RAIN: - case WE_LIGHT_SNOW: - roll = roll + 1; - break; - case WE_HEAVY_HAIL: - case WE_MOD_RAIN: - case WE_MOD_SNOW: - case WE_SNOW_FLURRIES: - roll = roll + 2; - break; - case WE_HEAVY_RAIN: - case WE_GUSTING_RAIN: - case WE_HEAVY_SNOW: - roll = roll + 3; - break; - case WE_DOWNPOUR: - roll = roll + 4; - break; - default: - roll = -1; - break; - } - - return roll > 10; - } - - /** - * Returns how much higher or lower than a given range, divided by - * ten, rounded up, the temperature is - */ - public int getTemperatureDifference(int high, int low) { - int i = 0; - //if the low is more than the high, reverse - if (low > high) { - int tempLow = low; - low = high; - high = tempLow; - - } - - if ((getTemperature() >= low) - && (getTemperature() <= high)) { - return i; - } else if (getTemperature() < low) { - do { - i++; - } while ((getTemperature() + (i * 10)) < low); - return i; - } else { - do { - i++; - } while ((getTemperature() - (i * 10)) > high); - } - return i; - } - - /** - * - * @return a String with the reason why you cannot start a fire here - */ - public String cannotStartFire() { - if (atmosphere < ATMO_THIN) { - return "atmosphere too thin"; - } else if (windStrength > WI_STORM) { - return "a tornado"; - } else { - return null; - } - } - - /** - * Planetary conditions on movement, except for gravity - * @param en - the entity in question - * @return an int with the modifier to movement - */ - public int getMovementMods(Entity en) { - int mod = 0; - - // weather mods are calculated based on conditional effects ie extreme temperatures, wind - - // wind mods - switch (windStrength) { - case WI_LIGHT_GALE: - if (!(en instanceof BattleArmor) - && ((en.getMovementMode() == EntityMovementMode.INF_LEG) - || (en.getMovementMode() == EntityMovementMode.INF_JUMP))) { - mod -= 1; - } - break; - case WI_MOD_GALE: - if (en.isConventionalInfantry()) { - mod -= 1; - } - break; - case WI_STRONG_GALE: - case WI_STORM: - if (en instanceof BattleArmor) { - mod -= 1; - } else if (en instanceof Infantry) { - mod -= 2; - } - break; - case WI_TORNADO_F13: - if (en.isAirborne()) { - mod -= 1; - } else { - mod -= 2; - } - break; - } - - // atmospheric pressure mods - switch (atmosphere) { - case ATMO_THIN: - if (en.getMovementMode().isHoverVTOLOrWiGE()) { - mod -= 2; - } - break; - case ATMO_HIGH: - case ATMO_VHIGH: - if (en.getMovementMode().isHoverVTOLOrWiGE()) { - mod += 1; - } - break; - } - - // temperature difference - if ((en instanceof Tank) - || ((en instanceof Infantry) && !((Infantry) en).isXCT()) || (en instanceof Protomech)) { - mod -= Math.abs(getTemperatureDifference(50,-30)); - } - - return mod; - } - - /** - * is the given entity type doomed in these conditions? - * @return a string given the reason for being doomed, null if not doomed - */ - public String whyDoomed(Entity en, Game game) { - if ((atmosphere < ATMO_THIN) && en.doomedInVacuum()) { - return "vacuum"; - } - if ((windStrength == WI_TORNADO_F4) && !(en instanceof Mech)) { - return "tornado"; - } - if ((windStrength == WI_TORNADO_F13) && (en.isConventionalInfantry() - || ((en.getMovementMode() == EntityMovementMode.HOVER) - || (en.getMovementMode() == EntityMovementMode.WIGE) - || (en.getMovementMode() == EntityMovementMode.VTOL)))) { - return "tornado"; - } - if ((windStrength == WI_STORM) && en.isConventionalInfantry()) { - return "storm"; - } - if (isExtremeTemperature() && en.doomedInExtremeTemp() && !Compute.isInBuilding(game, en)) { - return "extreme temperature"; - } - return null; - } - - /** - * visual range based on conditions - * - */ - public int getVisualRange(Entity en, boolean targetIlluminated) { - - boolean Spotlight = false; - - boolean isMechVee = false; - boolean isLargeCraft = false; - boolean isAero = false; - - // Needed for MekWars for Maximum Visual Range. - if (en == null) { - isMechVee = true; - Spotlight = targetIlluminated; - } else { - Spotlight = en.isUsingSearchlight(); - isMechVee = (en instanceof Mech && !en.isAero()) || (en instanceof Tank); - isLargeCraft = (en instanceof Dropship) || (en instanceof Jumpship); - 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; - } - - int lightRange = 0; - - // TO:AR v6 p189 - // Illuminated? Flat 45 hex distance - if (targetIlluminated && (isIlluminationEffective())) { - lightRange = 45; - } else if (Spotlight && (isIlluminationEffective())) { - // Using a searchlight? Flat 30 hex range - if (isMechVee || isAero || isLargeCraft) { - lightRange = 30; - } else { - // Except infantry/handheld, 10 hexes - lightRange = 10; - } - } else if (lightConditions == L_PITCH_BLACK) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - lightRange = 3; - } else if (isAero) { - lightRange = 5; - } else if (isLargeCraft) { - lightRange = 4; - } else { - lightRange = 1; - } - } else if (lightConditions == L_MOONLESS) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - lightRange = 5; - } else if (isAero) { - lightRange = 10; - } else if (isLargeCraft) { - lightRange = 8; - } else { - lightRange = 2; - } - } else if (lightConditions == L_FULL_MOON) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - lightRange = 10; - } else if (isAero) { - lightRange = 20; - } else if (isLargeCraft) { - lightRange = 15; - } else { - lightRange = 5; - } - } else if (lightConditions == L_DUSK) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - lightRange = 15; - } else if (isAero) { - lightRange = 30; - } else if (isLargeCraft) { - lightRange = 20; - } else { - lightRange = 8; - } - } else { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - lightRange = 60; - } else if (isAero) { - lightRange = 120; - } else if (isLargeCraft) { - lightRange = 70; - } else { - lightRange = 30; - } - } - - int otherRange = 0; - - if (fog == FOG_HEAVY) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 5; - } else if (isAero) { - otherRange = 10; - } else if (isLargeCraft) { - otherRange = 8; - } else { - otherRange = 2; - } - } else if ((weatherConditions == WE_HEAVY_HAIL) - || (weatherConditions == WE_SLEET) - || (weatherConditions == WE_HEAVY_SNOW) - || (blowingSand && (windStrength >= WI_MOD_GALE)) - || (weatherConditions == WE_GUSTING_RAIN) - || (weatherConditions == WE_ICE_STORM) - || (weatherConditions == WE_DOWNPOUR)) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 10; - } else if (isAero) { - otherRange = 20; - } else if (isLargeCraft) { - otherRange = 15; - } else { - otherRange = 5; - } - } else if ((weatherConditions == WE_HEAVY_RAIN) - || (weatherConditions == WE_SNOW_FLURRIES) - || (weatherConditions == WE_MOD_SNOW) && (windStrength >= WI_MOD_GALE)) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 15; - } else if (isAero) { - otherRange = 30; - } else if (isLargeCraft) { - otherRange = 20; - } else { - otherRange = 8; - } - } else if ((weatherConditions == WE_MOD_SNOW) - || (weatherConditions == WE_MOD_RAIN)) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 20; - } else if (isAero) { - otherRange = 50; - } else if (isLargeCraft) { - otherRange = 25; - } else { - otherRange = 10; - } - } else if ((weatherConditions == WE_LIGHT_SNOW) - || (weatherConditions == WE_LIGHT_RAIN) - || (weatherConditions == WE_LIGHT_HAIL) - || (fog == FOG_LIGHT)) { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 30; - } else if (isAero) { - otherRange = 60; - } else if (isLargeCraft) { - otherRange = 35; - } else { - otherRange = 15; - } - } else { - if (isMechVee || (isAero && (en.getAltitude() < 2))) { - otherRange = 60; - } else if (isAero) { - otherRange = 120; - } else if (isLargeCraft) { - otherRange = 70; - } else { - otherRange = 30; - } - } - - return Math.min(lightRange, otherRange); - } - - public int getDropRate() { - // atmospheric pressure mods - switch (atmosphere) { - case ATMO_TRACE: - return 8; - case ATMO_THIN: - return 5; - case ATMO_HIGH: - return 2; - case ATMO_VHIGH: - return 1; - default: - return 3; - } - } - - public void setLight(int type) { - lightConditions = type; - } - - - /** @return The time of day lighting conditions (one of PlanetaryConditions.L_*). */ - public int getLight() { - return lightConditions; - } - - public void setWeather(int type) { - if ((type < 0) || (type >= WE_SIZE)) { - LogManager.getLogger().error(String.format("Invalid weather type supplied: %d", type)); - } else { - weatherConditions = type; - } - } - - public int getWeather() { - return weatherConditions; - } - - public void setWindStrength(int type) { - windStrength = type; - } - - public int getWindStrength() { - return windStrength; - } - - public void setWindDirection(int type) { - windDirection = type; - } - - public int getWindDirection() { - return windDirection; - } - - public void setShiftingWindDirection(boolean b) { - shiftWindDirection = b; - } - - public boolean shiftingWindDirection() { - return shiftWindDirection; - } - - public void setShiftingWindStrength(boolean b) { - shiftWindStrength = b; - } - - public boolean shiftingWindStrength() { - return shiftWindStrength; - } - - public void setAtmosphere(int a) { - atmosphere = a; - } - - public int getAtmosphere() { - return atmosphere; - } - - public void setTemperature(int tem) { - temperature = tem; - } - - public int getTemperature() { - return temperature; - } - - public boolean isVacuum() { - return (atmosphere == ATMO_VACUUM) || (atmosphere == ATMO_TRACE); - } - - public static boolean isExtremeTemperature(int temperature) { - return (temperature > 50) || (temperature < -30); - } - - public boolean isExtremeTemperature() { - return isExtremeTemperature(temperature); - } - - public void setGravity(float f) { - gravity = f; - } - - public float getGravity() { - return gravity; - } - - public void setEMI(boolean b) { - emi = b; - } - - public boolean hasEMI() { - return emi; - } - - public int getFog() { - return fog; - } - - public void setFog(int fog) { - this.fog = fog; - } - - public void setTerrainAffected(boolean b) { - terrainAffected = b; - } - - // can weather alter the terrain (add snow, mud, etc.) - public boolean isTerrainAffected() { - return terrainAffected; - } - - public boolean isRecklessConditions() { - return (fog > FOG_NONE) || (lightConditions > L_DUSK); - } - - public int getMaxWindStrength() { - return maxWindStrength; - } - - public void setMaxWindStrength(int strength) { - maxWindStrength = strength; - } - - public int getMinWindStrength() { - return minWindStrength; - } - - public void setMinWindStrength(int strength) { - minWindStrength = strength; - } - - public boolean isSandBlowing() { - return blowingSand; - } - - public void setBlowingSand(boolean b) { - blowingSand = b; - } - - public void alterConditions(PlanetaryConditions conditions) { - lightConditions = conditions.lightConditions; - weatherConditions = conditions.weatherConditions; - windStrength = conditions.windStrength; - windDirection = conditions.windDirection; - shiftWindDirection = conditions.shiftWindDirection; - shiftWindStrength = conditions.shiftWindStrength; - minWindStrength = conditions.minWindStrength; - maxWindStrength = conditions.maxWindStrength; - atmosphere = conditions.atmosphere; - temperature = conditions.temperature; - gravity = conditions.gravity; - emi = conditions.emi; - fog = conditions.fog; - terrainAffected = conditions.terrainAffected; - blowingSand = conditions.blowingSand; - runOnce = conditions.runOnce; - - if (!runOnce) { - setTempFromWeather(); - setWindFromWeather(); - setSandStorm(); - runOnce = true; - } - - } - - private void setTempFromWeather() { - switch (weatherConditions) { - case WE_SLEET: - case WE_LIGHT_SNOW: - temperature = -40; - break; - case WE_MOD_SNOW: - case WE_SNOW_FLURRIES: - case WE_HEAVY_SNOW: - temperature = -50; - break; - case WE_ICE_STORM: - temperature = -60; - break; - } - } - - private void setWindFromWeather() { - switch (weatherConditions) { - case WE_SLEET: - setSleet(true); - break; - case WE_ICE_STORM: - case WE_SNOW_FLURRIES: - windStrength = WI_MOD_GALE; - shiftWindStrength = false; - break; - case WE_GUSTING_RAIN: - windStrength = WI_STRONG_GALE; - shiftWindStrength = false; - break; - } - } - - public boolean isSleeting() { - return isSleeting; - } - - public void setSleet(boolean sleet) { - isSleeting = sleet; - } - - private void doSleetCheck() { - if (isSleeting && windStrength < WI_MOD_GALE) { - setSleet(false); - weatherConditions = WE_NONE; - oldWeatherConditions = WE_SLEET; - oldTemperature = temperature; - temperature = 25; - } - if (isSleeting() && windStrength > WI_MOD_GALE) { - shiftWindStrength = false; - windStrength = WI_MOD_GALE; - } - if ((oldWeatherConditions == WE_SLEET) - && (windStrength == WI_MOD_GALE) - && !isSleeting()) { - setSleet(true); - temperature = oldTemperature; - oldWeatherConditions = WE_NONE; - oldTemperature = 25; - weatherConditions = WE_SLEET; - } - } - - private void setSandStorm() { - if (blowingSand && windStrength < WI_MOD_GALE) { - windStrength = WI_MOD_GALE; - sandStorm = true; - } - } - - private void doSandStormCheck() { - if (blowingSand && windStrength < WI_MOD_GALE) { - sandStorm = blowingSand; - blowingSand = false; - } - if (sandStorm && windStrength > WI_LIGHT_GALE) { - sandStorm = blowingSand; - blowingSand = true; - } - } - - public void setRunOnce(boolean run) { - runOnce = run; - } - - public boolean isExtremeTemperatureHeat() { - return (isExtremeTemperature() && (temperature > 0)); - } - - public boolean isExtremeTemperatureCold() { - return (isExtremeTemperature() && (temperature < 0)); - } - - public String getLightIndicator(int type) { - if ((type >= 0) && (type < L_SIZE)) { - return lightIndicators[type]; - } - throw new IllegalArgumentException("Unknown light Indicator"); - } - - public String getLightIndicator() { - return getLightIndicator(lightConditions); - } - - public String getFogIndicator(int type) { - if ((type >= 0) && (type < FOG_SIZE)) { - return fogIndicators[type]; - } - throw new IllegalArgumentException("Unknown Fog Indicator"); - } - - public String getFogIndicator() { - return getFogIndicator(fog); - } - - public String getWindStrengthIndicator(int type) { - if ((type >= 0) && (type < WI_SIZE)) { - return windStrengthIndicators[type]; - } - throw new IllegalArgumentException("Unknown Wind Strength Indicator"); - } - - public String getWindStrengthIndicator() { - return getWindStrengthIndicator(windStrength); - } - - public String getWindDirectionIndicator(int type) { - if ((type >= 0) && (type < DIR_SIZE)) { - return windDirectionIndicators[type]; - } - throw new IllegalArgumentException("Unknown Wind Direction Indicator"); - } - - public String getWindDirectionIndicator() { - return getWindDirectionIndicator(windDirection); - } - - public String getWeatherIndicator(int type) { - if ((type >= 0) && (type < WE_SIZE)) { - return weatherIndicators[type]; - } - throw new IllegalArgumentException("Unknown Weather Indicator"); - } - - public String getWeatherIndicator() { - return getWeatherIndicator(weatherConditions); - } - - public String getAtmosphereIndicator(int type) { - if ((type >= 0) && (type < ATMO_SIZE)) { - return atmosphereIndicators[type]; - } - throw new IllegalArgumentException("Unknown Atmosphere Indicator"); - } - - public String getAtmosphereIndicator() { - return getAtmosphereIndicator(atmosphere); - } - - public String getGravityIndicator() { - if (gravity > 1.0) { - return MSG_INDICATOR_GRAVITY_HIGH; - } - else if ((gravity < 1.0)) { - return MSG_INDICATOR_GRAVITY_LOW; - } - - return MSG_INDICATOR_GRAVITY_NORMAL; - } - - public String getTemperatureIndicator() { - if (isExtremeTemperatureHeat()) { - return MSG_INDICATOR_TEMPERATURE_HEAT; - } - else if (isExtremeTemperatureCold()) { - return MSG_INDICATOR_TEMPERATURE_COLD; - } - - return MSG_INDICATOR_TEMPERATURE_NORMAL; - } - - public String getEMIIndicator() { - return hasEMI() ? MSG_INDICATOR_EMI_TRUE : MSG_INDICATOR_EMI_FALSE; - } - - public String getSandBlowingIndicator() { - return hasEMI() ? MSG_INDICATOR_BLOWINGSAND_TRUE : MSG_INDICATOR_BLOWINGSAND_FALSE; - } - - public String getEMIDisplayableValue() { - return hasEMI() ? MSG_NAME_EMI_TRUE : MSG_NAME_EMI_FALSE; - } - - public String getSandBlowingDisplayableValue() { - return isSandBlowing() ? MSG_NAME_BLOWINGSAND_TRUE : MSG_NAME_BLOWINGSAND_FALSE; - } - - public static String getEMIDisplayableValue(boolean b) { - return b ? MSG_NAME_EMI_TRUE : MSG_NAME_EMI_FALSE; - } - - public static String getSandBlowingDisplayableValue(boolean b) { - return b ? MSG_NAME_BLOWINGSAND_TRUE : MSG_NAME_BLOWINGSAND_FALSE; - } - -} diff --git a/megamek/src/megamek/common/Protomech.java b/megamek/src/megamek/common/Protomech.java index a77979b913e..7dd67aba45b 100644 --- a/megamek/src/megamek/common/Protomech.java +++ b/megamek/src/megamek/common/Protomech.java @@ -17,6 +17,7 @@ import megamek.common.cost.ProtoMekCostCalculator; import megamek.common.enums.AimingMode; import megamek.common.equipment.ArmorType; +import megamek.common.planetaryconditions.Atmosphere; import megamek.common.preference.PreferenceManager; import org.apache.logging.log4j.LogManager; @@ -421,22 +422,23 @@ public int getJumpMP(MPCalculationSetting mpCalculationSetting) { break; } if (!mpCalculationSetting.ignoreWeather && hasWorkingMisc(MiscType.F_PARTIAL_WING)) { - int atmo = PlanetaryConditions.ATMO_STANDARD; + Atmosphere atmo = Atmosphere.STANDARD; if (game != null) { atmo = game.getPlanetaryConditions().getAtmosphere(); } switch (atmo) { - case PlanetaryConditions.ATMO_VHIGH: - case PlanetaryConditions.ATMO_HIGH: + case VERY_HIGH: + case HIGH: jump += 3; break; - case PlanetaryConditions.ATMO_STANDARD: - case PlanetaryConditions.ATMO_THIN: + case STANDARD: + case THIN: jump += 2; break; - case PlanetaryConditions.ATMO_TRACE: + case TRACE: jump += 1; break; + default: } } diff --git a/megamek/src/megamek/common/QuadMech.java b/megamek/src/megamek/common/QuadMech.java index 94b7d180a4d..83bc3ca0b02 100644 --- a/megamek/src/megamek/common/QuadMech.java +++ b/megamek/src/megamek/common/QuadMech.java @@ -17,8 +17,8 @@ package megamek.common; import megamek.common.enums.AimingMode; -import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; import org.apache.logging.log4j.LogManager; @@ -176,12 +176,13 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if(getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { mp += 1; } } diff --git a/megamek/src/megamek/common/QuadVee.java b/megamek/src/megamek/common/QuadVee.java index a0b607253ef..f7430214f68 100644 --- a/megamek/src/megamek/common/QuadVee.java +++ b/megamek/src/megamek/common/QuadVee.java @@ -20,6 +20,7 @@ import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; /** * Quad Mek that can convert into either tracked or wheeled vehicle mode. @@ -200,12 +201,13 @@ public int getCruiseMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if(getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { mp += 1; } } diff --git a/megamek/src/megamek/common/Sensor.java b/megamek/src/megamek/common/Sensor.java index 58b672ab13f..32712ccf6f8 100644 --- a/megamek/src/megamek/common/Sensor.java +++ b/megamek/src/megamek/common/Sensor.java @@ -17,6 +17,7 @@ import java.util.List; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; /** * This class will hold all the information about a particular active sensor, @@ -180,7 +181,8 @@ public int adjustRange(int range, Game game, LosEffects los) { } if ((type != TYPE_MEK_SEISMIC) && (type != TYPE_VEE_SEISMIC)) { - if (game.getPlanetaryConditions().hasEMI()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { range -= 4; } // TODO: add lightning diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index 39d939d0cbc..e02fac897fc 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -19,6 +19,7 @@ import megamek.common.enums.GamePhase; import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.weapons.flamers.VehicleFlamerWeapon; import megamek.common.weapons.lasers.CLChemicalLaserWeapon; import org.apache.logging.log4j.LogManager; @@ -296,26 +297,23 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM)) { + if (conditions.getWeather().isIceStorm()) { mp += 2; } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SLEET) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_LIGHT_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_MOD_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES)) { + if (conditions.getWeather().isLightSnowOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet()) { mp += 1; } } if(getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { mp += 1; } } diff --git a/megamek/src/megamek/common/TripodMech.java b/megamek/src/megamek/common/TripodMech.java index 858113f4e1d..28b661354ea 100644 --- a/megamek/src/megamek/common/TripodMech.java +++ b/megamek/src/megamek/common/TripodMech.java @@ -21,6 +21,7 @@ import megamek.common.enums.AimingMode; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; import org.apache.logging.log4j.LogManager; @@ -142,7 +143,7 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { //A Mech using tracks has its movement reduced by 1/3 per leg or track destroyed, based //on analogy with biped and quad mechs. - if (getMovementMode() == EntityMovementMode.TRACKED) { + if (getMovementMode().isTracked()) { for (Mounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_TRACKS)) { if (m.isHit() || isLocationBad(m.getLocation())) { @@ -226,11 +227,12 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND) - && (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_NONE) - && (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_TORNADO_F13)) { + && conditions.getWeather().isClear() + && conditions.getWind().isTornadoF1ToF3()) { mp += 1; } } diff --git a/megamek/src/megamek/common/VTOL.java b/megamek/src/megamek/common/VTOL.java index 901188c4b23..e635f8573c2 100644 --- a/megamek/src/megamek/common/VTOL.java +++ b/megamek/src/megamek/common/VTOL.java @@ -16,6 +16,7 @@ import megamek.common.enums.AimingMode; import megamek.common.enums.MPBoosters; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import java.util.ArrayList; import java.util.Arrays; @@ -606,19 +607,16 @@ public int getWalkMP(MPCalculationSetting mpCalculationSetting) { } if (!mpCalculationSetting.ignoreWeather && (null != game)) { - int weatherMod = game.getPlanetaryConditions().getMovementMods(this); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + int weatherMod = conditions.getMovementMods(this); mp = Math.max(mp + weatherMod, 0); if (getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) { + if (conditions.getWeather().isIceStorm()) { mp += 2; } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SLEET) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_LIGHT_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_MOD_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES)) { + if (conditions.getWeather().isLightSnowOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet()) { mp += 1; } } diff --git a/megamek/src/megamek/common/WeatherRestriction.java b/megamek/src/megamek/common/WeatherRestriction.java index c6a864ee25c..6d51ada05af 100644 --- a/megamek/src/megamek/common/WeatherRestriction.java +++ b/megamek/src/megamek/common/WeatherRestriction.java @@ -15,6 +15,8 @@ package megamek.common; +import megamek.common.planetaryconditions.*; + import java.util.HashMap; /** @@ -33,77 +35,77 @@ public class WeatherRestriction { // init fog restrictions fogRestrictions = new HashMap<>(); - WeatherRestriction lightFogRestriction = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - fogRestrictions.put(PlanetaryConditions.FOG_LIGHT, lightFogRestriction); + WeatherRestriction lightFogRestriction = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + fogRestrictions.put(Fog.FOG_LIGHT.ordinal(), lightFogRestriction); - WeatherRestriction heavyFogRestriction = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - fogRestrictions.put(PlanetaryConditions.FOG_HEAVY, heavyFogRestriction); + WeatherRestriction heavyFogRestriction = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + fogRestrictions.put(Fog.FOG_HEAVY.ordinal(), heavyFogRestriction); // init weather restrictions weatherRestrictions = new HashMap<>(); - WeatherRestriction weatherRestrictionLtHail = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_LIGHT_HAIL, weatherRestrictionLtHail); + WeatherRestriction weatherRestrictionLtHail = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.LIGHT_HAIL.ordinal(), weatherRestrictionLtHail); - WeatherRestriction weatherRestrictionHvyHail = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_HEAVY_HAIL, weatherRestrictionHvyHail); + WeatherRestriction weatherRestrictionHvyHail = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.HEAVY_HAIL.ordinal(), weatherRestrictionHvyHail); - WeatherRestriction weatherRestrictionLtRain = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_LIGHT_RAIN, weatherRestrictionLtRain); + WeatherRestriction weatherRestrictionLtRain = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.LIGHT_RAIN.ordinal(), weatherRestrictionLtRain); - WeatherRestriction weatherRestrictionMdRain = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_MOD_RAIN, weatherRestrictionMdRain); + WeatherRestriction weatherRestrictionMdRain = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.MOD_RAIN.ordinal(), weatherRestrictionMdRain); - WeatherRestriction weatherRestrictionLtStorm = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_LIGHTNING_STORM, weatherRestrictionLtStorm); + WeatherRestriction weatherRestrictionLtStorm = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.LIGHTNING_STORM.ordinal(), weatherRestrictionLtStorm); - WeatherRestriction weatherRestrictionHvyRain = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_HEAVY_RAIN, weatherRestrictionHvyRain); + WeatherRestriction weatherRestrictionHvyRain = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.HEAVY_RAIN.ordinal(), weatherRestrictionHvyRain); - WeatherRestriction weatherRestrictionGustRain = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_GUSTING_RAIN, weatherRestrictionGustRain); + WeatherRestriction weatherRestrictionGustRain = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.GUSTING_RAIN.ordinal(), weatherRestrictionGustRain); - WeatherRestriction weatherRestrictionDownpour = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, null); - weatherRestrictions.put(PlanetaryConditions.WE_DOWNPOUR, weatherRestrictionDownpour); + WeatherRestriction weatherRestrictionDownpour = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), null); + weatherRestrictions.put(Weather.DOWNPOUR.ordinal(), weatherRestrictionDownpour); - WeatherRestriction weatherRestrictionLtSnow = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_LIGHT_SNOW, weatherRestrictionLtSnow); + WeatherRestriction weatherRestrictionLtSnow = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.LIGHT_SNOW.ordinal(), weatherRestrictionLtSnow); - WeatherRestriction weatherRestrictionMdSnow = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_MOD_SNOW, weatherRestrictionMdSnow); + WeatherRestriction weatherRestrictionMdSnow = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.MOD_SNOW.ordinal(), weatherRestrictionMdSnow); - WeatherRestriction weatherRestrictionSleet = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_SLEET, weatherRestrictionSleet); + WeatherRestriction weatherRestrictionSleet = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.SLEET.ordinal(), weatherRestrictionSleet); - WeatherRestriction weatherRestrictionFlurry = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_SNOW_FLURRIES, weatherRestrictionFlurry); + WeatherRestriction weatherRestrictionFlurry = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.SNOW_FLURRIES.ordinal(), weatherRestrictionFlurry); - WeatherRestriction weatherRestrictionHvySnow = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_HEAVY_SNOW, weatherRestrictionHvySnow); + WeatherRestriction weatherRestrictionHvySnow = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.HEAVY_SNOW.ordinal(), weatherRestrictionHvySnow); - WeatherRestriction weatherRestrictionIceStorm = new WeatherRestriction(PlanetaryConditions.ATMO_STANDARD, 30); - weatherRestrictions.put(PlanetaryConditions.WE_ICE_STORM, weatherRestrictionIceStorm); + WeatherRestriction weatherRestrictionIceStorm = new WeatherRestriction(Atmosphere.STANDARD.ordinal(), 30); + weatherRestrictions.put(Weather.ICE_STORM.ordinal(), weatherRestrictionIceStorm); // init wind restrictions windRestrictions = new HashMap<>(); - WeatherRestriction weatherRestrictionLtGale = new WeatherRestriction(PlanetaryConditions.ATMO_THIN, null); - windRestrictions.put(PlanetaryConditions.WI_LIGHT_GALE, weatherRestrictionLtGale); + WeatherRestriction weatherRestrictionLtGale = new WeatherRestriction(Atmosphere.THIN.ordinal(), null); + windRestrictions.put(Wind.LIGHT_GALE.ordinal(), weatherRestrictionLtGale); - WeatherRestriction weatherRestrictionMdGale = new WeatherRestriction(PlanetaryConditions.ATMO_TRACE, null); - windRestrictions.put(PlanetaryConditions.WI_MOD_GALE, weatherRestrictionMdGale); + WeatherRestriction weatherRestrictionMdGale = new WeatherRestriction(Atmosphere.TRACE.ordinal(), null); + windRestrictions.put(Wind.MOD_GALE.ordinal(), weatherRestrictionMdGale); - WeatherRestriction weatherRestrictionStGale = new WeatherRestriction(PlanetaryConditions.ATMO_TRACE, null); - windRestrictions.put(PlanetaryConditions.WI_STRONG_GALE, weatherRestrictionStGale); + WeatherRestriction weatherRestrictionStGale = new WeatherRestriction(Atmosphere.TRACE.ordinal(), null); + windRestrictions.put(Wind.STRONG_GALE.ordinal(), weatherRestrictionStGale); - WeatherRestriction weatherRestrictionStorm = new WeatherRestriction(PlanetaryConditions.ATMO_TRACE, null); - windRestrictions.put(PlanetaryConditions.WI_STORM, weatherRestrictionStorm); + WeatherRestriction weatherRestrictionStorm = new WeatherRestriction(Atmosphere.TRACE.ordinal(), null); + windRestrictions.put(Wind.STORM.ordinal(), weatherRestrictionStorm); - WeatherRestriction weatherRestrictionF13 = new WeatherRestriction(PlanetaryConditions.ATMO_TRACE, null); - windRestrictions.put(PlanetaryConditions.WI_TORNADO_F13, weatherRestrictionF13); + WeatherRestriction weatherRestrictionF13 = new WeatherRestriction(Atmosphere.TRACE.ordinal(), null); + windRestrictions.put(Wind.TORNADO_F1_TO_F3.ordinal(), weatherRestrictionF13); - WeatherRestriction weatherRestrictionF4 = new WeatherRestriction(PlanetaryConditions.ATMO_TRACE, null); - windRestrictions.put(PlanetaryConditions.WI_TORNADO_F4, weatherRestrictionF4); + WeatherRestriction weatherRestrictionF4 = new WeatherRestriction(Atmosphere.TRACE.ordinal(), null); + windRestrictions.put(Wind.TORNADO_F4.ordinal(), weatherRestrictionF4); } public WeatherRestriction(Integer minAtmoLevel, Integer maxTemp) { @@ -116,9 +118,9 @@ public WeatherRestriction(Integer minAtmoLevel, Integer maxTemp) { * Currently validates fog, weather (precipitation) and wind strength */ public static boolean IsRestricted(PlanetaryConditions conditions) { - return IsFogRestricted(conditions.getFog(), conditions.getAtmosphere(), conditions.getTemperature()) || - IsWeatherRestricted(conditions.getWeather(), conditions.getAtmosphere(), conditions.getTemperature()) || - IsWindRestricted(conditions.getWindStrength(), conditions.getAtmosphere(), conditions.getTemperature()); + return IsFogRestricted(conditions.getFog().ordinal(), conditions.getAtmosphere().ordinal(), conditions.getTemperature()) || + IsWeatherRestricted(conditions.getWeather().ordinal(), conditions.getAtmosphere().ordinal(), conditions.getTemperature()) || + IsWindRestricted(conditions.getWind().ordinal(), conditions.getAtmosphere().ordinal(), conditions.getTemperature()); } /** diff --git a/megamek/src/megamek/common/actions/AbstractAttackAction.java b/megamek/src/megamek/common/actions/AbstractAttackAction.java index 422387a56da..87420d9ee2a 100644 --- a/megamek/src/megamek/common/actions/AbstractAttackAction.java +++ b/megamek/src/megamek/common/actions/AbstractAttackAction.java @@ -15,11 +15,12 @@ package megamek.common.actions; import megamek.client.Client; -import megamek.client.ui.Messages; import megamek.common.*; import megamek.common.annotations.Nullable; -import megamek.common.enums.IlluminationLevel; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.IlluminationLevel; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; import java.util.Enumeration; @@ -97,8 +98,8 @@ public static ToHitData nightModifiers(Game game, Targetable target, AmmoType at Entity te = (target.getTargetType() == Targetable.TYPE_ENTITY) ? (Entity) target : null; ToHitData toHit = new ToHitData(); - int lightCond = game.getPlanetaryConditions().getLight(); - if (lightCond == PlanetaryConditions.L_DAY) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getLight().isDay()) { // It's the day, so just return return toHit; } @@ -106,8 +107,8 @@ public static ToHitData nightModifiers(Game game, Targetable target, AmmoType at // The base night penalty final IlluminationLevel hexIllumLvl = IlluminationLevel.determineIlluminationLevel(game, target.getPosition()); - int night_modifier = game.getPlanetaryConditions().getLightHitPenalty(isWeapon); - toHit.addModifier(night_modifier, game.getPlanetaryConditions().getLightDisplayableName()); + int night_modifier = conditions.getLightHitPenalty(isWeapon); + toHit.addModifier(night_modifier, conditions.getLight().toString()); boolean illuminated = false; if (te != null) { @@ -130,9 +131,11 @@ public static ToHitData nightModifiers(Game game, Targetable target, AmmoType at // Searchlights reduce the penalty to zero (or 1 for pitch-black) // (except for dusk/dawn) int searchlightMod = Math.min(3, night_modifier); - if ((te != null) && (lightCond > PlanetaryConditions.L_DUSK) - && (te.isUsingSearchlight() || illuminated)) { - if (te.isUsingSearchlight()) { + boolean isUsingSearchlight = (te != null) && te.isUsingSearchlight(); + boolean lighted = isUsingSearchlight || illuminated; + if (conditions.getLight().isDarkerThan(Light.DUSK) + && lighted) { + if (isUsingSearchlight) { toHit.addModifier(-searchlightMod, "target using searchlight"); night_modifier = night_modifier - searchlightMod; } else if (illuminated) { @@ -147,7 +150,7 @@ public static ToHitData nightModifiers(Game game, Targetable target, AmmoType at int fireMod = Math.min(2, night_modifier); toHit.addModifier(-fireMod, "target illuminated by fire"); night_modifier -= fireMod; - } else if ((lightCond > PlanetaryConditions.L_DUSK) && (hexIllumLvl.isSearchlight())) { + } else if ((conditions.getLight().isDarkerThan(Light.DUSK)) && (hexIllumLvl.isSearchlight())) { toHit.addModifier(-searchlightMod, "target illuminated by searchlight"); night_modifier -= searchlightMod; } else if (atype != null) { @@ -198,7 +201,7 @@ public static ToHitData nightModifiers(Game game, Targetable target, AmmoType at // now check for general hit bonuses for heat if ((te != null) && !attacker.isConventionalInfantry()) { - int heatBonus = game.getPlanetaryConditions().getLightHeatBonus(te.heat); + int heatBonus = conditions.getLightHeatBonus(te.heat); if (heatBonus < 0) { toHit.addModifier(heatBonus, "target excess heat at night"); } diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index 3d5899c139c..9596eb0feb3 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -19,17 +19,18 @@ import megamek.common.*; import megamek.common.enums.AimingMode; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import megamek.common.weapons.DiveBombAttack; import megamek.common.weapons.InfantryAttack; import megamek.common.weapons.Weapon; import megamek.common.weapons.artillery.ArtilleryCannonWeapon; import megamek.common.weapons.artillery.ArtilleryWeapon; -import megamek.common.weapons.autocannons.LBXACWeapon; import megamek.common.weapons.battlearmor.CLBALBX; import megamek.common.weapons.bayweapons.*; import megamek.common.weapons.capitalweapons.CapitalMissileWeapon; import megamek.common.weapons.gaussrifles.GaussWeapon; -import megamek.common.weapons.gaussrifles.ISHGaussRifle; import megamek.common.weapons.lasers.ISBombastLaser; import megamek.common.weapons.lasers.VariableSpeedPulseLaserWeapon; import megamek.common.weapons.lrms.LRTWeapon; @@ -1898,15 +1899,18 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta } } + // Ballistic and Missile weapons are subject to wind conditions - int windCond = game.getPlanetaryConditions().getWindStrength(); - if ((windCond == PlanetaryConditions.WI_TORNADO_F13) && wtype.hasFlag(WeaponType.F_MISSILE) + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getWind().isTornadoF1ToF3() && wtype.hasFlag(WeaponType.F_MISSILE) && !game.getBoard().inSpace()) { return Messages.getString("WeaponAttackAction.NoMissileTornado"); } - - if ((windCond == PlanetaryConditions.WI_TORNADO_F4) && !game.getBoard().inSpace() - && (wtype.hasFlag(WeaponType.F_MISSILE) || wtype.hasFlag(WeaponType.F_BALLISTIC))) { + boolean missleOrBallistic = wtype.hasFlag(WeaponType.F_MISSILE) + || wtype.hasFlag(WeaponType.F_BALLISTIC); + if (conditions.getWind().isTornadoF4() + && !game.getBoard().inSpace() + && missleOrBallistic) { return Messages.getString("WeaponAttackAction.F4Tornado"); } @@ -2849,6 +2853,7 @@ public void updateTurnsTilHit(Game game) { */ private static ToHitData compileEnvironmentalToHitMods(Game game, Entity ae, Targetable target, WeaponType wtype, AmmoType atype, ToHitData toHit, boolean isArtilleryIndirect) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (toHit == null) { // Without valid toHit data, the rest of this will fail @@ -2863,51 +2868,53 @@ private static ToHitData compileEnvironmentalToHitMods(Game game, Entity ae, Tar TargetRoll weatherToHitMods = new TargetRoll(); // weather mods (not in space) - int weatherMod = game.getPlanetaryConditions().getWeatherHitPenalty(ae); + int weatherMod = conditions.getWeatherHitPenalty(ae); if ((weatherMod != 0) && !game.getBoard().inSpace()) { - weatherToHitMods.addModifier(weatherMod, game.getPlanetaryConditions().getWeatherDisplayableName()); + weatherToHitMods.addModifier(weatherMod, conditions.getWeather().toString()); } // wind mods (not in space) if (!game.getBoard().inSpace()) { - int windCond = game.getPlanetaryConditions().getWindStrength(); - if (windCond == PlanetaryConditions.WI_MOD_GALE) { + if (conditions.getWind().isModerateGale()) { if (wtype != null && wtype.hasFlag(WeaponType.F_MISSILE)) { - weatherToHitMods.addModifier(1, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(1, conditions.getWind().toString()); } - } else if (windCond == PlanetaryConditions.WI_STRONG_GALE) { + } else if (conditions.getWind().isModerateGale()) { if (wtype != null && wtype.hasFlag(WeaponType.F_BALLISTIC) && wtype.hasFlag(WeaponType.F_DIRECT_FIRE)) { - weatherToHitMods.addModifier(1, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(1, conditions.getWind().toString()); } else if (wtype != null && wtype.hasFlag(WeaponType.F_MISSILE)) { - weatherToHitMods.addModifier(2, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(2, conditions.getWind().toString()); } - } else if (windCond == PlanetaryConditions.WI_STORM) { + } else if (conditions.getWind().isStorm()) { if (wtype != null && wtype.hasFlag(WeaponType.F_BALLISTIC) && wtype.hasFlag(WeaponType.F_DIRECT_FIRE)) { - weatherToHitMods.addModifier(2, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(2, conditions.getWind().toString()); } else if (wtype != null && wtype.hasFlag(WeaponType.F_MISSILE)) { - weatherToHitMods.addModifier(3, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(3, conditions.getWind().toString()); } - } else if (windCond == PlanetaryConditions.WI_TORNADO_F13) { + } else if (conditions.getWind().isTornadoF1ToF3()) { if (wtype != null && wtype.hasFlag(WeaponType.F_ENERGY)) { - weatherToHitMods.addModifier(2, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(2, conditions.getWind().toString()); } else if (wtype != null && wtype.hasFlag(WeaponType.F_BALLISTIC) && wtype.hasFlag(WeaponType.F_DIRECT_FIRE)) { - weatherToHitMods.addModifier(3, PlanetaryConditions.getWindDisplayableName(windCond)); + weatherToHitMods.addModifier(3, conditions.getWind().toString()); } - } else if (windCond == PlanetaryConditions.WI_TORNADO_F4) { - weatherToHitMods.addModifier(3, PlanetaryConditions.getWindDisplayableName(windCond)); + } else if (conditions.getWind().isTornadoF4()) { + weatherToHitMods.addModifier(3, conditions.getWind().toString()); } } // fog mods (not in space) - if (wtype != null && wtype.hasFlag(WeaponType.F_ENERGY) && !game.getBoard().inSpace() - && (game.getPlanetaryConditions().getFog() == PlanetaryConditions.FOG_HEAVY)) { + if (wtype != null + && wtype.hasFlag(WeaponType.F_ENERGY) + && !game.getBoard().inSpace() + && conditions.getFog().isFogHeavy()) { weatherToHitMods.addModifier(1, Messages.getString("WeaponAttackAction.HeavyFog")); } // blowing sand mods - if (wtype != null && wtype.hasFlag(WeaponType.F_ENERGY) && !game.getBoard().inSpace() - && game.getPlanetaryConditions().isSandBlowing() - && (game.getPlanetaryConditions().getWindStrength() > PlanetaryConditions.WI_LIGHT_GALE)) { + if (wtype != null + && wtype.hasFlag(WeaponType.F_ENERGY) + && !game.getBoard().inSpace() + && conditions.isBlowingSandActive()) { weatherToHitMods.addModifier(1, Messages.getString("WeaponAttackAction.BlowingSand")); } @@ -2920,7 +2927,7 @@ private static ToHitData compileEnvironmentalToHitMods(Game game, Entity ae, Tar // gravity mods (not in space) if (!game.getBoard().inSpace()) { - int mod = (int) Math.floor(Math.abs((game.getPlanetaryConditions().getGravity() - 1.0f) / 0.2f)); + int mod = (int) Math.floor(Math.abs((conditions.getGravity() - 1.0f) / 0.2f)); if ((mod != 0) && wtype != null && ((wtype.hasFlag(WeaponType.F_BALLISTIC) && wtype.hasFlag(WeaponType.F_DIRECT_FIRE)) || wtype.hasFlag(WeaponType.F_MISSILE))) { toHit.addModifier(mod, Messages.getString("WeaponAttackAction.Gravity")); @@ -2928,7 +2935,8 @@ private static ToHitData compileEnvironmentalToHitMods(Game game, Entity ae, Tar } // Electro-Magnetic Interference - if (game.getPlanetaryConditions().hasEMI() && !ae.isConventionalInfantry()) { + if (conditions.getEMI().isEMI() + && !ae.isConventionalInfantry()) { toHit.addModifier(2, Messages.getString("WeaponAttackAction.EMI")); } return toHit; @@ -5170,6 +5178,7 @@ public static ToHitData processAttackerQuirks(ToHitData toHit, Entity ae, Target } public static ToHitData processAttackerSPAs(ToHitData toHit, Entity ae, Targetable target, Mounted weapon, Game game){ + PlanetaryConditions conditions = game.getPlanetaryConditions(); // blood stalker SPA if (ae.getBloodStalkerTarget() > Entity.NONE) { @@ -5239,75 +5248,66 @@ public static ToHitData processAttackerSPAs(ToHitData toHit, Entity ae, Targetab // Fog Specialist if (ae.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_FOG) - && wtype.hasFlag(WeaponType.F_ENERGY) && !game.getBoard().inSpace() - && (game.getPlanetaryConditions().getFog() == PlanetaryConditions.FOG_HEAVY)) { + && wtype.hasFlag(WeaponType.F_ENERGY) + && !game.getBoard().inSpace() + && conditions.getFog().isFogHeavy()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.FogSpec")); } // Light Specialist if (ae.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_LIGHT)) { if (!te.isIlluminated() - && ((game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_DUSK) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_FULL_MOON) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_MOONLESS) - || (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_PITCH_BLACK))) { + && conditions.getLight().isDarkerThan(Light.DAY)) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.LightSpec")); } else if (te.isIlluminated() - && (game.getPlanetaryConditions().getLight() == PlanetaryConditions.L_PITCH_BLACK)) { + && conditions.getLight().isPitchBack()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.LightSpec")); } } // Rain Specialist if (ae.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_RAIN)) { - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_LIGHT_RAIN) + if (conditions.getWeather().isLightRain() && ae.isConventionalInfantry()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.RainSpec")); } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_MOD_RAIN) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_RAIN) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_GUSTING_RAIN) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_DOWNPOUR)) { + if (conditions.getWeather().isModerateRainOrHeavyRainOrGustingRainOrDownpour()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.RainSpec")); } } // Snow Specialist if (ae.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_SNOW)) { - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_LIGHT_SNOW) + if (conditions.getWeather().isLightSnow() && ae.isConventionalInfantry()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.SnowSpec")); } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) + if (conditions.getWeather().isIceStorm() && wtype.hasFlag(WeaponType.F_MISSILE)) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.SnowSpec")); } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SLEET) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_MOD_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW)) { + if (conditions.getWeather().isModerateSnowOrHeavySnowOrSnowFlurriesOrSleet()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.SnowSpec")); } } // Wind Specialist if (ae.getCrew().getOptions().stringOption(OptionsConstants.MISC_ENV_SPECIALIST).equals(Crew.ENVSPC_WIND)) { - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WI_MOD_GALE) + if (conditions.getWind().isModerateGale() && wtype.hasFlag(WeaponType.F_MISSILE)) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.SnowSpec")); } - if (wtype.hasFlag(WeaponType.F_MISSILE) && wtype.hasFlag(WeaponType.F_BALLISTIC) - && ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WI_STRONG_GALE) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WI_STORM))) { + if (wtype.hasFlag(WeaponType.F_MISSILE) + && wtype.hasFlag(WeaponType.F_BALLISTIC) + && conditions.getWind().isStrongGaleOrStorm()) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.WindSpec")); } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WI_TORNADO_F13) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WI_TORNADO_F4)) { + if (conditions.getWind().isStrongerThan(Wind.STORM)) { toHit.addModifier(-1, Messages.getString("WeaponAttackAction.WindSpec")); } } diff --git a/megamek/src/megamek/common/pathfinder/DestructionAwareDestinationPathfinder.java b/megamek/src/megamek/common/pathfinder/DestructionAwareDestinationPathfinder.java index e4b6dd56d31..1527deb6a5a 100644 --- a/megamek/src/megamek/common/pathfinder/DestructionAwareDestinationPathfinder.java +++ b/megamek/src/megamek/common/pathfinder/DestructionAwareDestinationPathfinder.java @@ -56,9 +56,10 @@ public BulldozerMovePath findPathToCoords(Entity entity, Set destination // if we're calculating a jump path and the entity has jump mp and can jump, start off with a jump // if we're trying to calc a jump path and the entity does not have jump mp, we're done - if (jump && (startPath.getCachedEntityState().getJumpMPWithTerrain() > 0) && - !entity.isProne() && !entity.isHullDown() && - (entity.getGame().getPlanetaryConditions().getWindStrength() != PlanetaryConditions.WI_TORNADO_F4)) { + if (jump + && (startPath.getCachedEntityState().getJumpMPWithTerrain() > 0) + && !entity.isProne() && !entity.isHullDown() + && !entity.getGame().getPlanetaryConditions().getWind().isTornadoF4()) { startPath.addStep(MoveStepType.START_JUMP); // if we specified a jump path, but can't actually jump } else if (jump) { diff --git a/megamek/src/megamek/common/planetaryconditions/Atmosphere.java b/megamek/src/megamek/common/planetaryconditions/Atmosphere.java new file mode 100644 index 00000000000..56ee088a2d9 --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/Atmosphere.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + + +public enum Atmosphere { + VACUUM("VACUUM", "PlanetaryConditions.DisplayableName.Atmosphere.Vacuum", "\u2726 \u2727 \u2727 \u25AF \u2727 \u2727"), + TRACE("TRACE", "PlanetaryConditions.DisplayableName.Atmosphere.Trace", "\u2726 \u2726 \u2727 \u25AF \u2727 \u2727"), + THIN("THIN", "PlanetaryConditions.DisplayableName.Atmosphere.Thin", "\u2726 \u2726 \u2726 \u25AF \u2727 \u2727"), + STANDARD("STANDARD", "PlanetaryConditions.DisplayableName.Atmosphere.Standard", "\u2726 \u2726 \u2726 \u25AE \u2727 \u2727"), + HIGH("HIGH", "PlanetaryConditions.DisplayableName.Atmosphere.High", "\u2726 \u2726 \u2726 \u25AE \u2726 \u2727"), + VERY_HIGH("VERY_HIGH", "PlanetaryConditions.DisplayableName.Atmosphere.VeryHigh", "\u2726 \u2726 \u2726 \u25AE \u2726 \u2726"); + private final String externalId; + private final String name; + private final String indicator; + + Atmosphere(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isVacuum() { + return this == VACUUM; + } + + public boolean isTrace() { + return this == TRACE; + } + + public boolean isThin() { + return this == THIN; + } + + public boolean isStandard() { + return this == STANDARD; + } + + public boolean isHigh() { + return this == HIGH; + } + + public boolean isVeryHigh() { + return this == VERY_HIGH; + } + + public boolean isTraceOrThin() { + return isTrace() + || isThin(); + } + + public boolean isLighterThan(final Atmosphere atmosphere) { + return compareTo(atmosphere) < 0; + } + + public boolean isDenserThan(final Atmosphere atmosphere) { + return compareTo(atmosphere) > 0; + } + + public static Atmosphere getAtmosphere(int i) { + return Atmosphere.values()[i]; + } + + public static Atmosphere getAtmosphere(String s) { + for (Atmosphere condition : Atmosphere.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return Atmosphere.STANDARD; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/BlowingSand.java b/megamek/src/megamek/common/planetaryconditions/BlowingSand.java new file mode 100644 index 00000000000..c3a13516e51 --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/BlowingSand.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum BlowingSand { + BLOWING_SAND_NONE("BLOWING_SAND_NONE", "PlanetaryConditions.DisplayableName.SandBlowing.false", "\uD83D\uDC41"), + BLOWING_SAND("BLOWING_SAND", "PlanetaryConditions.DisplayableName.SandBlowing.true", "\uD83C\uDF2C"); + private final String externalId; + private final String name; + private final String indicator; + + BlowingSand(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isBlowingSandNone() { + return this == BLOWING_SAND_NONE; + } + + public boolean isBlowingSand() { + return this == BLOWING_SAND; + } + + public static BlowingSand getBlowingSand(int i) { + return BlowingSand.values()[i]; + } + + public static BlowingSand getBlowingSand(String s) { + for (BlowingSand condition : BlowingSand.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return BlowingSand.BLOWING_SAND_NONE; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/EMI.java b/megamek/src/megamek/common/planetaryconditions/EMI.java new file mode 100644 index 00000000000..084844dcddb --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/EMI.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum EMI { + EMI_NONE("EMI_NONE", "PlanetaryConditions.DisplayableName.EMI.false", "\u2312"), + EMI("EMI", "PlanetaryConditions.DisplayableName.EMI.true", "\u2301"); + private final String externalId; + private final String name; + private final String indicator; + + EMI(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isEMINone() { + return this == EMI_NONE; + } + + public boolean isEMI() { + return this == EMI; + } + + public static EMI getEMI(int i) { + return EMI.values()[i]; + } + + public static EMI getEMI(String s) { + for (EMI condition : EMI.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return EMI.EMI_NONE; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/Fog.java b/megamek/src/megamek/common/planetaryconditions/Fog.java new file mode 100644 index 00000000000..4fc54d75fcf --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/Fog.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum Fog { + FOG_NONE("FOG_NONE", "PlanetaryConditions.DisplayableName.Fog.None", "\uD83D\uDC41"), + FOG_LIGHT("FOG_LIGHT", "PlanetaryConditions.DisplayableName.Fog.LightFog", "\u2588 \u2022"), + FOG_HEAVY("FOG_HEAVY", "PlanetaryConditions.DisplayableName.Fog.HeavyFog", "\u2588 \u2588"); + private final String externalId; + private final String name; + private final String indicator; + + Fog(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isFogNone() { + return this == FOG_NONE; + } + + public boolean isFogLight() { + return this == FOG_LIGHT; + } + + public boolean isFogHeavy() { + return this == FOG_HEAVY; + } + + public static Fog getFog(int i) { + return Fog.values()[i]; + } + + public static Fog getFog(String s) { + for (Fog condition : Fog.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return Fog.FOG_NONE; + } +} diff --git a/megamek/src/megamek/common/enums/IlluminationLevel.java b/megamek/src/megamek/common/planetaryconditions/IlluminationLevel.java similarity index 81% rename from megamek/src/megamek/common/enums/IlluminationLevel.java rename to megamek/src/megamek/common/planetaryconditions/IlluminationLevel.java index 02e71cf8369..725cde7f7ab 100644 --- a/megamek/src/megamek/common/enums/IlluminationLevel.java +++ b/megamek/src/megamek/common/planetaryconditions/IlluminationLevel.java @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with MegaMek. If not, see . */ -package megamek.common.enums; +package megamek.common.planetaryconditions; import megamek.client.ui.swing.GUIPreferences; import megamek.common.Coords; @@ -30,12 +30,18 @@ public enum IlluminationLevel { //region Enum Declarations - NONE, - FIRE, - FLARE, - SEARCHLIGHT; + NONE(""), + FIRE("\uD83D\uDD25"), + FLARE("\uD83C\uDF86"), + SEARCHLIGHT("\uD83D\uDD26"); //endregion Enum Declarations + private final String indicator; + + IlluminationLevel(final String indicator) { + this.indicator = indicator; + } + //region Boolean Comparison Methods public boolean isNone() { return this == NONE; @@ -54,6 +60,10 @@ public boolean isSearchlight() { } //endregion Boolean Comparison Methods + public String getIndicator() { + return indicator; + } + /** * @return the level of illumination for a given coords. Different light sources affect how much * the nighttime penalties are reduced. @@ -91,17 +101,4 @@ public static IlluminationLevel determineIlluminationLevel(final Game game, fina return neighbouringFire ? IlluminationLevel.FIRE : IlluminationLevel.NONE; } - - public static String getIlluminationLevelIndicator(final Game game, final Coords coords, final GUIPreferences GUIP) { - switch (IlluminationLevel.determineIlluminationLevel(game, coords)) { - case FIRE: - return DOT_SPACER + guiScaledFontHTML(GUIP.getCautionColor()) + " \uD83D\uDD25" + ""; - case FLARE: - return DOT_SPACER + guiScaledFontHTML(GUIP.getCautionColor()) + " \uD83C\uDF86" + ""; - case SEARCHLIGHT: - return DOT_SPACER + guiScaledFontHTML(GUIP.getCautionColor()) + " \uD83D\uDD26" + ""; - default: - return ""; - } - } } diff --git a/megamek/src/megamek/common/planetaryconditions/Light.java b/megamek/src/megamek/common/planetaryconditions/Light.java new file mode 100644 index 00000000000..ffa45094742 --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/Light.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum Light { + DAY("LIGHT_DAY", "PlanetaryConditions.DisplayableName.Light.Daylight", "\u2600"), + DUSK("LIGHT_DUSK", "PlanetaryConditions.DisplayableName.Light.Dusk", "\u263D \u263C"), + FULL_MOON("LIGHT_FULL_MOON", "PlanetaryConditions.DisplayableName.Light.FullMoonNight", "\u26AB"), + MOONLESS("LIGHT_MOONLESS", "PlanetaryConditions.DisplayableName.Light.MoonlessNight", "\u26AA"), + PITCH_BLACK("LIGHT_PITCH_BLACK", "PlanetaryConditions.DisplayableName.Light.PitchBlack", "\u2588"); + + private final String externalId; + private final String name; + private final String indicator; + + Light(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isDay() { + return this == DAY; + } + + public boolean isDusk() { + return this == DUSK; + } + + public boolean isFullMoon() { + return this == FULL_MOON; + } + + public boolean isMoonless() { + return this == MOONLESS; + } + + public boolean isPitchBack() { + return this == PITCH_BLACK; + } + + public boolean isLighterThan(final Light light) { + return compareTo(light) < 0; + } + + public boolean isDarkerThan(final Light light) { + return compareTo(light) > 0; + } + + public static Light getLight(int i) { + return Light.values()[i]; + } + + public static Light getLight(String s) { + for (Light condition : Light.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return Light.DAY; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/PlanetaryConditions.java b/megamek/src/megamek/common/planetaryconditions/PlanetaryConditions.java new file mode 100644 index 00000000000..f539d56937e --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/PlanetaryConditions.java @@ -0,0 +1,991 @@ +/* +* MegaMek - +* Copyright (C) 2005 Ben Mazur (bmazur@sev.org) +* Copyright (C) 2018 The MegaMek Team +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the GNU General Public License as published by the Free Software +* Foundation; either version 2 of the License, or (at your option) any later +* version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +* details. +*/ + +package megamek.common.planetaryconditions; + +import megamek.common.*; + +import java.io.Serializable; + + +/** + * This class will hold all the information on planetary conditions and a variety of helper functions + * for those conditions + */ +public class PlanetaryConditions implements Serializable { + + private static final long serialVersionUID = 6838624193286089781L; + + // set up the specific conditions + private BlowingSand blowingSand = BlowingSand.BLOWING_SAND_NONE; + private BlowingSand sandStorm = BlowingSand.BLOWING_SAND_NONE; + private EMI emi = EMI.EMI_NONE; + private boolean runOnce = false; + private Light light = Light.DAY; + private Weather weather = Weather.CLEAR; + private Weather oldWeather = Weather.CLEAR; + private Wind wind = Wind.CALM; + private Wind windMin = Wind.CALM; + private Wind windMax = Wind.TORNADO_F4; + private WindDirection windDirection = WindDirection.RANDOM; + private boolean shiftWindDirection = false; + private boolean shiftWindStrength = false; + private boolean isSleeting = false; + private Atmosphere atmosphere = Atmosphere.STANDARD; + private Fog fog = Fog.FOG_NONE; + private int temperature = 25; + private int oldTemperature = 25; + + public static final int BLACK_ICE_TEMP = -30; + private float gravity = (float) 1.0; + private boolean terrainAffected = true; + private static final String MSG_NAME_TEMPERATURE_COLD = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeCold"); + private static final String MSG_NAME_TEMPERATURE_HEAT = Messages.getString("PlanetaryConditions.DisplayableName.Temperature.ExtremeHeat"); + private static final String MSG_INDICATOR_TEMPERATURE_COLD = "\u2744"; + private static final String MSG_INDICATOR_TEMPERATURE_HEAT = "\uD83D\uDD25"; + private static final String MSG_INDICATOR_TEMPERATURE_NORMAL = "\uD83C\uDF21"; + private static final String MSG_INDICATOR_GRAVITY_LOW = "\u2B71"; + private static final String MSG_INDICATOR_GRAVITY_NORMAL = "\u23AF"; + private static final String MSG_INDICATOR_GRAVITY_HIGH = "\u2B73"; + + /** + * Constructor + */ + public PlanetaryConditions() { + + } + + /** Creates new PlanetaryConditions that is a duplicate of another */ + public PlanetaryConditions(PlanetaryConditions other) { + light = other.light; + weather = other.weather; + wind = other.wind; + windMin = other.windMin; + windMax = other.windMax; + windDirection = other.windDirection; + shiftWindDirection = other.shiftWindDirection; + shiftWindStrength = other.shiftWindStrength; + atmosphere = other.atmosphere; + temperature = other.temperature; + gravity = other.gravity; + emi = other.emi; + fog = other.fog; + terrainAffected = other.terrainAffected; + blowingSand = other.blowingSand; + runOnce = other.runOnce; + } + + /** clone! */ + @Override + public Object clone() { + return new PlanetaryConditions(this); + } + + public void alterConditions(PlanetaryConditions conditions) { + light = conditions.light; + weather = conditions.weather; + wind = conditions.wind; + windMin = conditions.windMin; + windMax = conditions.windMax; + windDirection = conditions.windDirection; + shiftWindDirection = conditions.shiftWindDirection; + shiftWindStrength = conditions.shiftWindStrength; + atmosphere = conditions.atmosphere; + temperature = conditions.temperature; + gravity = conditions.gravity; + emi = conditions.emi; + fog = conditions.fog; + terrainAffected = conditions.terrainAffected; + blowingSand = conditions.blowingSand; + runOnce = conditions.runOnce; + + if (!runOnce) { + setTempFromWeather(); + setWindFromWeather(); + setSandStorm(); + runOnce = true; + } + } + + public void setLight(Light light) { + this.light = light; + } + + /** @return The time of day lighting conditions (one of PlanetaryConditions.L_*). */ + public Light getLight() { + return light; + } + + public void setWeather(Weather weather) { + this.weather = weather; + } + + public Weather getWeather() { + return weather; + } + + public void setWind(Wind wind) { + this.wind = wind; + } + + public Wind getWind() { + return wind; + } + + public void setWindMin(Wind windMin) { + this.windMin = windMin; + } + + public Wind getWindMin() { + return windMin; + } + + public void setWindMax(Wind windMax) { + this.windMax = windMax; + } + + public Wind getWindMax() { + return windMax; + } + + public void setWindDirection(WindDirection windDirection) { + this.windDirection = windDirection; + } + + public WindDirection getWindDirection() { + return windDirection; + } + + public void setAtmosphere(Atmosphere atmosphere) { + this.atmosphere = atmosphere; + } + + public Atmosphere getAtmosphere() { + return atmosphere; + } + + public Fog getFog() { + return fog; + } + + public void setFog(Fog fog) { + this.fog = fog; + } + + public boolean isFog() { + return !fog.isFogNone(); + } + + public BlowingSand getBlowingSand() { + return blowingSand; + } + + public void setBlowingSand(BlowingSand blowingSand) { + this.blowingSand = blowingSand; + } + + public boolean isBlowingSand() { + return blowingSand.isBlowingSand(); + } + + public void setEMI(EMI emi) { + this.emi = emi; + } + + public EMI getEMI() { + return emi; + } + + public boolean isEMI() { + return emi.isEMI(); + } + + public static String getTemperatureDisplayableName(int temp) { + if (isExtremeTemperature(temp) + && (temp > 0)) { + return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_HEAT); + } else if (isExtremeTemperature(temp) + && (temp <= 0)) { + return String.format("%d (%s)", temp, MSG_NAME_TEMPERATURE_COLD); + } else { + return String.valueOf(temp); + } + } + + /** + * to-hit penalty for light + */ + public int getLightHitPenalty(boolean isWeapon) { + int penalty = 0; + if (isWeapon) { + if (getLight().isDusk()) { + penalty = 1; + } else if (getLight().isFullMoon()) { + penalty = 2; + } else if (getLight().isMoonless()) { + penalty = 3; + } else if (getLight().isPitchBack()) { + penalty = 4; + } + } else { + if (getLight().isMoonless()) { + penalty = 1; + } else if (getLight().isPitchBack()) { + penalty = 2; + } + } + + return penalty; + } + + /** + * heat bonus to hit for being overheated in darkness + */ + public int getLightHeatBonus(int heat) { + double divisor = 10000.0; + if (getLight().isDusk()) { + divisor = 25.0; + } else if (getLight().isFullMoon()) { + divisor = 20.0; + } else if (getLight().isMoonless()) { + divisor = 15.0; + } else if (getLight().isPitchBack()) { + divisor = 10.0; + } + + return (-1 * (int) Math.floor(heat / divisor)); + } + + /** + * to-hit penalty for weather + */ + public int getWeatherHitPenalty(Entity en) { + if (getWeather().isLightRainOrLightSnow() + && en.isConventionalInfantry()) { + return 1; + } else if (getWeather().isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet()) { + return 1; + } else if(getWeather().isDownpour()) { + return 2; + } else { + return 0; + } + } + + /** + * piloting penalty for weather + */ + public int getWeatherPilotPenalty() { + if (getWeather().isHeavyRainOrGustingRainOrHeavySnow()) { + return 1; + } else if (getWeather().isDownpour()) { + return 2; + } else { + return 0; + } + } + + /** + * gravity penalties to PSRs + * According to email from TPTB, you apply a penalty for every 0.5 gravities above or below 1 (rounding up) + */ + public int getGravityPilotPenalty() { + return (int) Math.floor(Math.abs(gravity - 1.0) / 0.5); + } + + /** + * piloting penalty for wind + */ + public int getWindPilotPenalty(Entity en) { + int penalty = 0; + + switch (wind) { + case MOD_GALE: + if ((en instanceof VTOL) + || en.getMovementMode().isWiGE()) { + penalty = 1; + } + break; + case STRONG_GALE: + if ((en instanceof VTOL) + || en.getMovementMode().isHoverOrWiGE()) { + penalty = 2; + } else if ((en instanceof Mech) + || (en.isAirborne())) { + penalty = 1; + } + break; + case STORM: + if ((en instanceof VTOL) + || (en instanceof Mech) + || en.getMovementMode().isHoverOrWiGE()) { + penalty = 3; + } else if (en.isAirborne()) { + penalty = 2; + } + break; + case TORNADO_F1_TO_F3: + penalty = 3; + break; + case TORNADO_F4: + penalty = 5; + break; + default: + break; + } + return penalty; + } + + public void determineWind() { + if (getWindDirection().isRandomWindDirection()) { + // Initial wind direction. If using level 2 rules, this + // will be the wind direction for the whole battle. + windDirection = WindDirection.getWindDirection(Compute.d6(1) - 1); + } else if (shiftWindDirection) { + // Wind direction changes on a roll of 1 or 6 + switch (Compute.d6()) { + case 1: // rotate clockwise + windDirection = windDirection.rotateClockwise(); + break; + case 6: // rotate counter-clockwise + windDirection = windDirection.rotateCounterClockwise(); + } + } + if (shiftWindStrength) { + // Wind strength changes on a roll of 1 or 6 + switch (Compute.d6()) { + case 1: // weaker + wind = wind.lowerWind(); + doSleetCheck(); + doSandStormCheck(); + break; + case 6: // stronger + wind = wind.raiseWind(); + doSleetCheck(); + doSandStormCheck(); + break; + } + } + + // atmospheric pressure may limit wind strength + if (getAtmosphere().isTrace() + && getWind().isStrongerThan(Wind.STORM)) { + wind = Wind.STORM; + } + + if (getAtmosphere().isThin() + && (getWind().isTornadoF4())) { + wind = Wind.TORNADO_F1_TO_F3; + } + } + + /** + * modifiers for fire ignition + */ + public int getIgniteModifiers() { + int mod = 0; + + if (getWeather().isLightRainOrModerateRain() ) { + mod += 1; + } + + if (getWeather().isHeavyRainOrGustingRainOrDownpourOrLightSnowOrModerateSnowOrSnowFlurries()) { + mod += 2; + } + + if (getWeather().isHeavySnowOrLightHailOrHeaveHail() ) { + mod += 3; + } + + if (getWind().isLightGaleOrModerateGale()) { + mod += 2; + } + + if (getWind().isStrongGaleOrStorm() + || getWeather().isIceStorm()) { + mod += 4; + } + + if (getTemperature() > 30) { + mod -= getTemperatureDifference(30,-30); + } else if (getTemperature() < 30) { + mod += getTemperatureDifference(30, -30); + } + + return mod; + } + + /** + * Do a roll for these weather conditions putting out fire + * return boolean + */ + public boolean putOutFire() { + int roll = Compute.d6(2); + switch (weather) { + case LIGHT_HAIL: + case LIGHT_RAIN: + case LIGHT_SNOW: + roll = roll + 1; + break; + case HEAVY_HAIL: + case MOD_RAIN: + case MOD_SNOW: + case SNOW_FLURRIES: + roll = roll + 2; + break; + case HEAVY_RAIN: + case GUSTING_RAIN: + case HEAVY_SNOW: + roll = roll + 3; + break; + case DOWNPOUR: + roll = roll + 4; + break; + default: + roll = -1; + break; + } + + return roll > 10; + } + + /** + * Returns how much higher or lower than a given range, divided by + * ten, rounded up, the temperature is + */ + public int getTemperatureDifference(int high, int low) { + int i = 0; + //if the low is more than the high, reverse + if (low > high) { + int tempLow = low; + low = high; + high = tempLow; + + } + + if ((getTemperature() >= low) + && (getTemperature() <= high)) { + return i; + } else if (getTemperature() < low) { + do { + i++; + } while ((getTemperature() + (i * 10)) < low); + return i; + } else { + do { + i++; + } while ((getTemperature() - (i * 10)) > high); + } + return i; + } + + /** + * + * @return a String with the reason why you cannot start a fire here + */ + public String cannotStartFire() { + if (getAtmosphere().isLighterThan(Atmosphere.THIN)) { + return "atmosphere too thin"; + } else if (getWind().isStrongerThan(Wind.STORM)) { + return "a tornado"; + } else { + return null; + } + } + + /** + * Planetary conditions on movement, except for gravity + * @param en - the entity in question + * @return an int with the modifier to movement + */ + public int getMovementMods(Entity en) { + int mod = 0; + + // weather mods are calculated based on conditional effects ie extreme temperatures, wind + + // wind mods + switch (wind) { + case LIGHT_GALE: + if (!(en instanceof BattleArmor) + && en.getMovementMode().isJumpOrLegInfantry()) { + mod -= 1; + } + break; + case MOD_GALE: + if (en.isConventionalInfantry()) { + mod -= 1; + } + break; + case STRONG_GALE: + case STORM: + if (en instanceof BattleArmor) { + mod -= 1; + } else if (en instanceof Infantry) { + mod -= 2; + } + break; + case TORNADO_F1_TO_F3: + if (en.isAirborne()) { + mod -= 1; + } else { + mod -= 2; + } + break; + default: + } + + // atmospheric pressure mods + switch (atmosphere) { + case THIN: + if (en.getMovementMode().isHoverVTOLOrWiGE()) { + mod -= 2; + } + break; + case HIGH: + case VERY_HIGH: + if (en.getMovementMode().isHoverVTOLOrWiGE()) { + mod += 1; + } + break; + default: + } + + // temperature difference + boolean InfantryNotXCT = (en instanceof Infantry) + && !((Infantry) en).isXCT(); + if ((en instanceof Tank) + || InfantryNotXCT + || (en instanceof Protomech)) { + mod -= Math.abs(getTemperatureDifference(50,-30)); + } + + return mod; + } + + /** + * is the given entity type doomed in these conditions? + * @return a string given the reason for being doomed, null if not doomed + */ + public String whyDoomed(Entity en, Game game) { + if (getAtmosphere().isLighterThan(Atmosphere.THIN) + && en.doomedInVacuum()) { + return "vacuum"; + } + if (getWind().isTornadoF4() + && !(en instanceof Mech)) { + return "tornado"; + } + boolean doomF1ToF3Types = en.isConventionalInfantry() + || en.getMovementMode().isHoverVTOLOrWiGE(); + if (getWind().isTornadoF1ToF3() + && doomF1ToF3Types) { + return "tornado"; + } + if (getWind().isStorm() + && en.isConventionalInfantry()) { + return "storm"; + } + if (isExtremeTemperature() + && en.doomedInExtremeTemp() + && !Compute.isInBuilding(game, en)) { + return "extreme temperature"; + } + return null; + } + + public boolean isBlowingSandActive() { + return getBlowingSand().isBlowingSand() + && getWind().isStrongerThan(Wind.LIGHT_GALE); + } + + /** + * visual range based on conditions + * + */ + public int getVisualRange(Entity en, boolean targetIlluminated) { + + boolean Spotlight = false; + + boolean isMechOrVee = false; + boolean isLargeCraft = false; + boolean isAero = false; + + // Needed for MekWars for Maximum Visual Range. + if (en == null) { + isMechOrVee = true; + Spotlight = targetIlluminated; + } else { + Spotlight = en.isUsingSearchlight(); + isMechOrVee = (en instanceof Mech && !en.isAero()) + || (en instanceof Tank); + isLargeCraft = (en instanceof Dropship) + || (en instanceof Jumpship); + 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; + } + + int lightRange = 0; + + // TO:AR v6 p189 + // Illuminated? Flat 45 hex distance + boolean isLowAltitudeAero = (isAero + && (en.getAltitude() < 2)); + if (targetIlluminated + && (getLight().isDarkerThan(Light.DAY))) { + lightRange = 45; + } else if (Spotlight + && (getLight().isDarkerThan(Light.DAY))) { + // Using a searchlight? Flat 30 hex range + if (isMechOrVee || isAero || isLargeCraft) { + lightRange = 30; + } else { + // Except infantry/handheld, 10 hexes + lightRange = 10; + } + } else if (getLight().isPitchBack()) { + if (isMechOrVee || isLowAltitudeAero) { + lightRange = 3; + } else if (isAero) { + lightRange = 5; + } else if (isLargeCraft) { + lightRange = 4; + } else { + lightRange = 1; + } + } else if (getLight().isMoonless()) { + if (isMechOrVee || isLowAltitudeAero) { + lightRange = 5; + } else if (isAero) { + lightRange = 10; + } else if (isLargeCraft) { + lightRange = 8; + } else { + lightRange = 2; + } + } else if (getLight().isFullMoon()) { + if (isMechOrVee || isLowAltitudeAero) { + lightRange = 10; + } else if (isAero) { + lightRange = 20; + } else if (isLargeCraft) { + lightRange = 15; + } else { + lightRange = 5; + } + } else if (getLight().isDusk()) { + if (isMechOrVee || isLowAltitudeAero) { + lightRange = 15; + } else if (isAero) { + lightRange = 30; + } else if (isLargeCraft) { + lightRange = 20; + } else { + lightRange = 8; + } + } else { + if (isMechOrVee || isLowAltitudeAero) { + lightRange = 60; + } else if (isAero) { + lightRange = 120; + } else if (isLargeCraft) { + lightRange = 70; + } else { + lightRange = 30; + } + } + + int otherRange = 0; + + if (getFog().isFogHeavy()) { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 5; + } else if (isAero) { + otherRange = 10; + } else if (isLargeCraft) { + otherRange = 8; + } else { + otherRange = 2; + } + } else if (isBlowingSandActive() + || getWeather().isGustingRainOrDownpourOrHeavySnowOrIceStormOrSleetOrHeavyHail()) { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 10; + } else if (isAero) { + otherRange = 20; + } else if (isLargeCraft) { + otherRange = 15; + } else { + otherRange = 5; + } + } else if (getWeather().isHeavyRainOrModerateSnowOrSnowFlurries() + && getWind().isStrongerThan(Wind.LIGHT_GALE)) { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 15; + } else if (isAero) { + otherRange = 30; + } else if (isLargeCraft) { + otherRange = 20; + } else { + otherRange = 8; + } + } else if (getWeather().isModerateRainOrModerateSnow()) { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 20; + } else if (isAero) { + otherRange = 50; + } else if (isLargeCraft) { + otherRange = 25; + } else { + otherRange = 10; + } + } else if (getWeather().isLightRainOrLightSnowOrLightHail() + || getFog().isFogLight()) { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 30; + } else if (isAero) { + otherRange = 60; + } else if (isLargeCraft) { + otherRange = 35; + } else { + otherRange = 15; + } + } else { + if (isMechOrVee || isLowAltitudeAero) { + otherRange = 60; + } else if (isAero) { + otherRange = 120; + } else if (isLargeCraft) { + otherRange = 70; + } else { + otherRange = 30; + } + } + + return Math.min(lightRange, otherRange); + } + + public int getDropRate() { + // atmospheric pressure mods + switch (atmosphere) { + case TRACE: + return 8; + case THIN: + return 5; + case HIGH: + return 2; + case VERY_HIGH: + return 1; + default: + return 3; + } + } + + public void setShiftingWindDirection(boolean b) { + shiftWindDirection = b; + } + + public boolean shiftingWindDirection() { + return shiftWindDirection; + } + + public void setShiftingWindStrength(boolean b) { + shiftWindStrength = b; + } + + public boolean shiftingWindStrength() { + return shiftWindStrength; + } + + public void setTemperature(int tem) { + temperature = tem; + } + + public int getTemperature() { + return temperature; + } + + + public static boolean isExtremeTemperature(int temperature) { + return (temperature > 50) || (temperature < -30); + } + + public boolean isExtremeTemperature() { + return isExtremeTemperature(temperature); + } + + public void setGravity(float f) { + gravity = f; + } + + public float getGravity() { + return gravity; + } + + public void setTerrainAffected(boolean b) { + terrainAffected = b; + } + + // can weather alter the terrain (add snow, mud, etc.) + public boolean isTerrainAffected() { + return terrainAffected; + } + + public boolean isRecklessConditions() { + return !getFog().isFogNone() + || getLight().isDarkerThan(Light.DUSK); + } + + public static int setTempFromWeather(Weather weather, int temperature) { + switch (weather) { + case SLEET: + case LIGHT_SNOW: + case LIGHT_HAIL: + case HEAVY_HAIL: + return -40; + case MOD_SNOW: + case SNOW_FLURRIES: + case HEAVY_SNOW: + return -50; + case ICE_STORM: + return -60; + default: + return temperature; + } + } + + private void setTempFromWeather() { + temperature = setTempFromWeather(weather, temperature); + } + + public static Wind setWindFromWeather(Weather weather, Wind wind) { + switch (weather) { + case ICE_STORM: + case SNOW_FLURRIES: + return Wind.MOD_GALE; + case GUSTING_RAIN: + return Wind.STRONG_GALE; + default: + return wind; + } + } + + private void setWindFromWeather() { + wind = setWindFromWeather(weather, wind); + + switch (weather) { + case SLEET: + setSleet(true); + break; + case SNOW_FLURRIES: + case GUSTING_RAIN: + shiftWindStrength = false; + break; + default: + } + } + + public boolean isSleeting() { + return isSleeting; + } + + public void setSleet(boolean sleet) { + isSleeting = sleet; + } + + private void doSleetCheck() { + if (isSleeting + && getWind().isWeakerThan(Wind.MOD_GALE)) { + setSleet(false); + weather = Weather.CLEAR; + oldWeather = Weather.SLEET; + oldTemperature = temperature; + temperature = 25; + } + if (isSleeting() + && getWind().isStrongerThan(Wind.MOD_GALE)) { + shiftWindStrength = false; + wind = Wind.MOD_GALE; + } + if (oldWeather.isSleet() + && getWind().isModerateGale() + && !isSleeting()) { + setSleet(true); + temperature = oldTemperature; + oldWeather = Weather.CLEAR; + oldTemperature = 25; + weather = Weather.SLEET; + } + } + + public static Wind setWindFromBlowingSand(BlowingSand blowingSand, Wind wind) { + if (blowingSand.isBlowingSand() + && wind.isWeakerThan(Wind.MOD_GALE)) { + return Wind.MOD_GALE; + } + return wind; + } + + private void setSandStorm() { + wind = setWindFromBlowingSand(blowingSand, wind); + sandStorm = BlowingSand.BLOWING_SAND; + } + + private void doSandStormCheck() { + if (isBlowingSand() + && getWind().isWeakerThan(Wind.MOD_GALE)) { + sandStorm = blowingSand; + blowingSand = BlowingSand.BLOWING_SAND_NONE; + } + if (sandStorm.isBlowingSand() + && getWind().isStrongerThan(Wind.LIGHT_GALE)) { + sandStorm = blowingSand; + blowingSand = BlowingSand.BLOWING_SAND; + } + } + + public boolean isExtremeTemperatureHeat() { + return (isExtremeTemperature() && (temperature > 0)); + } + + public boolean isExtremeTemperatureCold() { + return (isExtremeTemperature() && (temperature < 0)); + } + + public String getGravityIndicator() { + if (gravity > 1.0) { + return MSG_INDICATOR_GRAVITY_HIGH; + } else if (gravity < 1.0) { + return MSG_INDICATOR_GRAVITY_LOW; + } + + return MSG_INDICATOR_GRAVITY_NORMAL; + } + + public String getTemperatureIndicator() { + if (isExtremeTemperatureHeat()) { + return MSG_INDICATOR_TEMPERATURE_HEAT; + } else if (isExtremeTemperatureCold()) { + return MSG_INDICATOR_TEMPERATURE_COLD; + } + + return MSG_INDICATOR_TEMPERATURE_NORMAL; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/Weather.java b/megamek/src/megamek/common/planetaryconditions/Weather.java new file mode 100644 index 00000000000..29fc1f34641 --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/Weather.java @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum Weather { + CLEAR("WEATHER_CLEAR", "PlanetaryConditions.DisplayableName.Weather.Clear", "\u239A"), + LIGHT_RAIN("WEATHER_LIGHT_RAIN", "PlanetaryConditions.DisplayableName.Weather.LightRain", "\u2601 \u2022 \u2022 \u2022 \u2022"), + MOD_RAIN("WEATHER_MOD_RAIN", "PlanetaryConditions.DisplayableName.Weather.ModerateRain", "\u2601 \u2601 \u2022 \u2022 \u2022"), + HEAVY_RAIN("WEATHER_HEAVY_RAIN", "PlanetaryConditions.DisplayableName.Weather.HeavyRain", "\u2601 \u2601 \u2601 \u2022 \u2022"), + GUSTING_RAIN("WEATHER_GUSTING_RAIN", "PlanetaryConditions.DisplayableName.Weather.GustingRain", "\u2601 \u2601 \u2601 \u2601 \u2022"), + DOWNPOUR("WEATHER_DOWNPOUR", "PlanetaryConditions.DisplayableName.Weather.TorrentialDownpour", "\u2601 \u2601 \u2601 \u2601 \u2601"), + LIGHT_SNOW("WEATHER_LIGHT_SNOW", "PlanetaryConditions.DisplayableName.Weather.LightSnowfall", "\u2744 \u2022 \u2022 \u2022"), + MOD_SNOW("WEATHER_MOD_SNOW", "PlanetaryConditions.DisplayableName.Weather.ModerateSnowfall", "\u2744 \u2744 \u2022 \u2022"), + SNOW_FLURRIES("WEATHER_SNOW_FLURRIES", "PlanetaryConditions.DisplayableName.Weather.SnowFlurries", "\u2744 \u2744 \u2744 \u2022"), + HEAVY_SNOW("WEATHER_HEAVY_SNOW", "PlanetaryConditions.DisplayableName.Weather.HeavySnowfall", "\u2744 \u2744 \u2744 \u2744"), + SLEET("WEATHER_SLEET", "PlanetaryConditions.DisplayableName.Weather.Sleet", "\u26C6 \u2022"), + ICE_STORM("WEATHER_ICE_STORM", "PlanetaryConditions.DisplayableName.Weather.IceStorm", "\u26C6 \u26C6"), + LIGHT_HAIL("WEATHER_LIGHT_HAIL", "PlanetaryConditions.DisplayableName.Weather.LightHail", "\u2591 \u2022"), + HEAVY_HAIL("WEATHER_HEAVY_HAIL", "PlanetaryConditions.DisplayableName.Weather.HeavyHail", "\u2591 \u2591"), + LIGHTNING_STORM("WEATHER_LIGHTNING_STORM", "PlanetaryConditions.DisplayableName.Weather.LightningStorm", "\u2608"); + + private final String externalId; + private final String name; + private final String indicator; + + Weather(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public boolean isClear() { + return this == CLEAR; + } + + public boolean isLightRain() { + return this == LIGHT_RAIN; + } + + public boolean isModerateRain() { + return this == MOD_RAIN; + } + + public boolean isHeavyRain() { + return this == HEAVY_RAIN; + } + + public boolean isGustingRain() { + return this == GUSTING_RAIN; + } + + public boolean isDownpour() { + return this == DOWNPOUR; + } + + public boolean isLightSnow() { + return this == LIGHT_SNOW; + } + + public boolean isModerateSnow() { + return this == MOD_SNOW; + } + + public boolean isSnowFlurries() { + return this == SNOW_FLURRIES; + } + + public boolean isHeavySnow() { + return this == HEAVY_SNOW; + } + + public boolean isSleet() { + return this == SLEET; + } + + public boolean isIceStorm() { + return this == ICE_STORM; + } + + public boolean isLightHail() { + return this == LIGHT_HAIL; + } + + public boolean isHeavyHail() { + return this == HEAVY_HAIL; + } + + public boolean isLightningStorm() { + return this == LIGHTNING_STORM; + } + + public boolean isHeavyRainOrDownpour() { + return isHeavyRain() + || isDownpour(); + } + + public boolean isLightRainOrLightSnow() { + return isLightRain() + || isLightSnow(); + } + + public boolean isSnowFlurriesOrIceStorm() { + return isSnowFlurries() + || isIceStorm(); + } + + public boolean isHeavyRainOrGustingRain() { + return isHeavyRain() + || isGustingRain(); + } + + + public boolean isLightRainOrModerateRain() { + return isLightRain() + || isModerateRain(); + } + + public boolean isModerateSnowOrSnowFlurries() { + return isModerateSnow() + || isSnowFlurries(); + } + + public boolean isModerateRainOrModerateSnow() { + return isModerateRain() + || isModerateSnow(); + } + + public boolean isDownpourOrHeavySnowOrIceStorm() { + return isDownpour() + || isHeavySnow() + || isIceStorm(); + } + + public boolean isSnowFlurriesOrSleetOrIceStorm() { + return isSnowFlurries() + || isSleet() + || isIceStorm(); + } + + public boolean isHeavySnowOrLightHailOrHeaveHail() { + return isHeavySnow() + || isLightHail() + || isHeavyHail(); + } + + public boolean isLightRainOrLightSnowOrLightHail() { + return isLightRain() + || isLightSnow() + || isLightHail(); + } + + public boolean isHeavyRainOrGustingRainOrDownpour() { + return isHeavyRain() + || isGustingRain() + || isDownpour(); + } + + public boolean isHeavyRainOrGustingRainOrHeavySnow() { + return isHeavyRain() + || isGustingRain() + || isHeavySnow(); + } + + public boolean isHeavyRainOrModerateSnowOrSnowFlurries() { + return isHeavyRain() + || isModerateSnow() + || isSnowFlurries(); + } + + public boolean isModerateSnowOrHeavySnowOrSnowFlurries() { + return isModerateSnow() + || isHeavySnow() + || isSnowFlurries(); + } + + public boolean isLightSnowOrSleetOrLightHailOrHeavyHail() { + return isLightSnow() + || isSleet() + || isLightHail() + || isHeavyHail(); + } + + public boolean isModerateSnowOrHeavySnowOrSnowFlurriesOrSleet() { + return isModerateSnow() + || isHeavySnow() + || isSnowFlurries() + || isSleet(); + } + + public boolean isModerateRainOrHeavyRainOrGustingRainOrDownpour() { + return isModerateRain() + || isHeavyRain() + || isGustingRain() + || isDownpour(); + } + + public boolean isGustingRainOrSnowFlurriesOrIceStormOrLightningStorm() { + return isGustingRain() + || isSnowFlurries() + || isIceStorm() + || isLightningStorm(); + } + + public boolean isLightSnowOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet() { + return isLightSnow() + || isModerateSnow() + || isSnowFlurries() + || isHeavySnow() + || isSleet(); + } + + public boolean isGustingRainOrDownpourOrHeavySnowOrIceStormOrSleetOrHeavyHail() { + return isGustingRain() + || isDownpour() + || isHeavySnow() + || isIceStorm() + || isSleet() + || isHeavyHail(); + } + + public boolean isHeavyRainOrGustingRainOrDownpourOrLightSnowOrModerateSnowOrSnowFlurries() { + return isHeavyRain() + || isGustingRain() + || isDownpour() + || isLightSnow() + || isModerateSnow() + || isSnowFlurries(); + } + + public boolean isModerateRainOrHeavyRainOrGustingRainOrModerateSnowOrSnowFlurriesOrHeavySnowOrSleet() { + return isModerateRain() + || isHeavyRain() + || isGustingRain() + || isModerateSnow() + || isSnowFlurries() + || isHeavySnow() + || isSleet(); + } + + public static Weather getWeather(int i) { + return values()[i]; + } + + public static Weather getWeather(String s) { + for (Weather condition : Weather.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return Weather.CLEAR; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/Wind.java b/megamek/src/megamek/common/planetaryconditions/Wind.java new file mode 100644 index 00000000000..dcce8513797 --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/Wind.java @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum Wind { + CALM("WIND_CALM", "PlanetaryConditions.DisplayableName.WindStrength.Calm", "\u2690"), + LIGHT_GALE("WIND_LIGHT_GALE", "PlanetaryConditions.DisplayableName.WindStrength.LightGale", "\u21F6 \u2022 \u2022 \u2022"), + MOD_GALE("WIND_MOD_GALE", "PlanetaryConditions.DisplayableName.WindStrength.ModerateGale", "\u21F6 \u21F6 \u2022 \u2022"), + STRONG_GALE("WIND_STRONG_GALE", "PlanetaryConditions.DisplayableName.WindStrength.StrongGale", "\u21F6 \u21F6 \u21F6 \u2022"), + STORM("WIND_STORM", "PlanetaryConditions.DisplayableName.WindStrength.Storm", "\u21F6 \u21F6 \u21F6 \u21F6"), + TORNADO_F1_TO_F3("WIND_TORNADO_F1_TO_F3", "PlanetaryConditions.DisplayableName.WindStrength.TornadoF1-F3", "\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \u2022"), + TORNADO_F4("WIND_TORNADO_F4", "PlanetaryConditions.DisplayableName.WindStrength.TornadoF4", "\uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A \uD83C\uDF2A"); + private final String externalId; + private final String name; + private final String indicator; + + Wind(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public Wind lowerWind() { + switch (this) { + case TORNADO_F4: + return TORNADO_F1_TO_F3; + case TORNADO_F1_TO_F3: + return STORM; + case STRONG_GALE: + return MOD_GALE; + case MOD_GALE: + return LIGHT_GALE; + default: + return CALM; + } + } + + public Wind raiseWind() { + switch (this) { + case CALM: + return LIGHT_GALE; + case LIGHT_GALE: + return MOD_GALE; + case MOD_GALE: + return STORM; + case STRONG_GALE: + return TORNADO_F1_TO_F3; + default: + return TORNADO_F4; + } + } + + public boolean isCalm() { + return this == CALM; + } + + public boolean isLightGale() { + return this == LIGHT_GALE; + } + + public boolean isModerateGale() { + return this == MOD_GALE; + } + + public boolean isStrongGale() { + return this == STRONG_GALE; + } + + public boolean isStorm() { + return this == STORM; + } + + public boolean isTornadoF1ToF3() { + return this == TORNADO_F1_TO_F3; + } + + public boolean isTornadoF4() { + return this == TORNADO_F4; + } + + public boolean isLightGaleOrModerateGale() { + return isLightGale() || isModerateGale(); + } + + public boolean isStrongGaleOrStorm() { + return isStrongGale() || isStorm(); + } + + public boolean isWeakerThan(final Wind wind) { + return compareTo(wind) < 0; + } + + public boolean isStrongerThan(final Wind wind) { + return compareTo(wind) > 0; + } + + public static Wind getWind(int i) { + return Wind.values()[i]; + } + + public static Wind getWind(String s) { + for (Wind condition : Wind.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return Wind.CALM; + } +} diff --git a/megamek/src/megamek/common/planetaryconditions/WindDirection.java b/megamek/src/megamek/common/planetaryconditions/WindDirection.java new file mode 100644 index 00000000000..7179c8e2a3f --- /dev/null +++ b/megamek/src/megamek/common/planetaryconditions/WindDirection.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.common.planetaryconditions; + +import megamek.common.Messages; + +public enum WindDirection { + NORTH("NORTH", "PlanetaryConditions.DisplayableName.WindDirection.North", "\u2193"), + NORTHEAST("NORTHEAST", "PlanetaryConditions.DisplayableName.WindDirection.Northeast", "\u2B0B"), + SOUTHEAST("SOUTHEAST", "PlanetaryConditions.DisplayableName.WindDirection.Southeast", "\u2B09"), + SOUTH("SOUTH", "PlanetaryConditions.DisplayableName.WindDirection.South", "\u2191"), + SOUTHWEST("SOUTHWEST", "PlanetaryConditions.DisplayableName.WindDirection.Southwest", "\u2B08"), + NORTHWEST("NORTHWEST", "PlanetaryConditions.DisplayableName.WindDirection.Northwest", "\u2B0A"), + RANDOM("RANDOM", "PlanetaryConditions.DisplayableName.WindDirection.RandomWindDirection", ""); + private final String externalId; + private final String name; + private final String indicator; + + WindDirection(final String externalId, final String name, final String indicator) { + this.externalId = externalId; + this.name = name; + this.indicator = indicator; + } + + public String getIndicator() { + return indicator; + } + + public String getExternalId() { + return externalId; + } + + @Override + public String toString() { + return Messages.getString(name); + } + + public WindDirection rotateClockwise() { + switch (this) { + case NORTH: + return NORTHEAST; + case NORTHEAST: + return SOUTHEAST; + case SOUTHEAST: + return SOUTH; + case SOUTH: + return SOUTHWEST; + case SOUTHWEST: + return NORTHWEST; + case NORTHWEST: + return NORTH; + default: + return RANDOM; + } + } + + public WindDirection rotateCounterClockwise() { + switch (this) { + case NORTH: + return NORTHWEST; + case NORTHWEST: + return SOUTHWEST; + case SOUTHWEST: + return SOUTH; + case SOUTH: + return SOUTHEAST; + case SOUTHEAST: + return NORTHEAST; + case NORTHEAST: + return NORTH; + default: + return RANDOM; + } + } + + public boolean isRandomWindDirection() { + return this == RANDOM; + } + + public static WindDirection getWindDirection(int i) { + return WindDirection.values()[i]; + } + + public static WindDirection getWindDirection(String s) { + for (WindDirection condition : WindDirection.values()) { + if (condition.getExternalId().equals(s)) { + return condition; + } + } + return WindDirection.NORTH; + } +} diff --git a/megamek/src/megamek/common/scenario/ScenarioLoader.java b/megamek/src/megamek/common/scenario/ScenarioLoader.java index 9fde10877f5..d8e353f2423 100644 --- a/megamek/src/megamek/common/scenario/ScenarioLoader.java +++ b/megamek/src/megamek/common/scenario/ScenarioLoader.java @@ -21,13 +21,14 @@ import megamek.client.generator.RandomGenderGenerator; import megamek.common.*; import megamek.common.annotations.Nullable; -import megamek.common.enums.GamePhase; -import megamek.common.enums.Gender; +import megamek.common.enums.*; import megamek.common.icons.Camouflage; import megamek.common.loaders.EntityLoadingException; import megamek.common.options.IOption; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.*; import megamek.common.util.BoardUtilities; +import megamek.common.util.StringUtil; import megamek.common.util.fileUtils.MegaMekFile; import megamek.server.GameManager; import megamek.server.Messages; @@ -431,27 +432,27 @@ private void parsePlanetaryConditions(Game g, ScenarioInfo p) { } if (p.containsKey(PARAM_PLANETCOND_FOG)) { - g.getPlanetaryConditions().setFog(Integer.parseInt(p.getString(PARAM_PLANETCOND_FOG))); + g.getPlanetaryConditions().setFog(Fog.getFog(StringUtil.toInt(p.getString(PARAM_PLANETCOND_FOG), 0))); } if (p.containsKey(PARAM_PLANETCOND_ATMOS)) { - g.getPlanetaryConditions().setAtmosphere(Integer.parseInt(p.getString(PARAM_PLANETCOND_ATMOS))); + g.getPlanetaryConditions().setAtmosphere(Atmosphere.getAtmosphere(StringUtil.toInt(p.getString(PARAM_PLANETCOND_ATMOS),0))); } if (p.containsKey(PARAM_PLANETCOND_LIGHT)) { - g.getPlanetaryConditions().setLight(Integer.parseInt(p.getString(PARAM_PLANETCOND_LIGHT))); + g.getPlanetaryConditions().setLight(Light.getLight(StringUtil.toInt(p.getString(PARAM_PLANETCOND_LIGHT), 0))); } if (p.containsKey(PARAM_PLANETCOND_WEATHER)) { - g.getPlanetaryConditions().setWeather(Integer.parseInt(p.getString(PARAM_PLANETCOND_WEATHER))); + g.getPlanetaryConditions().setWeather(Weather.getWeather(StringUtil.toInt(p.getString(PARAM_PLANETCOND_WEATHER), 0))); } if (p.containsKey(PARAM_PLANETCOND_WIND)) { - g.getPlanetaryConditions().setWindStrength(Integer.parseInt(p.getString(PARAM_PLANETCOND_WIND))); + g.getPlanetaryConditions().setWind(Wind.getWind(StringUtil.toInt(p.getString(PARAM_PLANETCOND_WIND),0))); } if (p.containsKey(PARAM_PLANETCOND_WINDDIR)) { - g.getPlanetaryConditions().setWindDirection(Integer.parseInt(p.getString(PARAM_PLANETCOND_WINDDIR))); + g.getPlanetaryConditions().setWindDirection(WindDirection.getWindDirection(StringUtil.toInt(p.getString(PARAM_PLANETCOND_WINDDIR),0))); } if (p.containsKey(PARAM_PLANETCOND_WINDSHIFTINGDIR)) { @@ -463,15 +464,16 @@ private void parsePlanetaryConditions(Game g, ScenarioInfo p) { } if (p.containsKey(PARAM_PLANETCOND_WINDMIN)) { - g.getPlanetaryConditions().setMinWindStrength(Integer.parseInt(p.getString(PARAM_PLANETCOND_WINDMIN))); + g.getPlanetaryConditions().setWindMin(Wind.getWind(StringUtil.toInt(p.getString(PARAM_PLANETCOND_WINDMIN), 0))); } if (p.containsKey(PARAM_PLANETCOND_WINDMAX)) { - g.getPlanetaryConditions().setMaxWindStrength(Integer.parseInt(p.getString(PARAM_PLANETCOND_WINDMAX))); + g.getPlanetaryConditions().setWindMax(Wind.getWind(StringUtil.toInt(p.getString(PARAM_PLANETCOND_WINDMAX), 0))); } if (p.containsKey(PARAM_PLANETCOND_EMI)) { - g.getPlanetaryConditions().setEMI(parseBoolean(p, PARAM_PLANETCOND_EMI, false)); + EMI emi = parseBoolean(p, PARAM_PLANETCOND_EMI, false) ? EMI.EMI : EMI.EMI_NONE; + g.getPlanetaryConditions().setEMI(emi); } if (p.containsKey(PARAM_PLANETCOND_TERRAINCHANGES)) { @@ -479,7 +481,8 @@ private void parsePlanetaryConditions(Game g, ScenarioInfo p) { } if (p.containsKey(PARAM_PLANETCOND_BLOWINGSAND)) { - g.getPlanetaryConditions().setBlowingSand(parseBoolean(p, PARAM_PLANETCOND_BLOWINGSAND, false)); + BlowingSand blowingSand = parseBoolean(p, PARAM_PLANETCOND_BLOWINGSAND, false) ? BlowingSand.BLOWING_SAND : BlowingSand.BLOWING_SAND_NONE; + g.getPlanetaryConditions().setBlowingSand(blowingSand); } } diff --git a/megamek/src/megamek/common/util/BoardUtilities.java b/megamek/src/megamek/common/util/BoardUtilities.java index a819fc0e479..c8b142ba255 100644 --- a/megamek/src/megamek/common/util/BoardUtilities.java +++ b/megamek/src/megamek/common/util/BoardUtilities.java @@ -18,6 +18,8 @@ import megamek.client.bot.princess.CardinalEdge; import megamek.codeUtilities.MathUtility; import megamek.common.*; +import megamek.common.planetaryconditions.Weather; +import megamek.common.planetaryconditions.Wind; import megamek.common.util.generator.ElevationGenerator; import megamek.common.util.generator.SimplexGenerator; @@ -1110,14 +1112,14 @@ protected static void addCliffs(Board board, int modifier) { /* * adjust the board based on weather conditions */ - public static void addWeatherConditions(Board board, int weatherCond, int windCond) { + public static void addWeatherConditions(Board board, Weather weatherCond, Wind windCond) { for (int x = 0; x < board.getWidth(); x++) { for (int y = 0; y < board.getHeight(); y++) { Coords c = new Coords(x, y); Hex hex = board.getHex(c); //moderate rain - mud in clear hexes, depth 0 water, and dirt roads (not implemented yet) - if (weatherCond == PlanetaryConditions.WE_MOD_RAIN) { + if (weatherCond.isModerateRain()) { if ((hex.terrainsPresent() == 0) || (hex.containsTerrain(Terrains.WATER) && (hex.depth() == 0))) { hex.addTerrain(new Terrain(Terrains.MUD, 1)); if (hex.containsTerrain(Terrains.WATER)) { @@ -1128,8 +1130,7 @@ public static void addWeatherConditions(Board board, int weatherCond, int windCo //heavy rain - mud in all hexes except buildings, depth 1+ water, and non-dirt roads //rapids in all depth 1+ water - if ((weatherCond == PlanetaryConditions.WE_HEAVY_RAIN) - || (weatherCond == PlanetaryConditions.WE_GUSTING_RAIN)) { + if (weatherCond.isHeavyRainOrGustingRain()) { if (hex.containsTerrain(Terrains.WATER) && !hex.containsTerrain(Terrains.RAPIDS) && (hex.depth() > 0)) { hex.addTerrain(new Terrain(Terrains.RAPIDS, 1)); } else if (!hex.containsTerrain(Terrains.BUILDING) @@ -1144,7 +1145,7 @@ public static void addWeatherConditions(Board board, int weatherCond, int windCo //torrential downpour - mud in all hexes except buildings, depth 1+ water, and non-dirt roads //torrent in all depth 1+ water, swamps in all depth 0 water hexes - if (weatherCond == PlanetaryConditions.WE_DOWNPOUR) { + if (weatherCond.isDownpour()) { if (hex.containsTerrain(Terrains.WATER) && !(hex.terrainLevel(Terrains.RAPIDS) > 1) && (hex.depth() > 0)) { hex.addTerrain(new Terrain(Terrains.RAPIDS, 2)); } else if (hex.containsTerrain(Terrains.WATER)) { @@ -1158,10 +1159,10 @@ public static void addWeatherConditions(Board board, int weatherCond, int windCo } // check for rapids/torrents created by wind - if ((windCond > PlanetaryConditions.WI_MOD_GALE) - && hex.containsTerrain(Terrains.WATER) && (hex.depth() > 0)) { - - if (windCond > PlanetaryConditions.WI_STORM) { + if (windCond.isStrongerThan(Wind.MOD_GALE) + && hex.containsTerrain(Terrains.WATER) + && (hex.depth() > 0)) { + if (windCond.isStorm()) { if (!(hex.terrainLevel(Terrains.RAPIDS) > 1)) { hex.addTerrain(new Terrain(Terrains.RAPIDS, 2)); } diff --git a/megamek/src/megamek/common/util/StringUtil.java b/megamek/src/megamek/common/util/StringUtil.java index 3d1fa69bfc3..aacd01bf59c 100644 --- a/megamek/src/megamek/common/util/StringUtil.java +++ b/megamek/src/megamek/common/util/StringUtil.java @@ -168,4 +168,19 @@ public static int toInt(String s, int i) { return i; } } + + /** + * Returns float value from the passed string or default value if conversion fails. + */ + public static float toFloat(String s, float i) { + if (s.isEmpty()) { + return i; + } + + try { + return Float.parseFloat(s); + } catch (Exception ignored) { + return i; + } + } } diff --git a/megamek/src/megamek/common/weapons/AreaEffectHelper.java b/megamek/src/megamek/common/weapons/AreaEffectHelper.java index fe65e588de7..6d819956e6b 100644 --- a/megamek/src/megamek/common/weapons/AreaEffectHelper.java +++ b/megamek/src/megamek/common/weapons/AreaEffectHelper.java @@ -14,6 +14,8 @@ package megamek.common.weapons; import megamek.common.*; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; import org.apache.logging.log4j.LogManager; @@ -121,11 +123,11 @@ public static int getFuelAirBlastRadiusIndex(String name) { public static void processFuelAirDamage(Entity target, Coords center, EquipmentType ordnanceType, Entity attacker, Vector vPhaseReport, GameManager gameManager) { Game game = attacker.getGame(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // sanity check: if this attack is happening in vacuum through very thin atmo, add that to the phase report and terminate early - boolean notEnoughAtmo = game.getBoard().inSpace() || - game.getPlanetaryConditions().getAtmosphere() <= PlanetaryConditions.ATMO_TRACE; - - if (notEnoughAtmo) { + + if (game.getBoard().inSpace() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN)) { Report r = new Report(9986); r.indent(1); r.subject = attacker.getId(); @@ -134,10 +136,9 @@ public static void processFuelAirDamage(Entity target, Coords center, EquipmentT return; } - boolean thinAtmo = game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_THIN; int blastRadius = getFuelAirBlastRadiusIndex(ordnanceType.getInternalName()); - if (thinAtmo) { + if (conditions.getAtmosphere().isThin()) { Report r = new Report(9990); r.indent(1); r.subject = attacker.getId(); @@ -161,7 +162,7 @@ public static void processFuelAirDamage(Entity target, Coords center, EquipmentT } int damage = AreaEffectHelper.fuelAirDamage[damageBracket]; - if (thinAtmo) { + if (conditions.getAtmosphere().isThin()) { damage = (int) Math.ceil(damage / 2.0); } @@ -177,11 +178,10 @@ public static void processFuelAirDamage(Entity target, Coords center, EquipmentT public static void processFuelAirDamage(Coords center, EquipmentType ordnanceType, Entity attacker, Vector vPhaseReport, GameManager gameManager) { Game game = attacker.getGame(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // sanity check: if this attack is happening in vacuum through very thin atmo, add that to the phase report and terminate early - boolean notEnoughAtmo = game.getBoard().inSpace() || - game.getPlanetaryConditions().getAtmosphere() <= PlanetaryConditions.ATMO_TRACE; - - if (notEnoughAtmo) { + if (game.getBoard().inSpace() + || conditions.getAtmosphere().isLighterThan(Atmosphere.THIN)) { Report r = new Report(9986); r.indent(1); r.subject = attacker.getId(); @@ -190,10 +190,9 @@ public static void processFuelAirDamage(Coords center, EquipmentType ordnanceTyp return; } - boolean thinAtmo = game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_THIN; int blastRadius = getFuelAirBlastRadiusIndex(ordnanceType.getInternalName()); - if (thinAtmo) { + if (conditions.getAtmosphere().isThin()) { Report r = new Report(9990); r.indent(1); r.subject = attacker.getId(); @@ -215,7 +214,7 @@ public static void processFuelAirDamage(Coords center, EquipmentType ordnanceTyp List donut = center.allAtDistance(distFromCenter); for (Coords coords : donut) { int damage = AreaEffectHelper.fuelAirDamage[damageBracket]; - if (thinAtmo) { + if (conditions.getAtmosphere().isThin()) { damage = (int) Math.ceil(damage / 2.0); } diff --git a/megamek/src/megamek/common/weapons/CLIATMHandler.java b/megamek/src/megamek/common/weapons/CLIATMHandler.java index 024ac8246b4..9f745707e17 100644 --- a/megamek/src/megamek/common/weapons/CLIATMHandler.java +++ b/megamek/src/megamek/common/weapons/CLIATMHandler.java @@ -18,6 +18,7 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; import java.util.ArrayList; @@ -218,7 +219,8 @@ protected int calcMissileHits(Vector vPhaseReport) { } // Affects streak too. - if (game.getPlanetaryConditions().hasEMI()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { nMissilesModifier -= 2; } diff --git a/megamek/src/megamek/common/weapons/CLLBXPrototypeHandler.java b/megamek/src/megamek/common/weapons/CLLBXPrototypeHandler.java index 6bb9beeef82..6767e34084f 100644 --- a/megamek/src/megamek/common/weapons/CLLBXPrototypeHandler.java +++ b/megamek/src/megamek/common/weapons/CLLBXPrototypeHandler.java @@ -15,13 +15,11 @@ import java.util.Vector; -import megamek.common.Compute; -import megamek.common.Game; -import megamek.common.RangeType; -import megamek.common.Report; -import megamek.common.ToHitData; +import megamek.common.*; +import megamek.common.actions.PhysicalAttackAction; import megamek.common.actions.WeaponAttackAction; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; /** @@ -72,9 +70,8 @@ protected int calcHits(Vector vPhaseReport) { } else { // flat modifier of -1, because of prototype nHitsModifier -= 1; - - shotsHit = Compute.missilesHit(wtype.getRackSize(), nHitsModifier, - game.getPlanetaryConditions().hasEMI()); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + shotsHit = Compute.missilesHit(wtype.getRackSize(), nHitsModifier, conditions.getEMI().isEMI()); } Report r = new Report(3325); diff --git a/megamek/src/megamek/common/weapons/HVACWeaponHandler.java b/megamek/src/megamek/common/weapons/HVACWeaponHandler.java index d9f77a2f69b..78483be7cef 100644 --- a/megamek/src/megamek/common/weapons/HVACWeaponHandler.java +++ b/megamek/src/megamek/common/weapons/HVACWeaponHandler.java @@ -25,6 +25,7 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; import megamek.server.SmokeCloud; @@ -53,8 +54,9 @@ public HVACWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager */ @Override public boolean handle(GamePhase phase, Vector vPhaseReport) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_START_FIRE) - && (game.getPlanetaryConditions().getAtmosphere() >= PlanetaryConditions.ATMO_TRACE)) { + && !conditions.getAtmosphere().isVacuum()) { int rear = (ae.getFacing() + 3 + (weapon.isMechTurretMounted() ? weapon.getFacing() : 0)) % 6; Coords src = ae.getPosition(); Coords rearCoords = src.translated(rear); diff --git a/megamek/src/megamek/common/weapons/LBXHandler.java b/megamek/src/megamek/common/weapons/LBXHandler.java index c30855335c9..8cc4641ae6f 100644 --- a/megamek/src/megamek/common/weapons/LBXHandler.java +++ b/megamek/src/megamek/common/weapons/LBXHandler.java @@ -15,18 +15,11 @@ import java.util.Vector; -import megamek.common.AmmoType; -import megamek.common.Compute; -import megamek.common.Game; -import megamek.common.Infantry; -import megamek.common.RangeType; -import megamek.common.Report; -import megamek.common.ToHitData; -import megamek.common.WeaponType; +import megamek.common.*; import megamek.common.actions.WeaponAttackAction; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; -import megamek.server.Server; /** * @author Andrew Hunter @@ -108,9 +101,8 @@ protected int calcHits(Vector vPhaseReport) { shotsHit = (int) Math.ceil(shotsHit * .5); } } else { - - shotsHit = Compute.missilesHit(wtype.getRackSize(), nHitsModifier, - game.getPlanetaryConditions().hasEMI()); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + shotsHit = Compute.missilesHit(wtype.getRackSize(), nHitsModifier, conditions.getEMI().isEMI()); } Report r = new Report(3325); diff --git a/megamek/src/megamek/common/weapons/MPodHandler.java b/megamek/src/megamek/common/weapons/MPodHandler.java index adc33a8086a..7241d6c5813 100644 --- a/megamek/src/megamek/common/weapons/MPodHandler.java +++ b/megamek/src/megamek/common/weapons/MPodHandler.java @@ -15,11 +15,9 @@ import java.util.Vector; -import megamek.common.Compute; -import megamek.common.Game; -import megamek.common.Report; -import megamek.common.ToHitData; +import megamek.common.*; import megamek.common.actions.WeaponAttackAction; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; /** @@ -70,9 +68,9 @@ protected int calcHits(Vector vPhaseReport) { if (bLowProfileGlancing) { hitMod -= 4; } - - - if (game.getPlanetaryConditions().hasEMI()) { + + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { hitMod -= 2; } diff --git a/megamek/src/megamek/common/weapons/RapidfireHVACWeaponHandler.java b/megamek/src/megamek/common/weapons/RapidfireHVACWeaponHandler.java index bc140d78606..02150805a96 100644 --- a/megamek/src/megamek/common/weapons/RapidfireHVACWeaponHandler.java +++ b/megamek/src/megamek/common/weapons/RapidfireHVACWeaponHandler.java @@ -25,6 +25,7 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; import megamek.server.Server; import megamek.server.SmokeCloud; @@ -45,8 +46,9 @@ public RapidfireHVACWeaponHandler(ToHitData t, WeaponAttackAction w, Game g, Gam */ @Override public boolean handle(GamePhase phase, Vector vPhaseReport) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_START_FIRE) - && (game.getPlanetaryConditions().getAtmosphere() >= PlanetaryConditions.ATMO_TRACE)) { + && !conditions.getAtmosphere().isVacuum()) { int rear = (ae.getFacing() + 3 + (weapon.isMechTurretMounted() ? weapon.getFacing() : 0)) % 6; Coords src = ae.getPosition(); Coords rearCoords = src.translated(rear); diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index 14529c49190..e48251c6026 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -21,6 +21,7 @@ import megamek.common.enums.AimingMode; import megamek.common.enums.GamePhase; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; import megamek.server.Server; import megamek.server.SmokeCloud; @@ -2072,7 +2073,8 @@ protected int getClusterModifiers(boolean clusterRangePenalty) { nMissilesModifier += (toHit.getMoS() / 3) * 2; } - if (game.getPlanetaryConditions().hasEMI()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getEMI().isEMI()) { nMissilesModifier -= 2; } diff --git a/megamek/src/megamek/server/FireProcessor.java b/megamek/src/megamek/server/FireProcessor.java index ba3a7fe6f60..9ab00dba2ea 100644 --- a/megamek/src/megamek/server/FireProcessor.java +++ b/megamek/src/megamek/server/FireProcessor.java @@ -18,6 +18,9 @@ import megamek.common.*; import megamek.common.annotations.Nullable; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; +import megamek.common.planetaryconditions.WindDirection; import org.apache.logging.log4j.LogManager; import java.util.*; @@ -52,8 +55,8 @@ private void resolveFire() { Board board = game.getBoard(); int width = board.getWidth(); int height = board.getHeight(); - int windDirection = game.getPlanetaryConditions().getWindDirection(); - int windStrength = game.getPlanetaryConditions().getWindStrength(); + WindDirection windDirection = game.getPlanetaryConditions().getWindDirection(); + Wind windStrength = game.getPlanetaryConditions().getWind(); // Get the position map of all entities in the game. Hashtable> positionMap = game.getPositionMap(); @@ -151,16 +154,18 @@ private void resolveFire() { boolean containsForest = (currentHex.containsTerrain(Terrains.WOODS) || currentHex.containsTerrain(Terrains.JUNGLE)); boolean bInferno = currentHex.terrainLevel(Terrains.FIRE) == 2; - if ((game.getPlanetaryConditions().getWindStrength() < PlanetaryConditions.WI_TORNADO_F13) + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getWind().isWeakerThan(Wind.TORNADO_F1_TO_F3) && !(game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_FOREST_FIRES_NO_SMOKE) - && containsForest && (bldg == null))) { + && containsForest + && (bldg == null))) { ArrayList smokeList = new ArrayList<>(); - smokeList.add(currentCoords.translated(windDirection)); - smokeList.add(currentCoords.translated((windDirection + 1) % 6)); - smokeList.add(currentCoords.translated((windDirection + 5) % 6)); + smokeList.add(currentCoords.translated(windDirection.ordinal())); + smokeList.add(currentCoords.translated(windDirection.rotateClockwise().ordinal())); + smokeList.add(currentCoords.translated(windDirection.rotateCounterClockwise().ordinal())); - gameManager.addSmoke(smokeList, windDirection, bInferno); + gameManager.addSmoke(smokeList, windDirection.ordinal(), bInferno); board.initializeAround(currentXCoord, currentYCoord); } @@ -195,9 +200,9 @@ public Vector burnDownWoods(Coords coords) { /** * Spreads the fire around the specified coordinates. */ - public void spreadFire(int x, int y, int windDir, int windStr) { + public void spreadFire(int x, int y, WindDirection windDir, Wind windStr) { Coords src = new Coords(x, y); - Coords nextCoords = src.translated(windDir); + Coords nextCoords = src.translated(windDir.ordinal()); // check for height differences between hexes //TODO: until further clarification only the heights matter (not the base elevation) @@ -209,10 +214,11 @@ public void spreadFire(int x, int y, int windDir, int windStr) { TargetRoll directroll = new TargetRoll(9, "spread downwind"); TargetRoll obliqueroll = new TargetRoll(11, "spread 60 degrees to downwind"); - if ((windStr > PlanetaryConditions.WI_NONE) && (windStr < PlanetaryConditions.WI_STRONG_GALE)) { + if (windStr.isLightGale() + || windStr.isModerateGale()) { directroll.addModifier(-2, "light/moderate gale"); obliqueroll.addModifier(-1, "light/moderate gale"); - } else if (windStr > PlanetaryConditions.WI_MOD_GALE) { + } else if (windStr.isStrongerThan(Wind.MOD_GALE)) { directroll.addModifier(-3, "strong gale+"); directroll.addModifier(-2, "strong gale+"); } @@ -223,19 +229,19 @@ public void spreadFire(int x, int y, int windDir, int windStr) { // burning... // unless a higher hex intervenes Hex nextHex = game.getBoard().getHex(nextCoords); - Hex jumpHex = game.getBoard().getHex(nextCoords.translated(windDir)); + Hex jumpHex = game.getBoard().getHex(nextCoords.translated(windDir.ordinal())); if ((nextHex != null) && (jumpHex != null) && !(nextHex.containsTerrain(Terrains.FIRE)) && ((curHeight >= nextHex.ceiling()) || (jumpHex.ceiling() >= nextHex.ceiling()))) { // we've already gone one step in the wind direction, now go another directroll.addModifier(3, "crossing non-burning hex"); - spreadFire(src, nextCoords.translated(windDir), directroll, curHeight); + spreadFire(src, nextCoords.translated(windDir.ordinal()), directroll, curHeight); } // spread fire 60 degrees clockwise.... - spreadFire(src, src.translated((windDir + 1) % 6), obliqueroll, curHeight); + spreadFire(src, src.translated(windDir.rotateClockwise().ordinal()), obliqueroll, curHeight); // spread fire 60 degrees counterclockwise - spreadFire(src, src.translated((windDir + 5) % 6), obliqueroll, curHeight); + spreadFire(src, src.translated(windDir.rotateCounterClockwise().ordinal()), obliqueroll, curHeight); } /** @@ -263,13 +269,14 @@ public void spreadFire(final Coords origin, final Coords coords, final TargetRol /** Processes smoke drift and dissipation. */ private void resolveSmoke() { final Board board = game.getBoard(); - final int windDir = game.getPlanetaryConditions().getWindDirection(); - int windStr = game.getPlanetaryConditions().getWindStrength(); + final WindDirection windDir = game.getPlanetaryConditions().getWindDirection(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + Wind windStr = game.getPlanetaryConditions().getWind(); // If the Smoke Drift option is turned on, treat wind strength as light gale if there is none if (game.getOptions().booleanOption(OptionsConstants.BASE_BREEZE) - && (windStr == PlanetaryConditions.WI_NONE)) { - windStr = PlanetaryConditions.WI_LIGHT_GALE; + && conditions.getWind().isCalm()) { + windStr = Wind.LIGHT_GALE; } HashMap> allReplacementHexes = new HashMap<>(); @@ -359,8 +366,8 @@ private void removeSmokeTerrainFromHexes() { * @return the coordinates where the smoke has drifted to, or null if it dissipates while on the * board. */ - public @Nullable Coords driftAddSmoke(final Coords source, final int windDirection, - final int windStrength) { + public @Nullable Coords driftAddSmoke(final Coords source, final WindDirection windDirection, + final Wind windStrength) { return driftAddSmoke(source, windDirection, windStrength, 0); } @@ -376,13 +383,13 @@ private void removeSmokeTerrainFromHexes() { * @return the coordinates where the smoke has drifted to, or null if it dissipates while on the * board. */ - public @Nullable Coords driftAddSmoke(final Coords src, final int windDir, final int windStr, + public @Nullable Coords driftAddSmoke(final Coords src, final WindDirection windDir, final Wind windStr, final int directionChanges) { - Coords nextCoords = src.translated(windDir); + Coords nextCoords = src.translated(windDir.ordinal()); Board board = game.getBoard(); // if the wind conditions are calm, then don't drift it - if (windStr == PlanetaryConditions.WI_NONE) { + if (windStr.isCalm()) { return src; } @@ -416,10 +423,10 @@ private void removeSmokeTerrainFromHexes() { if ((hexElevation - nextElevation) < -4) { // Try Right if (directionChanges == 0) { - return driftAddSmoke(src, (windDir + 1) % 6, windStr, directionChanges + 1); + return driftAddSmoke(src, windDir.rotateClockwise(), windStr, directionChanges + 1); } else if ( directionChanges == 1) { // Try Left - return driftAddSmoke(src, (windDir - 2 ) % 6, windStr, directionChanges + 1); + return driftAddSmoke(src, windDir.rotateCounterClockwise(), windStr, directionChanges + 1); } else { // Stay put return src; @@ -427,8 +434,8 @@ private void removeSmokeTerrainFromHexes() { } // stronger wind causes smoke to drift farther - if (windStr > PlanetaryConditions.WI_MOD_GALE) { - return driftAddSmoke(nextCoords, windDir, windStr - 1); + if (windStr.isStrongerThan(Wind.MOD_GALE)) { + return driftAddSmoke(nextCoords, windDir, windStr.lowerWind()); } return nextCoords; @@ -442,8 +449,9 @@ private void removeSmokeTerrainFromHexes() { * @param windStr The current wind strength * @return True when the smoke cloud dissipates by a level or entirely */ - public boolean checkSmokeDissipation(SmokeCloud cloud, int windStr) { - if ((cloud.getDuration() == 1) || (windStr > PlanetaryConditions.WI_STORM)) { + public boolean checkSmokeDissipation(SmokeCloud cloud, Wind windStr) { + if ((cloud.getDuration() == 1) + || windStr.isStrongerThan(Wind.STORM)) { cloud.setSmokeLevel(0); return true; } else if (cloud.getDuration() > 1) { @@ -453,9 +461,10 @@ public boolean checkSmokeDissipation(SmokeCloud cloud, int windStr) { // Dissipate in various winds int roll = Compute.d6(2); - return (roll > 10) || ((roll > 9) && (windStr == PlanetaryConditions.WI_MOD_GALE)) - || ((roll > 7) && (windStr == PlanetaryConditions.WI_STRONG_GALE)) - || ((roll > 5) && (windStr == PlanetaryConditions.WI_STORM)); + return (roll > 10) + || ((roll > 9) && windStr.isModerateGale()) + || ((roll > 7) && windStr.isStrongGale()) + || ((roll > 5) && windStr.isStorm()); } public void driftSmokeReport(SmokeCloud cloud, boolean dissipated) { diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index 57e5aaca304..c8148b8a129 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -23,9 +23,7 @@ import megamek.common.actions.*; import megamek.common.annotations.Nullable; import megamek.common.containers.PlayerIDandList; -import megamek.common.enums.BasementType; -import megamek.common.enums.GamePhase; -import megamek.common.enums.WeaponSortOrder; +import megamek.common.enums.*; import megamek.common.equipment.ArmorType; import megamek.common.event.GameVictoryEvent; import megamek.common.force.Force; @@ -36,6 +34,10 @@ import megamek.common.options.IBasicOption; import megamek.common.options.IOption; import megamek.common.options.OptionsConstants; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.Light; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import megamek.common.preference.PreferenceManager; import megamek.common.util.*; import megamek.common.util.fileUtils.MegaMekFile; @@ -1077,8 +1079,9 @@ private void resetEntityPhase(GamePhase phase) { // reset spotlights // If deployment phase, set Searchlight state based on startSearchLightsOn; if (phase.isDeployment()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); boolean startSLOn = PreferenceManager.getClientPreferences().getStartSearchlightsOn() - && game.getPlanetaryConditions().isIlluminationEffective(); + && conditions.getLight().isDarkerThan(Light.DAY); entity.setSearchlightState(startSLOn); entity.setIlluminated(startSLOn); } @@ -2006,8 +2009,8 @@ public boolean accept(Entity entity) { resetEntityPhase(phase); clearReports(); resolveHeat(); - if (game.getPlanetaryConditions().isSandBlowing() - && (game.getPlanetaryConditions().getWindStrength() > PlanetaryConditions.WI_LIGHT_GALE)) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.isBlowingSandActive()) { addReport(resolveBlowingSandDamage()); } addReport(resolveControlRolls()); @@ -2909,7 +2912,7 @@ public void applyBoardSettings() { } if (game.getPlanetaryConditions().isTerrainAffected()) { BoardUtilities.addWeatherConditions(newBoard, game.getPlanetaryConditions().getWeather(), - game.getPlanetaryConditions().getWindStrength()); + game.getPlanetaryConditions().getWind()); } game.setBoard(newBoard); } @@ -3481,19 +3484,20 @@ private void writeInitiativeReport(boolean abbreviatedReport) { // we don't much care about wind direction and such in a hard vacuum if (!game.getBoard().inSpace()) { // Wind direction and strength + PlanetaryConditions conditions = game.getPlanetaryConditions(); Report rWindDir = new Report(1025, Report.PUBLIC); - rWindDir.add(game.getPlanetaryConditions().getWindDirDisplayableName()); + rWindDir.add(conditions.getWindDirection().toString()); rWindDir.newlines = 0; Report rWindStr = new Report(1030, Report.PUBLIC); - rWindStr.add(game.getPlanetaryConditions().getWindDisplayableName()); + rWindStr.add(conditions.getWind().toString()); rWindStr.newlines = 0; Report rWeather = new Report(1031, Report.PUBLIC); - rWeather.add(game.getPlanetaryConditions().getWeatherDisplayableName()); + rWeather.add(conditions.getWeather().toString()); rWeather.newlines = 0; Report rLight = new Report(1032, Report.PUBLIC); - rLight.add(game.getPlanetaryConditions().getLightDisplayableName()); + rLight.add(conditions.getLight().toString()); Report rVis = new Report(1033, Report.PUBLIC); - rVis.add(game.getPlanetaryConditions().getFogDisplayableName()); + rVis.add(conditions.getFog().toString()); addReport(rWindDir); addReport(rWindStr); addReport(rWeather); @@ -7934,7 +7938,7 @@ else if ((step.getElevation() + entity.height()) == 0) { int minTemp = -30; boolean useBlackIce = game.getOptions().booleanOption(OptionsConstants.ADVANCED_BLACK_ICE); boolean goodTemp = game.getPlanetaryConditions().getTemperature() <= minTemp; - boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + boolean goodWeather = game.getPlanetaryConditions().getWeather().isIceStorm(); if (isPavementStep && ((useBlackIce && goodTemp) || goodWeather)) { if (!curHex.containsTerrain(Terrains.BLACK_ICE)) { int blackIceChance = Compute.d6(1); @@ -8834,7 +8838,7 @@ 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() <= PlanetaryConditions.BLACK_ICE_TEMP; - boolean goodWeather = game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM; + boolean goodWeather = game.getPlanetaryConditions().getWeather().isIceStorm(); if ((useBlackIce && goodTemp) || goodWeather) { if (ServerHelper.checkEnteringBlackIce(this, curPos, curHex, useBlackIce, goodTemp, goodWeather)) { rollTarget = entity.checkLandingOnBlackIce(overallMoveType, curHex); @@ -11690,6 +11694,8 @@ public void addMovementHeat() { public Vector doSetLocationsExposure(Entity entity, Hex hex, boolean isJump, int elevation) { Vector vPhaseReport = new Vector<>(); + PlanetaryConditions conditions = game.getPlanetaryConditions(); + boolean aeroSpaceborne = (entity.getEntityType() & Entity.ETYPE_AERO) == 0 && entity.isSpaceborne(); if (hex == null) { return vPhaseReport; } @@ -11702,8 +11708,8 @@ public Vector doSetLocationsExposure(Entity entity, Hex hex, if ((entity instanceof Mech) && !entity.isProne() && (hex.terrainLevel(Terrains.WATER) <= partialWaterLevel)) { for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getPlanetaryConditions().isVacuum() - || ((entity.getEntityType() & Entity.ETYPE_AERO) == 0 && entity.isSpaceborne())) { + if (conditions.getAtmosphere().isLighterThan(Atmosphere.THIN) + || aeroSpaceborne) { entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); } else { entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); @@ -11726,8 +11732,7 @@ public Vector doSetLocationsExposure(Entity entity, Hex hex, } else { int status = ILocationExposureStatus.WET; if (entity.relHeight() >= 0) { - status = game.getPlanetaryConditions().isVacuum() ? - ILocationExposureStatus.VACUUM : ILocationExposureStatus.NORMAL; + status = conditions.getAtmosphere().isLighterThan(Atmosphere.THIN) ? ILocationExposureStatus.VACUUM : ILocationExposureStatus.NORMAL; } for (int loop = 0; loop < entity.locations(); loop++) { entity.setLocationStatus(loop, status); @@ -11738,8 +11743,8 @@ public Vector doSetLocationsExposure(Entity entity, Hex hex, } } else { for (int loop = 0; loop < entity.locations(); loop++) { - if (game.getPlanetaryConditions().isVacuum() - || ((entity.getEntityType() & Entity.ETYPE_AERO) == 0 && entity.isSpaceborne())) { + if (conditions.getAtmosphere().isLighterThan(Atmosphere.THIN) + || aeroSpaceborne) { entity.setLocationStatus(loop, ILocationExposureStatus.VACUUM); } else { entity.setLocationStatus(loop, ILocationExposureStatus.NORMAL); @@ -12972,7 +12977,8 @@ private void processDeployment(Entity entity, Coords coords, int nFacing, int el // all spheroid craft should have velocity of zero in atmosphere // regardless of what was entered IAero a = (IAero) entity; - if (a.isSpheroid() || game.getPlanetaryConditions().isVacuum()) { + if (a.isSpheroid() + || game.getPlanetaryConditions().getAtmosphere().isLighterThan(Atmosphere.THIN)) { a.setCurrentVelocity(0); a.setNextVelocity(0); } @@ -14676,7 +14682,7 @@ public boolean tryIgniteHex(Coords c, int entityId, boolean bHotGun, } // no lighting fires in tornadoes - if (game.getPlanetaryConditions().getWindStrength() > PlanetaryConditions.WI_STORM) { + if (game.getPlanetaryConditions().getWind().isStrongerThan(Wind.STORM)) { nTargetRoll = new TargetRoll(TargetRoll.AUTOMATIC_FAIL, "tornado"); } @@ -20278,12 +20284,17 @@ private void checkForSuffocation() { continue; } final Hex curHex = game.getBoard().getHex(entity.getPosition()); - if ((((entity.getElevation() < 0) && ((curHex - .terrainLevel(Terrains.WATER) > 1) || ((curHex - .terrainLevel(Terrains.WATER) == 1) && entity.isProne()))) || game - .getPlanetaryConditions().isVacuum()) - && (entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, - Mech.SYSTEM_LIFE_SUPPORT, Mech.LOC_HEAD) > 0)) { + + boolean depthOneProne = (curHex.terrainLevel(Terrains.WATER) == 1) + && entity.isProne(); + boolean inWater = (curHex.terrainLevel(Terrains.WATER) > 1) + || depthOneProne; + boolean underWater = (entity.getElevation() < 0) + && inWater; + boolean canNotBeathe = underWater + || game.getPlanetaryConditions().getAtmosphere().isLighterThan(Atmosphere.THIN); + if (canNotBeathe + && (entity.getHitCriticals(CriticalSlot.TYPE_SYSTEM, Mech.SYSTEM_LIFE_SUPPORT, Mech.LOC_HEAD) > 0)) { Report r = new Report(6020); r.subject = entity.getId(); r.addDesc(entity); @@ -21802,8 +21813,11 @@ public Vector damageEntity(Entity te, HitData hit, int damage, } // Is the infantry in vacuum? - if ((isPlatoon || isBattleArmor) && !te.isDestroyed() && !te.isDoomed() - && game.getPlanetaryConditions().isVacuum()) { + boolean platoonOrBattleArmor = isPlatoon || isBattleArmor; + if (platoonOrBattleArmor + && !te.isDestroyed() + && !te.isDoomed() + && game.getPlanetaryConditions().getAtmosphere().isLighterThan(Atmosphere.THIN)) { // PBI. Double damage. damage *= 2; r = new Report(6041); @@ -27182,10 +27196,11 @@ private Vector breachCheck(Entity entity, int loc, Hex hex, boolean unde int breachroll = 0; // set the target roll for the breach int target = 10; + PlanetaryConditions conditions = game.getPlanetaryConditions(); // if this is a vacuum check and we are in trace atmosphere then // adjust target if ((entity.getLocationStatus(loc) == ILocationExposureStatus.VACUUM) - && (game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_TRACE)) { + && conditions.getAtmosphere().isTrace()) { target = 12; } // if this is a surface naval vessel and the attack is not from @@ -28760,7 +28775,7 @@ public void removeFire(Coords fireCoords, String reason) { */ public void addSmoke(ArrayList coords, int windDir, boolean bInferno) { // if a tornado, then no smoke! - if (game.getPlanetaryConditions().getWindStrength() > PlanetaryConditions.WI_STORM) { + if (game.getPlanetaryConditions().getWind().isStrongerThan(Wind.STORM)) { return; } @@ -33218,6 +33233,7 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c boolean autoEject, Coords targetCoords, String desc) { PilotingRollData rollTarget = new PilotingRollData(entity.getId(), entity.getCrew().getPiloting(crewPos), desc); + PlanetaryConditions conditions = game.getPlanetaryConditions(); // Per SO p26, fighters can eject as per TO rules on 196 with some exceptions if (entity.isProne()) { rollTarget.addModifier(5, "Mech is prone"); @@ -33279,35 +33295,33 @@ public static PilotingRollData getEjectModifiers(Game game, Entity entity, int c if (!entity.isSpaceborne()) { // At present, the UI lets you set these atmospheric conditions for a space battle, but it shouldn't // That's a fix for another day, probably when I get around to space terrain and 'weather' - if (game.getPlanetaryConditions().getGravity() == 0) { + if (conditions.getGravity() == 0) { rollTarget.addModifier(3, "Zero-G"); - } else if (game.getPlanetaryConditions().getGravity() < 0.8) { + } else if (conditions.getGravity() < 0.8) { rollTarget.addModifier(2, "Low-G"); - } else if (game.getPlanetaryConditions().getGravity() > 1.2) { + } else if (conditions.getGravity() > 1.2) { rollTarget.addModifier(2, "High-G"); } //Vacuum shouldn't apply to ASF ejection since they're designed for it, but the rules don't specify //High and low pressures make more sense to apply to all - if (game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_VACUUM) { + if (conditions.getAtmosphere().isVacuum()) { rollTarget.addModifier(3, "Vacuum"); - } else if (game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_VHIGH) { + } else if (conditions.getAtmosphere().isVeryHigh()) { rollTarget.addModifier(2, "Very High Atmosphere Pressure"); - } else if (game.getPlanetaryConditions().getAtmosphere() == PlanetaryConditions.ATMO_TRACE) { + } else if (conditions.getAtmosphere().isTrace()) { rollTarget.addModifier(2, "Trace atmosphere"); } } - if ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_ICE_STORM) - || (game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_DOWNPOUR) - || (game.getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_STRONG_GALE)) { + + if (conditions.getWeather().isDownpourOrHeavySnowOrIceStorm() + || conditions.getWind().isStrongGale()) { rollTarget.addModifier(2, "Bad Weather"); } - if ((game.getPlanetaryConditions().getWindStrength() >= PlanetaryConditions.WI_STORM) - || ((game.getPlanetaryConditions().getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) && (game - .getPlanetaryConditions().getWindStrength() == PlanetaryConditions.WI_STRONG_GALE))) { + if (conditions.getWind().isStrongerThan(Wind.STRONG_GALE) + || (conditions.getWeather().isHeavySnow() && conditions.getWind().isStrongGale())) { rollTarget.addModifier(3, "Really Bad Weather"); } return rollTarget; @@ -33396,7 +33410,9 @@ public Vector abandonEntity(Entity entity) { r.indent(3); vDesc.addElement(r); // Don't make ill-equipped pilots abandon into vacuum - if (game.getPlanetaryConditions().isVacuum() && !entity.isAero()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getAtmosphere().isLighterThan(Atmosphere.THIN) + && !entity.isAero()) { return vDesc; } @@ -33438,7 +33454,8 @@ public Vector abandonEntity(Entity entity) { else if (game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_VEHICLES_CAN_EJECT) && (entity instanceof Tank)) { // Don't make them abandon into vacuum - if (game.getPlanetaryConditions().isVacuum()) { + PlanetaryConditions conditions = game.getPlanetaryConditions(); + if (conditions.getAtmosphere().isLighterThan(Atmosphere.THIN)) { return vDesc; } EjectedCrew crew = new EjectedCrew(entity); @@ -34768,8 +34785,8 @@ public List getSmokeCloudList() { private Vector resolveBlowingSandDamage() { Vector vFullReport = new Vector<>(); vFullReport.add(new Report(5002, Report.PUBLIC)); - int damage_bonus = Math.max(0, game.getPlanetaryConditions().getWindStrength() - - PlanetaryConditions.WI_MOD_GALE); + int damage_bonus = Math.max(0, game.getPlanetaryConditions().getWind().ordinal() + - Wind.MOD_GALE.ordinal()); // cycle through each team and damage 1d6 airborne VTOL/WiGE for (Team team : game.getTeams()) { Vector airborne = getAirborneVTOL(team); diff --git a/megamek/src/megamek/server/WeatherProcessor.java b/megamek/src/megamek/server/WeatherProcessor.java index 6bf10cf0c97..5008d5deddb 100644 --- a/megamek/src/megamek/server/WeatherProcessor.java +++ b/megamek/src/megamek/server/WeatherProcessor.java @@ -17,6 +17,8 @@ import java.util.Vector; import megamek.common.*; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; /** * Cycle through hexes on a map and make any necessary adjustments based on weather @@ -54,10 +56,10 @@ void doEndPhaseChanges(Vector vPhaseReport) { } private void resolveWeather() { + PlanetaryConditions conditions = game.getPlanetaryConditions(); Board board = game.getBoard(); int width = board.getWidth(); int height = board.getHeight(); - PlanetaryConditions conditions = game.getPlanetaryConditions(); boolean lightSnow = false; boolean deepSnow = false; boolean ice = false; @@ -67,8 +69,7 @@ private void resolveWeather() { } // first we need to increment the conditions - if (conditions.getWeather() == PlanetaryConditions.WE_MOD_SNOW - || conditions.getWeather() == PlanetaryConditions.WE_SNOW_FLURRIES + if (conditions.getWeather().isModerateSnowOrSnowFlurries() && game.getBoard().onGround()) { modSnowTurn = modSnowTurn + 1; if (modSnowTurn == 9) { @@ -79,8 +80,8 @@ private void resolveWeather() { ice = true; } } - if (((conditions.getWeather() == PlanetaryConditions.WE_HEAVY_SNOW) - && game.getBoard().onGround())) { + if (conditions.getWeather().isHeavySnow() + && game.getBoard().onGround()) { heavySnowTurn = heavySnowTurn + 1; if (heavySnowTurn == 4) { lightSnow = true; @@ -92,14 +93,14 @@ private void resolveWeather() { ice = true; } } - if (conditions.getWeather() == PlanetaryConditions.WE_SLEET + if (conditions.getWeather().isSleet() && game.getBoard().onGround()) { sleetTurn = sleetTurn + 1; if (sleetTurn == 14) { ice = true; } } - if (conditions.getWeather() == PlanetaryConditions.WE_ICE_STORM + if (conditions.getWeather().isIceStorm() && game.getBoard().onGround()) { iceTurn = iceTurn + 1; if (iceTurn == 9) { @@ -214,15 +215,13 @@ private void resolveWeather() { // 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) + if (currentHex.containsTerrain(Terrains.WATER) && currentHex.depth(true) > 0) { - - if (conditions.getWindStrength() > PlanetaryConditions.WI_STORM) { + if (conditions.getWind().isStrongerThan(Wind.STORM)) { if (!(currentHex.terrainLevel(Terrains.RAPIDS) > 1)) { currentHex.addTerrain(new Terrain(Terrains.RAPIDS, 2)); } - } else { + } else if (conditions.getWind().isStrongerThan(Wind.MOD_GALE)) { if (!currentHex.containsTerrain(Terrains.RAPIDS)) { currentHex.addTerrain(new Terrain(Terrains.RAPIDS, 1)); } diff --git a/megamek/unittests/megamek/common/PlanetaryConditionsTest.java b/megamek/unittests/megamek/common/PlanetaryConditionsTest.java index fd1f5f45276..134b0b75b2e 100644 --- a/megamek/unittests/megamek/common/PlanetaryConditionsTest.java +++ b/megamek/unittests/megamek/common/PlanetaryConditionsTest.java @@ -1,5 +1,8 @@ package megamek.common; +import megamek.common.planetaryconditions.Atmosphere; +import megamek.common.planetaryconditions.PlanetaryConditions; +import megamek.common.planetaryconditions.Wind; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -28,7 +31,7 @@ public void testWhyDoomed() { // Trace atmosphere - Entity doomed in vacuum/trace atmosphere PlanetaryConditions planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setAtmosphere(PlanetaryConditions.ATMO_TRACE); + planetaryConditions.setAtmosphere(Atmosphere.TRACE); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); Entity mockEntity = mock(Infantry.class); when(mockEntity.doomedInVacuum()).thenReturn(true); @@ -37,17 +40,19 @@ public void testWhyDoomed() { // Trace atmosphere - Entity not doomed in vacuum/trace atmosphere planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setAtmosphere(PlanetaryConditions.ATMO_TRACE); + planetaryConditions.setAtmosphere(Atmosphere.TRACE); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); mockEntity = mock(Infantry.class); + when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockEntity.doomedInVacuum()).thenReturn(false); assertNull(planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame); // F4 Tornado - Entity is a mech (not doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F4); + planetaryConditions.setWind(Wind.TORNADO_F4); mockEntity = mock(Mech.class); + when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.BIPED); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); assertNull(planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame); @@ -55,15 +60,16 @@ public void testWhyDoomed() { // F4 Tornado - Entity is not a mech (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F4); + planetaryConditions.setWind(Wind.TORNADO_F4); mockEntity = mock(Infantry.class); + when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); assertEquals("tornado", planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame); // F1-3 Tornado - Entity movement mode is hover (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F13); + planetaryConditions.setWind(Wind.TORNADO_F1_TO_F3); mockEntity = mock(Tank.class); when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.HOVER); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); @@ -72,7 +78,7 @@ public void testWhyDoomed() { // F1-3 Tornado - Entity movement mode is WiGE (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F13); + planetaryConditions.setWind(Wind.TORNADO_F1_TO_F3); mockEntity = mock(Tank.class); when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.WIGE); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); @@ -81,7 +87,7 @@ public void testWhyDoomed() { // F1-3 Tornado - Entity movement mode is VTOL (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F13); + planetaryConditions.setWind(Wind.TORNADO_F1_TO_F3); mockEntity = mock(VTOL.class); when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.VTOL); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); @@ -90,7 +96,7 @@ public void testWhyDoomed() { // F1-3 Tornado - Entity is regular infantry (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F13); + planetaryConditions.setWind(Wind.TORNADO_F1_TO_F3); mockEntity = mock(Infantry.class); when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); @@ -99,15 +105,16 @@ public void testWhyDoomed() { // F1-3 Tornado - Entity is battle armor infantry (not doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_TORNADO_F13); + planetaryConditions.setWind(Wind.TORNADO_F1_TO_F3); mockEntity = mock(BattleArmor.class); + when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.INF_LEG); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); assertNull(planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame); // Storm - Entity is regular infantry (doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_STORM); + planetaryConditions.setWind(Wind.STORM); mockEntity = mock(Infantry.class); when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); @@ -116,8 +123,9 @@ public void testWhyDoomed() { // Storm - Entity is battle armor infantry (not doomed) planetaryConditions = new PlanetaryConditions(); - planetaryConditions.setWindStrength(PlanetaryConditions.WI_STORM); + planetaryConditions.setWind(Wind.STORM); mockEntity = mock(BattleArmor.class); + when(mockEntity.getMovementMode()).thenReturn(EntityMovementMode.INF_LEG); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); assertNull(planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame); @@ -135,6 +143,7 @@ public void testWhyDoomed() { when(mockHex.containsTerrain(Terrains.BUILDING)).thenReturn(true); when(mockHex.terrainLevel(Terrains.BLDG_ELEV)).thenReturn(2); mockEntity = mock(Infantry.class); + when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockEntity.doomedInExtremeTemp()).thenReturn(true); when(mockEntity.getPosition()).thenReturn(mockCoords); when(mockEntity.getElevation()).thenReturn(1); @@ -147,6 +156,7 @@ public void testWhyDoomed() { planetaryConditions.setTemperature(100); when(mockGame.getPlanetaryConditions()).thenReturn(planetaryConditions); mockEntity = mock(Infantry.class); + when(mockEntity.isConventionalInfantry()).thenReturn(true); when(mockEntity.doomedInExtremeTemp()).thenReturn(true); assertEquals("extreme temperature", planetaryConditions.whyDoomed(mockEntity, mockGame)); reset(mockEntity, mockGame);