feat: Enhance interaction and inventory systems with new components and functionality

- Added BPC_UsableWorldObjectSystem for handling various interactable world objects with detailed manual implementation guide.
- Introduced BPC_ActiveItemSystem to manage quick slots and active item usage, including cycling and selection logic.
- Implemented BPC_DocumentArchiveSystem for managing collectible documents with read tracking and categorization.
- Developed BPC_JournalSystem for narrative entries with auto-adding features based on gameplay events.
- Created BPC_KeyItemSystem for key management with consumable and persistent key support.
- Enhanced BPC_FirearmSystem for ranged weapon mechanics, including hitscan and projectile firing.
- Updated BPC_MeleeSystem for melee combat with combo and blocking mechanics.
- Established BPC_ReloadSystem for managing weapon reloading processes, including partial reloads and state management.
This commit is contained in:
Lefteris Notas
2026-05-19 18:37:42 +03:00
parent f272257cb3
commit eeb1bf82c9
11 changed files with 1361 additions and 11 deletions

View File

@@ -94,4 +94,167 @@
## 7. Reuse Notes
- All puzzle logic is data-driven via `DA_PuzzleData`
- LinkedActor pattern decouples puzzle from effect
- LinkedActor pattern decouples puzzle from effect
---
## 8. Manual Implementation Guide
### 8.1 Class Setup
1. Create Blueprint Class: Parent = `Actor`, Name = `BP_PuzzleDeviceActor`
2. Add components: StaticMesh (visual), InteractionCollision (Sphere), WidgetComponent (for interaction prompt)
3. Implement Interfaces: `I_Interactable`
4. Save to: `Content/Framework/Interaction/`
### 8.2 Variable Initialization (BeginPlay / Construction Script)
```
Event BeginPlay
├─ Set CurrentState = Unsolved (or Locked if requires unlock first)
├─ Set CurrentAttempts = 0
├─ Load PuzzleData → if valid:
│ ├─ Set InteractionPrompt = PuzzleData.PromptText
│ ├─ Set MaxAttempts = PuzzleData.MaxAttempts
│ ├─ Set CooldownSeconds = PuzzleData.Cooldown
│ └─ Apply initial visual state (dim if locked, glowing if interactable)
└─ Register with SS_SaveManager if implements I_Persistable
```
### 8.3 Function Implementations
#### `I_Interactable: OnInteract(Instigator: Actor)` → `Boolean`
```
[Function: OnInteract] — called by BPC_InteractionDetector
Step 1: Branch on CurrentState:
Case Unsolved → Call BeginInteraction(Instigator) → Return true
Case Solved → Play solved animation/sound → Return false (already solved)
Case Locked → Check if Instigator has required key:
If yes → unlock → BeginInteraction
If no → Play locked feedback → Return false
Case InProgress → Return false (already interacting)
Case Failed → If bResetOnFail: ResetPuzzle → BeginInteraction
```
#### `BeginInteraction(Instigator: Actor)` → `void`
```
[Function: BeginInteraction]
Step 1: Set CurrentState = InProgress
Step 2: Set bIsInteractable = false (block re-interaction during solve)
Step 3: Fire OnPuzzleStateChanged(InProgress)
Step 4: Branch on PuzzleData.PuzzleType:
Lever, PressurePlate, ValveWheel:
- No UI overlay needed; player manipulates world objects
- Enable input on the puzzle's interactive levers/buttons
Keypad, CombinationLock, CircuitBoard:
- Open puzzle UI widget (attached to WidgetComponent or fullscreen)
- Set player input mode to UI Only
- Route input to puzzle widget
Step 5: Block player movement (optional, per puzzle config)
Step 6: Set interaction camera view (zoom to puzzle if needed)
```
#### `CheckSolution(PlayerInput: varies by puzzle type)` → `Boolean`
```
[Function: CheckSolution]
Step 1: Read correct solution from PuzzleData.Solution
Step 2: Compare player input against solution:
- Lever sequence: check order of pulled levers matches solution
- Keypad: check entered code matches solution code
- CombinationLock: check each dial position
- CircuitBoard: check all connections match solution
- PressurePlate: check weight/actor matches
Step 3: If match:
Call OnPuzzleSolved(Instigator)
Return true
Step 4: If no match:
Increment CurrentAttempts
Branch on MaxAttempts != -1 AND CurrentAttempts >= MaxAttempts:
True → Call OnPuzzleFailed()
False → Show hint/wrong feedback, allow retry
Return false
```
**Node example for keypad puzzle:**
```
Get SolutionString from PuzzleData
Branch: PlayerInputCode == SolutionString
```
#### `OnPuzzleSolved(Solver: Actor)` → `void`
```
[Function: OnPuzzleSolved]
Step 1: Set CurrentState = Solved
Step 2: Set bIsInteractable = false (permanently)
Step 3: Play solved visual: change material to green/solved glow
Step 4: Play solved sound via SS_AudioManager
Step 5: Fire OnPuzzleSolved(Solver)
Step 6: Fire OnPuzzleStateChanged(Solved)
Step 7: Notify LinkedActor (if set):
If LinkedActor valid:
If LinkedActor implements I_Toggleable → Call Toggle(Solver)
If LinkedActor implements I_Lockable → Call Unlock(Solver)
Fire OnPuzzleLinkedActorTriggered(LinkedActor)
Step 8: Grant rewards from PuzzleData:
Get BPC_InventorySystem → If PuzzleData.RewardItem valid → Call AddItem
Get BPC_NarrativeStateSystem → Set flag: PuzzleData.CompletionFlag
Step 9: EndInteraction()
```
#### `OnPuzzleFailed()` → `void`
```
[Function: OnPuzzleFailed]
Step 1: Set CurrentState = Failed
Step 2: Play failure sound/visual
Step 3: Fire OnPuzzleFailed(CurrentAttempts)
Step 4: Fire OnPuzzleStateChanged(Failed)
Step 5: Branch on bResetOnFail:
True → Start timer for CooldownSeconds → Call ResetPuzzle
False → If MaxAttempts reached: Set CurrentState = Locked permanently
Step 6: EndInteraction()
```
#### `EndInteraction()` → `void`
```
[Function: EndInteraction]
Step 1: Close puzzle UI widget (if open)
Step 2: Restore player input mode to Game Only
Step 3: Re-enable player movement
Step 4: Restore camera to default
Step 5: If CurrentState != InProgress → Set bIsInteractable = true
```
#### `ResetPuzzle()` → `void`
```
[Function: ResetPuzzle]
Step 1: Set CurrentState = Unsolved
Step 2: Set CurrentAttempts = 0
Step 3: Reset all puzzle levers/dials/inputs to default positions
Step 4: Set bIsInteractable = true
Step 5: Fire OnPuzzleStateChanged(Unsolved)
```
### 8.4 Blueprint Build Checklist
- [ ] Create BP_PuzzleDeviceActor actor with mesh + collision + widget components
- [ ] Implement I_Interactable interface
- [ ] Add all variables: PuzzleData, CurrentState, bIsInteractable, LinkedActor, MaxAttempts, etc.
- [ ] Implement BeginInteraction with type-switch (lever vs UI vs custom)
- [ ] Implement CheckSolution with type-specific validation
- [ ] Implement OnPuzzleSolved (visual, sound, LinkedActor, rewards, narrative flag)
- [ ] Implement OnPuzzleFailed (retry or lockout)
- [ ] Implement EndInteraction (UI close, input restore, camera restore)
- [ ] Implement ResetPuzzle for retryable puzzles
- [ ] Bind to BPC_InteractionDetector via I_Interactable
- [ ] Test: approach puzzle → interact → solve → door unlocks → save/load restores state