#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 { EnvMgr::EnvMgr() { mForcedBloodMoonRequested = false; mDeactivateForcedBloodMoon = false; mForcedBloodMoonReady = false; mBloodMoonProhibited = false; mForcedBloodMoonStatus = {}; mForcedBloodMoonTimer = {}; reset(); for (int i = 0; i < mEnvAttributes.size(); ++i) initEnvAttribute(i); for (int i = 0; i < mEnvPalettes.size(); ++i) initEnvPalette(i); for (int i = 0; i < mWeatherInfluences.size(); ++i) initWeatherInfluence(i); for (int i = 0; i < mRemains.size(); ++i) initRemains(i); initIndoorPalette(); initEnvPaletteStatic(); initDungeonFog(); mDungeonSizeType = DungeonSize::M; _6b5b0 = 1.0; } EnvMgr::EnvPaletteStatic::EnvPaletteStatic() = default; void EnvMgr::initEnvAttribute(int idx) { auto& attr = mEnvAttributes[idx]; if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &attr.obj; attr.DifUse.init(false, "DifUse", "", obj); attr.DifXang.init(0.0, "DifXang", "", obj); attr.DifYang.init(0.0, "DifYang", "", obj); attr.PaletteSel00.init(8 * idx, "PaletteSel00", "", obj); attr.PaletteSel01.init(8 * idx + 1, "PaletteSel01", "", obj); attr.PaletteSel02.init(8 * idx + 2, "PaletteSel02", "", obj); attr.PaletteSel03.init(8 * idx + 3, "PaletteSel03", "", obj); attr.PaletteSel04.init(8 * idx + 4, "PaletteSel04", "", obj); attr.PaletteSel05.init(8 * idx + 5, "PaletteSel05", "", obj); attr.PaletteSel06.init(8 * idx + 6, "PaletteSel06", "", obj); attr.PaletteSel07.init(8 * idx + 7, "PaletteSel07", "", obj); } void EnvMgr::initEnvPalette(int idx) { auto& pal = mEnvPalettes[idx]; if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &pal.obj; pal.BgDifColor.init({1.0, 0.894, 0.68, 0.0}, "BgDifColor", "", obj); pal.BgDifIntencity.init(8.0, "BgDifIntencity", "", obj); pal.FogColor.init({0.535, 0.763, 0.568, 0.4}, "FogColor", "", obj); pal.FogStart.init(0.0, "FogStart", "", obj); pal.FogEnd.init(600.0, "FogEnd", "", obj); pal.YFogColor.init({1.288, 0.992, 0.178, 0.8}, "YFogColor", "", obj); pal.YFogStart.init(0.0, "YFogStart", "", obj); pal.SkySunColorNoUse.init(1, "SkySunColorNoUse", "", obj); pal.SkySunColor.init({1.0, 0.894, 0.68, 10.0}, "SkySunColor", "", obj); pal.SkyIsotropicfade.init(0.0, "SkyIsotropicfade", "", obj); pal.SfParam_near.init(0.0, "SfParam_near", "", obj); pal.SfParam_attenuation.init(15.0, "SfParam_attenuation", "", obj); pal.SfParam_horizontal.init(2.4, "SfParam_horizontal", "", obj); pal.afParam_attenuationForGrd.init(2.5, "afParam_attenuationForGrd", "", obj); pal.afParam_attenuationForSky.init(0.25, "afParam_attenuationForSky", "", obj); pal.SkyRParam_rayleigh_amplifier.init(1.0, "SkyRParam_rayleigh_amplifier", "", obj); pal.SkyRParam_mie_symmetricalProperty.init(0.8, "SkyRParam_mie_symmetricalProperty", "", obj); pal.SkyRParam_mie_amplifier.init(2.0, "SkyRParam_mie_amplifier", "", obj); pal.AmplifierForEnvMap.init(5.0, "AmplifierForEnvMap", "", obj); pal.cloud.Cloud0_ColorBase.init({0.956, 0.643137, 0.0, 0.835}, "Cloud0_ColorBase", "", obj); pal.cloud.Cloud0_IntencityBase.init(0.376, "Cloud0_IntencityBase", "", obj); pal.cloud.Cloud0_ColorHilight.init({0.8, 0.92, 0.557, 1.0}, "Cloud0_ColorHilight", "", obj); pal.cloud.Cloud0_IntencityHilight.init(11.76, "Cloud0_IntencityHilight", "", obj); pal.cloud.Cloud0_ColorShadow.init({0.44, 0.577, 0.61, 1.0}, "Cloud0_ColorShadow", "", obj); pal.cloud.Cloud0_IntencityShadow.init(1.0, "Cloud0_IntencityShadow", "", obj); pal.cloud.Cloud0_ColorBackLight.init({1.0, 0.95, 0.645, 1.0}, "Cloud0_ColorBackLight", "", obj); const u32 i = idx - 8; if (i < 8) pal.Cloud0_BacklightPower.init(1.2, "Cloud0_BacklightPower", "", obj); else pal.Cloud0_BacklightPower.init(1.6, "Cloud0_BacklightPower", "", obj); pal.cloud.Cloud1_ColorBase.init({1.0, 1.0, 1.0, 1.0}, "Cloud1_ColorBase", "", obj); pal.cloud.Cloud1_IntencityBase.init(0.0, "Cloud1_IntencityBase", "", obj); pal.cloud.Cloud1_ColorHilight.init({1.0, 1.0, 1.0, 1.0}, "Cloud1_ColorHilight", "", obj); pal.cloud.Cloud1_IntencityHilight.init(0.0, "Cloud1_IntencityHilight", "", obj); pal.cloud.Cloud1_ColorShadow.init({1.0, 1.0, 1.0, 1.0}, "Cloud1_ColorShadow", "", obj); pal.cloud.Cloud1_IntencityShadow.init(0.0, "Cloud1_IntencityShadow", "", obj); pal.cloud.Cloud1_ColorBackLight.init({1.0, 1.0, 1.0, 1.0}, "Cloud1_ColorBackLight", "", obj); if (i < 8) pal.Cloud1_BacklightPower.init(1.2, "Cloud1_BacklightPower", "", obj); else pal.Cloud1_BacklightPower.init(1.6, "Cloud1_BacklightPower", "", obj); pal.cloud.Cloud2_ColorBase.init({1.0, 0.91, 0.72, 1.0}, "Cloud2_ColorBase", "", obj); pal.cloud.Cloud2_IntencityBase.init(1.0, "Cloud2_IntencityBase", "", obj); pal.cloud.Cloud2_ColorHilight.init({1.0, 0.91, 0.72, 1.0}, "Cloud2_ColorHilight", "", obj); pal.cloud.Cloud2_IntencityHilight.init(48.0, "Cloud2_IntencityHilight", "", obj); pal.cloud.Cloud2_ColorShadow.init({0.0, 0.541, 0.437, 0.994}, "Cloud2_ColorShadow", "", obj); pal.cloud.Cloud2_IntencityShadow.init(2.0, "Cloud2_IntencityShadow", "", obj); pal.cloud.Cloud2_ColorBackLight.init({0.0, 0.0, 0.0, 0.0}, "Cloud2_ColorBackLight", "", obj); if (i < 8) pal.Cloud2_BacklightPower.init(1.2, "Cloud2_BacklightPower", "", obj); else pal.Cloud2_BacklightPower.init(1.6, "Cloud2_BacklightPower", "", obj); pal.Cloud2NoUse.init(1, "Cloud2NoUse", "", obj); pal.CloudShadowOnOff.init(true, "CloudShadowOnOff", "", obj); pal.BloomOffsetStart.init(19999.0, "BloomOffsetStart", "", obj); pal.BloomOffsetEnd.init(20000.0, "BloomOffsetEnd", "", obj); pal.BloomOffset.init(2.0, "BloomOffset", "", obj); pal.BloomClampedLuminance.init(64.0, "BloomClampedLuminance", "", obj); pal.BloomThreshhold.init(2.0, "BloomThreshhold", "", obj); pal.BloomIntencity.init(0.1, "BloomIntencity", "", obj); pal.VolumeMaskColorNoUse.init(1, "VolumeMaskColorNoUse", "", obj); pal.VolumeMaskColor.init({1.0, 1.0, 1.0, 1.0}, "VolumeMaskColor", "", obj); pal.VolumeMaskIntencity.init(1.0, "VolumeMaskIntencity", "", obj); pal.AmbientIntencity.init(1.0, "AmbientIntencity", "", obj); pal.Exposure.init(0.0, "Exposure", "", obj); } void EnvMgr::initWeatherInfluence(int idx) { auto& entry = mWeatherInfluences[idx]; if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &entry.obj; entry.FeatureColor.init({1.0, 1.0, 1.0, 1.0}, "FeatureColor", "", obj); entry.FeatureFogColor.init({1.0, 1.0, 1.0, 1.0}, "FeatureFogColor", "", obj); entry.CalcRayleigh.init(1.0, "CalcRayleigh", "", "Min=0.0f, Max=2.0f", obj); entry.CalcMieSymmetrical.init(1.0, "CalcMieSymmetrical", "", "Min=0.0f, Max=10.0f", obj); entry.CalcMie.init(1.0, "CalcMie", "", "Min=0.0f, Max=100.0f", obj); entry.CalcVolumeMaskIntencity.init(1.0, "CalcVolumeMaskIntencity", "", "Min=0.0f, Max=20.0f", obj); entry.BloomThreshhold.init(1.0, "BloomThreshhold", "", "Min=0.0f, Max=2.0f", obj); entry.BloomIntencity.init(1.0, "BloomIntencity", "", "Min=0.0f, Max=2.0f", obj); entry.AddMoisture.init(0.0, "AddMoisture", "", "Min=0.0f, Max=100.0f", obj); } void EnvMgr::initRemains(int idx) { auto& entry = mRemains[idx]; if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &entry.obj; entry.FeatureColor.init({1.0, 1.0, 1.0, 1.0}, "FeatureColor", "", obj); entry.FeatureFogColor.init({1.0, 1.0, 1.0, 1.0}, "FeatureFogColor", "", obj); entry.AddFog_near.init(0.0, "AddFog_near", "", obj); entry.AddFog_far.init(300.0, "AddFog_far", "", obj); entry.AddFog_ratio.init(0.0, "AddFog_ratio", "", obj); entry.SfParam_near.init(0.0, "SfParam_near", "", obj); entry.SfParam_attenuation.init(0.0, "SfParam_attenuation", "", obj); entry.CalcRayleigh.init(1.0, "CalcRayleigh", "", obj); entry.CalcMieSymmetrical.init(1.0, "CalcMieSymmetrical", "", obj); entry.CalcMie.init(1.0, "CalcMie", "", obj); entry.BloomThreshhold.init(1.0, "BloomThreshhold", "", obj); entry.BloomIntencity.init(1.0, "BloomIntencity", "", obj); entry.CalcVolumeMaskIntencity.init(1.0, "CalcVolumeMaskIntencity", "", obj); } void EnvMgr::initIndoorPalette() { if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &mIndoorPalette.obj; mIndoorPalette.FeatureColor.init({0.5, 0.342, 0.274, 0.175}, "FeatureColor", "", obj); mIndoorPalette.CalcVolumeMaskIntencity.init(2.0, "CalcVolumeMaskIntencity", "", obj); mIndoorPalette.BloomClampedLuminance.init(64.0, "BloomClampedLuminance", "", obj); mIndoorPalette.BloomThreshhold.init(2.0, "BloomThreshhold", "", obj); mIndoorPalette.BloomIntencity.init(3.0, "BloomIntencity", "", obj); mIndoorPalette.IndoorFogRatio.init(0.175, "IndoorFogRatio", "", obj); mIndoorPalette.IndoorFogStart.init(5.0, "IndoorFogStart", "", obj); mIndoorPalette.IndoorFogEnd.init(15.0, "IndoorFogEnd", "", obj); mIndoorPalette.attenuationForGrd.init(0.75, "attenuationForGrd", "", obj); } void EnvMgr::initEnvPaletteStatic() { if (Manager::instance()->worldInfoLoaded()) return; auto* obj = &mEnvPaletteStatic.obj; mEnvPaletteStatic.rayleigh_baseHeigh.init(20.0, "rayleigh_baseHeigh", "", obj); mEnvPaletteStatic.mie_baseHeight.init(2.0, "mie_baseHeight", "", obj); mEnvPaletteStatic.mie_scatteringCoeff.init(0.0018, "mie_scatteringCoeff", "", obj); mEnvPaletteStatic.mie_symmetricalPropert.init(0.8, "mie_symmetricalPropert", "", obj); mEnvPaletteStatic.YFogEnd.init(160.0, "YFogEnd", "", obj); mEnvPaletteStatic.SfParam_far.init(24000.0, "SfParam_far", "", obj); mEnvPaletteStatic.SfParam_density.init(0.85, "SfParam_density", "", obj); mEnvPaletteStatic.BloomComposeColorNoUse_8_8.init(0, "BloomComposeColorNoUse_8_8", "", obj); mEnvPaletteStatic.BloomLayerColor_8_8.init({1.0, 1.0, 1.0, 0.5}, "BloomLayerColor_8_8", "", obj); mEnvPaletteStatic.BloomLayerColorNoUse_16_16.init(0, "BloomLayerColorNoUse_16_16", "", obj); mEnvPaletteStatic.BloomLayerColor_16_16.init({1.0, 1.0, 1.0, 1.0}, "BloomLayerColor_16_16", "", obj); mEnvPaletteStatic.BloomLayerColorNoUse_32_32.init(1, "BloomLayerColorNoUse_32_32", "", obj); mEnvPaletteStatic.BloomLayerColor_32_32.init({1.0, 1.0, 1.0, 1.0}, "BloomLayerColor_32_32", "", obj); mEnvPaletteStatic.BloomLayerColorNoUse_64_64.init(1, "BloomLayerColorNoUse_64_64", "", obj); mEnvPaletteStatic.BloomLayerColor_64_64.init({1.0, 1.0, 1.0, 0.0}, "BloomLayerColor_64_64", "", obj); mEnvPaletteStatic.BloomComposeColor.init({1.0, 1.0, 1.0, 1.0}, "BloomComposeColor", "", obj); } KSYS_ALWAYS_INLINE void EnvMgr::initDungeonFog() { if (Manager::instance()->worldInfoLoaded()) return; for (int i = 0; i < mCdanAddFog.size(); ++i) { auto& entry = mCdanAddFog[i]; auto* obj = &entry.obj; entry.DungeonFogFogEnd.init(300.0, "DungeonFogFogEnd", "", obj); entry.DungeonFogVolA.init(10.0, "DungeonFogVolA", "", obj); } } EnvMgr::~EnvMgr() = default; void EnvMgr::init_(sead::Heap* heap) { mBloodMoonEndState = {}; mBloodMoonStartState = {}; mBloodMoonProgress = 1.0; } void EnvMgr::calc_() {} void EnvMgr::updateTimeDivision() { auto* wm = Manager::instance(); const auto time = wm->getTimeMgr()->getTimeForSkyEnv(); float transition = 1.0; u32 division = 0; if (wm->getStageType() == StageType::Indoor) { division = 0; } else if (time >= 3_h && time < 4_h) { division = 0; if (time < timeToFloat(3, 40)) transition = (time - 3_h) / timeToFloat(0, 40); } else if (time >= 4_h && time < 6_h) { division = 1; if (time < 5_h) transition = (time - 4_h) / 1_h; } else if (time >= 6_h && time < 9_h) { division = 2; if (time < 7_h) transition = (time - 6_h) / 1_h; } else if (time >= 9_h && time < 16_h) { division = 3; if (time < 10_h) transition = (time - 9_h) / 1_h; } else if (time >= 16_h && time < 18_h) { division = 4; if (time < 17_h) transition = (time - 16_h) / 1_h; } else if (time >= 18_h && time < 20_h) { division = 5; if (time < 19_h) transition = (time - 18_h) / 1_h; } else if (time >= 20_h && time < 21_h) { division = 6; if (time < timeToFloat(20, 40)) transition = (time - 20_h) / timeToFloat(0, 40); } else if (time >= 21_h && time < 22_h) { division = 7; transition = (time - 21_h) / 1_h; } else { division = 7; } if (mSkyEnvTimeDivision != division) { mPrevSkyEnvTimeDivision = division == 0 ? 7 : division - 1; mSkyEnvTimeDivision = division; } mEnvTimeTransition = transition; } bool EnvMgr::isBloodMoonNight() const { auto* wm = Manager::instance(); const auto time = wm->getTimeMgr()->getTimeForSkyEnv(); bool bm = false; bm |= wm->getTimeMgr()->isBloodyDay(); bm |= wm->getTimeMgr()->wasBloodyDay() && time < 1_h; bm |= wm->getTimeMgr()->isBloodMoonForced(); return bm; } bool EnvMgr::isInBloodMoonTimeRange() const { return mBloodMoonTimeRangeProgress > 0.001f; } float EnvMgr::getConcentrationBM() const { return mConcentrationBM; } void EnvMgr::activateForcedBloodMoon() { if (Manager::instance()->isMainField()) mForcedBloodMoonRequested = true; mBloodMoonProhibited = false; } void EnvMgr::setBloodMoonProhibition(bool prohibited) { if (!mDeactivateForcedBloodMoon) 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()->getDeltaFrame(); if (mForcedBloodMoonTimer <= 0.0f) { mForcedBloodMoonTimer = 0.0f; mForcedBloodMoonStatus = 0; mForcedBloodMoonReady = false; } } else { mForcedBloodMoonTimer += VFR::instance()->getDeltaFrame(); 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()->getDeltaFrame(); 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()->getDeltaFrame(); if (mForcedBloodMoonTimer <= 0.0f) { mForcedBloodMoonTimer = 0.0f; mForcedBloodMoonStatus = 0; return; } } else { mForcedBloodMoonTimer += VFR::instance()->getDeltaFrame(); 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::returnFalse() const { return false; } bool EnvMgr::isInSandstorm() const { if (mActivePaletteSet != 4 && mActivePaletteSet != 8) return false; return isPaletteSetTransitionDone(); } bool EnvMgr::isInYigaClanHideoutArea() const { if (mActivePaletteSet != 15) return false; return isPaletteSetTransitionDone(); } float EnvMgr::getConcentrationDarkness() const { if (mActivePaletteSet == 7) return mPaletteSetTransition; return 0.0f; } bool EnvMgr::isPaletteSetTransitionDone() const { if (mPaletteSetTransition >= 1.0f) return true; #ifdef MATCHING_HACK_NX_CLANG asm(""); #endif return false; } void EnvMgr::worldMgrCalc2() {} int EnvMgr::getPaletteSet() const { if (mPaletteSetOverride >= 0) return mPaletteSetOverride; return mPaletteSetForClimate; } bool EnvMgr::isWaterRelicRainOn(Climate climate) const { if (climate != Climate::ZoraTemperateClimate) return false; bool on = false; const auto flag = Manager::instance()->getTimeMgr()->getWaterRelicRainStopFlag(); if (flag == gdt::InvalidHandle) return false; gdt::Manager::instance()->getBool(flag, &on, true); return !on; } void EnvMgr::setPaletteSelSpeed(int speed) { mPaletteSelSpeed = speed; mPaletteSelSpeedTimer = 4; } void EnvMgr::setPaletteSet(int palette) { if (mBlockPaletteSetOverride) return; mPaletteSetOverride = palette; mPaletteSetOverrideTimer = 4; _6b5c8 = 1; _6b5cc = 1; _6b550 = 1.0; } void EnvMgr::setCharAmbientScale(sead::Color4f color) { mCharAmbientScaleTimer = 2; mCharAmbientScale = color; } void EnvMgr::setCharMainLightScale(sead::Color4f color) { mCharMainLightScaleTimer = 2; mCharMainLightScale = color; } void EnvMgr::setWarpMistIntensity(float intensity) { if (mWarpMistIntensity <= intensity && !(intensity >= 1.0 && mWarpMistIntensity <= 0.0)) { mWarpMistIntensity = intensity; mWarpMistTimer = 4; } } void EnvMgr::setFogDirect(bool fog_near_use, bool fog_instant_sw, bool fog_far_use, float fog_ratio, float fog_near, float fog_far) { mFogSetDirectTimer = 2; mFogRatio = fog_ratio; mFogNear = fog_near; mFogNearUse = fog_near_use; mFogFar = fog_far; mFogFagUse = fog_far_use; mFogInstantSW = fog_instant_sw; } float EnvMgr::getBloodMoonProgress() const { if (mBloodMoonStartState == 2) return mBloodMoonProgress; if (mBloodMoonEndState == 2) return 1.0f - mBloodMoonProgress; return 0.0f; } void EnvMgr::allowPaletteOverride() { mBlockPaletteSetOverride = false; } } // namespace ksys::world