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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user