Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Source/P_RD/GameMode/CombatGameMode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ void ACombatGameMode::InitializeCombat()
const FRoomTransactionState& Transactions = GetRunPersistData()->GetRoomTransactions();
mGoldRewardClaimed = Transactions.GoldClaimed;
mExpRewardClaimed = Transactions.ExpClaimed;
mResumePendingLevelUpAfterExp = Transactions.ExpClaimed
&& Transactions.LevelUpSkills.ContainsByPredicate(
[](const FLevelUpSkillReward& Reward) { return !Reward.Completed; });
mClaimedRewardChoiceIndices = Transactions.ClaimedChoices;
mRewardSelectionClaimed = Transactions.SelectedArtifact.IsValid();
mSelectedRewardArtifactId = Transactions.SelectedArtifact;
Expand Down Expand Up @@ -495,6 +498,8 @@ void ACombatGameMode::InitializeCombat()
// HUD가 먼저 만들어져 앵커를 등록한 경우에도 구독 직후 같은 값을 카메라에 적용한다.
HandleChangeFocusScreenAnchor(mCombatUIModel->GetFocusScreenAnchor());
mRewardUIModel->OnRewardClaimRequested.AddUniqueDynamic(this, &ACombatGameMode::HandleRewardClaimed);
mRewardUIModel->OnExperiencePresentationCompleted.AddUniqueDynamic(
this, &ACombatGameMode::HandleExperiencePresentationCompleted);
mRewardUIModel->OnRewardSelectionRequested.AddUniqueDynamic(
this, &ACombatGameMode::HandleRewardSelectionRequested);

Expand Down Expand Up @@ -594,8 +599,7 @@ void ACombatGameMode::BeginCombatAfterEntrance()
}
UE_LOG(LogCombatGameMode, Display, TEXT("RD_BOSS_ENTRANCE combat begins after entrance=%d"), bHadEntrance);
if (auto* Combat = GetWorldSubsystemModel<USRPGCombatModel>(this)) Combat->BeginCombat();
// Pending reward choices belong to the completed-room checkpoint, not a new EXP grant.
mLevelUpSkillRewardFlow->Open(GetRunPersistData(), GetPartyModel(), GetWorld()->GetFirstPlayerController());
// A restored skill choice resumes only after the experience page is advanced.
}

UCombatUIModel* ACombatGameMode::GetCombatUIModel() const
Expand Down Expand Up @@ -864,6 +868,14 @@ void ACombatGameMode::HandleRewardClaimed(ERewardClaimKind ClaimKind, int32 Choi
}
}

void ACombatGameMode::HandleExperiencePresentationCompleted()
{
if (!mResumePendingLevelUpAfterExp || !mLevelUpSkillRewardFlow) return;
mResumePendingLevelUpAfterExp = false;
mLevelUpSkillRewardFlow->Open(GetRunPersistData(), GetPartyModel(),
GetWorld()->GetFirstPlayerController());
}

