ksys/world: Implement more EnvMgr blood moon functions

This commit is contained in:
Léo Lam 2021-05-13 15:24:51 +02:00
parent 3af5a55a65
commit d090c3881b
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
4 changed files with 151 additions and 5 deletions

View File

@ -89267,10 +89267,10 @@
0x00000071010db52c,wm::SkyMgr::getConcentrationBM,16,_ZNK4ksys5world6EnvMgr18getConcentrationBMEv
0x00000071010db53c,wm::SkyMgr::activateForcedBloodMoon,64,_ZN4ksys5world6EnvMgr23activateForcedBloodMoonEv
0x00000071010db57c,wm::SkyMgr::setBloodMoonTempProhibited,36,_ZN4ksys5world6EnvMgr23setBloodMoonProhibitionEb
0x00000071010db5a0,sub_71010DB5A0,1116,
0x00000071010db5a0,sub_71010DB5A0,1116,_ZN4ksys5world6EnvMgr21updateForcedBloodMoonEv
0x00000071010db9fc,wm::SkyMgr::isFadeOrFadeDemoScreenOpened,352,
0x00000071010dbb5c,wm::SkyMgr::updateBloodMoon,792,
0x00000071010dbe74,wm::SkyMgr::updateBloodMoonFlags,964,
0x00000071010dbe74,wm::SkyMgr::updateBloodMoonFlags,964,_ZN4ksys5world6EnvMgr20updateBloodMoonFlagsEv
0x00000071010dc238,wm::SkyMgr::return0,8,
0x00000071010dc240,wm::SkyMgr::x_4,56,
0x00000071010dc278,wm::SkyMgr::x,52,
@ -89285,7 +89285,7 @@
0x00000071010dc650,wm::SkyMgr::x_2,68,
0x00000071010dc694,wm::SkyMgr::setWarpMistTimer,68,
0x00000071010dc6d8,wm::SkyMgr::setFogDirect,104,
0x00000071010dc740,wm::SkyMgr::getBloodMoonProgress,56,
0x00000071010dc740,wm::SkyMgr::getBloodMoonProgress,56,_ZNK4ksys5world6EnvMgr20getBloodMoonProgressEv
0x00000071010dc778,sub_71010DC778,16,
0x00000071010dc788,wm::SkyMgr::rtti1,204,_ZNK4ksys5world6EnvMgr27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x00000071010dc854,wm::SkyMgr::rtti2,92,_ZNK4ksys5world6EnvMgr18getRuntimeTypeInfoEv

Can't render this file because it is too large.

View File

