Files
Naked-Desire/Source/NakedDesire/Commissions/Commission.h
T
2026-06-03 15:17:02 +03:00

87 lines
3.1 KiB
C++

// © 2025 Naked People Team. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "CommissionTypes.h"
#include "Commission.generated.h"
class UCommissionObjective;
class ANakedDesireCharacter;
class UCommission;
DECLARE_MULTICAST_DELEGATE_OneParam(FOnCommissionChangedSignature, UCommission*);
/**
* A commission (GDD §13). Authored inline in a UCommissionBoardConfig and duplicated to a runtime
* instance by UMissionSubsystem; the duplicate owns the state machine and its live objectives.
* Completes when every objective reports satisfied; the subsystem pays the reward and persists state.
*/
UCLASS(EditInlineNew, BlueprintType)
class NAKEDDESIRE_API UCommission : public UObject
{
GENERATED_BODY()
public:
// --- Authoring ---
// Stable id used for save/restore (must be unique within the board config).
UPROPERTY(EditDefaultsOnly)
FName CommissionId;
UPROPERTY(EditDefaultsOnly)
FText Title;
// Lore-only forum poster (§13.3) — no gameplay effect.
UPROPERTY(EditDefaultsOnly)
FText PosterUsername;
UPROPERTY(EditDefaultsOnly)
ECommissionTier Tier = ECommissionTier::Daily;
UPROPERTY(EditDefaultsOnly)
FCommissionReward Reward;
UPROPERTY(EditDefaultsOnly, Instanced)
TArray<UCommissionObjective*> Objectives;
// When true, objectives activate one at a time in array order (strip at A -> walk to B -> ... ).
// When false (default), all objectives are active at once and may be satisfied in any order.
UPROPERTY(EditDefaultsOnly)
bool bSequentialObjectives = false;
// --- Runtime ---
FOnCommissionChangedSignature OnStateChanged; // any transition
FOnCommissionChangedSignature OnCompleted; // -> Completed
ECommissionState GetState() const { return State; }
UFUNCTION(BlueprintPure) ECommissionTier GetTier() const { return Tier; }
UFUNCTION(BlueprintPure) FText GetTitle() const { return Title; }
UFUNCTION(BlueprintPure) FText GetPosterUsername() const { return PosterUsername; }
UFUNCTION(BlueprintPure) FCommissionReward GetReward() const { return Reward; }
UFUNCTION(BlueprintPure) TArray<UCommissionObjective*> GetObjectives() const { return Objectives; }
void Accept(ANakedDesireCharacter* InPlayer); // Offered -> Accepted; arms objectives
void Abandon(); // Accepted -> Offered; no penalty (§13.2)
void Expire(); // Accepted -> Expired (deadline)
// Re-apply a persisted state on load (re-arms objectives when restoring Accepted).
void RestoreState(ECommissionState SavedState, ANakedDesireCharacter* InPlayer);
private:
void Complete();
bool AreAllObjectivesSatisfied() const;
void ArmObjectives();
void DisarmObjectives();
void AdvanceSequential(); // activate the first unsatisfied objective, or complete if none remain
void SetState(ECommissionState NewState);
void HandleObjectiveStateChanged(UCommissionObjective* Objective);
ECommissionState State = ECommissionState::Offered;
int32 ActiveObjectiveIndex = INDEX_NONE; // sequential mode: the objective currently armed
UPROPERTY()
ANakedDesireCharacter* Player = nullptr;
};