Merge branch 'FavourSystem' into dev

# Conflicts:
#	EndlessVendetta/EndlessVendetta.uproject
This commit is contained in:
Rafal Swierczek 2023-10-15 13:20:15 +01:00
commit e71d022e65
49 changed files with 635 additions and 204 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:69b27343598f650b7535e6394e8f71edd12579339b4bbf6a5530e2058f984463
size 247653

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -61,7 +61,7 @@ void ABountyClass::IncrementBountyCheckpoint()
}
// Bounty Completion Condition
if (BountyCheckpoints.Num() <= MinCPsRequiredForCompletion)
if (BountyCheckpoints.Num() <= 1)
{
Completed = true;
BountyCheckpoints[0]->Active = false;
@ -93,38 +93,6 @@ 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);
}
}
}

View File

@ -36,12 +36,6 @@ protected:
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;
@ -61,7 +55,7 @@ public:
{
return Completed;
}
FString GetBountyTitle()
{
return BountyTitle;
@ -72,6 +66,11 @@ public:
return BountyDesc;
}
int GetBountyrewardMoney()
{
return RewardMoney;
}
FVector GetCheckpointLocation()
{
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr)
@ -126,17 +125,4 @@ public:
// 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);
};

View File

@ -3,6 +3,7 @@
#include "BountyDirector.h"
#include "Blueprint/UserWidget.h"
#include "Components/ArrowComponent.h"
// Sets default values
@ -34,16 +35,8 @@ void ABountyDirector::BeginPlay()
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()
@ -61,27 +54,22 @@ void ABountyDirector::SpawnBountyAndItsSideBounties()
const FAttachmentTransformRules AttachmentTransformRules(EAttachmentRule::SnapToTarget, true);
BountyActor->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
ActiveBounty = Cast<ABountyClass>(BountyActor);
ActiveBounty = Cast<AMainBountyClass>(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)
ActiveSideBounties.Reset();
for (TSubclassOf<ASideBountyClass> SideBountyClass : ActiveBounty->GetSideBountiesToSpawn())
{
if (SideBountyClassArray.Num() <= CurrentSideBountyIndex || !IsValid(SideBountyClassArray[CurrentSideBountyIndex])) continue;
AActor* SideBountyActor = GetWorld()->SpawnActor<AActor>(SideBountyClassArray[CurrentSideBountyIndex], PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams);
if (!IsValid(SideBountyClass)) continue;
AActor* SideBountyActor = GetWorld()->SpawnActor<AActor>(SideBountyClass, PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams);
SideBountyActor->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
ASideBountyClass* SideBounty = Cast<ASideBountyClass>(SideBountyActor);
SideBounty->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
ActiveSideBounties[ActiveSideBountyIndex] = SideBounty;
SideBounty->ActiveSBC_Index = ActiveSideBountyIndex;
ActiveSideBounties[ActiveSideBountyIndex]->CompletedSideBounty.AddDynamic(this, &ABountyDirector::SideBountyCompleted);
if (!IsValid(SideBounty)) UE_LOG(LogTemp, Fatal, TEXT("A SideBounty for %s has been set to a wrong type"), *ActiveBounty->GetBountyTitle());
int i = ActiveSideBounties.Add(SideBounty);
ActiveSideBounties[i]->CompletedSideBounty.AddDynamic(this, &ABountyDirector::EarnFavours);
// ONCE AGAIN WHEN MARCEL STOPS PLAYING WITH THE CHARACTER, ADD THIS SIDE BOUNTY TO PLAYERS ARRAY OF ACTIVE BOUNTIES!!!!!
ActiveSideBountyIndex++;
}
}
@ -97,28 +85,21 @@ 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()
@ -132,21 +113,169 @@ void ABountyDirector::DestroyActiveSideBounties()
SideBounty->DestroyCheckpoints();
SideBounty->Destroy();
}
UpdateBountyDisplay();
}
void ABountyDirector::SideBountyCompleted(int SideBountyIndex)
// ----------- Favour Shop ---------------
void ABountyDirector::EarnFavours(int FavoursEarned)
{
UE_LOG(LogTemp,Warning,TEXT("Updating Main Bounties Checkpoints"));
ActiveBounty->UpdateBountyCheckpoints(ActiveSideBounties[SideBountyIndex]->GetReplacementCheckpoints());
Favours += FavoursEarned;
}
// WHEN MARCEL STOPS PLAYING WITH PLAYER CHAR, REMOVE THIS SIDE BOUNTY FROM ACTIVE BOUNTIES
ActiveSideBounties[SideBountyIndex]->CollectRewards();
ActiveSideBounties[SideBountyIndex]->DestroyCheckpoints();
ActiveSideBounties[SideBountyIndex]->Destroy();
UpdateBountyDisplay();
void ABountyDirector::BuyCustomBountyAlteration_1()
{
if (!IsValid(ActiveBounty)) return;
int Cost = ActiveBounty->GetCustomBountyAlteration_1_Cost();
if (Cost == 0 || Favours < Cost || ActiveBounty->ActivatedCBA_1) return;
Favours -= Cost;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivatedCBA_1 = true;
ActiveBounty->ActivateCustomBountyAlteration_1();
}
void ABountyDirector::BuyCustomBountyAlteration_2()
{
if (!IsValid(ActiveBounty)) return;
int Cost = ActiveBounty->GetCustomBountyAlteration_2_Cost();
if (Cost == 0 || Favours < Cost || ActiveBounty->ActivatedCBA_2) return;
Favours -= Cost;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivatedCBA_2 = true;
ActiveBounty->ActivateCustomBountyAlteration_2();
}
void ABountyDirector::BuyCustomBountyAlteration_3()
{
if (!IsValid(ActiveBounty)) return;
int Cost = ActiveBounty->GetCustomBountyAlteration_3_Cost();
if (Cost == 0 || Favours < Cost || ActiveBounty->ActivatedCBA_3) return;
Favours -= Cost;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivatedCBA_3 = true;
ActiveBounty->ActivateCustomBountyAlteration_3();
}
void ABountyDirector::BuyAmmoDrop()
{
if (!IsValid(ActiveBounty)) return;
if (Favours < 1 || ActiveBounty->ActivateAmmoDrops) return;
Favours--;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivateAmmoDrops = true;
ActiveBounty->SpawnAmmoDrops();
}
void ABountyDirector::BuyHealthDrop()
{
if (!IsValid(ActiveBounty)) return;
if (Favours < 1 || ActiveBounty->ActivatedHealthDrops) return;
Favours--;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivatedHealthDrops = true;
ActiveBounty->SpawnHealthDrops();
}
void ABountyDirector::BuyEnemyRadio()
{
if (!IsValid(ActiveBounty)) return;
if (Favours < 1 || ActiveBounty->ActivatedRadio) return;
Favours--;
PC_Display->UpdateFavourCount(Favours);
ActiveBounty->ActivatedRadio = true;
ActiveBounty->ActivateEnemyRadio();
}
void ABountyDirector::BuyFavours()
{
if (PlayerChar->Money < FavourCost) return;
PlayerChar->Money -= FavourCost;
Favours++;
PC_Display->UpdateFavourCount(Favours);
}
// ----------- PC Display ---------------
void ABountyDirector::Interact()
{
UpdateBountyProgression();
FInputModeUIOnly InputMode;
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
PC_DisplayWidget = CreateWidget<UUserWidget>(GetWorld(), PC_DisplayWidgetClass);
PC_DisplayWidget->AddToViewport(3);
PlayerController->SetInputMode(InputMode);
PlayerController->bShowMouseCursor = true;
PlayerController->bEnableClickEvents = true;
PlayerController->bEnableMouseOverEvents = true;
PC_Display = Cast<UPC_Display>(PC_DisplayWidget);
bool GameOver = !IsValid(ActiveBounty);
PC_Display->PC_Display_Info.IsGameOver = GameOver;
PC_Display->LogoutFromBountyDirectorPC.AddDynamic(this, &ABountyDirector::DestroyBountyDirectorPCWidget);
if (GameOver)
{
PC_Display->LoadOS();
return;
}
// Info about main bounty
PC_Display->PC_Display_Info.MB_Title = GetBountyTitle();
PC_Display->PC_Display_Info.MB_Desc = GetBountyDescription();
PC_Display->PC_Display_Info.MB_Reward = GetBountyReward();
// Info about side bounties
PC_Display->PC_Display_Info.SB_Title.Reset();
PC_Display->PC_Display_Info.SB_Icon.Reset();
PC_Display->PC_Display_Info.SB_Desc.Reset();
PC_Display->PC_Display_Info.SB_Reward.Reset();
for (ASideBountyClass* SideBounty : ActiveSideBounties)
{
if (!IsValid(SideBounty) || SideBounty->IsCompleted()) continue;
PC_Display->PC_Display_Info.SB_Title.Add(SideBounty->GetBountyTitle());
PC_Display->PC_Display_Info.SB_Icon.Add(SideBounty->GetActiveWaypointIcon());
PC_Display->PC_Display_Info.SB_Desc.Add(SideBounty->GetBountyDesc());
PC_Display->PC_Display_Info.SB_Reward.Add(SideBounty->GetRewardInFavours());
}
// Info about main bounty alterations
PC_Display->PC_Display_Info.CustomBountyAlteration_Desc.Reset();
PC_Display->PC_Display_Info.CustomBountyAlteration_Cost.Reset();
PC_Display->PC_Display_Info.CustomBountyAlteration_Desc.Add(ActiveBounty->GetCustomBountyAlteration_1_Description());
PC_Display->PC_Display_Info.CustomBountyAlteration_Desc.Add(ActiveBounty->GetCustomBountyAlteration_2_Description());
PC_Display->PC_Display_Info.CustomBountyAlteration_Desc.Add(ActiveBounty->GetCustomBountyAlteration_3_Description());
PC_Display->PC_Display_Info.CustomBountyAlteration_Cost.Add(ActiveBounty->GetCustomBountyAlteration_1_Cost());
PC_Display->PC_Display_Info.CustomBountyAlteration_Cost.Add(ActiveBounty->GetCustomBountyAlteration_2_Cost());
PC_Display->PC_Display_Info.CustomBountyAlteration_Cost.Add(ActiveBounty->GetCustomBountyAlteration_3_Cost());
PC_Display->PC_Display_Info.PlayersFavourAmount = Favours;
// Button Delegates
PC_Display->BuyCba_1.AddDynamic(this, &ABountyDirector::BuyCustomBountyAlteration_1);
PC_Display->BuyCba_2.AddDynamic(this, &ABountyDirector::BuyCustomBountyAlteration_2);
PC_Display->BuyCba_3.AddDynamic(this, &ABountyDirector::BuyCustomBountyAlteration_3);
PC_Display->BuyAmmoDrop.AddDynamic(this, &ABountyDirector::BuyAmmoDrop);
PC_Display->BuyHealthDrop.AddDynamic(this, &ABountyDirector::BuyHealthDrop);
PC_Display->BuyRadio.AddDynamic(this, &ABountyDirector::BuyEnemyRadio);
PC_Display->BuyFavour.AddDynamic(this, &ABountyDirector::BuyFavours);
PC_Display->LoadOS();
}
void ABountyDirector::DestroyBountyDirectorPCWidget()
{
if (IsValid(PC_DisplayWidget)) PC_DisplayWidget->RemoveFromParent();
FInputModeGameOnly InputMode;
APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
PlayerController->SetInputMode(InputMode);
PlayerController->bShowMouseCursor = false;
PlayerController->bEnableClickEvents = false;
PlayerController->bEnableMouseOverEvents = false;
}

