diff options
| author | Léo Lam <leo@leolam.fr> | 2021-05-02 11:18:59 +0200 |
|---|---|---|
| committer | Léo Lam <leo@leolam.fr> | 2021-05-02 17:48:37 +0200 |
| commit | da65708ded005b1613ce868337952d72bdf80e4d (patch) | |
| tree | e715b5f4ba3137c9d78330740fdf4e15caae365c /src/KingSystem/World/worldTimeMgr.cpp | |
| parent | e5e2427c8bf997469c5f99bdb95cf8e75d844ebc (diff) | |
ksys/world: Implement more TimeMgr functions
Diffstat (limited to 'src/KingSystem/World/worldTimeMgr.cpp')
| -rw-r--r-- | src/KingSystem/World/worldTimeMgr.cpp | 234 |
1 files changed, 227 insertions, 7 deletions
diff --git a/src/KingSystem/World/worldTimeMgr.cpp b/src/KingSystem/World/worldTimeMgr.cpp index b914772b..2c7eff5e 100644 --- a/src/KingSystem/World/worldTimeMgr.cpp +++ b/src/KingSystem/World/worldTimeMgr.cpp @@ -1,5 +1,6 @@ #include "KingSystem/World/worldTimeMgr.h" #include "KingSystem/GameData/gdtManager.h" +#include "KingSystem/World/worldManager.h" namespace ksys::world { @@ -16,7 +17,7 @@ TimeMgr::TimeMgr() { mForceBloodyDay = false; _14b = false; _cc = {}; - mMoonType = MoonType::Unknown; + mMoonType = MoonType::Auto; } void TimeMgr::init_(sead::Heap* heap) { @@ -24,7 +25,7 @@ void TimeMgr::init_(sead::Heap* heap) { mTimeForAocFieldSkyEnv = DefaultTime; mTimeStep = DefaultTimeStep; mTimeUpdateMode = {}; - mBloodMoonTimer = 0.0; + resetBloodMoonTimer(); mBloodyEndReserveTimer = 0; } @@ -41,21 +42,240 @@ void TimeMgr::resetForStageUnload() { _30[9]._4 = -1; gdt::Manager::instance()->setBool(false, mAnimalMasterCtrl.appearance_flag); - mAnimalMasterCtrl.state = {}; - mAnimalMasterCtrl.appearance_hour = {}; - mAnimalMasterCtrl.valid_hour = {}; - mAnimalMasterCtrl.start_day_of_week = {}; + mAnimalMasterCtrl.resetState(); +} + +void TimeMgr::loadInfo() { + mTimeStep = DefaultTimeStep; + mTimeUpdateMode = TimeUpdateMode::Normal; + mForceBloodyDay = false; + _14b = false; + _cc = 0.0; + mMoonType = MoonType::Auto; + + loadFlags(); + + if (mIsPlayedDemo103Flag != gdt::InvalidHandle) { + gdt::Manager::instance()->getBool(mIsPlayedDemo103Flag, &mPlayedDemo103Or997, true); + if (!mPlayedDemo103Or997) + gdt::Manager::instance()->getBool(mDemo997Flag, &mPlayedDemo103Or997, true); + } + + if (mFindDungeonActivatedFlag != gdt::InvalidHandle) + gdt::Manager::instance()->getBool(mFindDungeonActivatedFlag, &mFindDungeonActivated, true); + + bool animal_master_appearance = false; + gdt::Manager::instance()->getBool(mAnimalMasterCtrl.appearance_flag, &animal_master_appearance); + if (!animal_master_appearance) { + mAnimalMasterCtrl.resetState(); + } + + mWasBloodyDayAndDayPassed = false; +} + +void TimeMgr::loadFlags() { + mTimeFlag = gdt::Manager::instance()->getF32Handle("WM_Time"); + mNumberOfDaysFlag = gdt::Manager::instance()->getS32Handle("WM_NumberOfDays"); + mTimeDivisionFlag = gdt::Manager::instance()->getS32Handle("WM_TimeDivision"); + + gdt::Manager::instance()->getF32(mTimeFlag, &mTime); + gdt::Manager::instance()->getS32(mNumberOfDaysFlag, &mNumberOfDays); + gdt::Manager::instance()->getS32(mTimeDivisionFlag, &mTimeDivision); + + mIsDaytimeFlag = gdt::Manager::instance()->getBoolHandle("WM_DaytimeFlag"); + mIsNighttimeFlag = gdt::Manager::instance()->getBoolHandle("WM_NighttimeFlag"); + mIsPlayedDemo103Flag = gdt::Manager::instance()->getBoolHandle("IsPlayed_Demo103_0"); + mDemo997Flag = gdt::Manager::instance()->getBoolHandle("Demo997_0"); + mFindDungeonActivatedFlag = gdt::Manager::instance()->getBoolHandle("FindDungeon_Activated"); + mIsMorningAFlag = gdt::Manager::instance()->getBoolHandle("WM_IsMorningA"); + mIsMorningBFlag = gdt::Manager::instance()->getBoolHandle("WM_IsMorningB"); + mIsNoonAFlag = gdt::Manager::instance()->getBoolHandle("WM_IsNoonA"); + mIsNoonBFlag = gdt::Manager::instance()->getBoolHandle("WM_IsNoonB"); + mIsEveningAFlag = gdt::Manager::instance()->getBoolHandle("WM_IsEveningA"); + mIsEveningBFlag = gdt::Manager::instance()->getBoolHandle("WM_IsEveningB"); + mIsNightAFlag = gdt::Manager::instance()->getBoolHandle("WM_IsNightA"); + mIsNightBFlag = gdt::Manager::instance()->getBoolHandle("WM_IsNightB"); + mWaterRelicRainStopFlag = gdt::Manager::instance()->getBoolHandle("Water_Relic_RainStop"); + mIsGetPlayerStole2Flag = gdt::Manager::instance()->getBoolHandle("IsGet_PlayerStole2"); + mBloodyDayFlag = gdt::Manager::instance()->getBoolHandle("WM_BloodyDay"); + + mBloodyMoonTimerFlag = gdt::Manager::instance()->getF32Handle("WM_BloodyMoonTimer"); + gdt::Manager::instance()->getF32(mBloodyMoonTimerFlag, &mBloodMoonTimer); + + mBloodyEndReserveTimerFlag = gdt::Manager::instance()->getS32Handle("WM_bloodyEndReserveTimer"); + if (mBloodyEndReserveTimerFlag != gdt::InvalidHandle) + gdt::Manager::instance()->getS32(mBloodyEndReserveTimerFlag, &mBloodyEndReserveTimer); + + mAnimalMasterCtrl.appearance_flag = + gdt::Manager::instance()->getBoolHandle("AnimalMaster_Appearance"); + mAnimalMasterCtrl.existence_flag = + gdt::Manager::instance()->getBoolHandle("AnimalMaster_Existence"); + + mIsInHyruleCastleAreaFlag = gdt::Manager::instance()->getBoolHandle("IsInHyruleCastleArea"); + mLastBossGanonBeastGenerateFlag = + gdt::Manager::instance()->getBoolHandle("LastBossGanonBeastGenerateFlag"); + mWindRelicBattleStartFlag = gdt::Manager::instance()->getBoolHandle("Wind_Relic_BattleStart"); + mElectricRelicBattleFlag = gdt::Manager::instance()->getBoolHandle("Electric_Relic_Battle"); + mWaterRelicBattleTimeFlag = gdt::Manager::instance()->getBoolHandle("Water_Relic_BattleTime"); + mBloodyMoonProhibitionFlag = gdt::Manager::instance()->getBoolHandle("BloodyMoonProhibition"); } TimeMgr::~TimeMgr() = default; +bool TimeMgr::isBloodMoonProhibited() const { + bool prohibited = !Manager::instance()->isMainField(); + + if (gdt::Manager::instance()) { + bool castle = false; + gdt::Manager::instance()->getBool(mIsInHyruleCastleAreaFlag, &castle); + if (castle) + prohibited = true; + + bool last_boss = false; + gdt::Manager::instance()->getBool(mLastBossGanonBeastGenerateFlag, &last_boss); + if (last_boss) + prohibited = true; + } + + if (isBloodMoonProhibitionFlagSet()) + prohibited = true; + + return prohibited; +} + +bool TimeMgr::isBloodMoonProhibitionFlagSet() const { + bool value = false; + if (mBloodyMoonProhibitionFlag == gdt::InvalidHandle) + return false; + gdt::Manager::instance()->getBool(mBloodyMoonProhibitionFlag, &value); + return value; +} + +bool TimeMgr::isInRelicBattle() const { + auto* wm = Manager::instance(); + bool in_battle = false; + + if (gdt::Manager::instance()) { + bool value = false; + gdt::Manager::instance()->getBool(mWindRelicBattleStartFlag, &value); + if (value) + in_battle = true; + + value = false; + gdt::Manager::instance()->getBool(mElectricRelicBattleFlag, &value); + if (value) + in_battle = true; + + value = false; + gdt::Manager::instance()->getBool(mWaterRelicBattleTimeFlag, &value); + if (value) + in_battle = true; + } + + if (wm->getSkyMgr()->checkConcentrationDarkness()) + in_battle = true; + + return in_battle; +} + void TimeMgr::calcType1_() {} void TimeMgr::calcType2_() {} -void TimeMgr::setNewTime(float time) { +void TimeMgr::resetBloodMoonTimer() { + mBloodMoonTimer = 0.0; +} + +void TimeMgr::setTimeWithoutDayChecks(float time) { if (time >= 0.0) mNewTime = time; } +void TimeMgr::setTime(float time) { + auto* wm = Manager::instance(); + mNewTime = time; + mWasBloodyDayAndDayPassed = false; + + if (mTime > mNewTime) { + mNeedToHandleNewDay = true; + + bool was_bloody_day = false; + if (gdt::Manager::instance()) { + if (!gdt::Manager::instance()->getBool(mBloodyDayFlag, &was_bloody_day, false, true)) + return; + + if (was_bloody_day) + mWasBloodyDayAndDayPassed = true; + + if (mWasBloodyDayAndDayPassed && !wm->isMainField()) { + mWasBloodyDayAndDayPassed = false; + mResetGdtOnNextSceneUnloadForBloodMoon = true; + } + } + } +} + +bool TimeMgr::isBloodyDay() const { + bool value = false; + if (!gdt::Manager::instance()) + return false; + gdt::Manager::instance()->getBool(mBloodyDayFlag, &value); + return value; +} + +float TimeMgr::getTimeForSkyEnv() const { + if (Manager::instance()->getStageType() == StageType::OpenWorld && + Manager::instance()->getFieldType() == FieldType::AocField && + Manager::instance()->getScalingMode() == ScalingMode::Disabled) { + return mTimeForAocFieldSkyEnv; + } + return mTime; +} + +void TimeMgr::setAocFieldTimeForSkyEnv(float time) { + mTimeForAocFieldSkyEnv = time; +} + +int TimeMgr::getHour() const { + auto hour = int(mTime / durationToFloat(1, 0)); + if (hour >= 24) + hour -= 24; + return hour; +} + +MoonType TimeMgr::getMoonType() const { + auto type = MoonType(u32(mNumberOfDays + (mTime > timeToFloat(12, 0)) + 1) % 8); + + if (mMoonType != MoonType::Auto) + type = mMoonType; + + if (!willBloodMoonHappenTonight() && !mWasBloodyDay) + return type; + + return MoonType::FullMoon; +} + +bool TimeMgr::willBloodMoonHappenTonight() const { + return Manager::instance()->getTimeMgr()->getHour() >= 4 && isBloodyDay(); +} + +float TimeMgr::getTemperatureMultiplier() const { + const auto time = Manager::instance()->getTimeMgr()->getTime(); + + if (time > 4_h && time < 9_h) + return (time - 4_h) / (4_h - 9_h) + 1.0f; + + if (time >= 9_h && time < 16_h) + return 0.0f; + + if (time >= 16_h && time < 21_h) + return (21_h - time) / (16_h - 21_h) + 1.0f; + + return 1.0f; +} + +bool TimeMgr::isTimeFlowingNormally() const { + return mIsTimeFlowingNormally; +} + } // namespace ksys::world |
