Skip to content

Commit

Permalink
Weather code rework (#559)
Browse files Browse the repository at this point in the history
* tweak: ReleaseWeatherOverride

* tweak: weather rework

* tweak: remove unnecessary bool

* tweak: removed old code

* fix: weather hooks not going through
  • Loading branch information
RobbeBryssinck committed Jan 13, 2023
1 parent 1716a04 commit 126ff69
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 20 deletions.
1 change: 1 addition & 0 deletions Code/client/Games/Fallout4/Sky/Sky.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ struct Sky

void SetWeather(TESWeather* apWeather) noexcept;
void ForceWeather(TESWeather* apWeather) noexcept;
void ReleaseWeatherOverride() noexcept;
void ResetWeather() noexcept;

TESWeather* GetWeather() const noexcept;
Expand Down
17 changes: 17 additions & 0 deletions Code/client/Games/References.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,17 @@ void Sky::ForceWeather(TESWeather* apWeather) noexcept
TiltedPhoques::ThisCall(RealForceWeather, this, apWeather, true);
}

void Sky::ReleaseWeatherOverride() noexcept
{
#if TP_SKYRIM64
TP_THIS_FUNCTION(TReleaseWeatherOverride, void, Sky);
POINTER_SKYRIMSE(TReleaseWeatherOverride, releaseWeatherOverride, 26244);
// TODO(ft)

TiltedPhoques::ThisCall(releaseWeatherOverride, this);
#endif
}

void Sky::ResetWeather() noexcept
{
TP_THIS_FUNCTION(TResetWeather, void, Sky);
Expand Down Expand Up @@ -997,20 +1008,24 @@ void TP_MAKE_THISCALL(HookSetCurrentPickREFR, Console, BSPointerHandle<TESObject

void TP_MAKE_THISCALL(HookSetWeather, Sky, TESWeather* apWeather, bool abOverride, bool abAccelerate)
{
#if 0
spdlog::debug("Set weather form id: {:X}, override: {}, accelerate: {}", apWeather ? apWeather->formID : 0, abOverride, abAccelerate);

if (!Sky::s_shouldUpdateWeather)
return;
#endif

TiltedPhoques::ThisCall(RealSetWeather, apThis, apWeather, abOverride, abAccelerate);
}

void TP_MAKE_THISCALL(HookForceWeather, Sky, TESWeather* apWeather, bool abOverride)
{
#if 0
spdlog::debug("Force weather form id: {:X}, override: {}", apWeather ? apWeather->formID : 0, abOverride);

if (!Sky::s_shouldUpdateWeather)
return;
#endif

TiltedPhoques::ThisCall(RealForceWeather, apThis, apWeather, abOverride);
}
Expand All @@ -1020,8 +1035,10 @@ static TUpdateWeather* RealUpdateWeather = nullptr;

void TP_MAKE_THISCALL(HookUpdateWeather, Sky)
{
#if 0
if (!Sky::s_shouldUpdateWeather)
return;
#endif

TiltedPhoques::ThisCall(RealUpdateWeather, apThis);
}
Expand Down
1 change: 1 addition & 0 deletions Code/client/Games/Skyrim/Sky/Sky.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct Sky

void SetWeather(TESWeather* apWeather) noexcept;
void ForceWeather(TESWeather* apWeather) noexcept;
void ReleaseWeatherOverride() noexcept;
void ResetWeather() noexcept;

TESWeather* GetWeather() const noexcept;
Expand Down
60 changes: 41 additions & 19 deletions Code/client/Services/Generic/WeatherService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,9 @@ void WeatherService::OnDisconnected(const DisconnectedEvent& acEvent) noexcept

void WeatherService::OnPartyJoinedEvent(const PartyJoinedEvent& acEvent) noexcept
{
Sky::s_shouldUpdateWeather = acEvent.IsLeader;

if (!acEvent.IsLeader)
{
// TODO: why is this loop here? Party should always have a leader.
auto view = m_world.view<PlayerComponent>();
const auto& partyService = m_world.GetPartyService();

Expand Down Expand Up @@ -133,21 +132,24 @@ void WeatherService::OnWeatherChange(const NotifyWeatherChange& acMessage) noexc
}

Sky::Get()->ForceWeather(pWeather);

m_cachedWeatherId = weatherId;
}

void WeatherService::RunWeatherUpdates(const double acDelta) noexcept
{
if (!m_world.GetPartyService().IsLeader())
return;

Sky* pSky = Sky::Get();
if (!pSky)
return;

TESWeather* pWeather = pSky->GetWeather();
if (!pWeather)
{
m_cachedWeatherId = 0;
if (m_world.GetPartyService().IsLeader())
m_cachedWeatherId = 0;
else
SetCachedWeather();

return;
}

Expand All @@ -159,29 +161,49 @@ void WeatherService::RunWeatherUpdates(const double acDelta) noexcept
if (pWeather->formID == m_cachedWeatherId)
return;

m_cachedWeatherId = pWeather->formID;
if (m_world.GetPartyService().IsLeader())
{
m_cachedWeatherId = pWeather->formID;

RequestWeatherChange request{};
RequestWeatherChange request{};

auto& modSystem = m_world.GetModSystem();
if (!modSystem.GetServerModId(pWeather->formID, request.Id))
auto& modSystem = m_world.GetModSystem();
if (!modSystem.GetServerModId(pWeather->formID, request.Id))
{
spdlog::error(__FUNCTION__ ": weather server ID not found, form id: {:X}", pWeather->formID);
return;
}

m_transport.Send(request);
}
else
{
spdlog::error(__FUNCTION__ ": weather server ID not found, form id: {:X}", pWeather->formID);
return;
SetCachedWeather();
}

m_transport.Send(request);
}

void WeatherService::ToggleGameWeatherSystem(bool aToggle) noexcept
{
Sky::s_shouldUpdateWeather = aToggle;

if (aToggle)
Sky::Get()->ResetWeather();

if (!aToggle)
Sky::Get()->ReleaseWeatherOverride();
else
m_transport.Send(RequestCurrentWeather());

m_cachedWeatherId = 0;
}

void WeatherService::SetCachedWeather() noexcept
{
if (m_cachedWeatherId == 0)
return;

TESWeather* pWeather = Cast<TESWeather>(TESForm::GetById(m_cachedWeatherId));

if (!pWeather)
{
spdlog::error(__FUNCTION__ ": weather not found, form id: {:X}", m_cachedWeatherId);
return;
}

Sky::Get()->ForceWeather(pWeather);
}
7 changes: 6 additions & 1 deletion Code/client/Services/WeatherService.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@ struct WeatherService
void RunWeatherUpdates(const double acDelta) noexcept;

void ToggleGameWeatherSystem(bool aToggle) noexcept;
void SetCachedWeather() noexcept;

private:
World& m_world;
TransportService& m_transport;

bool m_isInParty{};
/**
* This variable has two uses:
* For the party leader, it is used to detect weather changes.
* For non-leaders, it is used to reapply the server weather if it changes.
*/
uint32_t m_cachedWeatherId{};

entt::scoped_connection m_updateConnection;
Expand Down

0 comments on commit 126ff69

Please sign in to comment.