Merge pull request #2 from Games-Academy-Student-Work-23-24/dev

Dev
This commit is contained in:
RAFAL SWIERCZEK 2023-10-16 16:54:13 +01:00 committed by GitHub Enterprise
commit 370cff50c9
57 changed files with 690 additions and 233 deletions

View File

@ -4,7 +4,7 @@
+EditProfiles=(Name="Trigger",CustomResponses=((Channel=Projectile, Response=ECR_Ignore))) +EditProfiles=(Name="Trigger",CustomResponses=((Channel=Projectile, Response=ECR_Ignore)))
[/Script/EngineSettings.GameMapsSettings] [/Script/EngineSettings.GameMapsSettings]
EditorStartupMap=/Game/FirstPerson/Maps/GunMechanicTester.GunMechanicTester EditorStartupMap=/Game/LevelPrototyping/Scenes/TutorialHit.TutorialHit
LocalMapOptions= LocalMapOptions=
TransitionMap=None TransitionMap=None
bUseSplitscreen=True bUseSplitscreen=True
@ -13,7 +13,7 @@ ThreePlayerSplitscreenLayout=FavorTop
FourPlayerSplitscreenLayout=Grid FourPlayerSplitscreenLayout=Grid
bOffsetPlayerGamepadIds=False bOffsetPlayerGamepadIds=False
GameInstanceClass=/Script/Engine.GameInstance GameInstanceClass=/Script/Engine.GameInstance
GameDefaultMap=/Game/FirstPerson/Maps/GunMechanicTester.GunMechanicTester GameDefaultMap=/Game/LevelPrototyping/Scenes/TutorialHit.TutorialHit
ServerDefaultMap=/Engine/Maps/Entry.Entry ServerDefaultMap=/Engine/Maps/Entry.Entry
GlobalDefaultGameMode=/Game/FirstPerson/GunMechanicWorld.GunMechanicWorld_C GlobalDefaultGameMode=/Game/FirstPerson/GunMechanicWorld.GunMechanicWorld_C
GlobalDefaultServerGameMode=None GlobalDefaultServerGameMode=None

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -25,7 +25,6 @@ AAICharacter::AAICharacter()
void AAICharacter::BeginPlay() void AAICharacter::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
} }
// Called every frame // Called every frame
@ -54,31 +53,7 @@ float AAICharacter::TakeDamage(const float DamageAmount, FDamageEvent const& Dam
CurrentHealth = 0; CurrentHealth = 0;
UE_LOG(LogTemp, Display, TEXT("%s is dead"), *CharacterName.ToString()); UE_LOG(LogTemp, Display, TEXT("%s is dead"), *CharacterName.ToString());
/*const AAI_EnemyController* AIController = Cast<AAI_EnemyController>(GetController()); OnDeath();
AIController->GetBrainComponent()->StopLogic(" is dead");*/
this->Tags.Add(FName("Dead"));
//Ragdoll
DetachFromControllerPendingDestroy();
UCapsuleComponent* CapsuleComp = GetCapsuleComponent();
CapsuleComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CapsuleComp->SetCollisionResponseToAllChannels(ECR_Ignore);
GetMesh()->SetCollisionProfileName(TEXT("Ragdoll"));
SetActorEnableCollision(true);
GetMesh()->SetAllBodiesSimulatePhysics(true);
GetMesh()->SetSimulatePhysics(true);
GetMesh()->WakeAllRigidBodies();
GetMesh()->bBlendPhysics = true;
if (UCharacterMovementComponent* CharacterComp = Cast<UCharacterMovementComponent>(GetMovementComponent()))
{
CharacterComp->StopMovementImmediately();
CharacterComp->DisableMovement();
CharacterComp->SetComponentTickEnabled(false);
}
SetLifeSpan(30.0f);
} }
return Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); return Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
} }
@ -98,3 +73,31 @@ void AAICharacter::SetupStimuliSourceComponent()
} }
} }
void AAICharacter::OnDeath()
{
/*const AAI_EnemyController* AIController = Cast<AAI_EnemyController>(GetController());
AIController->GetBrainComponent()->StopLogic(" is dead");*/
this->Tags.Add(FName("Dead"));
//Ragdoll
DetachFromControllerPendingDestroy();
UCapsuleComponent* CapsuleComp = GetCapsuleComponent();
CapsuleComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CapsuleComp->SetCollisionResponseToAllChannels(ECR_Ignore);
GetMesh()->SetCollisionProfileName(TEXT("Ragdoll"));
SetActorEnableCollision(true);
GetMesh()->SetAllBodiesSimulatePhysics(true);
GetMesh()->SetSimulatePhysics(true);
GetMesh()->WakeAllRigidBodies();
GetMesh()->bBlendPhysics = true;
if (UCharacterMovementComponent* CharacterComp = Cast<UCharacterMovementComponent>(GetMovementComponent()))
{
CharacterComp->StopMovementImmediately();
CharacterComp->DisableMovement();
CharacterComp->SetComponentTickEnabled(false);
}
SetLifeSpan(30.0f);
}

