Bugfixes and review

This commit is contained in:
Oleg Petruny 2025-07-11 00:01:19 +02:00
parent 0774965cc8
commit eaff75b652
68 changed files with 257 additions and 149 deletions

View File

@ -1,3 +1,5 @@
All sounds are liecesed under [CC0](https://creativecommons.org/publicdomain/zero/1.0/) when was downloaded.
Click - https://freesound.org/people/ccr_fs/sounds/484719/
ElectricTransform - https://freesound.org/people/ShahruhAudio/sounds/336881/
ElectricZap - https://freesound.org/people/egomassive/sounds/536741/

View File

@ -62,10 +62,13 @@ InternationalizationPreset=English
LocalizationTargetCatchAllChunkId=0
bCookAll=False
bCookMapsOnly=False
bTreatWarningsAsErrorsOnCook=False
bSkipEditorContent=True
bSkipMovies=False
-IniKeyDenylist=KeyStorePassword
-IniKeyDenylist=KeyPassword
-IniKeyDenylist=DebugKeyStorePassword
-IniKeyDenylist=DebugKeyPassword
-IniKeyDenylist=rsa.privateexp
-IniKeyDenylist=rsa.modulus
-IniKeyDenylist=rsa.publicexp
@ -81,6 +84,8 @@ bSkipMovies=False
-IniKeyDenylist=MobileProvision
-IniKeyDenylist=IniKeyDenylist
-IniKeyDenylist=IniSectionDenylist
+IniKeyDenylist=DebugKeyStorePassword
+IniKeyDenylist=DebugKeyPassword
+IniKeyDenylist=KeyStorePassword
+IniKeyDenylist=KeyPassword
+IniKeyDenylist=rsa.privateexp
@ -100,6 +105,8 @@ bSkipMovies=False
+IniKeyDenylist=IniSectionDenylist
-IniSectionDenylist=HordeStorageServers
-IniSectionDenylist=StorageServers
-IniSectionDenylist=/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings
+IniSectionDenylist=/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings
+IniSectionDenylist=HordeStorageServers
+IniSectionDenylist=StorageServers
+DirectoriesToAlwaysCook=(Path="/Game/Misc/Interactables")
@ -115,6 +122,7 @@ bSkipMovies=False
+DirectoriesToAlwaysCook=(Path="/Game/Audio/FMOD/Reverbs")
+DirectoriesToAlwaysCook=(Path="/Game/Audio/FMOD/Snapshots")
+DirectoriesToAlwaysCook=(Path="/Game/Audio/FMOD/VCAs")
+DirectoriesToAlwaysCook=(Path="/NNEDenoiser")
+DirectoriesToAlwaysStageAsNonUFS=(Path="Audio/FMOD/Desktop")
bRetainStagedDirectory=False
CustomStageCopyHandler=

View File

@ -37,3 +37,5 @@ HDRDisplayOutputNits=1000
[/Script/Engine.GameUserSettings]
bUseDesiredScreenHeight=False
[ScalabilityGroups]
sg.ResolutionQuality=100

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -55,6 +55,17 @@ int32 UCommonFunctions::StringIndexInTextArray(const TArray<FText>& array, const
return -1;
}
int32 UCommonFunctions::SubstringCount(const FString& in, const FString& substr)
{
int32 result = 0;
int32 i = -1;
while((i = in.Find(substr, ESearchCase::Type::CaseSensitive, ESearchDir::Type::FromStart, i + 1)) != INDEX_NONE)
++result;
return result;
}
void UCommonFunctions::DestroyActorRecursively(AActor* actor)
{
TArray<AActor*> childs;

View File

@ -53,6 +53,8 @@ public:
UFUNCTION(BlueprintPure)
static int32 StringIndexInTextArray(const TArray<FText>& array, const FString& value);
UFUNCTION(BlueprintPure)
static int32 SubstringCount(const FString& in, const FString& substr);
/** Recursively destroy actor and all its childs (the default Destroy doesn't have consistent behavior) */
UFUNCTION(BlueprintCallable, Category = Actor)

View File

@ -130,21 +130,19 @@ void UCustomGameInstance::SaveGame(FName checkpointName)
if(!levelScript)
return;
auto player = APlayerBase::Get();
if(!player)
return;
saveData->level = GetWorld()->GetFName();
saveData->state = levelScript->GetState();
saveData->checkpoint = checkpointName;
if(player->leftPocketItem)
auto player = APlayerBase::Get();
if(player && player->leftPocketItem)
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
else
saveData->playerLeftPocketItem = FName(TEXT(""));
if(player->rightPocketItem)
saveData->playerLeftPocketItem = {};
if(player && player->rightPocketItem)
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
else
saveData->playerRightPocketItem = FName(TEXT(""));
saveData->playerRightPocketItem = {};
UGameplayStatics::SaveGameToSlot(saveData, saveName, saveIndex);
}

View File

@ -116,11 +116,7 @@ void UGraphicsSettingsHelper::CenterWindowPosition(UCustomGameSettings* settings
return;
FIntPoint position;
if(GetDisplayMode(settings) == EDisplayMode::Fullscreen)
{
position = { 0, 0 };
}
else
if(GetDisplayMode(settings) == EDisplayMode::Windowed)
{
auto monitors = GetAvailableMonitors();
int32 monitorId = GetMonitorId(settings);
@ -132,6 +128,10 @@ void UGraphicsSettingsHelper::CenterWindowPosition(UCustomGameSettings* settings
FIntPoint window = GetResolution(settings);
position = { offset + (monitor.X - window.X) / 2, (monitor.Y - window.Y) / 2 };
}
else
{
position = { 0, 0 };
}
SetWindowPosition(settings, position);
}
@ -361,8 +361,9 @@ FIntPoint UGraphicsSettingsHelper::FilterClosestResolution(const TArray<FIntPoin
for(int32 i = 1; i < resolutions.Num(); ++i)
{
float c = resolutions[i].X / (float)target.X;
if((coefficient > 1 && c < coefficient)
|| (coefficient < 1 && c > coefficient && c < 1))
if((coefficient > 1 && c < coefficient) // 1 < new result < old result
|| (c < 1 && c > coefficient) // old result < new result < 1
|| UCommonFunctions::FloatIsZero(c - 1)) // new result == Omega(1)
{
coefficient = c;
resultId = i;

View File

@ -10,14 +10,18 @@
#include "Engine/SkyLight.h"
#include "LevelSequencePlayer.h"
#include "CustomGameInstance.h"
#include "CutsceneManager.h"
void ALevel1::BeginPlay()
{
ALevelBase::BeginPlay();
TurnLight(false);
TurnFog(false);
//TurnLight(false);
//TurnFog(false);
if(auto GI = UCustomGameInstance::Get())
GI->SaveGame({});
CallNextState();
}

View File

@ -2,9 +2,14 @@
#include "Level2.h"
#include "CustomGameInstance.h"
void ALevel2::BeginPlay()
{
ALevelBase::BeginPlay();
if(auto GI = UCustomGameInstance::Get())
GI->SaveGame({});
CallNextState();
}

View File

@ -8,6 +8,7 @@
#include "Engine/SkyLight.h"
#include "LevelSequencePlayer.h"
#include "CustomGameInstance.h"
#include "CutsceneManager.h"
#include "MainGameModeBase.h"
@ -15,5 +16,8 @@ void ALevel3::BeginPlay()
{
ALevelBase::BeginPlay();
CallNextState();
if(auto GI = UCustomGameInstance::Get())
GI->SaveGame({});
//CallNextState();
}

View File

@ -89,32 +89,37 @@ void ALevelBase::ApplySaveData()
if(!player)
return;
for(TActorIterator<ACheckpoint> it(GetWorld()); it; ++it)
if(!GI->saveData->checkpoint.IsNone())
{
if(it->GetFName() == GI->saveData->checkpoint)
for(TActorIterator<ACheckpoint> it(GetWorld()); it; ++it)
{
player->SetActorLocation(it->GetActorLocation(), false, nullptr, ETeleportType::ResetPhysics);
player->Controller->SetControlRotation(it->GetActorRotation());
break;
if(it->GetFName() == GI->saveData->checkpoint)
{
player->SetActorLocation(it->GetActorLocation(), false, nullptr, ETeleportType::ResetPhysics);
player->Controller->SetControlRotation(it->GetActorRotation());
break;
}
}
}
int pocketItems = 0;
for(TActorIterator<AInteractable> it(GetWorld()); it; ++it)
if(!GI->saveData->playerLeftPocketItem.IsNone() || !GI->saveData->playerRightPocketItem.IsNone())
{
if(it->GetFName() == GI->saveData->playerLeftPocketItem)
int pocketItems = 0;
for(TActorIterator<AInteractable> it(GetWorld()); it; ++it)
{
++pocketItems;
player->TakeItemToLeftHand(*it);
}
else if(it->GetFName() == GI->saveData->playerRightPocketItem)
{
++pocketItems;
player->TakeItemToRightHand(*it);
}
if(pocketItems > 1)
{
break;
if(pocketItems > 1)
break;
if(it->GetFName() == GI->saveData->playerLeftPocketItem)
{
++pocketItems;
player->TakeItemToLeftHand(*it);
}
else if(it->GetFName() == GI->saveData->playerRightPocketItem)
{
++pocketItems;
player->TakeItemToRightHand(*it);
}
}
}
}

View File

@ -56,3 +56,11 @@ void AMinigame::Restart()
OnRestart_Internal();
OnRestart();
}
void AMinigame::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if(instance == this)
instance = nullptr;
Super::EndPlay(EndPlayReason);
}

View File

@ -47,6 +47,8 @@ public:
TSoftObjectPtr<class UInputMappingContext> GetInputMappings() { return context; }
protected:
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void OnStart_Internal() {}
UFUNCTION(BlueprintImplementableEvent)
void OnStart();

View File

@ -348,30 +348,7 @@ void APlayerBase::ShowJournal()
void APlayerBase::ShowMenu()
{
if(auto WM = AMainGameModeBase::GetWidgetsManager())
{
if(GetWorld()->IsPaused())
{
WM->HideMainMenu();
if(auto PC = ACustomPlayerController::Get())
{
PC->SetShowMouseCursor(false);
PC->SetInputMode(FInputModeGameOnly{});
}
UnlockPlayer(FPlayerLock::All());
UGameplayStatics::SetGamePaused(GetWorld(), false);
}
else
{
WM->ShowMainMenu();
if(auto PC = ACustomPlayerController::Get())
{
PC->SetShowMouseCursor(true);
PC->SetInputMode(FInputModeGameAndUI{});
}
LockPlayer(FPlayerLock::All());
UGameplayStatics::SetGamePaused(GetWorld(), true);
}
}
WM->MenuCall();
}
FPlayerLock FPlayerLock::All()

View File

@ -9,6 +9,11 @@
#include "MainMenuButtonWidget.h"
#include "Widgets/WidgetsManager.h"
namespace
{
constexpr float userCallDelaySeconds = 0.1f;
}
bool UMainMenuWidget::Initialize()
{
//FWidgetAnimationDynamicEvent closeFinished;
@ -18,6 +23,25 @@ bool UMainMenuWidget::Initialize()
return UUserWidget::Initialize();
}
void UMainMenuWidget::UserCall()
{
float time = GetWorld()->GetRealTimeSeconds();
if(time - userCallTimeStamp < userCallDelaySeconds)
return;
userCallTimeStamp = time;
if(Visibility == ESlateVisibility::Hidden)
{
if(auto GM = AMainGameModeBase::Get())
if(auto WM = GM->GetWidgetsManager())
WM->ShowMainMenu(true);
}
else
{
OnUserCall();
}
}
void UMainMenuWidget::Show(bool fast)
{
SetVisibility(ESlateVisibility::Visible);

View File

@ -18,6 +18,9 @@ class UMainMenuWidget : public UUserWidget
public:
virtual bool Initialize() override;
void UserCall();
UFUNCTION(BlueprintImplementableEvent)
void OnUserCall();
UFUNCTION(BlueprintCallable)
void Show(bool fast = true);
UFUNCTION(BlueprintCallable)
@ -38,4 +41,7 @@ public:
protected:
UFUNCTION()
void Closed();
private:
float userCallTimeStamp = 0;
};

View File

@ -11,6 +11,7 @@
#include "CustomGameInstance.h"
#include "CustomGameSettings.h"
#include "CustomPlayerController.h"
#include "Interactable/Interactable.h"
#include "Interactable/Modificators/InteractableModificator.h"
#include "Interactable/Modificators/InventoryInteractableModificator.h"
@ -165,8 +166,24 @@ void UWidgetsManager::RemoveOverlayWidget(UUserWidget* widget)
void UWidgetsManager::MenuCall()
{
mainMenuWidget->UserCall();
}
void UWidgetsManager::ShowMainMenu(bool pause)
{
if(auto PC = ACustomPlayerController::Get())
{
PC->SetShowMouseCursor(true);
PC->SetInputMode(FInputModeGameAndUI{});
}
if(auto p = APlayerBase::Get())
{
p->LockPlayer(FPlayerLock::All());
}
UGameplayStatics::SetGamePaused(GetWorld(), true);
mainMenuWidget->Show(pause);
HideJournal();
HideCheatMenu();
@ -174,6 +191,17 @@ void UWidgetsManager::ShowMainMenu(bool pause)
void UWidgetsManager::HideMainMenu()
{
if(auto PC = ACustomPlayerController::Get())
{
PC->SetShowMouseCursor(false);
PC->SetInputMode(FInputModeGameOnly{});
}
if(auto p = APlayerBase::Get())
{
p->UnlockPlayer(FPlayerLock::All());
}
UGameplayStatics::SetGamePaused(GetWorld(), false);
mainMenuWidget->Hide();
}

View File

@ -32,7 +32,10 @@ public:
UFUNCTION(BlueprintCallable, Category = WidgetsManager)
void RemoveOverlayWidget(class UUserWidget* widget);
void MenuCall();
UFUNCTION(BlueprintCallable, Category = WidgetsManager)
void ShowMainMenu(bool pause = true);
UFUNCTION(BlueprintCallable, Category = WidgetsManager)
void HideMainMenu();
UFUNCTION(BlueprintCallable, Category = WidgetsManager)