Adjusted sky update interval, added clothing assets
This commit is contained in:
@@ -9,7 +9,7 @@ inline const FString DefaultSaveSlotName = TEXT("Slot1");
|
||||
|
||||
// --- Time of day / calendar (GDD §2.4, §10.1; tuning §21) ---
|
||||
// 1440 in-game minutes elapse over the ~90 real-minute day/night cycle.
|
||||
inline constexpr float INGAME_MINUTES_PER_REAL_SECOND = 16.0f;
|
||||
inline constexpr float INGAME_MINUTES_PER_REAL_SECOND = 1.0f;
|
||||
inline constexpr int32 MINUTES_PER_HOUR = 60;
|
||||
inline constexpr int32 MINUTES_PER_DAY = 1440;
|
||||
inline constexpr float DAY_START_HOUR = 8.0f; // 08:00 — day phase begins (§10.1)
|
||||
@@ -20,3 +20,7 @@ inline constexpr int32 CAMPAIGN_LENGTH_DAYS = 90; // §3.3 survive 90 days
|
||||
inline constexpr int32 WEEK_LENGTH_DAYS = 7; // §2.4 rent due each week
|
||||
inline constexpr float WEEKLY_RENT = 20000.0f; // §15.3 early-tier placeholder (§21 tuning)
|
||||
|
||||
// How often the current time is pushed to the sky actor. Decoupled from the in-game
|
||||
// minute so the sun moves smoothly regardless of how fast the clock runs.
|
||||
inline constexpr double SKY_PUSH_INTERVAL_SECONDS = 1.0 / 30.0; // 30fps
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnPushTimeToSkySignature, const FTi
|
||||
|
||||
/**
|
||||
* The single authoritative clock (GDD §2.4, §10.1). Owns time-of-day and the
|
||||
* calendar in C++ and pushes the current time to the UltraDynamicSky actor each
|
||||
* in-game minute via ANakedDesireGameMode::SetCurrentTime — inverting the old
|
||||
* BP-drives-time flow. Persists to UGlobalSaveGameData (MinuteOfDay / DaysPassed).
|
||||
* calendar in C++ and pushes the current time to the UltraDynamicSky actor at 30fps
|
||||
* (SKY_PUSH_INTERVAL_SECONDS) via ANakedDesireGameMode::SetCurrentTime — inverting the
|
||||
* old BP-drives-time flow. Persists to UGlobalSaveGameData (MinuteOfDay / DaysPassed).
|
||||
*
|
||||
* The calendar rolls at 04:00 (DAY_ROLL_HOUR); the day phase flips at 08:00 / 20:00.
|
||||
* Weekly rent is charged every WEEK_LENGTH_DAYS-th roll; follower income deposits
|
||||
@@ -121,13 +121,15 @@ public:
|
||||
FOnPushTimeToSkySignature OnPushTimeToSky;
|
||||
|
||||
private:
|
||||
void AdvanceClock(double DeltaMinutes);
|
||||
// bForceSkyPush bypasses the 30fps throttle for discrete jumps (skips / load),
|
||||
// so the sky snaps to the new time immediately instead of waiting a frame.
|
||||
void AdvanceClock(double DeltaMinutes, bool bForceSkyPush = false);
|
||||
void HandleHourBoundary(int32 HourOfDay); // 0–23
|
||||
void SetPhase(EDayPhase NewPhase);
|
||||
void AdvanceCalendarDay();
|
||||
void ChargeWeeklyRent();
|
||||
void DepositDailyFollowerIncome();
|
||||
void PushTimeToSky();
|
||||
void PushTimeToSky(bool bForce = false);
|
||||
|
||||
static EDayPhase ComputePhase(float InMinuteOfDay);
|
||||
|
||||
@@ -135,8 +137,8 @@ private:
|
||||
void RestorePlayerEnergy() const;
|
||||
void Autosave() const;
|
||||
|
||||
// Last whole in-game minute pushed to the sky, to throttle the push to ~1/min.
|
||||
int32 LastPushedMinute = -1;
|
||||
// Real-time stamp (seconds, FApp clock) of the last sky push, to throttle to 30fps.
|
||||
double LastSkyPushRealTime = -1.0;
|
||||
EDayPhase CurrentPhase = EDayPhase::Day;
|
||||
TSet<FName> PauseReasons;
|
||||
bool bBegunPlay = false;
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "InputMappingContext.h"
|
||||
#include "NakedDesire/Clothing/BodyPart.h"
|
||||
#include "NakedDesire/Global/Gait.h"
|
||||
#include "NakedDesire/Global/NakedDesireUserSettings.h"
|
||||
#include "NakedDesire/Global/Stance.h"
|
||||
#include "Perception/AISightTargetInterface.h"
|
||||
#include "NakedDesireCharacter.generated.h"
|
||||
|
||||
Reference in New Issue
Block a user