Adjusted sky update interval, added clothing assets

This commit is contained in:
2026-05-31 16:59:02 +03:00
parent bc98ea274b
commit a0c91c81fa
18 changed files with 72 additions and 43 deletions
@@ -4,6 +4,7 @@
#include "TimeOfDaySubsystem.h"
#include "Constants.h"
#include "Kismet/GameplayStatics.h"
#include "Misc/App.h"
#include "Misc/Timecode.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"
#include "NakedDesire/SaveGame/GlobalSaveGameData.h"
@@ -20,7 +21,12 @@ void UTimeOfDaySubsystem::OnWorldBeginPlay(UWorld& InWorld)
}
bBegunPlay = true;
PushTimeToSky(); // sync the sky to the loaded time immediately
PushTimeToSky(/*bForce=*/true); // sync the sky to the loaded time immediately
// Sanity-log the clock speed: how long a full 24h in-game day takes in real time.
const double RealMinutesPerDay = MINUTES_PER_DAY / (INGAME_MINUTES_PER_REAL_SECOND * 60.0);
UE_LOG(LogTemp, Warning, TEXT("UTimeOfDaySubsystem: a full in-game day takes %.2f real minutes (%.1f in-game minutes/real second)."),
RealMinutesPerDay, INGAME_MINUTES_PER_REAL_SECOND);
}
void UTimeOfDaySubsystem::Tick(float DeltaTime)
@@ -67,7 +73,8 @@ void UTimeOfDaySubsystem::SkipTime(float Minutes)
{
if (Minutes > 0.0f)
{
AdvanceClock(static_cast<double>(Minutes));
// Discrete jump — snap the sky to the new time, don't wait for the throttle.
AdvanceClock(static_cast<double>(Minutes), /*bForceSkyPush=*/true);
}
}
@@ -79,7 +86,7 @@ void UTimeOfDaySubsystem::SkipToNextMorning()
{
Delta += MINUTES_PER_DAY;
}
AdvanceClock(Delta);
AdvanceClock(Delta, /*bForceSkyPush=*/true);
}
void UTimeOfDaySubsystem::Sleep()
@@ -101,7 +108,7 @@ void UTimeOfDaySubsystem::PopPause(FName Reason)
PauseReasons.Remove(Reason);
}
void UTimeOfDaySubsystem::AdvanceClock(double DeltaMinutes)
void UTimeOfDaySubsystem::AdvanceClock(double DeltaMinutes, bool bForceSkyPush)
{
UGlobalSaveGameData* Save = GetSave();
if (!Save || DeltaMinutes <= 0.0)
@@ -125,7 +132,7 @@ void UTimeOfDaySubsystem::AdvanceClock(double DeltaMinutes)
}
Save->MinuteOfDay = static_cast<float>(Next);
PushTimeToSky();
PushTimeToSky(bForceSkyPush);
}
void UTimeOfDaySubsystem::HandleHourBoundary(int32 HourOfDay)
@@ -207,20 +214,31 @@ void UTimeOfDaySubsystem::DepositDailyFollowerIncome()
// follower attribute yet, so this is intentionally a no-op (payout reads 0).
}
void UTimeOfDaySubsystem::PushTimeToSky()
void UTimeOfDaySubsystem::PushTimeToSky(bool bForce)
{
const UGlobalSaveGameData* Save = GetSave();
if (!Save)
return;
const int32 CurMinute = FMath::FloorToInt(Save->MinuteOfDay);
if (CurMinute == LastPushedMinute)
// Throttle continuous updates to 30fps of real time. Discrete jumps (load / skips)
// force a push so the sky snaps to the new time without waiting for the next frame.
const double Now = FApp::GetCurrentTime();
if (!bForce && LastSkyPushRealTime >= 0.0 && (Now - LastSkyPushRealTime) < SKY_PUSH_INTERVAL_SECONDS)
return;
LastPushedMinute = CurMinute;
LastSkyPushRealTime = Now;
const int32 Hours = CurMinute / MINUTES_PER_HOUR;
const int32 Minutes = CurMinute % MINUTES_PER_HOUR;
OnPushTimeToSky.Broadcast(FTimecode(Hours, Minutes, 0, 0, false));
// Carry sub-minute precision so the sun moves smoothly between minute marks. The
// fractional minute becomes seconds + frames (at the same 30fps cadence).
const double MinuteOfDay = Save->MinuteOfDay;
const int32 Hours = FMath::FloorToInt(MinuteOfDay / MINUTES_PER_HOUR);
const int32 Minutes = FMath::FloorToInt(MinuteOfDay) % MINUTES_PER_HOUR;
const double FracMinute = MinuteOfDay - FMath::FloorToDouble(MinuteOfDay);
const double FracSeconds = FracMinute * 60.0;
const int32 Seconds = FMath::FloorToInt(FracSeconds);
const int32 Frames = FMath::FloorToInt((FracSeconds - Seconds) * 30.0);
OnPushTimeToSky.Broadcast(FTimecode(Hours, Minutes, Seconds, Frames, false));
}
EDayPhase UTimeOfDaySubsystem::ComputePhase(float InMinuteOfDay)
@@ -256,7 +274,7 @@ void UTimeOfDaySubsystem::Autosave() const
{
if (const UGameInstance* GameInstance = GetWorld()->GetGameInstance())
{
if (USaveSubsystem* SaveSubsystem = GameInstance->GetSubsystem<USaveSubsystem>())
if (const USaveSubsystem* SaveSubsystem = GameInstance->GetSubsystem<USaveSubsystem>())
{
SaveSubsystem->SaveGame();
}