mirror of https://github.com/zeldaret/botw.git
ksys/world: Implement more EnvMgr blood moon functions
This commit is contained in:
parent
3af5a55a65
commit
d090c3881b
|
|
@ -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.
|
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue