mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add support for DCS 2.7 weather generation.
https://github.com/Khopa/dcs_liberation/issues/981
This commit is contained in:
parent
e63743f537
commit
38f632097e
@ -7,6 +7,7 @@ Saves from 2.4 are not compatible with 2.5.
|
||||
* **[Flight Planner]** Added AEW&C missions. (by siKruger)
|
||||
* **[Kneeboard]** Added dark kneeboard option (by GvonH)
|
||||
* **[Campaigns]** Multiple EWR sites may now be generated, and EWR sites may be generated outside bases (by SnappyComebacks)
|
||||
* **[Mission Generation]** Cloudy and rainy (but not thunderstorm) weather will use the cloud presets from DCS 2.7.
|
||||
|
||||
## Fixes
|
||||
|
||||
|
||||
@ -3,11 +3,12 @@ from __future__ import annotations
|
||||
import datetime
|
||||
import logging
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from dcs.weather import Weather as PydcsWeather, Wind
|
||||
from dcs.cloud_presets import Clouds as PydcsClouds
|
||||
from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind
|
||||
|
||||
from game.settings import Settings
|
||||
from game.utils import Distance, meters
|
||||
@ -36,6 +37,23 @@ class Clouds:
|
||||
density: int
|
||||
thickness: int
|
||||
precipitation: PydcsWeather.Preceptions
|
||||
preset: Optional[CloudPreset] = field(default=None)
|
||||
|
||||
@classmethod
|
||||
def random_preset(cls, rain: bool) -> Clouds:
|
||||
clouds = (p.value for p in PydcsClouds)
|
||||
if rain:
|
||||
presets = [p for p in clouds if "Rain" in p.name]
|
||||
else:
|
||||
presets = [p for p in clouds if "Rain" not in p.name]
|
||||
preset = random.choice(presets)
|
||||
return Clouds(
|
||||
base=random.randint(preset.min_base, preset.max_base),
|
||||
density=0,
|
||||
thickness=0,
|
||||
precipitation=PydcsWeather.Preceptions.None_,
|
||||
preset=preset,
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@ -101,12 +119,11 @@ class ClearSkies(Weather):
|
||||
|
||||
class Cloudy(Weather):
|
||||
def generate_clouds(self) -> Optional[Clouds]:
|
||||
return Clouds(
|
||||
base=self.random_cloud_base(),
|
||||
density=random.randint(1, 8),
|
||||
thickness=self.random_cloud_thickness(),
|
||||
precipitation=PydcsWeather.Preceptions.None_,
|
||||
)
|
||||
return Clouds.random_preset(rain=False)
|
||||
|
||||
def generate_fog(self) -> Optional[Fog]:
|
||||
# DCS 2.7 says to not use fog with the cloud presets.
|
||||
return None
|
||||
|
||||
def generate_wind(self) -> WindConditions:
|
||||
return self.random_wind(0, 4)
|
||||
@ -114,12 +131,11 @@ class Cloudy(Weather):
|
||||
|
||||
class Raining(Weather):
|
||||
def generate_clouds(self) -> Optional[Clouds]:
|
||||
return Clouds(
|
||||
base=self.random_cloud_base(),
|
||||
density=random.randint(5, 8),
|
||||
thickness=self.random_cloud_thickness(),
|
||||
precipitation=PydcsWeather.Preceptions.Rain,
|
||||
)
|
||||
return Clouds.random_preset(rain=True)
|
||||
|
||||
def generate_fog(self) -> Optional[Fog]:
|
||||
# DCS 2.7 says to not use fog with the cloud presets.
|
||||
return None
|
||||
|
||||
def generate_wind(self) -> WindConditions:
|
||||
return self.random_wind(0, 6)
|
||||
|
||||
@ -17,6 +17,7 @@ class EnvironmentGenerator:
|
||||
self.mission.weather.clouds_thickness = clouds.thickness
|
||||
self.mission.weather.clouds_density = clouds.density
|
||||
self.mission.weather.clouds_iprecptns = clouds.precipitation
|
||||
self.mission.weather.clouds_preset = clouds.preset
|
||||
|
||||
def set_fog(self, fog: Optional[Fog]) -> None:
|
||||
if fog is None:
|
||||
|
||||
@ -7,7 +7,7 @@ from PySide2.QtWidgets import (
|
||||
QLabel,
|
||||
QVBoxLayout,
|
||||
)
|
||||
from dcs.weather import Weather as PydcsWeather
|
||||
from dcs.weather import CloudPreset, Weather as PydcsWeather
|
||||
|
||||
import qt_ui.uiconstants as CONST
|
||||
from game.utils import mps
|
||||
@ -162,7 +162,7 @@ class QWeatherWidget(QGroupBox):
|
||||
self.turn = turn
|
||||
self.conditions = conditions
|
||||
|
||||
self.updateForecast()
|
||||
self.update_forecast()
|
||||
self.updateWinds()
|
||||
|
||||
def updateWinds(self):
|
||||
@ -186,55 +186,76 @@ class QWeatherWidget(QGroupBox):
|
||||
self.windFL26SpeedLabel.setText(f"{int(windFL26Speed.knots)}kts")
|
||||
self.windFL26DirLabel.setText(f"{windFL26Dir}º")
|
||||
|
||||
def updateForecast(self):
|
||||
def update_forecast_from_preset(self, preset: CloudPreset) -> None:
|
||||
self.forecastFog.setText("No fog")
|
||||
if "Rain" in preset.name:
|
||||
self.forecastRain.setText("Rain")
|
||||
self.update_forecast_icons("rain")
|
||||
else:
|
||||
self.forecastRain.setText("No rain")
|
||||
self.update_forecast_icons("partly-cloudy")
|
||||
|
||||
# We get a description like the following for the cloud preset.
|
||||
#
|
||||
# 09 ##Two Layer Broken/Scattered \nMETAR:BKN 7.5/10 SCT 20/22 FEW41
|
||||
#
|
||||
# The second line is probably interesting but doesn't fit into the widget
|
||||
# currently, so for now just extract the first line.
|
||||
self.forecastClouds.setText(preset.description.splitlines()[0].split("##")[1])
|
||||
|
||||
def update_forecast(self):
|
||||
"""Updates the Forecast Text and icon with the current conditions wind info."""
|
||||
icon = []
|
||||
if (
|
||||
self.conditions.weather.clouds
|
||||
and self.conditions.weather.clouds.preset is not None
|
||||
):
|
||||
self.update_forecast_from_preset(self.conditions.weather.clouds.preset)
|
||||
return
|
||||
|
||||
if self.conditions.weather.clouds is None:
|
||||
cloudDensity = 0
|
||||
cloud_density = 0
|
||||
precipitation = None
|
||||
else:
|
||||
cloudDensity = self.conditions.weather.clouds.density
|
||||
cloud_density = self.conditions.weather.clouds.density
|
||||
precipitation = self.conditions.weather.clouds.precipitation
|
||||
|
||||
fog = self.conditions.weather.fog or None
|
||||
is_night = self.conditions.time_of_day == TimeOfDay.Night
|
||||
time = "night" if is_night else "day"
|
||||
|
||||
if cloudDensity <= 0:
|
||||
if not cloud_density:
|
||||
self.forecastClouds.setText("Sunny")
|
||||
icon = [time, "clear"]
|
||||
|
||||
if cloudDensity > 0 and cloudDensity < 3:
|
||||
weather_type = "clear"
|
||||
elif cloud_density < 3:
|
||||
self.forecastClouds.setText("Partly Cloudy")
|
||||
icon = [time, "partly-cloudy"]
|
||||
|
||||
if cloudDensity >= 3 and cloudDensity < 5:
|
||||
weather_type = "partly-cloudy"
|
||||
elif cloud_density < 5:
|
||||
self.forecastClouds.setText("Mostly Cloudy")
|
||||
icon = [time, "partly-cloudy"]
|
||||
|
||||
if cloudDensity >= 5:
|
||||
weather_type = "partly-cloudy"
|
||||
else:
|
||||
self.forecastClouds.setText("Totally Cloudy")
|
||||
icon = [time, "partly-cloudy"]
|
||||
weather_type = "partly-cloudy"
|
||||
|
||||
if precipitation == PydcsWeather.Preceptions.Rain:
|
||||
self.forecastRain.setText("Rain")
|
||||
icon = [time, "rain"]
|
||||
|
||||
weather_type = "rain"
|
||||
elif precipitation == PydcsWeather.Preceptions.Thunderstorm:
|
||||
self.forecastRain.setText("Thunderstorm")
|
||||
icon = [time, "thunderstorm"]
|
||||
|
||||
weather_type = "thunderstorm"
|
||||
else:
|
||||
self.forecastRain.setText("No Rain")
|
||||
self.forecastRain.setText("No rain")
|
||||
|
||||
if not fog:
|
||||
if not self.conditions.weather.fog is not None:
|
||||
self.forecastFog.setText("No fog")
|
||||
else:
|
||||
visibility = round(fog.visibility.nautical_miles, 1)
|
||||
visibility = round(self.conditions.weather.fog.visibility.nautical_miles, 1)
|
||||
self.forecastFog.setText(f"Fog vis: {visibility}nm")
|
||||
icon = [time, ("cloudy" if cloudDensity > 1 else None), "fog"]
|
||||
if cloud_density > 1:
|
||||
weather_type = "cloudy-fog"
|
||||
else:
|
||||
weather_type = "fog"
|
||||
|
||||
icon_key = "Weather_{}".format("-".join(filter(None.__ne__, icon)))
|
||||
self.update_forecast_icons(weather_type)
|
||||
|
||||
def update_forecast_icons(self, weather_type: str) -> None:
|
||||
time = "night" if self.conditions.time_of_day == TimeOfDay.Night else "day"
|
||||
icon_key = f"Weather_{time}-{weather_type}"
|
||||
icon = CONST.ICONS.get(icon_key) or CONST.ICONS["Weather_night-partly-cloudy"]
|
||||
self.weather_icon.setPixmap(icon)
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user