summaryrefslogtreecommitdiff
path: root/src/KingSystem/World/worldTimeMgr.cpp
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-05-02 11:18:59 +0200
committerLéo Lam <leo@leolam.fr>2021-05-02 17:48:37 +0200
commitda65708ded005b1613ce868337952d72bdf80e4d (patch)
treee715b5f4ba3137c9d78330740fdf4e15caae365c /src/KingSystem/World/worldTimeMgr.cpp
parente5e2427c8bf997469c5f99bdb95cf8e75d844ebc (diff)
ksys/world: Implement more TimeMgr functions
Diffstat (limited to 'src/KingSystem/World/worldTimeMgr.cpp')
-rw-r--r--src/KingSystem/World/worldTimeMgr.cpp234
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