Added commissions system
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
// © 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;
|
||||
};
|
||||
Reference in New Issue
Block a user