/
GhostAiController.h
182 lines (135 loc) · 4.72 KB
/
GhostAiController.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#pragma once
#include "CoreMinimal.h"
#include "Math/IntPoint.h"
#include "AIController.h"
#include "AStar/GridLocation.h"
#include "ChompGameState.h"
#include "AStar/MovementPath.h"
#include "LevelGenerator/LevelLoader.h"
#include "GhostAiController.generated.h"
class AGhostHouseQueue;
UENUM()
enum class EGhostState : uint8
{
Normal,
Frightened,
Eaten,
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGhostStateChanged,
EGhostState, HasBeenEaten);
// TODO: This class has many responsibilities, see the bottom of this file for potential refactorings when it's expedient.
UCLASS()
class AGhostAiController : public AAIController
{
GENERATED_BODY()
// Whether to print out A* map info in the logs.
UPROPERTY(EditDefaultsOnly, Category = "Custom Settings")
bool DebugAStarMap = false;
UPROPERTY(VisibleInstanceOnly, Category = "Debug View")
EGhostState GhostState = EGhostState::Normal;
UFUNCTION()
void UpdateWhenSubstateChanges(EChompPlayingSubstateEnum OldState, EChompPlayingSubstateEnum NewState);
UFUNCTION()
void HandleDotsConsumedUpdated(int NewDotsConsumed);
static TArray<FGridLocation> ComputePath(
ULevelLoader* LevelInstance,
FVector2D CurrentWorldPosition,
FGridLocation StartGridPos,
FGridLocation EndGridPos,
bool Debug
);
static void DebugAStar(
const std::unordered_map<FGridLocation, FGridLocation>& CameFrom,
ULevelLoader* LevelInstance
);
void ResetGhostState();
bool IsStartingPositionInGhostHouse() const;
bool IsInGhostHouseQueue() const;
AGhostHouseQueue* GetGhostHouseQueue() const;
bool IsPlayerAlive() const;
// A setter that will also notify observers of the changed internal state.
void SetGhostState(const EGhostState NewGhostState);
UFUNCTION()
void HandleGhostStateChanged(const EGhostState NewGhostState);
FMovementPath ReturnToGhostHouse() const;
FGridLocation ComputeDestinationNodeInFrightened(const FGridLocation& GridLocation) const;
protected:
UPROPERTY(EditDefaultsOnly, Category = "Custom Settings")
TSubclassOf<ULevelLoader> Level;
UPROPERTY(VisibleInstanceOnly)
FMovementPath MovementPath;
UPROPERTY(VisibleInstanceOnly)
FGridLocation CurrentScatterOrigin;
UPROPERTY(VisibleInstanceOnly)
FGridLocation CurrentScatterDestination;
virtual void OnPossess(APawn* InPawn) override;
virtual void Tick(float DeltaTime) override;
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual FGridLocation GetPlayerGridLocation() const;
virtual FGridLocation GetPlayerGridDirection() const;
virtual FVector GetPlayerWorldLocation() const;
FMovementPath UpdateMovementPathWhenInChase() const;
FMovementPath UpdateMovementPathWhenInScatter();
FMovementPath UpdateMovementPathWhenInFrightened() const;
public:
UPROPERTY(BlueprintAssignable, BlueprintCallable)
FOnGhostStateChanged OnGhostStateChanged;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Customizable AI Behavior")
FGridLocation GetChaseEndGridPosition() const;
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Customizable AI Behavior")
void DecideToUpdateMovementPathInChase(FVector NewLocation);
virtual FGridLocation GetChaseEndGridPosition_Implementation() const;
virtual void DecideToUpdateMovementPathInChase_Implementation(FVector NewLocation);
void HandleGameStateChanged(EChompGameStateEnum OldState, EChompGameStateEnum NewState);
int GetLeaveGhostHousePriority() const;
UFUNCTION(BlueprintCallable)
bool IsEaten() const;
UFUNCTION(BlueprintCallable)
bool IsNormal() const;
void Consume();
};
#if false
* GhostAiController (the brain of the Ghost pawn)
* GhostState (field)
* UpdateWhenSubstateChanged
* ResetGhostState (emit an event)
* SetGhostState
* HandleGhostStateChanged
* OnPossess
* Tick()
* OnGhostStateChanged
* HandleGameStateChanged
* IsEaten
* Consume
* Member of ghosthousequeue (component)
* HandleDotsConsumedUpdated
* ResetGhostState
* IsInGhostHouseQueue
* GetGhostHouseQueue
* IsStartingPositionInGhostHouse (helper)
* GetLeaveGhostHousePriority
* A* maze navigator component
* ComputePath
* DebugAStarMap (config), whether to print out map
* DebugAStar
* ReturnToGhostHouse
* MovementPath (field)
* CurrentScatterOrigin
* CurrentScatterDestination
* Tick()
* Possibly use state pattern:
* UpdateMovementPathWhenInChase
* UpdateMovementPathWhenInScatter
* UpdateMovementPathWhenInFrightened
* GetChaseEndGridPosition
* DecideToUpdateMovementPathInChase
* GetChaseEndGridPosition_Implementation
* DecideToUpdateMovementPathInChase_Implementation
* Util (FSafeGet)
* IsPlayerAlive
* ChompPlayerController
* GetPlayerGridLocation (static)
* GetPlayerGridDirection (static)
* GetPlayerWorldLocation (static)
#endif