@ -1,5 +1,7 @@
#include "KingSystem/World/worldEnvMgr.h"
#include "KingSystem/Event/evtManager.h"
#include "KingSystem/GameData/gdtManager.h"
#include "KingSystem/System/VFR.h"
#include "KingSystem/World/worldManager.h"
namespace ksys::world {
@ -299,7 +301,7 @@ bool EnvMgr::isBloodMoonNight() const {
bool bm = false;
bm |= wm->getTimeMgr()->isBloodyDay();
bm |= wm->getTimeMgr()->wasBloodyDay() && time < 1_h;
bm |= wm->getTimeMgr()->getBloodMoonForceMode() != TimeMgr::BloodMoonForceMode::Disabled;
bm |= wm->getTimeMgr()->isBloodMoonForced();
return bm;
}
@ -322,6 +324,138 @@ void EnvMgr::setBloodMoonProhibition(bool prohibited) {
mBloodMoonProhibited = prohibited;
}
// FIXME: remove this once EnvMgr::isLoadingScreenOpened is implemented
// This is necessary because Clang would otherwise pass this to the member function
// as it can't see that "this" is unused
bool isLoadingScreenOpened_TEMP();
void EnvMgr::updateForcedBloodMoon() {
static constexpr float BloodMoonTimerDuration = 90.0f;
switch (mForcedBloodMoonStatus) {
case 0:
// Wait for a forced blood moon to be requested
if (!mForcedBloodMoonRequested || evt::Manager::instance()->hasActiveEvent())
break;
mForcedBloodMoonTimer = 0.0f;
mForcedBloodMoonReady = false;
++mForcedBloodMoonStatus;
break;
case 1:
// Update the forced blood moon timer
if (evt::Manager::instance()->hasActiveEvent() || mBloodMoonProhibited) {
mForcedBloodMoonTimer -= VFR::instance()->getDeltaTime();
if (mForcedBloodMoonTimer <= 0.0f) {
mForcedBloodMoonTimer = 0.0f;
mForcedBloodMoonStatus = 0;
mForcedBloodMoonReady = false;
}
} else {
mForcedBloodMoonTimer += VFR::instance()->getDeltaTime();
if (mForcedBloodMoonTimer >= BloodMoonTimerDuration) {
mForcedBloodMoonTimer = BloodMoonTimerDuration;
mForcedBloodMoonReady = true;
++mForcedBloodMoonStatus;
}
}
break;
case 2:
// Wait for the blood moon cutscene to be triggered externally
if (mBloodMoonProhibited && !mDeactivateForcedBloodMoon) {
mForcedBloodMoonStatus = 4;
mForcedBloodMoonReady = false;
break;
}
if (mForcedBloodMoonReady || isLoadingScreenOpened_TEMP())
break;
mForcedBloodMoonTimer = BloodMoonTimerDuration;
++mForcedBloodMoonStatus;
break;
case 3:
// Slowly fade out the blood moon state
mForcedBloodMoonTimer -= VFR::instance()->getDeltaTime();
if (mForcedBloodMoonTimer <= 0.0f) {
mForcedBloodMoonTimer = 0.0f;
mForcedBloodMoonStatus = 0;
mForcedBloodMoonRequested = false;
mForcedBloodMoonReady = false;
mDeactivateForcedBloodMoon = false;
}
break;
case 4:
// [Alternative state 2] Wait for blood moons to be allowed again
if (mBloodMoonProhibited && !mDeactivateForcedBloodMoon) {
mForcedBloodMoonTimer -= VFR::instance()->getDeltaTime();
if (mForcedBloodMoonTimer <= 0.0f) {
mForcedBloodMoonTimer = 0.0f;
mForcedBloodMoonStatus = 0;
return;
}
} else {
mForcedBloodMoonTimer += VFR::instance()->getDeltaTime();
if (mForcedBloodMoonTimer >= BloodMoonTimerDuration) {
mForcedBloodMoonTimer = BloodMoonTimerDuration;
mForcedBloodMoonReady = true;
mForcedBloodMoonStatus = 2;
}
}
break;
}
if (mForcedBloodMoonStatus == 1) {
const float progress = mForcedBloodMoonTimer / BloodMoonTimerDuration;
if (mBloodMoonStartState != 2) {
mBloodMoonEndState = mBloodMoonStartState;
mBloodMoonStartState = 2;
}
mBloodMoonProgress = progress;
} else if (mForcedBloodMoonStatus >= 2) {
const float progress = mForcedBloodMoonTimer / -BloodMoonTimerDuration + 1.0f;
if (mBloodMoonEndState != 2) {
mBloodMoonStartState = mBloodMoonEndState;
mBloodMoonEndState = 2;
}
mBloodMoonProgress = progress;
}
}
void EnvMgr::updateBloodMoonFlags() {
auto* wm = Manager::instance();
const auto time = wm->getTimeMgr()->getTimeForSkyEnv();
if (!wm->isMainField())
return;
bool bloody_night = false;
bloody_night |= time >= 21_h && isBloodMoonNight();
bloody_night |= wm->getTimeMgr()->wasBloodyDay() && time < 1_h;
bloody_night |= wm->getTimeMgr()->isBloodMoonForced();
bloody_night &= !wm->getTimeMgr()->isInRelicBattle();
float concentration = 0.0;
if (bloody_night) {
if (time > timeToFloat(23, 30)) {
concentration = (time - timeToFloat(23, 30)) / timeToFloat(0, 30);
} else if (time < timeToFloat(0, 15)) {
concentration = (timeToFloat(0, 15) - time) / timeToFloat(0, 15);
}
}
mBloodMoonTimeRangeProgress = concentration;
if (!evt::Manager::instance()->hasActiveEvent() &&
!wm->getTimeMgr()->isBloodMoonProhibitionFlagSet()) {
VFR::lerp(&mConcentrationBM, concentration, 0.1, 0.01);
} else {
VFR::lerp(&mConcentrationBM, 0.0f, 0.1, 0.01);
}
if (wm->getTimeMgr()->isBloodMoonForced())
mConcentrationBM = concentration;
}
bool EnvMgr::isWaterRelicRainOn(Climate climate) const {
if (climate != Climate::ZoraTemperateClimate)
return false;
@ -334,4 +468,12 @@ bool EnvMgr::isWaterRelicRainOn(Climate climate) const {
return !on;
}
float EnvMgr::getBloodMoonProgress() const {
if (mBloodMoonStartState == 2)
return mBloodMoonProgress;
if (mBloodMoonEndState == 2)
return 1.0f - mBloodMoonProgress;
return 0.0f;
}
} // namespace ksys::world

View File

@ -187,8 +187,10 @@ public:
float getConcentrationBM() const;
void activateForcedBloodMoon();
void setBloodMoonProhibition(bool prohibited);
bool isLoadingScreenOpened() const;
bool isWaterRelicRainOn(Climate climate) const;
float getBloodMoonProgress() const;
protected:
void init_(sead::Heap* heap) override;
@ -205,6 +207,7 @@ private:
void updateTimeDivision();
void updateBloodMoon();
void updateBloodMoonFlags();
void updateForcedBloodMoon();
EnvPaletteStatic mEnvPaletteStatic;
@ -273,7 +276,7 @@ private:
u32 _6b5e8;
u32 _6b5ec;
u32 _6b5f0;
u32 mForcedBloodMoonStatus;
int mForcedBloodMoonStatus;
u32 _6b5f8;
u32 _6b5fc;
u32 mFogMode;

View File

@ -102,6 +102,7 @@ public:
return mResetGdtOnNextSceneUnloadForBloodMoon;
}
bool wasBloodyDay() const { return mWasBloodyDay; }
bool isBloodMoonForced() const { return mBloodMoonForceMode != BloodMoonForceMode::Disabled; }
gdt::FlagHandle getWaterRelicRainStopFlag() const { return mWaterRelicRainStopFlag; }