void ACombatGameMode::HandleRewardSelectionRequested(
const FPrimaryAssetId RewardId)
{
Expand Down
3 changes: 3 additions & 0 deletions Source/P_RD/GameMode/CombatGameMode.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ class P_RD_API ACombatGameMode : public ARoomGameModeBase

UFUNCTION()
void HandleRewardClaimed(ERewardClaimKind ClaimKind, int32 ChoiceIndex);
UFUNCTION()
void HandleExperiencePresentationCompleted();

/** @brief 엘리트·보스 SelectOne 정책 요청을 실제 아티팩트 지급으로 연결한다. */
UFUNCTION()
Expand Down Expand Up @@ -325,6 +327,7 @@ class P_RD_API ACombatGameMode : public ARoomGameModeBase
UPROPERTY(Category = "UI", VisibleAnywhere, DuplicateTransient, meta = (DisplayName = "RewardUIModel"))
TObjectPtr<URewardUIModel> mRewardUIModel;
UPROPERTY() TObjectPtr<ULevelUpSkillRewardFlow> mLevelUpSkillRewardFlow;
bool mResumePendingLevelUpAfterExp = false;

private:
/** @brief 다음 액션/턴이 시작돼 더 이상 유효하지 않은 카메라 복귀 대기를 취소한다. */
Expand Down
72 changes: 72 additions & 0 deletions Source/P_RD/GameMode/RoomGameModeBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "Singleton/WorldSubsystem/WorldWidgetSubsystem.h"
#include "Blueprint/UserWidget.h"
#include "UI/RDUserWidget.h"
#include "UI/SettingsPanelWidget.h"
#include "Singleton/WorldSubsystem/WorldWidgetType.h"

#include "Setting/RDWorldSettings.h"

Expand Down Expand Up @@ -355,6 +357,13 @@ void ARoomGameModeBase::InitializeCommonRoom()
void ARoomGameModeBase::BeginRoom()
{
Super::BeginRoom();
if (USettingsPanelWidget* Settings = GetRunSettingsPanel())
{
Settings->OnSaveAndExitRequested.AddUniqueDynamic(
this, &ARoomGameModeBase::HandleSettingsSaveAndExitRequested);
Settings->OnAbandonRunConfirmed.AddUniqueDynamic(
this, &ARoomGameModeBase::HandleSettingsAbandonConfirmed);
}

/* 터치 세팅 */

Expand All @@ -372,6 +381,69 @@ void ARoomGameModeBase::BeginRoom()
PlayerController->SetInputMode(InputMode);
}

USettingsPanelWidget* ARoomGameModeBase::GetRunSettingsPanel() const
{
UWorld* World = GetWorld();
UWorldWidgetSubsystem* Widgets = World ? World->GetSubsystem<UWorldWidgetSubsystem>() : nullptr;
return Widgets ? Widgets->GetWorldWidget<USettingsPanelWidget>(EWorldWidgetType::InGameSettings) : nullptr;
}

void ARoomGameModeBase::CompleteSettingsRunAction(bool bSuccess, bool bSaveAndExit)
{
if (bSuccess) return; // The room transition owns the successful path.
mCommonSettingsRunActionPending = false;
if (USettingsPanelWidget* Settings = GetRunSettingsPanel())
{
Settings->SetRunActionsEnabled(true);
Settings->SetStatusText(bSaveAndExit
? NSLOCTEXT("RoomGameModeBase", "SaveAndExitFailed", "저장 후 종료에 실패했습니다.")
: NSLOCTEXT("RoomGameModeBase", "AbandonRunFailed", "런 포기 요청에 실패했습니다."));
}
}

void ARoomGameModeBase::HandleSettingsSaveAndExitRequested()
{
if (mCommonSettingsRunActionPending || IsSaveAndExitPending()) return;
USettingsPanelWidget* Settings = GetRunSettingsPanel();
if (Settings)
{
Settings->SetRunActionsEnabled(false);
Settings->SetStatusText(NSLOCTEXT("RoomGameModeBase", "SavingRun", "저장 중..."));
}
USaveGameSubsystem* Saves = GetGameInstance()
? GetGameInstance()->GetSubsystem<USaveGameSubsystem>() : nullptr;
if (!Saves) { CompleteSettingsRunAction(false, true); return; }
mCommonSettingsRunActionPending = true;
Saves->SaveOptionAsync(FAsyncSaveGameToSlotDelegate::CreateWeakLambda(this,
[this](const FString&, int32, bool bSaved)
{
if (!bSaved) { CompleteSettingsRunAction(false, true); return; }
SaveAndExitRunFromRoomAsync(FOnRoomSaveAndExitComplete::CreateWeakLambda(this,
[this](bool bSuccess) { CompleteSettingsRunAction(bSuccess, true); }));
}));
}

void ARoomGameModeBase::HandleSettingsAbandonConfirmed()
{
if (mCommonSettingsRunActionPending || IsSaveAndExitPending()) return;
USettingsPanelWidget* Settings = GetRunSettingsPanel();
if (Settings)
{
Settings->HideAbandonConfirm();
Settings->SetRunActionsEnabled(false);
Settings->SetStatusText(FText::GetEmpty());
}
USaveGameSubsystem* Saves = GetGameInstance()
? GetGameInstance()->GetSubsystem<USaveGameSubsystem>() : nullptr;
if (!Saves) { CompleteSettingsRunAction(false, false); return; }
mCommonSettingsRunActionPending = true;
Saves->SaveOptionAsync(FAsyncSaveGameToSlotDelegate::CreateWeakLambda(this,
[this](const FString&, int32, bool bSaved)
{
CompleteSettingsRunAction(bSaved && AbandonRunFromRoom(), false);
}));
}

bool ARoomGameModeBase::SelectNextRoom(int32 RoomRow, int32 RoomColumn)
{
if (mWasNextRoomPreloadRequested == true)
Expand Down
7 changes: 7 additions & 0 deletions Source/P_RD/GameMode/RoomGameModeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogRoomGameMode, Log, All)

class UPartyModel;
class UPlayerUnitModel;
class USettingsPanelWidget;
struct FCombatArtifactUI;
struct FSkillDetailUI;

Expand Down Expand Up @@ -193,6 +194,12 @@ class P_RD_API ARoomGameModeBase : public ARDGameModeBase
int32 mSelectedRoomColumn = INDEX_NONE;

private:
USettingsPanelWidget* GetRunSettingsPanel() const;
UFUNCTION() void HandleSettingsSaveAndExitRequested();
UFUNCTION() void HandleSettingsAbandonConfirmed();
void CompleteSettingsRunAction(bool bSuccess, bool bSaveAndExit);

bool mCommonSettingsRunActionPending = false;
FName mSelectedRoomSpawnSettingName = NAME_None;
bool mSaveAndExitPending = false;
bool mFinalRunClosed = false;
Expand Down
Loading
Loading