1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-28 01:04:50 +01:00

Cleanup the Climate file (#23755)

* Rename kClimateTransitions, kClimateWeatherData, kClimateWeatherGloom

* Rename WeatherTransition::DistributionSize to RandomBias

* Rename WeatherTransition type to WeatherPattern

* Rename WeatherState type to WeatherTrait and take internally

* Rename ThunderStatus type, kMaxThunderInstances constant
This commit is contained in:
Aaron van Geffen
2025-01-31 23:27:37 +01:00
committed by GitHub
parent 3c03fa308d
commit 0049345f33
2 changed files with 84 additions and 79 deletions

View File

@@ -33,24 +33,34 @@
using namespace OpenRCT2;
using namespace OpenRCT2::Audio;
constexpr int32_t MAX_THUNDER_INSTANCES = 2;
constexpr int32_t kMaxThunderInstances = 2;
enum class THUNDER_STATUS
enum class ThunderStatus
{
NONE,
PLAYING,
none,
playing,
};
struct WeatherTransition
struct WeatherPattern
{
int8_t BaseTemperature;
int8_t DistributionSize;
WeatherType Distribution[24];
int8_t baseTemperature;
int8_t randomBias;
WeatherType distribution[24];
};
extern const WeatherTransition* ClimateTransitions[4];
extern const WeatherState ClimateWeatherData[EnumValue(WeatherType::Count)];
extern const FilterPaletteID ClimateWeatherGloomColours[4];
struct WeatherTrait
{
int8_t temperatureDelta;
WeatherEffectType effectLevel;
int8_t gloomLevel;
WeatherLevel level;
uint32_t spriteId;
};
// TODO: no need for these to be declared extern, just move the definitions up
extern const WeatherPattern* kClimatePatterns[4];
extern const WeatherTrait kClimateWeatherTraits[EnumValue(WeatherType::Count)];
extern const FilterPaletteID kClimateWeatherGloomColours[4];
// Climate data
uint16_t gClimateLightningFlash;
@@ -59,10 +69,10 @@ uint16_t gClimateLightningFlash;
static int32_t _weatherVolume = 1;
static uint32_t _lightningTimer;
static uint32_t _thunderTimer;
static std::shared_ptr<IAudioChannel> _thunderSoundChannels[MAX_THUNDER_INSTANCES];
static THUNDER_STATUS _thunderStatus[MAX_THUNDER_INSTANCES] = {
THUNDER_STATUS::NONE,
THUNDER_STATUS::NONE,
static std::shared_ptr<IAudioChannel> _thunderSoundChannels[kMaxThunderInstances];
static ThunderStatus _thunderStatus[kMaxThunderInstances] = {
ThunderStatus::none,
ThunderStatus::none,
};
static OpenRCT2::Audio::SoundId _thunderSoundId;
static int32_t _thunderVolume;
@@ -70,7 +80,7 @@ static int32_t _thunderStereoEcho = 0;
static std::shared_ptr<IAudioChannel> _weatherSoundChannel;
static int8_t ClimateStepWeatherLevel(int8_t currentWeatherLevel, int8_t nextWeatherLevel);
static void ClimateDetermineFutureWeather(int32_t randomDistribution);
static void ClimateDetermineFutureWeather(int32_t randomValue);
static void ClimateUpdateWeatherSound();
static void ClimateUpdateThunderSound();
static void ClimateUpdateLightning();
@@ -87,18 +97,19 @@ int32_t ClimateCelsiusToFahrenheit(int32_t celsius)
*/
void ClimateReset(ClimateType climate)
{
auto& gameState = GetGameState();
auto weather = WeatherType::PartiallyCloudy;
int32_t month = GetDate().GetMonth();
const WeatherTransition* transition = &ClimateTransitions[EnumValue(climate)][month];
const WeatherState* weatherState = &ClimateWeatherData[EnumValue(weather)];
const WeatherPattern& pattern = kClimatePatterns[EnumValue(climate)][month];
const WeatherTrait& trait = kClimateWeatherTraits[EnumValue(weather)];
auto& gameState = GetGameState();
gameState.Climate = climate;
gameState.ClimateCurrent.Weather = weather;
gameState.ClimateCurrent.Temperature = transition->BaseTemperature + weatherState->TemperatureDelta;
gameState.ClimateCurrent.WeatherEffect = weatherState->EffectLevel;
gameState.ClimateCurrent.WeatherGloom = weatherState->GloomLevel;
gameState.ClimateCurrent.Level = weatherState->Level;
gameState.ClimateCurrent.Temperature = pattern.baseTemperature + trait.temperatureDelta;
gameState.ClimateCurrent.WeatherEffect = trait.effectLevel;
gameState.ClimateCurrent.WeatherGloom = trait.gloomLevel;
gameState.ClimateCurrent.Level = trait.level;
_lightningTimer = 0;
_thunderTimer = 0;
@@ -201,14 +212,15 @@ void ClimateForceWeather(WeatherType weather)
{
auto& gameState = GetGameState();
int32_t month = GetDate().GetMonth();
const WeatherTransition* transition = &ClimateTransitions[EnumValue(gameState.Climate)][month];
const auto weatherState = &ClimateWeatherData[EnumValue(weather)];
const auto& pattern = kClimatePatterns[EnumValue(gameState.Climate)][month];
const auto& trait = kClimateWeatherTraits[EnumValue(weather)];
gameState.ClimateCurrent.Weather = weather;
gameState.ClimateCurrent.WeatherGloom = weatherState->GloomLevel;
gameState.ClimateCurrent.Level = weatherState->Level;
gameState.ClimateCurrent.WeatherEffect = weatherState->EffectLevel;
gameState.ClimateCurrent.Temperature = transition->BaseTemperature + weatherState->TemperatureDelta;
gameState.ClimateCurrent.WeatherGloom = trait.gloomLevel;
gameState.ClimateCurrent.Level = trait.level;
gameState.ClimateCurrent.WeatherEffect = trait.effectLevel;
gameState.ClimateCurrent.Temperature = pattern.baseTemperature + trait.temperatureDelta;
gameState.ClimateUpdateTimer = 1920;
ClimateUpdate();
@@ -258,9 +270,9 @@ FilterPaletteID ClimateGetWeatherGloomPaletteId(const ClimateState& state)
{
auto paletteId = FilterPaletteID::PaletteNull;
auto gloom = state.WeatherGloom;
if (gloom < std::size(ClimateWeatherGloomColours))
if (gloom < std::size(kClimateWeatherGloomColours))
{
paletteId = ClimateWeatherGloomColours[gloom];
paletteId = kClimateWeatherGloomColours[gloom];
}
return paletteId;
}
@@ -268,9 +280,9 @@ FilterPaletteID ClimateGetWeatherGloomPaletteId(const ClimateState& state)
uint32_t ClimateGetWeatherSpriteId(const ClimateState& state)
{
uint32_t spriteId = SPR_WEATHER_SUN;
if (EnumValue(state.Weather) < std::size(ClimateWeatherData))
if (EnumValue(state.Weather) < std::size(kClimateWeatherTraits))
{
spriteId = ClimateWeatherData[EnumValue(state.Weather)].SpriteId;
spriteId = kClimateWeatherTraits[EnumValue(state.Weather)].spriteId;
}
return spriteId;
}
@@ -291,22 +303,23 @@ static int8_t ClimateStepWeatherLevel(int8_t currentWeatherLevel, int8_t nextWea
* for nextWeather. The other weather parameters are then looked up depending only on the
* next weather.
*/
static void ClimateDetermineFutureWeather(int32_t randomDistribution)
static void ClimateDetermineFutureWeather(int32_t randomValue)
{
int32_t month = GetDate().GetMonth();
auto& gameState = GetGameState();
// Generate a random variable with values 0 up to DistributionSize-1 and chose weather from the distribution table
// accordingly
const WeatherTransition* transition = &ClimateTransitions[EnumValue(gameState.Climate)][month];
WeatherType nextWeather = (transition->Distribution[((randomDistribution & 0xFF) * transition->DistributionSize) >> 8]);
// Generate a random index with values 0 up to randomBias-1
// and choose weather from the distribution table accordingly
const auto& pattern = kClimatePatterns[EnumValue(gameState.Climate)][month];
auto randomIndex = ((randomValue % 256) * pattern.randomBias) / 256;
auto nextWeather = pattern.distribution[randomIndex];
gameState.ClimateNext.Weather = nextWeather;
const auto nextWeatherState = &ClimateWeatherData[EnumValue(nextWeather)];
gameState.ClimateNext.Temperature = transition->BaseTemperature + nextWeatherState->TemperatureDelta;
gameState.ClimateNext.WeatherEffect = nextWeatherState->EffectLevel;
gameState.ClimateNext.WeatherGloom = nextWeatherState->GloomLevel;
gameState.ClimateNext.Level = nextWeatherState->Level;
const auto& nextWeatherTrait = kClimateWeatherTraits[EnumValue(nextWeather)];
gameState.ClimateNext.Temperature = pattern.baseTemperature + nextWeatherTrait.temperatureDelta;
gameState.ClimateNext.WeatherEffect = nextWeatherTrait.effectLevel;
gameState.ClimateNext.WeatherGloom = nextWeatherTrait.gloomLevel;
gameState.ClimateNext.Level = nextWeatherTrait.level;
gameState.ClimateUpdateTimer = 1920;
}
@@ -373,15 +386,15 @@ static void ClimateUpdateThunderSound()
}
// Stop thunder sounds if they have finished
for (int32_t i = 0; i < MAX_THUNDER_INSTANCES; i++)
for (int32_t i = 0; i < kMaxThunderInstances; i++)
{
if (_thunderStatus[i] != THUNDER_STATUS::NONE)
if (_thunderStatus[i] != ThunderStatus::none)
{
auto& channel = _thunderSoundChannels[i];
if (!channel->IsPlaying())
{
channel->Stop();
_thunderStatus[i] = THUNDER_STATUS::NONE;
_thunderStatus[i] = ThunderStatus::none;
}
}
}
@@ -414,7 +427,7 @@ static void ClimateUpdateThunder()
uint32_t randomNumber = UtilRand();
if (randomNumber & 0x10000)
{
if (_thunderStatus[0] == THUNDER_STATUS::NONE && _thunderStatus[1] == THUNDER_STATUS::NONE)
if (_thunderStatus[0] == ThunderStatus::none && _thunderStatus[1] == ThunderStatus::none)
{
// Play thunder on left side
_thunderSoundId = (randomNumber & 0x20000) ? OpenRCT2::Audio::SoundId::Thunder1
@@ -428,7 +441,7 @@ static void ClimateUpdateThunder()
}
else
{
if (_thunderStatus[0] == THUNDER_STATUS::NONE)
if (_thunderStatus[0] == ThunderStatus::none)
{
_thunderSoundId = (randomNumber & 0x20000) ? OpenRCT2::Audio::SoundId::Thunder1
: OpenRCT2::Audio::SoundId::Thunder2;
@@ -444,31 +457,32 @@ static void ClimatePlayThunder(int32_t instanceIndex, OpenRCT2::Audio::SoundId s
_thunderSoundChannels[instanceIndex] = CreateAudioChannel(soundId, false, DStoMixerVolume(volume), DStoMixerPan(pan));
if (_thunderSoundChannels[instanceIndex] != nullptr)
{
_thunderStatus[instanceIndex] = THUNDER_STATUS::PLAYING;
_thunderStatus[instanceIndex] = ThunderStatus::playing;
}
}
#pragma region Climate / Weather data tables
const FilterPaletteID ClimateWeatherGloomColours[4] = {
const FilterPaletteID kClimateWeatherGloomColours[4] = {
FilterPaletteID::PaletteNull,
FilterPaletteID::PaletteDarken1,
FilterPaletteID::PaletteDarken2,
FilterPaletteID::PaletteDarken3,
};
// There is actually a sprite at 0x5A9C for snow but only these weather types seem to be fully implemented
const WeatherState ClimateWeatherData[EnumValue(WeatherType::Count)] = {
{ 10, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_SUN }, // Sunny
{ 5, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_SUN_CLOUD }, // Partially Cloudy
{ 0, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_CLOUD }, // Cloudy
{ -2, WeatherEffectType::Rain, 1, WeatherLevel::Light, SPR_WEATHER_LIGHT_RAIN }, // Rain
{ -4, WeatherEffectType::Rain, 2, WeatherLevel::Heavy, SPR_WEATHER_HEAVY_RAIN }, // Heavy Rain
{ 2, WeatherEffectType::Storm, 2, WeatherLevel::Heavy, SPR_WEATHER_STORM }, // Thunderstorm
{ -10, WeatherEffectType::Snow, 1, WeatherLevel::Light, SPR_WEATHER_SNOW }, // Snow
{ -15, WeatherEffectType::Snow, 2, WeatherLevel::Heavy, SPR_WEATHER_SNOW }, // Heavy Snow
{ -20, WeatherEffectType::Blizzard, 2, WeatherLevel::Heavy, SPR_WEATHER_SNOW }, // Blizzard
// clang-format off
const WeatherTrait kClimateWeatherTraits[EnumValue(WeatherType::Count)] = {
{ 10, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_SUN }, // Sunny
{ 5, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_SUN_CLOUD }, // Partially Cloudy
{ 0, WeatherEffectType::None, 0, WeatherLevel::None, SPR_WEATHER_CLOUD }, // Cloudy
{ -2, WeatherEffectType::Rain, 1, WeatherLevel::Light, SPR_WEATHER_LIGHT_RAIN }, // Rain
{ -4, WeatherEffectType::Rain, 2, WeatherLevel::Heavy, SPR_WEATHER_HEAVY_RAIN }, // Heavy Rain
{ 2, WeatherEffectType::Storm, 2, WeatherLevel::Heavy, SPR_WEATHER_STORM }, // Thunderstorm
{ -10, WeatherEffectType::Snow, 1, WeatherLevel::Light, SPR_WEATHER_SNOW }, // Snow
{ -15, WeatherEffectType::Snow, 2, WeatherLevel::Heavy, SPR_WEATHER_SNOW }, // Heavy Snow
{ -20, WeatherEffectType::Blizzard, 2, WeatherLevel::Heavy, SPR_WEATHER_SNOW }, // Blizzard
};
// clang-format on
constexpr auto S = WeatherType::Sunny;
constexpr auto P = WeatherType::PartiallyCloudy;
@@ -477,7 +491,7 @@ constexpr auto R = WeatherType::Rain;
constexpr auto H = WeatherType::HeavyRain;
constexpr auto T = WeatherType::Thunder;
static constexpr WeatherTransition ClimateTransitionsCoolAndWet[] = {
static constexpr WeatherPattern kClimatePatternsCoolAndWet[] = {
{ 8, 18, { S, P, P, P, P, P, C, C, C, C, C, C, C, R, R, R, H, H, S, S, S, S, S } },
{ 10, 21, { P, P, P, P, P, C, C, C, C, C, C, C, C, C, R, R, R, H, H, H, T, S, S } },
{ 14, 17, { S, S, S, P, P, P, P, P, P, C, C, C, C, R, R, R, H, S, S, S, S, S, S } },
@@ -487,7 +501,7 @@ static constexpr WeatherTransition ClimateTransitionsCoolAndWet[] = {
{ 16, 19, { S, S, S, P, P, P, P, P, C, C, C, C, C, C, R, R, H, H, T, S, S, S, S } },
{ 13, 16, { S, S, P, P, P, P, C, C, C, C, C, C, R, R, H, T, S, S, S, S, S, S, S } },
};
static constexpr WeatherTransition ClimateTransitionsWarm[] = {
static constexpr WeatherPattern kClimatePatternsWarm[] = {
{ 12, 21, { S, S, S, S, S, P, P, P, P, P, P, P, P, C, C, C, C, C, C, C, H, S, S } },
{ 13, 22, { S, S, S, S, S, P, P, P, P, P, P, C, C, C, C, C, C, C, C, C, R, T, S } },
{ 16, 17, { S, S, S, S, S, S, P, P, P, P, P, P, C, C, C, C, R, S, S, S, S, S, S } },
@@ -497,7 +511,7 @@ static constexpr WeatherTransition ClimateTransitionsWarm[] = {
{ 19, 17, { S, S, S, S, S, P, P, P, P, P, C, C, C, C, C, C, R, S, S, S, S, S, S } },
{ 16, 17, { S, S, P, P, P, P, P, C, C, C, C, C, C, C, C, C, H, S, S, S, S, S, S } },
};
static constexpr WeatherTransition ClimateTransitionsHotAndDry[] = {
static constexpr WeatherPattern kClimatePatternsHotAndDry[] = {
{ 12, 15, { S, S, S, S, P, P, P, P, P, P, P, P, C, C, R, S, S, S, S, S, S, S, S } },
{ 14, 12, { S, S, S, S, S, P, P, P, P, P, C, C, S, S, S, S, S, S, S, S, S, S, S } },
{ 16, 11, { S, S, S, S, S, S, P, P, P, P, C, S, S, S, S, S, S, S, S, S, S, S, S } },
@@ -507,7 +521,7 @@ static constexpr WeatherTransition ClimateTransitionsHotAndDry[] = {
{ 21, 12, { S, S, S, S, S, S, S, P, P, P, C, T, S, S, S, S, S, S, S, S, S, S, S } },
{ 16, 13, { S, S, S, S, S, S, S, S, P, P, P, C, R, S, S, S, S, S, S, S, S, S, S } },
};
static constexpr WeatherTransition ClimateTransitionsCold[] = {
static constexpr WeatherPattern kClimatePatternsCold[] = {
{ 4, 18, { S, S, S, S, P, P, P, P, P, C, C, C, C, C, C, C, R, H, S, S, S, S, S } },
{ 5, 21, { S, S, S, S, P, P, P, P, P, C, C, C, C, C, C, C, C, C, R, H, T, S, S } },
{ 7, 17, { S, S, S, S, P, P, P, P, P, P, P, C, C, C, C, R, H, S, S, S, S, S, S } },
@@ -518,11 +532,11 @@ static constexpr WeatherTransition ClimateTransitionsCold[] = {
{ 6, 16, { S, S, P, P, P, P, C, C, C, C, C, C, R, R, H, T, S, S, S, S, S, S, S } },
};
const WeatherTransition* ClimateTransitions[] = {
ClimateTransitionsCoolAndWet,
ClimateTransitionsWarm,
ClimateTransitionsHotAndDry,
ClimateTransitionsCold,
const WeatherPattern* kClimatePatterns[] = {
kClimatePatternsCoolAndWet,
kClimatePatternsWarm,
kClimatePatternsHotAndDry,
kClimatePatternsCold,
};
#pragma endregion

View File

@@ -50,15 +50,6 @@ enum class WeatherLevel
Heavy,
};
struct WeatherState
{
int8_t TemperatureDelta;
WeatherEffectType EffectLevel;
int8_t GloomLevel;
WeatherLevel Level;
uint32_t SpriteId;
};
struct ClimateState
{
WeatherType Weather;