Implemented Bounty Class Functionality
This commit is contained in:
parent
44e0a6bc2d
commit
52af66afec
BIN
EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset
(Stored with Git LFS)
BIN
EndlessVendetta/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset
(Stored with Git LFS)
Binary file not shown.
@ -11,17 +11,120 @@ ABountyClass::ABountyClass()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
|
||||||
void ABountyClass::BeginPlay()
|
void ABountyClass::BeginPlay()
|
||||||
{
|
{
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
SpawnCheckpoints();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called every frame
|
|
||||||
void ABountyClass::Tick(float DeltaTime)
|
void ABountyClass::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaTime);
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ABountyClass::SpawnCheckpoints()
|
||||||
|
{
|
||||||
|
// Spawn all checkpoints associated with this bounty and store them in order
|
||||||
|
FActorSpawnParameters SpawnParameters;
|
||||||
|
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
|
||||||
|
for(TSubclassOf<ACheckpointClass> CheckpointClass : CheckpointsToSpawn)
|
||||||
|
{
|
||||||
|
if (CheckpointClass == nullptr)
|
||||||
|
{
|
||||||
|
// An unassigned checkpoint class can lead to undefined behaviour, hence the fatal log
|
||||||
|
UE_LOG(LogTemp, Fatal, TEXT("A checkpoint class wasn't set for %s"), *BountyTitle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector Loc = CheckpointClass.GetDefaultObject()->GetCheckpointSpawnTransform().GetLocation();
|
||||||
|
FRotator Rot = CheckpointClass.GetDefaultObject()->GetCheckpointSpawnTransform().GetRotation().Rotator();
|
||||||
|
ACheckpointClass* SpawnedCheckpoint = Cast<ACheckpointClass>(GetWorld()->SpawnActor<AActor>(CheckpointClass, Loc, Rot, SpawnParameters));
|
||||||
|
BountyCheckpoints.Add(SpawnedCheckpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activate the first checkpoint and listen for its completion
|
||||||
|
BountyCheckpoints[0]->Active = true;
|
||||||
|
BountyCheckpoints[0]->CompletedCheckpoint.AddDynamic(this, &ABountyClass::IncrementBountyCheckpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyClass::IncrementBountyCheckpoint()
|
||||||
|
{
|
||||||
|
// Broadcast that the first Checkpoint has been completed so that side bounties can be destroyed
|
||||||
|
if (!BountyStarted)
|
||||||
|
{
|
||||||
|
BountyStarted = true;
|
||||||
|
CompletedFirstCheckpoint.Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bounty Completion Condition
|
||||||
|
if (BountyCheckpoints.Num() <= MinCPsRequiredForCompletion)
|
||||||
|
{
|
||||||
|
Completed = true;
|
||||||
|
BountyCheckpoints[0]->Active = false;
|
||||||
|
BountyCheckpoints[0]->Destroy();
|
||||||
|
BountyCheckpoints.RemoveAt(0);
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT(" You've Completed the Bounty!! Well done"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BountyCheckpoints[0] == nullptr)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Fatal, TEXT("Missing checkpoint in bounty checkpoints, could've failed to spawn or cast"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destroy Actor and Shrink Array
|
||||||
|
BountyCheckpoints[0]->Active = false;
|
||||||
|
BountyCheckpoints[0]->Destroy();
|
||||||
|
BountyCheckpoints.RemoveAt(0);
|
||||||
|
|
||||||
|
// Set the new checkpoint in pos 0 to be active and listen for it's completion
|
||||||
|
BountyCheckpoints[0]->Active = true;
|
||||||
|
BountyCheckpoints[0]->CompletedCheckpoint.AddDynamic(this, &ABountyClass::IncrementBountyCheckpoint);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyClass::CollectRewards_Implementation()
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("The player has gained $%d for completing the bounty!"), RewardMoney);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyClass::UpdateBountyCheckpoints(TMap<int, TSubclassOf<ACheckpointClass>> ReplacementCheckpoints)
|
||||||
|
{
|
||||||
|
if (ReplacementCheckpoints.IsEmpty())
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("No Replacement Steps found"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FActorSpawnParameters SpawnParameters;
|
||||||
|
SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
|
||||||
|
for (auto ReplacementCheckpoint : ReplacementCheckpoints)
|
||||||
|
{
|
||||||
|
BountyCheckpoints[ReplacementCheckpoint.Key]->Destroy();
|
||||||
|
ReplacementCheckpointClass = ReplacementCheckpoint.Value;
|
||||||
|
|
||||||
|
FVector Loc = ReplacementCheckpointClass.GetDefaultObject()->GetCheckpointSpawnTransform().GetLocation();
|
||||||
|
FRotator Rot = ReplacementCheckpointClass.GetDefaultObject()->GetCheckpointSpawnTransform().GetRotation().Rotator();
|
||||||
|
ACheckpointClass* SpawnedCheckpoint = Cast<ACheckpointClass>(GetWorld()->SpawnActor<AActor>(ReplacementCheckpoint.Value, Loc, Rot, SpawnParameters));
|
||||||
|
|
||||||
|
if (SpawnedCheckpoint == nullptr)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Fatal, TEXT("The new checkpoint hasn't spawned in properly or can't be cast to"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BountyCheckpoints[ReplacementCheckpoint.Key] = SpawnedCheckpoint;
|
||||||
|
if (ReplacementCheckpoint.Key == 0)
|
||||||
|
{
|
||||||
|
BountyCheckpoints[ReplacementCheckpoint.Key]->Active = true;
|
||||||
|
BountyCheckpoints[ReplacementCheckpoint.Key]->CompletedCheckpoint.AddDynamic(this, &ABountyClass::IncrementBountyCheckpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,24 +3,140 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "CheckpointClass.h"
|
||||||
#include "GameFramework/Actor.h"
|
#include "GameFramework/Actor.h"
|
||||||
#include "BountyClass.generated.h"
|
#include "BountyClass.generated.h"
|
||||||
|
|
||||||
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCompletedFirstCheckpoint)
|
||||||
|
|
||||||
UCLASS()
|
UCLASS()
|
||||||
class ENDLESSVENDETTA_API ABountyClass : public AActor
|
class ENDLESSVENDETTA_API ABountyClass : public AActor
|
||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
// Used to temp store value of incoming replacement checkpoint class
|
||||||
|
TSubclassOf<ACheckpointClass> ReplacementCheckpointClass;
|
||||||
|
|
||||||
public:
|
bool BountyStarted = false;
|
||||||
// Sets default values for this actor's properties
|
|
||||||
ABountyClass();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// ------- Properties Set in Editor --------------
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
TArray<TSubclassOf<ACheckpointClass>> CheckpointsToSpawn;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
int RewardMoney = 0;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
FString BountyTitle;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
FString BountyDesc;
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
bool Completed = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default is 2 as final step in most Bounties is to return to ship,
|
||||||
|
* which can't be completed. Change to 1 if that's not the case.
|
||||||
|
*/
|
||||||
|
int MinCPsRequiredForCompletion = 2;
|
||||||
|
|
||||||
|
// Spawned in Checkpoints for this Bounty
|
||||||
|
TArray<ACheckpointClass*> BountyCheckpoints;
|
||||||
|
|
||||||
|
// Spawns and stores this Bounties Checkpoints in order
|
||||||
|
void SpawnCheckpoints();
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
// Called when the game starts or when spawned
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
public:
|
|
||||||
// Called every frame
|
public:
|
||||||
virtual void Tick(float DeltaTime) override;
|
// Broadcast when first checkpoint from this bounty is completed
|
||||||
|
FCompletedFirstCheckpoint CompletedFirstCheckpoint;
|
||||||
|
|
||||||
|
// ------ Getters for Bounty and Checkpoint Properties ------
|
||||||
|
bool IsCompleted()
|
||||||
|
{
|
||||||
|
return Completed;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString GetBountyTitle()
|
||||||
|
{
|
||||||
|
return BountyTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
FString GetBountyDesc()
|
||||||
|
{
|
||||||
|
return BountyDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector GetCheckpointLocation()
|
||||||
|
{
|
||||||
|
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr)
|
||||||
|
{
|
||||||
|
return FVector(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BountyCheckpoints[0]->GetCheckpointSpawnTransform().GetLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
FVector GetActiveWaypointLocation()
|
||||||
|
{
|
||||||
|
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr)
|
||||||
|
{
|
||||||
|
return FVector(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BountyCheckpoints[0]->GetWaypointLoc();
|
||||||
|
}
|
||||||
|
|
||||||
|
UTexture2D* GetActiveWaypointIcon()
|
||||||
|
{
|
||||||
|
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BountyCheckpoints[0]->GetWaypointIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
FString GetCheckpointDescription()
|
||||||
|
{
|
||||||
|
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr)
|
||||||
|
{
|
||||||
|
return FString("No more Bounty checkpoints, check BountyClass.h GetCheckpointDescription()");
|
||||||
|
}
|
||||||
|
|
||||||
|
return BountyCheckpoints[0]->GetCheckpointDesc();
|
||||||
|
}
|
||||||
|
// ----------------------------------------------------------
|
||||||
|
|
||||||
|
// Sets default values for this actor's properties
|
||||||
|
ABountyClass();
|
||||||
|
|
||||||
|
// Called every frame
|
||||||
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
|
// Called when a checkpoint is completed, handles moving onto next checkpoint and discarding the old one
|
||||||
|
UFUNCTION()
|
||||||
|
virtual void IncrementBountyCheckpoint();
|
||||||
|
|
||||||
|
// Collect Money in C++, any other special reward will be implemented in BP if neccessary
|
||||||
|
UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
|
||||||
|
void CollectRewards();
|
||||||
|
|
||||||
|
void DestroyReturnToShipStep()
|
||||||
|
{
|
||||||
|
if (BountyCheckpoints.Num() > 1)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("Didn't Destroy final step as more than one steps still left in Bounty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BountyCheckpoints[0]->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by Bounty Director, replaces specified checkpoints to alter Bounty when player completes a side bounty
|
||||||
|
void UpdateBountyCheckpoints(TMap<int, TSubclassOf<ACheckpointClass>> ReplacementCheckpoints);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user