View File

@ -35,6 +35,8 @@ protected:
class UAIPerceptionStimuliSourceComponent* StimuliSourceComponent; class UAIPerceptionStimuliSourceComponent* StimuliSourceComponent;
void SetupStimuliSourceComponent(); void SetupStimuliSourceComponent();
virtual void OnDeath();
public: public:
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;

View File

@ -74,3 +74,8 @@ void AAIControlHub::SetPlayerLastKnownLocation(FVector Location)
PlayerLastKnownLocation = Location; PlayerLastKnownLocation = Location;
} }
} }
void AAIControlHub::RemoveEnemyActor(AEnemyCharacter* EnemyActor)
{
EnemyActors.Remove(EnemyActor);
}

View File

@ -35,6 +35,7 @@ public:
int GetAlertLevel() const; int GetAlertLevel() const;
void OnAlertLevelChanged(); void OnAlertLevelChanged();
void SetPlayerLastKnownLocation(FVector Location = FVector(0, 0, 0)); void SetPlayerLastKnownLocation(FVector Location = FVector(0, 0, 0));
void RemoveEnemyActor(AEnemyCharacter* EnemyActor);
private: private:
int AlertLevel = 0; int AlertLevel = 0;

View File

@ -23,6 +23,16 @@ void AEnemyCharacter::BeginPlay()
CharacterName = "Enemy"; CharacterName = "Enemy";
} }
void AEnemyCharacter::OnDeath()
{
Super::OnDeath();
DelegatedControlHub->AlertLevelEvent.Remove(AlertLevelDelegateHandle);
DelegatedControlHub->HuntPlayerEvent.Remove(HuntPlayerDelegateHandle);
AlertLevelDelegateHandle.Reset();
HuntPlayerDelegateHandle.Reset();
DelegatedControlHub->RemoveEnemyActor(this);
}
// Called every frame // Called every frame
void AEnemyCharacter::Tick(float DeltaTime) void AEnemyCharacter::Tick(float DeltaTime)
{ {
@ -38,6 +48,8 @@ void AEnemyCharacter::SubscribeToGroupAIEvents(AAIControlHub* ControlHub)
void AEnemyCharacter::SetAlertLevel(const int NewAlertLevel) const void AEnemyCharacter::SetAlertLevel(const int NewAlertLevel) const
{ {
if (!IsValid(this)) return;
if (!IsValid(GetController())) return;
Cast<AAIController>(GetController())->GetBlackboardComponent()->SetValueAsInt("AlertLevel", NewAlertLevel); Cast<AAIController>(GetController())->GetBlackboardComponent()->SetValueAsInt("AlertLevel", NewAlertLevel);
} }
@ -49,6 +61,8 @@ void AEnemyCharacter::SetLocalAlertLevel(int NewAlertLevel) const
void AEnemyCharacter::HuntPlayer(FVector PlayerLastKnownLocation) void AEnemyCharacter::HuntPlayer(FVector PlayerLastKnownLocation)
{ {
if (!IsValid(this)) return;
if (!IsValid(GetController())) return;
SetAlertLevel(2); SetAlertLevel(2);
Cast<AAIController>(GetController())->GetBlackboardComponent()->SetValueAsVector("LastKnownLocation", PlayerLastKnownLocation); Cast<AAIController>(GetController())->GetBlackboardComponent()->SetValueAsVector("LastKnownLocation", PlayerLastKnownLocation);
} }

View File

@ -21,6 +21,7 @@ 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;
class AAIControlHub* DelegatedControlHub; class AAIControlHub* DelegatedControlHub;
virtual void OnDeath() override;
public: public:
// Called every frame // Called every frame

View File

@ -19,7 +19,7 @@ EBTNodeResult::Type UBTTask_AttackPlayer::ExecuteTask(UBehaviorTreeComponent& Ow
{ {
FVector const Origin = AIController->GetPawn()->GetActorLocation(); FVector const Origin = AIController->GetPawn()->GetActorLocation();
FVector const PlayerLocation = Blackboard->GetValueAsVector("TargetLocation"); FVector const PlayerLocation = Blackboard->GetValueAsVector("TargetLocation");
DrawDebugLine(GetWorld(), Origin, PlayerLocation, FColor::Green, false, 1.f, 0, 1.f); //DrawDebugLine(GetWorld(), Origin, PlayerLocation, FColor::Green, false, 1.f, 0, 1.f);
FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded); FinishLatentTask(OwnerComp, EBTNodeResult::Succeeded);
return EBTNodeResult::Succeeded; return EBTNodeResult::Succeeded;

View File

@ -61,7 +61,7 @@ void ABountyClass::IncrementBountyCheckpoint()
} }
// Bounty Completion Condition // Bounty Completion Condition
if (BountyCheckpoints.Num() <= MinCPsRequiredForCompletion) if (BountyCheckpoints.Num() <= 1)
{ {
Completed = true; Completed = true;
BountyCheckpoints[0]->Active = false; 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); 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; 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 // Spawned in Checkpoints for this Bounty
TArray<ACheckpointClass*> BountyCheckpoints; TArray<ACheckpointClass*> BountyCheckpoints;
@ -72,6 +66,11 @@ public:
return BountyDesc; return BountyDesc;
} }
int GetBountyrewardMoney()
{
return RewardMoney;
}
FVector GetCheckpointLocation() FVector GetCheckpointLocation()
{ {
if (BountyCheckpoints.IsEmpty() || BountyCheckpoints[0] == nullptr) 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 // Collect Money in C++, any other special reward will be implemented in BP if neccessary
UFUNCTION(BlueprintCallable, BlueprintNativeEvent) UFUNCTION(BlueprintCallable, BlueprintNativeEvent)
void CollectRewards(); 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 "BountyDirector.h"
#include "Blueprint/UserWidget.h"
#include "Components/ArrowComponent.h" #include "Components/ArrowComponent.h"
// Sets default values // Sets default values
@ -35,15 +36,7 @@ void ABountyDirector::BeginPlay()
break; break;
} }
// Setup up starting Side Bounty indexes
for (int Index = 0; Index < 3; Index++)
{
CurrentSideBountyIndexes.Add(Index);
}
ActiveSideBounties.SetNum(3);
SpawnBountyAndItsSideBounties(); SpawnBountyAndItsSideBounties();
UpdateBountyDisplay();
} }
void ABountyDirector::SpawnBountyAndItsSideBounties() void ABountyDirector::SpawnBountyAndItsSideBounties()
@ -61,27 +54,22 @@ void ABountyDirector::SpawnBountyAndItsSideBounties()
const FAttachmentTransformRules AttachmentTransformRules(EAttachmentRule::SnapToTarget, true); const FAttachmentTransformRules AttachmentTransformRules(EAttachmentRule::SnapToTarget, true);
BountyActor->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules); 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")); 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!!!!! // WHEN MARCEL STOPS PLAYING WITH THE CHARACTER, ADD THIS BOUNTY TO PLAYERS ARRAY OF ACTIVE BOUNTIES!!!!!
ActiveBounty->CompletedFirstCheckpoint.AddDynamic(this, &ABountyDirector::DestroyActiveSideBounties); ActiveBounty->CompletedFirstCheckpoint.AddDynamic(this, &ABountyDirector::DestroyActiveSideBounties);
ActiveSideBounties.Reset();
// Spawn in Side Bounties which are linked to the Main Bounty for (TSubclassOf<ASideBountyClass> SideBountyClass : ActiveBounty->GetSideBountiesToSpawn())
int ActiveSideBountyIndex = 0;
for (int CurrentSideBountyIndex : CurrentSideBountyIndexes)
{ {
if (SideBountyClassArray.Num() <= CurrentSideBountyIndex || !IsValid(SideBountyClassArray[CurrentSideBountyIndex])) continue; if (!IsValid(SideBountyClass)) continue;
AActor* SideBountyActor = GetWorld()->SpawnActor<AActor>(SideBountyClass, PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams);
AActor* SideBountyActor = GetWorld()->SpawnActor<AActor>(SideBountyClassArray[CurrentSideBountyIndex], PlayerChar->GetActorLocation(), PlayerChar->GetActorRotation(), SpawnParams); SideBountyActor->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules);
ASideBountyClass* SideBounty = Cast<ASideBountyClass>(SideBountyActor); ASideBountyClass* SideBounty = Cast<ASideBountyClass>(SideBountyActor);
SideBounty->AttachToComponent(BountyAttachmentPoint, AttachmentTransformRules); 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[ActiveSideBountyIndex] = SideBounty; ActiveSideBounties[i]->CompletedSideBounty.AddDynamic(this, &ABountyDirector::EarnFavours);
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!!!!! // 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(); ActiveBounty->CollectRewards();
// Destroy old Bounties // Destroy old Bounties
ActiveBounty->DestroyReturnToShipStep();
ActiveBounty->Destroy(); ActiveBounty->Destroy();
DestroyActiveSideBounties(); DestroyActiveSideBounties();
// Increment Main and Side Bounty Indexes // Increment Main and Side Bounty Indexes
CurrentBountyIndex++; CurrentBountyIndex++;
for (int i = 0; i < 3; i++)
{
CurrentSideBountyIndexes[i] += 3;
}
// Game Completion Check // Game Completion Check
if (CurrentBountyIndex >= BountyClassArray.Num()) if (CurrentBountyIndex >= BountyClassArray.Num())
{ {
UE_LOG(LogTemp, Warning, TEXT("Finished all bounties currently available in the game :)")); UE_LOG(LogTemp, Warning, TEXT("Finished all bounties currently available in the game :)"));
ActiveBounty = nullptr; ActiveBounty = nullptr;
UpdateBountyDisplay();
return; return;
} }
SpawnBountyAndItsSideBounties(); SpawnBountyAndItsSideBounties();
UpdateBountyDisplay();
} }
void ABountyDirector::DestroyActiveSideBounties() void ABountyDirector::DestroyActiveSideBounties()
@ -132,21 +113,169 @@ void ABountyDirector::DestroyActiveSideBounties()
SideBounty->DestroyCheckpoints(); SideBounty->DestroyCheckpoints();
SideBounty->Destroy(); SideBounty->Destroy();
} }
UpdateBountyDisplay();
} }
void ABountyDirector::SideBountyCompleted(int SideBountyIndex) // ----------- Favour Shop ---------------
void ABountyDirector::EarnFavours(int FavoursEarned)
{ {
UE_LOG(LogTemp,Warning,TEXT("Updating Main Bounties Checkpoints")); Favours += FavoursEarned;
ActiveBounty->UpdateBountyCheckpoints(ActiveSideBounties[SideBountyIndex]->GetReplacementCheckpoints()); }
// WHEN MARCEL STOPS PLAYING WITH PLAYER CHAR, REMOVE THIS SIDE BOUNTY FROM ACTIVE BOUNTIES void ABountyDirector::BuyCustomBountyAlteration_1()
ActiveSideBounties[SideBountyIndex]->CollectRewards(); {
ActiveSideBounties[SideBountyIndex]->DestroyCheckpoints(); if (!IsValid(ActiveBounty)) return;
ActiveSideBounties[SideBountyIndex]->Destroy(); int Cost = ActiveBounty->GetCustomBountyAlteration_1_Cost();
if (Cost == 0 || Favours < Cost || ActiveBounty->ActivatedCBA_1) return;
UpdateBountyDisplay(); 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 #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "BountyClass.h" #include "MainBountyClass.h"
#include "SideBountyClass.h" #include "SideBountyClass.h"
#include "EndlessVendetta/EndlessVendettaCharacter.h" #include "EndlessVendetta/EndlessVendettaCharacter.h"
#include "EndlessVendetta/InteractableActor.h"
#include "EndlessVendetta/UserWidgets/PC_Display.h"
#include "GameFramework/Actor.h" #include "GameFramework/Actor.h"
#include "BountyDirector.generated.h" #include "BountyDirector.generated.h"
UCLASS() UCLASS()
class ENDLESSVENDETTA_API ABountyDirector : public AActor class ENDLESSVENDETTA_API ABountyDirector : public AInteractableActor
{ {
GENERATED_BODY() GENERATED_BODY()
@ -20,25 +22,28 @@ class ENDLESSVENDETTA_API ABountyDirector : public AActor
UArrowComponent* BountyAttachmentPoint; UArrowComponent* BountyAttachmentPoint;
// Ordered Array of Main Bounties // Ordered Array of Main Bounties
UPROPERTY(EditDefaultsOnly, Category = "Bounty") UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
TArray<TSubclassOf<ABountyClass>> BountyClassArray; TArray<TSubclassOf<AMainBountyClass>> BountyClassArray;
// Ordered Array of Side Bounties, in three's UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
UPROPERTY(EditDefaultsOnly, Category = "Bounty") int FavourCost = 500;
TArray<TSubclassOf<ASideBountyClass>> SideBountyClassArray;
UPROPERTY(EditDefaultsOnly, Category = "Bounty Director")
TSubclassOf<UPC_Display> PC_DisplayWidgetClass;
UUserWidget* PC_DisplayWidget;
UPC_Display* PC_Display;
int CurrentBountyIndex = 0; int CurrentBountyIndex = 0;
TArray<int> CurrentSideBountyIndexes;
UPROPERTY(VisibleAnywhere, Category = "Bounty") UPROPERTY(VisibleAnywhere, Category = "Bounty")
ABountyClass* ActiveBounty; AMainBountyClass* ActiveBounty;
UPROPERTY(VisibleAnywhere, Category = "Bounty") UPROPERTY(VisibleAnywhere, Category = "Bounty")
TArray<ASideBountyClass*> ActiveSideBounties; TArray<ASideBountyClass*> ActiveSideBounties;
// Checks if completed the bounty, and moves onto the next if so // Checks if completed the bounty, and moves onto the next if so
UFUNCTION(BlueprintCallable, Category = "Bounty")
void UpdateBountyProgression(); void UpdateBountyProgression();
void SpawnBountyAndItsSideBounties(); void SpawnBountyAndItsSideBounties();
@ -46,22 +51,47 @@ class ENDLESSVENDETTA_API ABountyDirector : public AActor
// Collect reward for current Bounty and prepare for the next // Collect reward for current Bounty and prepare for the next
void FinishActiveBounty(); void FinishActiveBounty();
// Opens up Bounty Director PC Interface
void Interact() override;
protected: protected:
int Favours = 20;
// 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() UFUNCTION()
void DestroyActiveSideBounties(); 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: public:
// Called every frame // Called every frame
virtual void Tick(float DeltaTime) override; virtual void Tick(float DeltaTime) override;
@ -70,29 +100,24 @@ public:
ABountyDirector(); ABountyDirector();
// ------ Getters ------ // ------ Getters ------
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetBountyTitle() FString GetBountyTitle()
{ {
return !IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyTitle(); return !IsValid(ActiveBounty) ? FString("") : ActiveBounty->GetBountyTitle();
}
UTexture2D* GetBountyIcon()
{
return !IsValid(ActiveBounty) ? nullptr : ActiveBounty->GetActiveWaypointIcon();
} }
UFUNCTION(BlueprintCallable, Category = "Bounty")
FString GetBountyDescription() FString GetBountyDescription()
{ {
return !IsValid(ActiveBounty) ? FString("N/A") : ActiveBounty->GetBountyDesc(); return !IsValid(ActiveBounty) ? FString("") : ActiveBounty->GetBountyDesc();
} }
UFUNCTION(BlueprintCallable, Category = "Bounty") int GetBountyReward()
FString GetSideBountyTitle(int SideBountyIndex)
{ {
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

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

View File

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

View File

@ -6,6 +6,7 @@
#include "Components/CapsuleComponent.h" #include "Components/CapsuleComponent.h"
#include "EnhancedInputComponent.h" #include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h" #include "EnhancedInputSubsystems.h"
#include "InteractableActor.h"
#include "AI/EnemyCharacter.h" #include "AI/EnemyCharacter.h"
#include "GameFramework/CharacterMovementComponent.h" #include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
@ -102,9 +103,29 @@ void AEndlessVendettaCharacter::SetupPlayerInputComponent(class UInputComponent*
//Crouching //Crouching
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Started, this, &AEndlessVendettaCharacter::SetCrouch); EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Started, this, &AEndlessVendettaCharacter::SetCrouch);
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Completed, this, &AEndlessVendettaCharacter::SetUnCrouch); 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() void AEndlessVendettaCharacter::SetCrouch()
{ {
Crouch(); Crouch();

View File

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