Implemented Bounty Director Class Functionality
This commit is contained in:
parent
5e6f5e4b9e
commit
0fd1b60d52
BIN
EndlessVendetta/Content/StarterContent/Architecture/Floor_400x400.uasset
(Stored with Git LFS)
BIN
EndlessVendetta/Content/StarterContent/Architecture/Floor_400x400.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset
(Stored with Git LFS)
BIN
EndlessVendetta/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset
(Stored with Git LFS)
Binary file not shown.
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "BountyDirector.h"
|
#include "BountyDirector.h"
|
||||||
|
|
||||||
|
#include "Components/ArrowComponent.h"
|
||||||
|
|
||||||
// Sets default values
|
// Sets default values
|
||||||
ABountyDirector::ABountyDirector()
|
ABountyDirector::ABountyDirector()
|
||||||
{
|
{
|
||||||
@ -11,17 +13,139 @@ ABountyDirector::ABountyDirector()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
|
||||||
void ABountyDirector::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called every frame
|
// Called every frame
|
||||||
void ABountyDirector::Tick(float DeltaTime)
|
void ABountyDirector::Tick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::Tick(DeltaTime);
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// Called when the game starts or when spawned
|
||||||
|
void ABountyDirector::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
PlayerChar = Cast<AEndlessVendettaCharacter>(GetWorld()->GetFirstPlayerController()->GetCharacter());
|
||||||
|
if (!IsValid(PlayerChar)) UE_LOG(LogTemp, Fatal, TEXT("Players Character isn't being loaded in BeginPlay() in BountyDirector"));
|
||||||
|
|
||||||
|
// Setup a component for bounties to attach to on the player
|
||||||
|
for (UActorComponent* ActorComp : PlayerChar->GetComponentsByTag(UArrowComponent::StaticClass(), FName("Bounty")))
|
||||||
|
{
|
||||||
|
BountyAttachmentPoint = Cast<UArrowComponent>(ActorComp);
|
||||||
|
if (!IsValid(BountyAttachmentPoint)) UE_LOG(LogTemp, Fatal, TEXT("There's no Bounty Attachment UArrowComponent on Players Char "));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup up starting Side Bounty indexes
|
||||||
|
for (int Index = 0; Index < 3; Index++)
|
||||||
|
{
|
||||||
|
CurrentSideBountyIndexes.Add(Index);
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveSideBounties.SetNum(3);
|
||||||
|
SpawnBountyAndItsSideBounties();
|
||||||
|
UpdateBountyDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyDirector::SpawnBountyAndItsSideBounties()
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("Spawning Bounty..."));
|
||||||
|
|
||||||
|
if (BountyClassArray.IsEmpty()) return;
|
||||||
|
if (!IsValid(BountyClassArray[CurrentBountyIndex])) UE_LOG(LogTemp, Fatal, TEXT("Missing Bounty at Index: %d"), CurrentBountyIndex);
|
||||||
|
|
||||||
|
// Spawn Main Bounty which the current bounty index is pointing to
|
||||||
|
FActorSpawnParameters SpawnParams;
|
||||||
|
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||||
|
|
||||||
|
AActor* BountyActor = GetWorld()->SpawnActor<AActor>(BountyClassArray[CurrentBountyIndex], PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams);
|
||||||
|
const FAttachmentTransformRules AttachmentTransformRules(EAttachmentRule::SnapToTarget, true);
|
||||||
|
BountyActor->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
|
||||||
|
|
||||||
|
ActiveBounty = Cast<ABountyClass>(BountyActor);
|
||||||
|
if (!IsValid(ActiveBounty)) UE_LOG(LogTemp, Fatal, TEXT("Failed to Cast to Bounty class"));
|
||||||
|
|
||||||
|
// WHEN MARCEL STOPS PLAYING WITH THE CHARACTER, ADD THIS BOUNTY TO PLAYERS ARRAY OF ACTIVE BOUNTIES!!!!!
|
||||||
|
ActiveBounty->CompletedFirstCheckpoint.AddDynamic(this, &ABountyDirector::DestroyActiveSideBounties);
|
||||||
|
|
||||||
|
// Spawn in Side Bounties which are linked to the Main Bounty
|
||||||
|
int ActiveSideBountyIndex = 0;
|
||||||
|
for (int CurrentSideBountyIndex : CurrentSideBountyIndexes)
|
||||||
|
{
|
||||||
|
if (SideBountyClassArray.Num() <= CurrentSideBountyIndex || !IsValid(SideBountyClassArray[CurrentSideBountyIndex])) continue;
|
||||||
|
|
||||||
|
AActor* SideBountyActor = GetWorld()->SpawnActor<AActor>(SideBountyClassArray[CurrentSideBountyIndex], PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams);
|
||||||
|
ASideBountyClass* SideBounty = Cast<ASideBountyClass>(SideBountyActor);
|
||||||
|
SideBounty->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
|
||||||
|
|
||||||
|
ActiveSideBounties[ActiveSideBountyIndex] = SideBounty;
|
||||||
|
SideBounty->ActiveSBC_Index = ActiveSideBountyIndex;
|
||||||
|
ActiveSideBounties[ActiveSideBountyIndex]->CompletedSideBounty.AddDynamic(this, &ABountyDirector::SideBountyCompleted);
|
||||||
|
// ONCE AGAIN WHEN MARCEL STOPS PLAYING WITH THE CHARACTER, ADD THIS SIDE BOUNTY TO PLAYERS ARRAY OF ACTIVE BOUNTIES!!!!!
|
||||||
|
ActiveSideBountyIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyDirector::UpdateBountyProgression()
|
||||||
|
{
|
||||||
|
if (!IsValid(ActiveBounty)) return;
|
||||||
|
|
||||||
|
if (ActiveBounty->IsCompleted()) FinishActiveBounty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyDirector::FinishActiveBounty()
|
||||||
|
{
|
||||||
|
ActiveBounty->CollectRewards();
|
||||||
|
|
||||||
|
// Destroy old Bounties
|
||||||
|
ActiveBounty->DestroyReturnToShipStep();
|
||||||
|
ActiveBounty->Destroy();
|
||||||
|
DestroyActiveSideBounties();
|
||||||
|
|
||||||
|
// Increment Main and Side Bounty Indexes
|
||||||
|
CurrentBountyIndex++;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
CurrentSideBountyIndexes[i] += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Game Completion Check
|
||||||
|
if (CurrentBountyIndex >= BountyClassArray.Num())
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("Finished all bounties currently available in the game :)"));
|
||||||
|
ActiveBounty = nullptr;
|
||||||
|
UpdateBountyDisplay();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpawnBountyAndItsSideBounties();
|
||||||
|
UpdateBountyDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyDirector::DestroyActiveSideBounties()
|
||||||
|
{
|
||||||
|
for (ASideBountyClass* SideBounty : ActiveSideBounties)
|
||||||
|
{
|
||||||
|
if (!IsValid(SideBounty)) continue;
|
||||||
|
|
||||||
|
// WHEN MARCEL STOPS PLAYING WITH PLAYERS CHARACTER, REMOVE THIS SIDE BOUNTY FROM ACTIVE BOUNTIES
|
||||||
|
|
||||||
|
SideBounty->DestroyCheckpoints();
|
||||||
|
SideBounty->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateBountyDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ABountyDirector::SideBountyCompleted(int SideBountyIndex)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp,Warning,TEXT("Updating Main Bounties Checkpoints"));
|
||||||
|
ActiveBounty->UpdateBountyCheckpoints(ActiveSideBounties[SideBountyIndex]->GetReplacementCheckpoints());
|
||||||
|
|
||||||
|
// WHEN MARCEL STOPS PLAYING WITH PLAYER CHAR, REMOVE THIS SIDE BOUNTY FROM ACTIVE BOUNTIES
|
||||||
|
ActiveSideBounties[SideBountyIndex]->DestroyCheckpoints();
|
||||||
|
ActiveSideBounties[SideBountyIndex]->Destroy();
|
||||||
|
|
||||||
|
UpdateBountyDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "BountyClass.h"
|
||||||
|
#include "SideBountyClass.h"
|
||||||
|
#include "EndlessVendetta/EndlessVendettaCharacter.h"
|
||||||
#include "GameFramework/Actor.h"
|
#include "GameFramework/Actor.h"
|
||||||
#include "BountyDirector.generated.h"
|
#include "BountyDirector.generated.h"
|
||||||
|
|
||||||
@ -11,16 +14,85 @@ class ENDLESSVENDETTA_API ABountyDirector : public AActor
|
|||||||
{
|
{
|
||||||
GENERATED_BODY()
|
GENERATED_BODY()
|
||||||
|
|
||||||
public:
|
AEndlessVendettaCharacter* PlayerChar;
|
||||||
// Sets default values for this actor's properties
|
|
||||||
ABountyDirector();
|
|
||||||
|
|
||||||
|
// Scene Component Used to Attach Bounties to
|
||||||
|
UArrowComponent* BountyAttachmentPoint;
|
||||||
|
|
||||||
|
// Ordered Array of Main Bounties
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
TArray<TSubclassOf<ABountyClass>> BountyClassArray;
|
||||||
|
|
||||||
|
// Ordered Array of Side Bounties, in three's
|
||||||
|
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
|
||||||
|
TArray<TSubclassOf<ASideBountyClass>> SideBountyClassArray;
|
||||||
|
|
||||||
|
int CurrentBountyIndex = 0;
|
||||||
|
|
||||||
|
TArray<int> CurrentSideBountyIndexes;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, Category = "Bounty")
|
||||||
|
ABountyClass* ActiveBounty;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, Category = "Bounty")
|
||||||
|
TArray<ASideBountyClass*> ActiveSideBounties;
|
||||||
|
|
||||||
|
// Checks if completed the bounty, and moves onto the next if so
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Bounty")
|
||||||
|
void UpdateBountyProgression();
|
||||||
|
|
||||||
|
void SpawnBountyAndItsSideBounties();
|
||||||
|
|
||||||
|
// Collect reward for current Bounty and prepare for the next
|
||||||
|
void FinishActiveBounty();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Called when the game starts or when spawned
|
// Called when the game starts or when spawned
|
||||||
virtual void BeginPlay() override;
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
|
/** Blueprint implemented function called from c++, handles aesthetic changes to bounty display
|
||||||
|
based on data from ActiveBC and ActiveSBC */
|
||||||
|
UFUNCTION(BlueprintImplementableEvent, Category = "bounty")
|
||||||
|
void UpdateBountyDisplay();
|
||||||
|
|
||||||
|
// Ran when a Side Bounty is completed and wants to update the active bounties checkpoints
|
||||||
|
UFUNCTION()
|
||||||
|
void SideBountyCompleted(int SideBountyIndex);
|
||||||
|
|
||||||
|
UFUNCTION()
|
||||||
|
void DestroyActiveSideBounties();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Called every frame
|
// Called every frame
|
||||||
virtual void Tick(float DeltaTime) override;
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
|
// Sets default values for this actor's properties
|
||||||
|
ABountyDirector();
|
||||||
|
|
||||||
|
// ------ Getters ------
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Bounty")
|
||||||
|
FString GetBountyTitle()
|
||||||
|
{
|
||||||
|
return IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Bounty")
|
||||||
|
FString GetBountyDescription()
|
||||||
|
{
|
||||||
|
return IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyDesc();
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Bounty")
|
||||||
|
FString GetSideBountyTitle(int SideBountyIndex)
|
||||||
|
{
|
||||||
|
return (SideBountyIndex > 2 || SideBountyIndex < 0 || IsValid(ActiveSideBounties[SideBountyIndex])) ? FString("N/A") : ActiveSideBounties[SideBountyIndex]->GetBountyTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Bounty")
|
||||||
|
FString GetSideBountyDescription(int SideBountyIndex)
|
||||||
|
{
|
||||||
|
return (SideBountyIndex > 2 || SideBountyIndex < 0 || IsValid(ActiveSideBounties[SideBountyIndex])) ? FString("N/A") : ActiveSideBounties[SideBountyIndex]->GetBountyDesc();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@ class ENDLESSVENDETTA_API ACheckpointClass : public AActor
|
|||||||
UFUNCTION(BlueprintCallable, Category = "Checkpoint")
|
UFUNCTION(BlueprintCallable, Category = "Checkpoint")
|
||||||
void BroadcastCompletion()
|
void BroadcastCompletion()
|
||||||
{
|
{
|
||||||
|
UE_LOG(LogTemp, Warning, TEXT("Completed Checkpoint"));
|
||||||
CompletedCheckpoint.Broadcast();
|
CompletedCheckpoint.Broadcast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user