View File

@ -3,14 +3,16 @@
#pragma once
#include "CoreMinimal.h"
#include "BountyClass.h"
#include "MainBountyClass.h"
#include "SideBountyClass.h"
#include "EndlessVendetta/EndlessVendettaCharacter.h"
#include "EndlessVendetta/InteractableActor.h"
#include "EndlessVendetta/UserWidgets/PC_Display.h"
#include "GameFramework/Actor.h"
#include "BountyDirector.generated.h"
UCLASS()
class ENDLESSVENDETTA_API ABountyDirector : public AActor
class ENDLESSVENDETTA_API ABountyDirector : public AInteractableActor
{
GENERATED_BODY()
@ -20,48 +22,76 @@ class ENDLESSVENDETTA_API ABountyDirector : public AActor
UArrowComponent* BountyAttachmentPoint;
// Ordered Array of Main Bounties
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<TSubclassOf<ABountyClass>> BountyClassArray;
UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
TArray<TSubclassOf<AMainBountyClass>> BountyClassArray;
// Ordered Array of Side Bounties, in three's
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<TSubclassOf<ASideBountyClass>> SideBountyClassArray;
UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
int FavourCost = 500;
UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
TSubclassOf<UPC_Display> PC_DisplayWidgetClass;
UUserWidget* PC_DisplayWidget;
UPC_Display* PC_Display;
int CurrentBountyIndex = 0;
TArray<int> CurrentSideBountyIndexes;
UPROPERTY(VisibleAnywhere, Category = "Bounty")
ABountyClass* ActiveBounty;
AMainBountyClass* 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();
// Opens up Bounty Director PC Interface
void Interact() override;
protected:
int Favours = 20;
// Called when the game starts or when spawned
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();
UFUNCTION()
void DestroyBountyDirectorPCWidget();
// Listens for when a side bounty is completed
UFUNCTION()
void EarnFavours(int FavoursEarned);
// -------- Buy Buttons --------
UFUNCTION()
void BuyCustomBountyAlteration_1();
UFUNCTION()
void BuyCustomBountyAlteration_2();
UFUNCTION()
void BuyCustomBountyAlteration_3();
UFUNCTION()
void BuyAmmoDrop();
UFUNCTION()
void BuyHealthDrop();
UFUNCTION()
void BuyEnemyRadio();
UFUNCTION()
void BuyFavours();
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
@ -70,29 +100,24 @@ public:
ABountyDirector();
// ------ Getters ------
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetBountyTitle()
{
return !IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyTitle();
return !IsValid(ActiveBounty) ? FString("") : ActiveBounty->GetBountyTitle();
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
UTexture2D* GetBountyIcon()
{
return !IsValid(ActiveBounty) ? nullptr : ActiveBounty->GetActiveWaypointIcon();
}
FString GetBountyDescription()
{
return !IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyDesc();
return !IsValid(ActiveBounty) ? FString("") : ActiveBounty->GetBountyDesc();
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetSideBountyTitle(int SideBountyIndex)
int GetBountyReward()
{
return (SideBountyIndex > 2 || SideBountyIndex < 0 || !IsValid(ActiveSideBounties[SideBountyIndex])) ? FString("N/A") : ActiveSideBounties[SideBountyIndex]->GetBountyTitle();
return !IsValid(ActiveBounty) ? 0 : ActiveBounty->GetBountyrewardMoney();
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetSideBountyDescription(int SideBountyIndex)
{
return (SideBountyIndex > 2 || SideBountyIndex < 0 || !IsValid(ActiveSideBounties[SideBountyIndex])) ? FString("N/A") : ActiveSideBounties[SideBountyIndex]->GetBountyDesc();
}
};

View File

@ -0,0 +1,26 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "MainBountyClass.h"
void AMainBountyClass::SpawnAmmoDrops()
{
UE_LOG(LogTemp, Display, TEXT("Bought Ammo Drops, but its not implemented yet"));
// FActorSpawnParameters SpawnParameters;
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
// for (FTransform Spawn : AmmoDropSpawnTransforms)
// {
// GetWorld()->SpawnActor<AActor>(AmmoDropClass, Spawn.GetLocation(), Spawn.GetRotation().Rotator(), SpawnParameters);
// }
}
void AMainBountyClass::SpawnHealthDrops()
{
UE_LOG(LogTemp, Display, TEXT("Bought Health Drops, but its not implemented yet"));
// FActorSpawnParameters SpawnParameters;
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
// for (FTransform Spawn : HealthDropSpawnTransforms)
// {
// GetWorld()->SpawnActor<AActor>(HealthDropClass, Spawn.GetLocation(), Spawn.GetRotation().Rotator(), SpawnParameters);
// }
}

View File

@ -0,0 +1,122 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "BountyClass.h"
#include "SideBountyClass.h"
#include "MainBountyClass.generated.h"
/**
*
*/
UCLASS()
class ENDLESSVENDETTA_API AMainBountyClass : public ABountyClass
{
GENERATED_BODY()
protected:
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<TSubclassOf<ASideBountyClass>> SideBountiesToSpawn;
// ---------------- Bounty Alterations ----------------
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<FString> CustomBountyAlteration_Description;
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<int> CustomBountyAlteration_Cost;
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<FTransform> AmmoDropSpawnTransforms;
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TSubclassOf<AActor> AmmoDropClass;
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TArray<FTransform> HealthDropSpawnTransforms;
UPROPERTY(EditDefaultsOnly, Category = "Bounty")
TSubclassOf<AActor> HealthDropClass;
bool HasEnemyRadio = false;
public:
TArray<TSubclassOf<ASideBountyClass>> GetSideBountiesToSpawn()
{
return SideBountiesToSpawn;
}
// ------------- Custom Bounty Alterations -------------
UFUNCTION(BlueprintImplementableEvent, Category = "Bounty")
void ActivateCustomBountyAlteration_1();
UFUNCTION(BlueprintImplementableEvent, Category = "Bounty")
void ActivateCustomBountyAlteration_2();
UFUNCTION(BlueprintImplementableEvent, Category = "Bounty")
void ActivateCustomBountyAlteration_3();
bool ActivatedCBA_1 = false;
bool ActivatedCBA_2 = false;
bool ActivatedCBA_3 = false;
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetCustomBountyAlteration_1_Description()
{
return CustomBountyAlteration_Description.IsEmpty() ? FString("") : CustomBountyAlteration_Description[0];
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetCustomBountyAlteration_2_Description()
{
return CustomBountyAlteration_Description.Num() <= 1 ? FString("") : CustomBountyAlteration_Description[1];
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetCustomBountyAlteration_3_Description()
{
return CustomBountyAlteration_Description.Num() <= 2 ? FString("") : CustomBountyAlteration_Description[2];
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
int GetCustomBountyAlteration_1_Cost()
{
return CustomBountyAlteration_Cost.IsEmpty() ? 0 : CustomBountyAlteration_Cost[0];
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
int GetCustomBountyAlteration_2_Cost()
{
return CustomBountyAlteration_Cost.Num() <= 1 ? 0 : CustomBountyAlteration_Cost[1];
}
UFUNCTION(BlueprintCallable, Category = "Bounty")
int GetCustomBountyAlteration_3_Cost()
{
return CustomBountyAlteration_Cost.Num() <= 2 ? 0 : CustomBountyAlteration_Cost[2];
}
// ------------- Simple Bounty Alterations -------------
void SpawnAmmoDrops();
bool ActivateAmmoDrops = false;
void SpawnHealthDrops();
bool ActivatedHealthDrops = false;
void ActivateEnemyRadio()
{
UE_LOG(LogTemp, Display, TEXT("Bought Radio, but it's not implemented yet"));
HasEnemyRadio = true;
}
bool ActivatedRadio = false;
// Concerned Enemies will call this function, if true, play funny poop voice line and stop enemies from being concerned
bool CheckIfHasEnemyRadio()
{
return HasEnemyRadio;
};
};

View File

@ -6,8 +6,7 @@
void ASideBountyClass::BeginPlay()
{
Super::BeginPlay();
MinCPsRequiredForCompletion = 1;
}
void ASideBountyClass::IncrementBountyCheckpoint()
@ -16,8 +15,7 @@ void ASideBountyClass::IncrementBountyCheckpoint()
if (Completed)
{
CompletedSideBounty.Broadcast(ActiveSBC_Index);
CompletedSideBounty.Broadcast(FavoursEarnedForCompletion);
}
}

View File

@ -6,30 +6,26 @@
#include "BountyClass.h"
#include "SideBountyClass.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCompletedSideBounty, int, SB_Index);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCompletedSideBounty, int, FavoursEarned);
UCLASS()
class ENDLESSVENDETTA_API ASideBountyClass : public ABountyClass
{
GENERATED_BODY()
UPROPERTY(EditDefaultsOnly, Category = "Side Bounty")
TMap<int, TSubclassOf<ACheckpointClass>> ReplacementCheckpoints;
protected:
UPROPERTY(EditDefaultsOnly, Category = "Side Bounty")
int FavoursEarnedForCompletion = 1;
virtual void BeginPlay() override;
public:
FCompletedSideBounty CompletedSideBounty;
int ActiveSBC_Index;
TMap<int, TSubclassOf<ACheckpointClass>> GetReplacementCheckpoints()
{
return ReplacementCheckpoints;
}
virtual void IncrementBountyCheckpoint() override;
void DestroyCheckpoints();
int GetRewardInFavours()
{
return FavoursEarnedForCompletion;
}
};

View File

@ -6,6 +6,7 @@
#include "Components/CapsuleComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InteractableActor.h"
#include "AI/EnemyCharacter.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/GameplayStatics.h"
@ -102,9 +103,29 @@ void AEndlessVendettaCharacter::SetupPlayerInputComponent(class UInputComponent*
//Crouching
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Started, this, &AEndlessVendettaCharacter::SetCrouch);
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Completed, this, &AEndlessVendettaCharacter::SetUnCrouch);
//Interacting
EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Started, this, &AEndlessVendettaCharacter::Interact);
}
}
void AEndlessVendettaCharacter::Interact()
{
FHitResult OutHit;
FCollisionQueryParams QueryParams = FCollisionQueryParams::DefaultQueryParam;
QueryParams.AddIgnoredActor(this);
FVector LT_Start = FirstPersonCameraComponent->GetComponentLocation();
FVector LT_End = LT_Start + (FirstPersonCameraComponent->GetForwardVector() * InteractionRange);
if (!GetWorld()->LineTraceSingleByChannel(OutHit, LT_Start, LT_End, ECC_Camera, QueryParams)) return;
AActor* HitActor = OutHit.GetActor();
AInteractableActor* InteractableActor = Cast<AInteractableActor>(HitActor);
if (!IsValid(InteractableActor)) return;
InteractableActor->Interact();
}
void AEndlessVendettaCharacter::SetCrouch()
{
Crouch();

View File

@ -68,6 +68,9 @@ class AEndlessVendettaCharacter : public ACharacter
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* CrouchAction;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
UInputAction* InteractAction;
public:
AEndlessVendettaCharacter();
@ -86,6 +89,8 @@ protected:
AGadgetManager* GadgetManager;
public:
int Money = 2000;
/** Look Input Action */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Input, meta = (AllowPrivateAccess = "true"))
class UInputAction* LookAction;
@ -144,6 +149,9 @@ protected:
void EquipPrimary();
void EquipSecondary();
UPROPERTY(EditDefaultsOnly, Category = "Interaction")
float InteractionRange = 250;
void Interact();
protected:
// APawn interface

View File

@ -0,0 +1,33 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "InteractableActor.h"
// Sets default values
AInteractableActor::AInteractableActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AInteractableActor::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AInteractableActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AInteractableActor::Interact()
{
UE_LOG(LogTemp, Warning, TEXT("Interacted with %s"), *GetName());
}

View File

@ -0,0 +1,26 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "InteractableActor.generated.h"
UCLASS()
class ENDLESSVENDETTA_API AInteractableActor : public AActor
{
GENERATED_BODY()
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Sets default values for this actor's properties
AInteractableActor();
// Called every frame
virtual void Tick(float DeltaTime) override;
virtual void Interact();
};

View File

@ -0,0 +1,6 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "PC_Display.h"

View File

@ -0,0 +1,93 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "PC_Display.generated.h"
USTRUCT(BlueprintType)
struct FPC_Display_Info
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
bool IsGameOver;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
FString MB_Title;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
FString MB_Desc;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
int MB_Reward;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<FString> SB_Title;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<UTexture2D*> SB_Icon;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<FString> SB_Desc;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<int> SB_Reward;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<FString> CustomBountyAlteration_Desc;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
TArray<int> CustomBountyAlteration_Cost;
UPROPERTY(BlueprintReadWrite, Category = "PC_Display_Info")
int PlayersFavourAmount;
};
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FLogoutFromBountyDirectorPC);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyCBA_1);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyCBA_2);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyCBA_3);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyAmmoDrop);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyHealthDrop);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyRadio);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBuyFavour);
UCLASS()
class ENDLESSVENDETTA_API UPC_Display : public UUserWidget
{
GENERATED_BODY()
public:
// Button Delegates
UPROPERTY(BlueprintCallable, Category = PC_Display)
FLogoutFromBountyDirectorPC LogoutFromBountyDirectorPC;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyCBA_1 BuyCba_1;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyCBA_2 BuyCba_2;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyCBA_3 BuyCba_3;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyAmmoDrop BuyAmmoDrop;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyHealthDrop BuyHealthDrop;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyRadio BuyRadio;
UPROPERTY(BlueprintCallable, Category = PC_Display)
FBuyFavour BuyFavour;
// USTRUCT
UPROPERTY(BlueprintReadOnly)
FPC_Display_Info PC_Display_Info;
// Takes USTRUCT and uses its values to fill in widget
UFUNCTION(BlueprintImplementableEvent, Category = "PC_Display")
void LoadOS();
UFUNCTION(BlueprintImplementableEvent, Category = "PC_Display")
void UpdateFavourCount(int NewFavourCount);
};