Sequence startup story before character selection

This commit is contained in:
2026-05-21 22:55:52 +00:00
parent 5cd0c9c6d5
commit e7bd783309
7 changed files with 354 additions and 26 deletions
+22 -2
View File
@@ -6,16 +6,27 @@ ROOT = Path(__file__).resolve().parents[1]
REQUIRED = { REQUIRED = {
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeActor.h": [ ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeActor.h": [
"float NoticeDurationSeconds = 24.0f;", "float NoticeDurationSeconds = 24.0f;",
"bool bAutoShowNotice = false;",
"Investor Demo v0.1.N - Build 2026.05.18", "Investor Demo v0.1.N - Build 2026.05.18",
], ],
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.h": [ ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.h": [
"virtual void NativeConstruct() override;", "virtual void NativeConstruct() override;",
"NativeOnKeyDown",
"NativeOnMouseButtonDown",
"EAgrarianStartupPresentationSegment",
"DrawSplash",
"DrawStory",
"DrawCinematicCredits", "DrawCinematicCredits",
"DrawCreditIllustration", "DrawCreditIllustration",
"CreditsStartTimeSeconds", "SegmentStartTimeSeconds",
"Investor Demo v0.1.N - Build 2026.05.18", "Investor Demo v0.1.N - Build 2026.05.18",
], ],
ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.cpp": [ ROOT / "Source" / "AgrarianGame" / "AgrarianDemoNoticeWidget.cpp": [
"The lights did not go out at once.",
"Agrarian begins at Ground Zero.",
"Press any key to skip to credits",
"RequestSkipSegment",
"AgrarianSkipStartupPresentation",
"Nathan Slaven", "Nathan Slaven",
"Lead Developer", "Lead Developer",
"Hunter Slaven", "Hunter Slaven",
@@ -33,10 +44,19 @@ REQUIRED = {
"Agrarian Startup Credits", "Agrarian Startup Credits",
], ],
ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.h": [ ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.h": [
"MvpFrontendStartupDelaySeconds = 24.25f", "StartupSplashSeconds = 4.0f",
"StartupStorySeconds = 60.0f",
"StartupCreditsSeconds = 20.75f",
"StartupPresentationWidget",
"AgrarianSkipStartupPresentation",
"ShowMvpFrontend", "ShowMvpFrontend",
], ],
ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.cpp": [ ROOT / "Source" / "AgrarianGame" / "AgrarianGamePlayerController.cpp": [
"StartStartupPresentation",
"ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Splash",
"ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Story",
"ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Credits",
"FinishStartupPresentation",
"GetWorldTimerManager().SetTimer", "GetWorldTimerManager().SetTimer",
"ShowMvpFrontend", "ShowMvpFrontend",
"FInputModeUIOnly", "FInputModeUIOnly",
@@ -17,6 +17,11 @@ void AAgrarianDemoNoticeActor::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
if (!bAutoShowNotice)
{
return;
}
APlayerController* PlayerController = GetWorld() ? GetWorld()->GetFirstPlayerController() : nullptr; APlayerController* PlayerController = GetWorld() ? GetWorld()->GetFirstPlayerController() : nullptr;
if (!PlayerController || !NoticeWidgetClass) if (!PlayerController || !NoticeWidgetClass)
{ {
@@ -44,4 +49,3 @@ void AAgrarianDemoNoticeActor::RemoveNotice()
ActiveNoticeWidget = nullptr; ActiveNoticeWidget = nullptr;
} }
} }
@@ -22,6 +22,9 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo", meta = (ClampMin = "1.0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo", meta = (ClampMin = "1.0"))
float NoticeDurationSeconds = 24.0f; float NoticeDurationSeconds = 24.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
bool bAutoShowNotice = false;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.N - Build 2026.05.18")); FText VersionLabel = FText::FromString(TEXT("Investor Demo v0.1.N - Build 2026.05.18"));
@@ -2,7 +2,10 @@
#include "AgrarianDemoNoticeWidget.h" #include "AgrarianDemoNoticeWidget.h"
#include "AgrarianGamePlayerController.h"
#include "Engine/World.h" #include "Engine/World.h"
#include "Input/Reply.h"
#include "InputCoreTypes.h"
#include "Rendering/DrawElements.h" #include "Rendering/DrawElements.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
@@ -46,12 +49,76 @@ float GetCreditsSequenceDurationSeconds()
} }
return Duration; return Duration;
} }
struct FAgrarianStoryBeat
{
const TCHAR* Title;
const TCHAR* Body;
};
const FAgrarianStoryBeat StoryBeats[] = {
{ TEXT("The lights did not go out at once."), TEXT("They failed by region, by habit, by trust. Cities still glowed in places, but the systems beneath them no longer answered together.") },
{ TEXT("People carried what they could."), TEXT("A few tools. A little seed. Names, debts, grief, and the stubborn memory of how life used to work.") },
{ TEXT("The old world became material."), TEXT("Roads became paths. Machines became shelter. Stores became ruins. Every useful thing had to be understood again before it could be used.") },
{ TEXT("The land kept its own calendar."), TEXT("Rain returned when it returned. Trees grew in years, not minutes. Hunger did not wait for plans, and winter did not care who was ready.") },
{ TEXT("Knowledge became inheritance."), TEXT("A fire tended well could save a night. A field understood well could save a season. A lesson taught well could save a generation.") },
{ TEXT("Agrarian begins at Ground Zero."), TEXT("One person steps forward. What they build, waste, protect, plant, teach, and remember becomes the first line of a new history.") },
};
} }
void UAgrarianDemoNoticeWidget::NativeConstruct() void UAgrarianDemoNoticeWidget::NativeConstruct()
{ {
Super::NativeConstruct(); Super::NativeConstruct();
CreditsStartTimeSeconds = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f; SetIsFocusable(true);
SegmentStartTimeSeconds = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f;
SetKeyboardFocus();
}
FReply UAgrarianDemoNoticeWidget::NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent)
{
if (PresentationSegment == EAgrarianStartupPresentationSegment::Splash
|| PresentationSegment == EAgrarianStartupPresentationSegment::Story
|| PresentationSegment == EAgrarianStartupPresentationSegment::Credits)
{
RequestSkipSegment();
return FReply::Handled();
}
return Super::NativeOnKeyDown(InGeometry, InKeyEvent);
}
FReply UAgrarianDemoNoticeWidget::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
if (PresentationSegment == EAgrarianStartupPresentationSegment::Splash
|| PresentationSegment == EAgrarianStartupPresentationSegment::Story
|| PresentationSegment == EAgrarianStartupPresentationSegment::Credits)
{
RequestSkipSegment();
return FReply::Handled();
}
return Super::NativeOnMouseButtonDown(InGeometry, InMouseEvent);
}
void UAgrarianDemoNoticeWidget::SetPresentationSegment(EAgrarianStartupPresentationSegment NewSegment)
{
PresentationSegment = NewSegment;
SegmentStartTimeSeconds = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0f;
SetKeyboardFocus();
}
float UAgrarianDemoNoticeWidget::GetSegmentElapsedSeconds() const
{
const UWorld* World = GetWorld();
return World ? World->GetTimeSeconds() - SegmentStartTimeSeconds : 0.0f;
}
void UAgrarianDemoNoticeWidget::RequestSkipSegment() const
{
if (AAgrarianGamePlayerController* AgrarianController = Cast<AAgrarianGamePlayerController>(GetOwningPlayer()))
{
AgrarianController->AgrarianSkipStartupPresentation();
}
} }
int32 UAgrarianDemoNoticeWidget::NativePaint( int32 UAgrarianDemoNoticeWidget::NativePaint(
@@ -66,9 +133,19 @@ int32 UAgrarianDemoNoticeWidget::NativePaint(
LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); LayerId = Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
const FVector2D Size = AllottedGeometry.GetLocalSize(); const FVector2D Size = AllottedGeometry.GetLocalSize();
const UWorld* World = GetWorld(); if (PresentationSegment == EAgrarianStartupPresentationSegment::Splash)
const float Elapsed = World ? World->GetTimeSeconds() - CreditsStartTimeSeconds : 0.0f; {
if (Elapsed <= GetCreditsSequenceDurationSeconds() + 1.0f) DrawSplash(OutDrawElements, LayerId, AllottedGeometry);
return LayerId;
}
if (PresentationSegment == EAgrarianStartupPresentationSegment::Story)
{
DrawStory(OutDrawElements, LayerId, AllottedGeometry);
return LayerId;
}
if (PresentationSegment == EAgrarianStartupPresentationSegment::Credits)
{ {
FSlateDrawElement::MakeBox( FSlateDrawElement::MakeBox(
OutDrawElements, OutDrawElements,
@@ -120,6 +197,104 @@ int32 UAgrarianDemoNoticeWidget::NativePaint(
return LayerId; return LayerId;
} }
void UAgrarianDemoNoticeWidget::DrawSplash(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const
{
const FVector2D Size = AllottedGeometry.GetLocalSize();
const float Elapsed = GetSegmentElapsedSeconds();
const float Pulse = 0.5f + (0.5f * FMath::Sin(Elapsed * 2.1f));
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(Size), FSlateLayoutTransform(FVector2f::ZeroVector)),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.005f, 0.007f, 0.006f, 1.0f));
const FVector2D MarkSize(148.0f, 148.0f);
const FVector2D MarkPosition((Size.X - MarkSize.X) * 0.5f, (Size.Y * 0.5f) - 185.0f);
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(MarkSize), FSlateLayoutTransform(FVector2f(MarkPosition))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.10f, 0.16f, 0.095f, 0.78f));
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(92.0f, 12.0f), FSlateLayoutTransform(FVector2f(MarkPosition.X + 28.0f, MarkPosition.Y + 96.0f))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.68f, 0.86f, 0.44f, 0.85f + (0.15f * Pulse)));
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", 72);
const FSlateFontInfo StudioFont = FCoreStyle::GetDefaultFontStyle("Regular", 24);
const FSlateFontInfo NoticeFont = FCoreStyle::GetDefaultFontStyle("Regular", 16);
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("AGRARIAN")), Size.Y * 0.5f - 12.0f, TitleFont, FLinearColor(0.92f, 0.98f, 0.84f, 1.0f));
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Agrarian Studio")), Size.Y * 0.5f + 78.0f, StudioFont, FLinearColor(0.70f, 0.82f, 0.60f, 1.0f));
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, CopyrightNotice, Size.Y - 86.0f, NoticeFont, FLinearColor(0.58f, 0.64f, 0.54f, 1.0f));
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Press any key to continue")), Size.Y - 56.0f, NoticeFont, FLinearColor(0.72f, 0.80f, 0.66f, 0.65f + (0.35f * Pulse)));
}
void UAgrarianDemoNoticeWidget::DrawStory(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const
{
const FVector2D Size = AllottedGeometry.GetLocalSize();
const float Elapsed = FMath::Clamp(GetSegmentElapsedSeconds(), 0.0f, 59.99f);
const int32 BeatIndex = FMath::Clamp(FMath::FloorToInt(Elapsed / 10.0f), 0, UE_ARRAY_COUNT(StoryBeats) - 1);
const float BeatTime = FMath::Fmod(Elapsed, 10.0f);
const float FadeIn = SmoothStep(BeatTime / 1.35f);
const float FadeOut = 1.0f - SmoothStep((BeatTime - 8.25f) / 1.25f);
const float Alpha = FMath::Clamp(FadeIn * FadeOut, 0.0f, 1.0f);
const float Drift = (BeatTime - 5.0f) * 8.0f;
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(Size), FSlateLayoutTransform(FVector2f::ZeroVector)),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.008f, 0.010f, 0.008f, 1.0f));
for (int32 BandIndex = 0; BandIndex < 5; ++BandIndex)
{
const float BandY = Size.Y * (0.18f + (0.15f * BandIndex)) + (FMath::Sin(Elapsed * 0.22f + BandIndex) * 16.0f);
const float BandWidth = Size.X * (0.42f + (0.08f * BandIndex));
const float BandX = FMath::Fmod((Elapsed * (18.0f + BandIndex * 7.0f)) + BandIndex * 220.0f, Size.X + BandWidth) - BandWidth;
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(BandWidth, 3.0f + BandIndex), FSlateLayoutTransform(FVector2f(BandX, BandY))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.28f, 0.44f, 0.26f, 0.14f));
}
const FVector2D PanelSize(FMath::Min(980.0f, Size.X - 140.0f), 360.0f);
const FVector2D PanelPosition((Size.X - PanelSize.X) * 0.5f + Drift, (Size.Y - PanelSize.Y) * 0.5f);
FSlateDrawElement::MakeBox(
OutDrawElements,
++LayerId,
AllottedGeometry.ToPaintGeometry(FVector2f(PanelSize), FSlateLayoutTransform(FVector2f(PanelPosition))),
FCoreStyle::Get().GetBrush(TEXT("WhiteBrush")),
ESlateDrawEffect::None,
FLinearColor(0.016f, 0.020f, 0.015f, 0.82f * Alpha));
const FSlateFontInfo TitleFont = FCoreStyle::GetDefaultFontStyle("Bold", 40);
const FSlateFontInfo BodyFont = FCoreStyle::GetDefaultFontStyle("Regular", 24);
const FSlateFontInfo LabelFont = FCoreStyle::GetDefaultFontStyle("Regular", 15);
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(StoryBeats[BeatIndex].Title), PanelPosition + FVector2D(46.0f, 58.0f), PanelSize.X - 92.0f, TitleFont, FLinearColor(0.90f, 0.96f, 0.82f, Alpha));
DrawTextAt(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(StoryBeats[BeatIndex].Body), PanelPosition + FVector2D(50.0f, 142.0f), PanelSize.X - 100.0f, BodyFont, FLinearColor(0.74f, 0.82f, 0.68f, Alpha));
DrawCenteredText(OutDrawElements, LayerId, AllottedGeometry, FText::FromString(TEXT("Press any key to skip to credits")), Size.Y - 54.0f, LabelFont, FLinearColor(0.68f, 0.76f, 0.62f, 0.78f));
}
void UAgrarianDemoNoticeWidget::DrawCenteredText( void UAgrarianDemoNoticeWidget::DrawCenteredText(
FSlateWindowElementList& OutDrawElements, FSlateWindowElementList& OutDrawElements,
int32& LayerId, int32& LayerId,
@@ -176,7 +351,7 @@ void UAgrarianDemoNoticeWidget::DrawCinematicCredits(
} }
const FVector2D Size = AllottedGeometry.GetLocalSize(); const FVector2D Size = AllottedGeometry.GetLocalSize();
const float Elapsed = World->GetTimeSeconds() - CreditsStartTimeSeconds; const float Elapsed = GetSegmentElapsedSeconds();
const float IntroDelay = 0.55f; const float IntroDelay = 0.55f;
const float SlamSeconds = 0.28f; const float SlamSeconds = 0.28f;
const float ExitSeconds = 0.48f; const float ExitSeconds = 0.48f;
+28 -1
View File
@@ -6,6 +6,15 @@
#include "Blueprint/UserWidget.h" #include "Blueprint/UserWidget.h"
#include "AgrarianDemoNoticeWidget.generated.h" #include "AgrarianDemoNoticeWidget.generated.h"
UENUM(BlueprintType)
enum class EAgrarianStartupPresentationSegment : uint8
{
Splash,
Story,
Credits,
DemoNotice
};
UCLASS() UCLASS()
class AGRARIANGAME_API UAgrarianDemoNoticeWidget : public UUserWidget class AGRARIANGAME_API UAgrarianDemoNoticeWidget : public UUserWidget
{ {
@@ -13,6 +22,10 @@ class AGRARIANGAME_API UAgrarianDemoNoticeWidget : public UUserWidget
public: public:
virtual void NativeConstruct() override; virtual void NativeConstruct() override;
virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
virtual FReply NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
void SetPresentationSegment(EAgrarianStartupPresentationSegment NewSegment);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Agrarian|Demo")
FText Motto = FText::FromString(TEXT("What survives after you are gone?")); FText Motto = FText::FromString(TEXT("What survives after you are gone?"));
@@ -37,7 +50,21 @@ protected:
bool bParentEnabled) const override; bool bParentEnabled) const override;
private: private:
float CreditsStartTimeSeconds = 0.0f; EAgrarianStartupPresentationSegment PresentationSegment = EAgrarianStartupPresentationSegment::DemoNotice;
float SegmentStartTimeSeconds = 0.0f;
float GetSegmentElapsedSeconds() const;
void RequestSkipSegment() const;
void DrawSplash(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const;
void DrawStory(
FSlateWindowElementList& OutDrawElements,
int32& LayerId,
const FGeometry& AllottedGeometry) const;
void DrawCenteredText( void DrawCenteredText(
FSlateWindowElementList& OutDrawElements, FSlateWindowElementList& OutDrawElements,
@@ -5,6 +5,7 @@
#include "AgrarianCampfire.h" #include "AgrarianCampfire.h"
#include "AgrarianCraftingComponent.h" #include "AgrarianCraftingComponent.h"
#include "AgrarianDebugHUD.h" #include "AgrarianDebugHUD.h"
#include "AgrarianDemoNoticeWidget.h"
#include "AgrarianGameCharacter.h" #include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h" #include "AgrarianInventoryComponent.h"
#include "AgrarianItemPickup.h" #include "AgrarianItemPickup.h"
@@ -102,22 +103,7 @@ void AAgrarianGamePlayerController::BeginPlay()
if (IsLocalPlayerController()) if (IsLocalPlayerController())
{ {
if (MvpFrontendStartupDelaySeconds > 0.0f) StartStartupPresentation();
{
SetMvpFrontendPresentationActive(true);
SetInputMode(FInputModeUIOnly());
bShowMouseCursor = false;
GetWorldTimerManager().SetTimer(
MvpFrontendStartupTimerHandle,
this,
&AAgrarianGamePlayerController::ShowMvpFrontend,
MvpFrontendStartupDelaySeconds,
false);
}
else
{
ShowMvpFrontend();
}
} }
// only spawn touch controls on local player controllers // only spawn touch controls on local player controllers
@@ -214,6 +200,80 @@ void AAgrarianGamePlayerController::ShowMvpFrontend()
bShowMouseCursor = true; bShowMouseCursor = true;
} }
void AAgrarianGamePlayerController::StartStartupPresentation()
{
if (!IsLocalPlayerController())
{
return;
}
SetMvpFrontendPresentationActive(true);
if (!StartupPresentationWidget)
{
StartupPresentationWidget = CreateWidget<UAgrarianDemoNoticeWidget>(this, UAgrarianDemoNoticeWidget::StaticClass());
}
if (StartupPresentationWidget && !StartupPresentationWidget->IsInViewport())
{
StartupPresentationWidget->AddToPlayerScreen(100);
}
ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Splash, StartupSplashSeconds);
}
void AAgrarianGamePlayerController::ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment Segment, float DurationSeconds)
{
StartupPresentationSegment = Segment;
if (StartupPresentationWidget)
{
StartupPresentationWidget->SetPresentationSegment(Segment);
SetInputMode(FInputModeUIOnly().SetWidgetToFocus(StartupPresentationWidget->TakeWidget()).SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock));
}
else
{
SetInputMode(FInputModeUIOnly());
}
bShowMouseCursor = false;
GetWorldTimerManager().ClearTimer(StartupPresentationTimerHandle);
GetWorldTimerManager().SetTimer(
StartupPresentationTimerHandle,
this,
&AAgrarianGamePlayerController::AdvanceStartupPresentation,
FMath::Max(0.1f, DurationSeconds),
false);
}
void AAgrarianGamePlayerController::AdvanceStartupPresentation()
{
if (StartupPresentationSegment == EAgrarianStartupPresentationSegment::Splash)
{
ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Story, StartupStorySeconds);
return;
}
if (StartupPresentationSegment == EAgrarianStartupPresentationSegment::Story)
{
ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment::Credits, StartupCreditsSeconds);
return;
}
FinishStartupPresentation();
}
void AAgrarianGamePlayerController::FinishStartupPresentation()
{
GetWorldTimerManager().ClearTimer(StartupPresentationTimerHandle);
if (StartupPresentationWidget)
{
StartupPresentationWidget->RemoveFromParent();
StartupPresentationWidget = nullptr;
}
ShowMvpFrontend();
}
void AAgrarianGamePlayerController::ShowMvpPauseMenu() void AAgrarianGamePlayerController::ShowMvpPauseMenu()
{ {
if (!IsLocalPlayerController()) if (!IsLocalPlayerController())
@@ -789,10 +849,26 @@ void AAgrarianGamePlayerController::AgrarianCompleteFrontend()
void AAgrarianGamePlayerController::AgrarianRepairGameplayInput() void AAgrarianGamePlayerController::AgrarianRepairGameplayInput()
{ {
bMvpFrontendPresentationActive = false; bMvpFrontendPresentationActive = false;
GetWorldTimerManager().ClearTimer(StartupPresentationTimerHandle);
if (StartupPresentationWidget)
{
StartupPresentationWidget->RemoveFromParent();
StartupPresentationWidget = nullptr;
}
RestoreGameplayControlState(); RestoreGameplayControlState();
ClientMessage(TEXT("Agrarian gameplay input repaired.")); ClientMessage(TEXT("Agrarian gameplay input repaired."));
} }
void AAgrarianGamePlayerController::AgrarianSkipStartupPresentation()
{
if (!StartupPresentationWidget)
{
return;
}
AdvanceStartupPresentation();
}
void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName) void AAgrarianGamePlayerController::AgrarianShowMvpScreen(FName ScreenName)
{ {
if (!MvpFrontendWidget) if (!MvpFrontendWidget)
@@ -3,12 +3,14 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "AgrarianDemoNoticeWidget.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "AgrarianGamePlayerController.generated.h" #include "AgrarianGamePlayerController.generated.h"
class UInputMappingContext; class UInputMappingContext;
class UUserWidget; class UUserWidget;
class UAgrarianMvpFrontendWidget; class UAgrarianMvpFrontendWidget;
class UAgrarianDemoNoticeWidget;
class AAgrarianShelterActor; class AAgrarianShelterActor;
class ACameraActor; class ACameraActor;
@@ -46,9 +48,19 @@ protected:
TObjectPtr<UAgrarianMvpFrontendWidget> MvpFrontendWidget; TObjectPtr<UAgrarianMvpFrontendWidget> MvpFrontendWidget;
UPROPERTY(EditAnywhere, Category = "Agrarian|MVP UI", meta = (ClampMin = "0.0")) UPROPERTY(EditAnywhere, Category = "Agrarian|MVP UI", meta = (ClampMin = "0.0"))
float MvpFrontendStartupDelaySeconds = 24.25f; float MvpFrontendStartupDelaySeconds = 0.0f;
UPROPERTY(EditAnywhere, Category = "Agrarian|Startup", meta = (ClampMin = "1.0"))
float StartupSplashSeconds = 4.0f;
UPROPERTY(EditAnywhere, Category = "Agrarian|Startup", meta = (ClampMin = "10.0"))
float StartupStorySeconds = 60.0f;
UPROPERTY(EditAnywhere, Category = "Agrarian|Startup", meta = (ClampMin = "5.0"))
float StartupCreditsSeconds = 20.75f;
FTimerHandle MvpFrontendStartupTimerHandle; FTimerHandle MvpFrontendStartupTimerHandle;
FTimerHandle StartupPresentationTimerHandle;
/** If true, the player will use UMG touch controls even if not playing on mobile platforms */ /** If true, the player will use UMG touch controls even if not playing on mobile platforms */
UPROPERTY(EditAnywhere, Config, Category = "Input|Touch Controls") UPROPERTY(EditAnywhere, Config, Category = "Input|Touch Controls")
@@ -63,6 +75,10 @@ protected:
/** Returns true if the player should use UMG touch controls */ /** Returns true if the player should use UMG touch controls */
bool ShouldUseTouchControls() const; bool ShouldUseTouchControls() const;
void ShowMvpFrontend(); void ShowMvpFrontend();
void StartStartupPresentation();
void AdvanceStartupPresentation();
void FinishStartupPresentation();
void ShowStartupPresentationSegment(EAgrarianStartupPresentationSegment Segment, float DurationSeconds);
void ShowMvpPauseMenu(); void ShowMvpPauseMenu();
void HandleMvpConfirmInput(); void HandleMvpConfirmInput();
void HandleMvpBackInput(); void HandleMvpBackInput();
@@ -80,7 +96,11 @@ protected:
UPROPERTY() UPROPERTY()
TObjectPtr<ACameraActor> MvpFrontendCameraActor; TObjectPtr<ACameraActor> MvpFrontendCameraActor;
UPROPERTY()
TObjectPtr<UAgrarianDemoNoticeWidget> StartupPresentationWidget;
bool bMvpFrontendPresentationActive = false; bool bMvpFrontendPresentationActive = false;
EAgrarianStartupPresentationSegment StartupPresentationSegment = EAgrarianStartupPresentationSegment::Splash;
bool bCachedMvpHudState = false; bool bCachedMvpHudState = false;
bool bCachedShowDebugHUD = true; bool bCachedShowDebugHUD = true;
bool bCachedShowMvpHudFrame = true; bool bCachedShowMvpHudFrame = true;
@@ -155,6 +175,9 @@ public:
UFUNCTION(Exec) UFUNCTION(Exec)
void AgrarianRepairGameplayInput(); void AgrarianRepairGameplayInput();
UFUNCTION(Exec)
void AgrarianSkipStartupPresentation();
UFUNCTION(Exec) UFUNCTION(Exec)
void AgrarianShowMvpScreen(FName ScreenName); void AgrarianShowMvpScreen(FName ScreenName);