Space Plunder
Loading...
Searching...
No Matches
ProceduralDungeonBuilder.h
Go to the documentation of this file.
1// Fill out your copyright notice in the Description page of Project Settings.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Data/DungeonData.h"
7#include "GameFramework/Actor.h"
8#include "ProceduralDungeonBuilder.generated.h"
9
12class IDungeonRoom;
13
14DECLARE_LOG_CATEGORY_EXTERN(LogDungeonBuilder, Display, All);
15
16
17// Create different Methods of generating
18// Method 1
19// Spawns Room, then spawning joining rooms at random
20// Problem with overlaps currently
21// Method 2
22// Create Grid that is the total size of the Ship
23// Split the grid up into different squares
24// Spawn Important Rooms and large rooms first
25// Then spawn connecting Hallways
26//
27
28
29
30
31UCLASS()
32class PROCEDURALDUNGEONS_API AProceduralDungeonBuilder : public AActor
33{
34 GENERATED_BODY()
35
36public:
38
39
40
41protected:
42 virtual void BeginPlay() override;
43 virtual void OnConstruction(const FTransform& Transform) override;
45 UFUNCTION(CallInEditor, Category="Dungeon|Editor")
46 void CreateDungeonInEditor();
48 UFUNCTION(CallInEditor, Category="Dungeon|Editor")
49 void DestroyDungeonInEditor();
50
51 UFUNCTION(CallInEditor, Category="Dungeon|Editor")
52 void HideAllRoomRoofs();
53
54 UFUNCTION(BlueprintCallable, Category="Dungeon")
55 void CreateDungeon();
56
57 UFUNCTION(BlueprintImplementableEvent, Category="Dungeon")
58 void OnDungeonComplete(const int32 NumOfRooms);
59 UFUNCTION(BlueprintImplementableEvent, Category="Dungeon")
60 void OnDoorsSpawned(const int32 NumOfDoors);
61
62 UFUNCTION(BlueprintImplementableEvent, Category="Dungeon")
63 void OnAISpawned(const int32 NumOfPawns);
64 UFUNCTION(NetMulticast, Reliable)
65 void Multicast_DungeonComplete(int32 NumRooms);
66
67 // UFUNCTION(BlueprintCallable, Category="Dungeon")
68 // void SetRandomStream(const FRandomStream& Stream){RandomStream = Stream;};
69 UFUNCTION(BlueprintCallable, Category="Dungeon")
70 FRandomStream& GetRandomStream() const;
71
72 UFUNCTION(BlueprintCallable, Category="Dungeon|Helper")
73 bool IsOverlapping(const FBox& CandidateBox);
74
75 // UFUNCTION(BlueprintCallable, Category="Dungeon|Helper")
76 // bool IsValidRoomConnection(const EDungeonRoomType ParentType, const EDungeonRoomType CandidateType) const;
77 UFUNCTION(BlueprintNativeEvent, Category="Dungeon|Helper")
78 bool GetIsValidRoomConnection(const EDungeonRoomType ParentType, const EDungeonRoomType CandidateType) const;
79
80
81 UFUNCTION(BlueprintCallable, Category="Dungeon|Debug")
82 UMaterialInstanceDynamic* GetMaterialInstance() const {return RoomMaterialInstance;};
83
84
85 //~ Lifetime of the Builder ~//
87 void SpawnStartingRoom();
88
90 void SpawnAllRooms();
91
92 void CreateDynamicMaterials();
93
95 void SpawnNextRoom();
96
97 // void SpawnNextRoomMathematically();
98
100 void ContinueSpawnNextRoom();
101
102 void SetInitialValues();
103
105 void SpawnSpecialRoom();
106 // void SpawnSpecialRoomMathematically();
107
108 void ScheduleSpawn(const FTimerDelegate::TMethodPtr<AProceduralDungeonBuilder> SpawnMethod);
109
111 void AddAISpawnPointsToList(const USceneComponent* AIRootComponent);
113 void CheckExitsForJoiningRooms();
115 void CloseHoles();
117 void SpawnDoorAtLocation();
119 void SpawnAIAtLocation();
120
122 void SetRoomsReady() const;
123
125 void DungeonComplete();
126 //~ Lifetime of the Builder ~//
127
128 //~ Main Variables to set ~//
130 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms")
131 FDungeonSpawns RoomTypes;
132
134 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms")
135 int32 StartingRoomNumber = 0;
136
137 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms|Amount")
138 int32 NumberOfRoomsToSpawn = 50;
140 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms|Amount")
141 bool bUseRandomNumberOfRooms = false;
142 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms|Amount", meta=(EditCondition="bUseRandomNumberOfRooms"))
143 int32 MinNumberOfRoomsToSpawn = 2;
144 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms")
145 TSubclassOf<AActor> RoomChecker = nullptr;
146 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms")
147 bool bApplyDynamicMaterial = true;
148 // Checks if the EDungeonRoomType is Compatable with the next Dungeon
149 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms", meta=(EditCondition="bApplyDynamicMaterial"))
150 UMaterialInterface* RoomMaterial = nullptr;
151 //@ TODO add on Base? or Base Helpers, Or somewhere..
152 // @ Check shipbuilder BP
153 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Rooms", meta=(EditCondition="bApplyDynamicMaterial"))
154 class UDataTable* MaterialDataTable = nullptr;
155
156 // if theres only 1 available exit left, don't spawn a Dead end.
157 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General|Exits")
158 bool bCheckRoomExitCount = false;
159 // Total Exits are at x Don't spawn dead ends,
160 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General|Exits")
161 int32 CheckRoomExitCountMin = 3;
162 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
163 bool bCheckRoomTypes = true;
164
165 // Gets the exit closest to the Origin when finding new Exits to spawn from
166 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General|Exits")
167 bool bGetClosestExit = false;
168 // Only Get closest Exit Randomly
169 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General|Exits", meta=(EditCondition=bGetClosestExit))
170 bool bRandomGetClosestExit = false;
171 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General|Exits", meta=(EditCondition=bRandomGetClosestExit))
172 float RandomClosesExitWeight = 0.5f;
173
174 // UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
175 // bool bUseSpawnNextRoomMathematically = true;
176
177 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
178 bool bUseRandomSeed = true;
179 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General", meta=(EditCondition="!bUseRandomSeed"))
180 int32 Seed = 0;
181 //@ TODO Change to Array?
182 //@ TODO Create Style Enum or Type, get from interface, then can match the Wall to the Room Style
184 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Walls")
185 TSubclassOf<AActor> WallFill = nullptr;
186 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Walls")
187 bool bFillWithDeadEndRooms = false;
189 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Doors")
190 bool bSpawnDoors = true;
191 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Doors", meta=(EditCondition="bSpawnDoors"))
192 bool bLimitDoors = true;
193 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Doors", meta=(EditCondition="bLimitDoors"))
194 int32 DoorLimit = 10;
195 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Doors")
196 TArray<TSubclassOf<AActor>> DoorTypes;
198 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|Doors")
199 TArray<int32> DoorWeights;
200 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
201 bool bCreateOnBeginPlay = true;
202 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
203 bool bUseGameModeStream = true;
204
205
206 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|General")
207 bool bCheckForJoiningRooms = true;
208
209 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|AI")
210 int32 AIToSpawn = 10;
211 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Dungeon|AI")
212 TArray<TSubclassOf<AActor>> AITypes;
213 //~ Main Variables to set ~//
214
215
216
217 //~ Variables about the Dungeon ~//
219 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
220 bool bComplete = false;
222 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
223 TArray<USceneComponent*> AvailableExits;
224 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
225 TArray<USceneComponent*> DoorLocations;
227 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
228 TArray<USceneComponent*> ExitsToFill;
229 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
230 USceneComponent* SelectedExit = nullptr;
232 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
233 AActor* LastSpawnedRoom = nullptr;
234 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
235 TArray<UPrimitiveComponent*> OverlappedComponents;
236 UPROPERTY(Replicated, VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
237 TArray<AActor*> DungeonActors;
238 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
239 TArray<TSubclassOf<AActor>> SpecialRoomTypeClasses;
240
241 //@TODO Move all Actors to Categories
242 // UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
243 // TArray<AActor*> DungeonRooms;
244 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Rooms")
245 UMaterialInstanceDynamic* RoomMaterialInstance = nullptr;
246
247 // Stores each successfully spawned room’s world bounding box.
248 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Rooms")
249 TArray<FBox> PlacedRoomBounds;
250
251 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
252 USceneComponent* SelectedAISpawn = nullptr;
253 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
254 USceneComponent* SelectedDoorSpawn = nullptr;
255 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
256 TArray<USceneComponent*> AISpawns;
257 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation")
258 bool bUsingGameModeSteam = false;
259 //~ Variables about the Dungeon ~//
260
261 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Debug")
262 TArray<USceneComponent*> AISpawnsSelected;
263 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Debug")
264 TArray<USceneComponent*> AISpawnsFailed;
265 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Debug")
266 TArray<USceneComponent*> DoorSpawnsSelected;
267 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Dungeon|Creation|Debug")
268 TArray<USceneComponent*> DoorSpawnsFailed;
269
270
271private:
273 void OnRoomsComplete();
274
276 void CheckRoomAttemptsNumber();
278 void SetSeed();
280 void SetNumberOfRooms();
281
283 bool GetShouldStopSpawningRooms() const;
284
285
287 bool GetShouldSpawnSpecialRoom() const;
288
289 USceneComponent* GetNextExit();
290
291 UClass* GetNewRoomClass() const;
292 UClass* GetStartingRoomClass();
293 UClass* GetSpecialRoomClass() const;
294 UClass* GetDeadEndRoomClass() const;
295
296 UFUNCTION(BlueprintCallable, Category="Dungeon", DisplayName="Get Rooms Of Type")
297 TArray<FDungeonSpawnRoom> GetRoomsOfTypeBP(const TArray<EDungeonRoomType>& FilterTypes, const bool bInverseSelection = false) const;
298
299 // Gets all rooms of the FilterTypes, Inverse will remove all these types
300 TArray<FDungeonSpawnRoom> GetRoomsOfType(const TArray<EDungeonRoomType>& FilterTypes, const bool bInverseSelection = false) const;
301 TArray<FDungeonSpawnRoom> GetRoomsOfType(const EDungeonRoomType FilterType, const bool bInverseSelection = false) const;
302
303 // TArray<FDungeonSpawnRoom> GetRoomsExceptType(const TArray<EDungeonRoomType>& FilterTypes) const;
304 TArray<FDungeonSpawnRoom> GetRoomsByExits() const;
305 // TArray<FDungeonSpawnRoom> GetRooms(const bool bFilterExits, const bool bFilter = false, const EDungeonRoomType FilterType = EDungeonRoomType::SpecialRoom) const;
306
307 void RemoveExitsByDistance(TArray<USceneComponent*>& ExitsA, TArray<USceneComponent*>& ExitsB) const;
308
309
310 // Returns if Success
311 bool SetDungeonValues();
312 // bool AddDungeon
313 // /** Gets random Room class from the array*/
314 // FDungeonSpecialItem* GetRandomSpecialItem(TArray<FDungeonSpecialItem>& Array, FRandomStream& Stream) const;
316 // USceneComponent* GetRandomSceneComponent(const TArray<USceneComponent*>& Array) const;
317 // /** Gets random from the array */
318 // UClass* GetRandomClass(const TArray<TSubclassOf<AActor>>& Array) const;
319
320 void LogDebugError(const FString& Message) const;
321 void LogDebugWarning(const FString& Message) const;
322 void LogDebugMessage(const FString& Message, const bool bWarning = false, const bool bError = false) const;
323
324
325
326
327 FActorSpawnParameters SpawnParams;
329 UPROPERTY(VisibleAnywhere, Category="Dungeon|Rooms")
330 int32 RoomsSpawned = 0;
332 int32 AttemptChecker = 0;
333
335 UPROPERTY(VisibleAnywhere, Category="Dungeon|Rooms")
336 int32 StartingNumberOfRoomsToSpawn = 0;
338 UPROPERTY(VisibleAnywhere, Category="Dungeon|Rooms")
339 int32 TotalNumberOfRoomsToSpawn = 0;
341 FDungeonSpawns StartingRoomTypes;
342 // TArray<TSubclassOf<AActor>> StartingRoomTypes;
344 // TArray<FDungeonSpecialItem> StartingSpecialRoomTypes;
345 UPROPERTY(VisibleAnywhere, Category="Dungeon|AI")
346 int32 StartingAIToSpawn = 0;
348 UPROPERTY(VisibleAnywhere, Category="Dungeon|AI")
349 int32 AISpawned = 0;
350 UPROPERTY(VisibleAnywhere, Category="Dungeon|Doors")
351 int32 DoorsSpawned = 0;
352
353
355 UPROPERTY(VisibleAnywhere, Category="Dungeon|Creation")
356 bool bCreatedInEditor = false;
357
359 FRandomStream RandomStream;
360 FRandomStream* RandomStreamPtr = nullptr;
361
362 FRandomStream NullRandomStream;
363
364 TArray<IDungeonRoom*> AllDungeonRooms;
365
366
368 UPROPERTY(EditAnywhere, Category="Dungeon|Optimization")
369 float ExitLocationDistanceOverlap = 0.1f;
370
371 // UPROPERTY(EditAnywhere, Category="Dungeon|Optimization")
372 // bool bRemove = true;
373
374
379 // REmove with oldFunction
380 UPROPERTY(EditAnywhere, Category="Dungeon|Optimization")
381 bool bDeleteExitBeforeSpawn = true;
383 UPROPERTY(EditAnywhere, Category="Dungeon|Optimization", meta=(ClampMin=1, ClampMax=5))
384 int32 RoomAttemptsBeforeFail = 5;
386 UPROPERTY(EditAnywhere, Category="Dungeon|Optimization", meta=(ClampMin=1, ClampMax=10))
387 int32 RoomAttemptsMathMultiplier = 5;
389 bool bHasInvalidClass = false;
390
391
392 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
393 bool bHideRoomRoofs = false;
394 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
395 bool bGiveRoomsRandomStream = false;
396 // Add the Start point as an exit, use when the start is a hallway etc.
397 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
398 bool bAddStartingExit = false;
399 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
400 bool bDebuggingMode = true;
401
402 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
403 bool bDrawFailedExits = false;
404
406 UPROPERTY(EditAnywhere, Category="Dungeon|Debug|Log")
407 bool bLogDungeonSummary = true;
409 UPROPERTY(EditAnywhere, Category="Dungeon|Debug|Log")
410 bool bLogDungeonSteps = false;
411
412 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
413 bool bResetRoomTypesOnComplete = false;
414
416 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
417 bool bDelayEachRoomBuild = false;
418 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
419 bool bDelayEachAISpawn = false;
420 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
421 bool bDelayEachDoorSpawn = false;
422
423 // Show AI Spawn Points,
424 // Show Used Spawn Points
425 // Show Failed Spawn Points
426
427
428 UPROPERTY(EditAnywhere, Category="Dungeon|Debug")
429 float BuildDelayTime = 0.1f;
430 FTimerHandle BuildDelayHandle;
431
432};
UCLASS(Blueprintable, BlueprintType, ClassGroup=(BucciGames), meta=(BlueprintSpawnableComponent)) class CHATSYSTEM_API UChatSystemComponent
Definition ChatSystemComponent.h:13
EDungeonRoomType
Definition DungeonEnums.h:11
DECLARE_LOG_CATEGORY_EXTERN(LogDungeonBuilder, Display, All)
Definition ProceduralDungeonBuilder.h:33
Definition DungeonRoom.h:21
Definition DungeonData.h:58
Definition DungeonData.h:169
Definition DungeonData.h:29