-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathPSEndGameWidget.cpp
183 lines (160 loc) · 6.63 KB
/
PSEndGameWidget.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// Copyright (c) Valerii Rotermel & Yevhenii Selivanov
#include "Widgets/PSEndGameWidget.h"
//---
#include "Data/PSDataAsset.h"
#include "Components/HorizontalBox.h"
#include "Components/Image.h"
#include "Widgets/PSStarWidget.h"
//---
#include "PoolManagerSubsystem.h"
#include "PoolManagerTypes.h"
#include "Components/StaticMeshComponent.h"
#include "Data/PSTypes.h"
#include "Data/PSWorldSubsystem.h"
#include "Engine/CurveTable.h"
#include "GameFramework/MyGameStateBase.h"
#include "GameFramework/MyPlayerState.h"
#include "Subsystems/GlobalEventsSubsystem.h"
#include "UtilityLibraries/MyBlueprintFunctionLibrary.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(PSEndGameWidget)
// Called after the underlying slate widget is constructed.
void UPSEndGameWidget::NativeConstruct()
{
Super::NativeConstruct();
// Hide this widget by default
SetVisibility(ESlateVisibility::Collapsed);
// Listen to handle input for each game state
BIND_ON_GAME_STATE_CHANGED(this, ThisClass::OnGameStateChanged);
// Binds the local player state ready event to the handler
BIND_ON_LOCAL_PLAYER_STATE_READY(this, ThisClass::OnLocalPlayerStateReady);
UPSWorldSubsystem& WorldSubsystem = UPSWorldSubsystem::Get();
WorldSubsystem.OnCurrentScoreChanged.AddUniqueDynamic(this, &ThisClass::OnCurrentScoreChanged);
}
// Called when the end game state was changed to toggle progression widget visibility
void UPSEndGameWidget::OnGameStateChanged_Implementation(ECurrentGameState CurrentGameState)
{
switch (CurrentGameState)
{
case ECurrentGameState::GameStarting: // Fallthrough
case ECurrentGameState::Menu:
SetVisibility(ESlateVisibility::Collapsed);
break;
default: break;
}
}
// Subscribes to the end game state change notification on the player state
void UPSEndGameWidget::OnLocalPlayerStateReady_Implementation(AMyPlayerState* PlayerState, int32 CharacterID)
{
// Ensure that PlayerState is not null before subscribing to the event
checkf(PlayerState, TEXT("ERROR: [%i] %hs:\n'PlayerState' is null!"), __LINE__, __FUNCTION__);
PlayerState->OnEndGameStateChanged.AddUniqueDynamic(this, &ThisClass::OnEndGameStateChanged);
}
// Called when the end game state was changed
void UPSEndGameWidget::OnEndGameStateChanged_Implementation(EEndGameState EndGameState)
{
if (EndGameState != EEndGameState::None)
{
// show the stars widget at the bottom.
SetVisibility(ESlateVisibility::Visible);
}
}
// Dynamically populates a Horizontal Box with images representing unlocked and locked progression icons.
void UPSEndGameWidget::AddImagesToHorizontalBox(float AmountOfUnlockedPoints, float AmountOfLockedPoints, float MaxLevelPoints)
{
//Return to Pool Manager the list of handles which is not needed (if there are any)
if (!PoolWidgetHandlersInternal.IsEmpty())
{
UPoolManagerSubsystem::Get().ReturnToPoolArray(PoolWidgetHandlersInternal);
PoolWidgetHandlersInternal.Empty();
}
// --- Prepare spawn request
const TWeakObjectPtr<ThisClass> WeakThis = this;
const FOnSpawnAllCallback OnTakeFromPoolCompleted = [WeakThis, AmountOfUnlockedPoints, AmountOfLockedPoints, MaxLevelPoints](const TArray<FPoolObjectData>& CreatedObjects)
{
if (UPSEndGameWidget* This = WeakThis.Get())
{
This->OnTakeFromPoolCompleted(CreatedObjects, AmountOfUnlockedPoints, AmountOfLockedPoints, MaxLevelPoints);
}
};
// --- Spawn widgets
const int32 TotalRequests = AmountOfLockedPoints + AmountOfUnlockedPoints;
if (TotalRequests == 0)
{
// no items to request nothing to add
return;
}
UPoolManagerSubsystem::Get().TakeFromPoolArray(PoolWidgetHandlersInternal, UPSDataAsset::Get().GetStarWidgetClass(), TotalRequests, OnTakeFromPoolCompleted);
}
// Dynamically populates a Horizontal Box with images representing unlocked and locked progression icons
void UPSEndGameWidget::OnTakeFromPoolCompleted(const TArray<FPoolObjectData>& CreatedObjects, float AmountOfUnlockedPoints, float AmountOfLockedPoints, float MaxLevelPoints)
{
if (!ensureMsgf(HorizontalBox, TEXT("ASSERT: [%i] %hs:\n'HorizontalBox' is null!"), __LINE__, __FUNCTION__))
{
return;
}
HorizontalBox->ClearChildren();
float CurrentAmountOfUnlocked = AmountOfUnlockedPoints;
float CurrentAmountOfLocked = AmountOfLockedPoints;
// Setup spawned widget
for (const FPoolObjectData& CreatedObject : CreatedObjects)
{
if (CurrentAmountOfUnlocked > 0)
{
// #1 Create MyFunction
UpdateStarImages(CreatedObject, 1, 0);
// more than 0 means that it's not an integer
if ((MaxLevelPoints - CurrentAmountOfUnlocked) > 0)
{
UpdateStarProgressBarValue(CreatedObject, CurrentAmountOfUnlocked);
}
CurrentAmountOfUnlocked--;
continue;
}
if (CurrentAmountOfLocked > 0)
{
UpdateStarImages(CreatedObject, 0, 1);
CurrentAmountOfLocked--;
}
}
}
// Updates star images icon to locked/unlocked according to input amounnt
void UPSEndGameWidget::UpdateStarImages(const FPoolObjectData& CreatedData, float AmountOfUnlockedStars, float AmountOfLockedStars)
{
UPSStarWidget& SpawnedWidget = CreatedData.GetChecked<UPSStarWidget>();
if (AmountOfUnlockedStars > 0)
{
SpawnedWidget.SetStarImage(UPSDataAsset::Get().GetUnlockedProgressionIcon());
SpawnedWidget.UpdateProgressionBarPercentage(AmountOfUnlockedStars);
}
if (AmountOfLockedStars > 0)
{
SpawnedWidget.SetStarImage(UPSDataAsset::Get().GetLockedProgressionIcon());
}
// Load and set the image texture here using ImagePath or other methods
if (!HorizontalBox->HasChild(&SpawnedWidget))
{
HorizontalBox->AddChildToHorizontalBox(&SpawnedWidget);
SpawnedWidget.UpdateProgressionBarPercentage(AmountOfUnlockedStars);
}
}
// Updates Progress bar icon for unlocked icons
void UPSEndGameWidget::UpdateStarProgressBarValue(const FPoolObjectData& CreatedData, float NewProgressBarValue)
{
UPSStarWidget& SpawnedWidget = CreatedData.GetChecked<UPSStarWidget>();
SpawnedWidget.UpdateProgressionBarPercentage(NewProgressBarValue);
}
// Updates the progression menu widget when player changed
void UPSEndGameWidget::OnCurrentScoreChanged_Implementation(const FPSSaveToDiskData& CurrenSaveToDiskDataRow, const FPSSettingsRow& CurrenProgressionSettingsRow)
{
//set updated amount of stars
if (CurrenSaveToDiskDataRow.CurrentLevelProgression >= CurrenProgressionSettingsRow.PointsToUnlock)
{
// set required points (stars) to achieve for a level
AddImagesToHorizontalBox(CurrenProgressionSettingsRow.PointsToUnlock, 0, CurrenProgressionSettingsRow.PointsToUnlock);
}
else
{
// Calculate the unlocked against locked points (stars)
AddImagesToHorizontalBox(CurrenSaveToDiskDataRow.CurrentLevelProgression, CurrenProgressionSettingsRow.PointsToUnlock - CurrenSaveToDiskDataRow.CurrentLevelProgression, CurrenProgressionSettingsRow.PointsToUnlock); // Listen game state changes events
}
}