diff --git a/data/uking_functions.csv b/data/uking_functions.csv index 2e63c9d0..5d1447cd 100644 --- a/data/uking_functions.csv +++ b/data/uking_functions.csv @@ -89438,7 +89438,7 @@ Address,Quality,Size,Name 0x00000071010ea324,U,000004,wm::WeatherMgr::m0 0x00000071010ea328,U,000036,wm::WeatherMgr::m1 0x00000071010ea34c,U,001696,wm::WeatherMgr::loadInfo -0x00000071010ea9ec,U,000408,wm::WeatherMgr::rollNewWeather +0x00000071010ea9ec,O,000408,_ZN4ksys5world10WeatherMgr14rollNewWeatherENS0_7ClimateE 0x00000071010eab84,U,000460,wm::WeatherMgr::x_0 0x00000071010ead50,U,001712,wm::WeatherMgr::calc_x 0x00000071010eb400,U,000040,wm::WeatherMgr::x_6 @@ -89571,9 +89571,9 @@ Address,Quality,Size,Name 0x00000071010f29b0,U,000004,nullsub_5569 0x00000071010f29b4,O,000504,_GLOBAL__sub_I_worldManager.cpp 0x00000071010f2bac,O,000008,_ZNK4ksys5world7Manager14getWeatherTypeEv -0x00000071010f2bb4,O,000080,_ZN4ksys5world7Manager14setWeatherTypeENS0_11WeatherTypeEbbb +0x00000071010f2bb4,O,000080,_ZN4ksys5world7Manager14setWeatherTypeEjbbb 0x00000071010f2c04,O,000376,_ZN4ksys5world7Manager14setWeatherTypeERKN4sead14SafeStringBaseIcEEbbb -0x00000071010f2d7c,O,000068,_ZN4ksys5world7Manager20getWeatherTypeStringENS0_11WeatherTypeE +0x00000071010f2d7c,O,000068,_ZN4ksys5world7Manager20getWeatherTypeStringEj 0x00000071010f2dc0,O,000356,_ZNK4ksys5world7Manager10getClimateERKN4sead7Vector3IfEE 0x00000071010f2f24,O,000008,_ZNK4ksys5world7Manager17getCurrentClimateEv 0x00000071010f2f2c,O,000008,_ZNK4ksys5world7Manager14getPrevClimateEv diff --git a/src/KingSystem/World/worldDefines.h b/src/KingSystem/World/worldDefines.h index 0646c99c..85878c7e 100644 --- a/src/KingSystem/World/worldDefines.h +++ b/src/KingSystem/World/worldDefines.h @@ -33,7 +33,7 @@ enum class ScalingMode { Disabled = 1, }; -enum class WeatherType { +enum class WeatherType : u8 { Bluesky, Cloudy, Rain, diff --git a/src/KingSystem/World/worldManager.cpp b/src/KingSystem/World/worldManager.cpp index 0fe61d70..cd2d9853 100644 --- a/src/KingSystem/World/worldManager.cpp +++ b/src/KingSystem/World/worldManager.cpp @@ -66,18 +66,18 @@ WeatherType Manager::getWeatherType() const { return mWeatherType; } -void Manager::setWeatherType(WeatherType weather_type, bool x, bool y, bool for_demo) { +void Manager::setWeatherType(u32 weather_type, bool x, bool y, bool for_demo) { // Ignore invalid weather requests. - if (u32(weather_type) >= NumWeatherTypes) + if (weather_type >= NumWeatherTypes) return; if (mWeatherSetForDemo && !for_demo) return; - if (mWeatherTypeTimer != 0 && y && mWeatherType.mValue > u8(weather_type)) + if (mWeatherTypeTimer != 0 && y && mWeatherType > WeatherType(weather_type)) return; - mWeatherType = weather_type; + mWeatherType = WeatherType(weather_type); mWeatherTypeTimer = 4; _7d5 = x; mWeatherSetForDemo = for_demo; @@ -86,15 +86,15 @@ void Manager::setWeatherType(WeatherType weather_type, bool x, bool y, bool for_ void Manager::setWeatherType(const sead::SafeString& weather_type, bool x, bool y, bool for_demo) { for (u8 i = 0; i < NumWeatherTypes; ++i) { if (weather_type == cWeatherTypes[i]) { - setWeatherType(WeatherType(i), x, y, for_demo); + setWeatherType(i, x, y, for_demo); return; } } } -const char* Manager::getWeatherTypeString(WeatherType type) { - auto index = ptrdiff_t(type); - if (u32(index) >= NumWeatherTypes) +const char* Manager::getWeatherTypeString(u32 type) { + auto index = s32(type); + if (type >= NumWeatherTypes) index = 0; return cWeatherTypes[index].cstr(); } diff --git a/src/KingSystem/World/worldManager.h b/src/KingSystem/World/worldManager.h index d23d21ff..4f35fd42 100644 --- a/src/KingSystem/World/worldManager.h +++ b/src/KingSystem/World/worldManager.h @@ -96,9 +96,12 @@ class Manager : public sead::hostio::Node { public: WeatherType getWeatherType() const; - void setWeatherType(WeatherType weather_type, bool x, bool y, bool for_demo); + void setWeatherType(u32 weather_type, bool x, bool y, bool for_demo); void setWeatherType(const sead::SafeString& weather_type, bool x, bool y, bool for_demo); - static const char* getWeatherTypeString(WeatherType type); + static const char* getWeatherTypeString(u32 type); + static const char* getWeatherTypeString(WeatherType type) { + return getWeatherTypeString(u32(type)); + } Climate getClimate(const sead::Vector3f& pos) const; Climate getCurrentClimate() const; @@ -290,7 +293,7 @@ private: int mWindChangeFinalTimer = 0; float mWindSpeedAocField = 0.75; WorldInfoLoadStatus mWorldInfoLoadStatus = WorldInfoLoadStatus::NotLoaded; - sead::SizedEnum mWeatherType = WeatherType::Invalid; + WeatherType mWeatherType = WeatherType::Invalid; u8 mDirectionalLightTimer = 0; bool mEnableAutoWind = true; bool mMapEdgeWindEnabled = false; diff --git a/src/KingSystem/World/worldTimeMgr.h b/src/KingSystem/World/worldTimeMgr.h index ba374793..83427ab8 100644 --- a/src/KingSystem/World/worldTimeMgr.h +++ b/src/KingSystem/World/worldTimeMgr.h @@ -105,7 +105,7 @@ public: } bool wasBloodyDay() const { return mWasBloodyDay; } bool isBloodMoonForced() const { return mBloodMoonForceMode != BloodMoonForceMode::Disabled; } - + gdt::FlagHandle isGetPlayerStole2Flag() const { return mIsGetPlayerStole2Flag; } gdt::FlagHandle getWaterRelicRainStopFlag() const { return mWaterRelicRainStopFlag; } protected: diff --git a/src/KingSystem/World/worldWeatherMgr.cpp b/src/KingSystem/World/worldWeatherMgr.cpp index d43706ba..d3407a83 100644 --- a/src/KingSystem/World/worldWeatherMgr.cpp +++ b/src/KingSystem/World/worldWeatherMgr.cpp @@ -1 +1,39 @@ #include "KingSystem/World/worldWeatherMgr.h" +#include +#include "KingSystem/GameData/gdtManager.h" +#include "KingSystem/World/worldManager.h" + +namespace ksys::world { + +WeatherType WeatherMgr::rollNewWeather(Climate climate) { + auto* wm = Manager::instance(); + int random = sead::GlobalRandom::instance()->getU32(99); + WeatherType weather = [&] { + const std::pair rates[] = { + {WeatherType::Bluesky, wm->getWeatherBlueskyRate(climate) - 1}, + {WeatherType::Cloudy, wm->getWeatherCloudyRate(climate)}, + {WeatherType::Rain, wm->getWeatherRainRate(climate)}, + {WeatherType::HeavyRain, wm->getWeatherHeavyRainRate(climate)}, + }; + for (auto [type, rate] : rates) { + if (random <= rate) + return type; + random -= rate; + } + return WeatherType::ThunderRain; + }(); + + if (wm->getEnvMgr()->isWaterRelicRainOn(climate)) + weather = WeatherType::Bluesky; + + bool plateau_done = false; + auto glider_handle = Manager::instance()->getTimeMgr()->isGetPlayerStole2Flag(); + if (glider_handle != gdt::InvalidHandle) { + gdt::Manager::instance()->getBool(glider_handle, &plateau_done, true); + } + + if (plateau_done || weather == WeatherType::Bluesky || weather == WeatherType::Cloudy) + return weather; + return WeatherType::Bluesky; +} +} // namespace ksys::world diff --git a/src/KingSystem/World/worldWeatherMgr.h b/src/KingSystem/World/worldWeatherMgr.h index 0a6b8df9..e7740cb9 100644 --- a/src/KingSystem/World/worldWeatherMgr.h +++ b/src/KingSystem/World/worldWeatherMgr.h @@ -1,10 +1,18 @@ #pragma once #include "KingSystem/Utils/Types.h" +#include "KingSystem/World/worldDefines.h" #include "KingSystem/World/worldJob.h" namespace ksys::world { +constexpr u32 NumWeatherCycles = 3; + +// This may be incorrect +struct ClimateWeathers { + s32 weather[NumWeatherCycles]; +}; + // TODO class WeatherMgr : public Job { public: @@ -17,8 +25,22 @@ public: void rerollClimateWindPowers(); static bool isExposureZero(); + void loadInfo(); + WeatherType rollNewWeather(Climate climate); + bool x_0(); - u8 _20[0x398 - 0x20]; + u8 _20[0x24 - 0x20]; + float _24; + // Unsure of the type / variable + u8 weather; + u8 _29; + WeatherType _2a[NumClimates * NumWeatherCycles * 6]; + u8 _193; + ClimateWeathers mClimateWeathers[NumClimates]; // 0x194 + u8 _284[0x318 - 0x284]; + float mTimeBlock; // 0x318 + u32 mWeekDay; // 0x31c + u8 _31c[0x398 - 0x320]; }; KSYS_CHECK_SIZE_NX150(WeatherMgr, 0x398);