diff --git a/EndlessVendetta/Content/AI/BP_RestrictedZone.uasset b/EndlessVendetta/Content/AI/BP_RestrictedZone.uasset new file mode 100644 index 00000000..35bda6ad --- /dev/null +++ b/EndlessVendetta/Content/AI/BP_RestrictedZone.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c89b6b00736d4a261b5fc9892934a451a08ca2b0c699e021e53aca0e99f1cca +size 20394 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/BB_BasicEnemy.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/BB_BasicEnemy.uasset index 62afc6a9..95232d5a 100644 --- a/EndlessVendetta/Content/AI/Enemy/Basic/BB_BasicEnemy.uasset +++ b/EndlessVendetta/Content/AI/Enemy/Basic/BB_BasicEnemy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad3bf87b66a3ee2e7ad18cea061511934ee56250c226b6f79d5b2128e37f23c4 -size 6580 +oid sha256:ae9dfbea15f5153c414b37908abba881d284122cc7084c860c337a10bbe56072 +size 6944 diff --git a/EndlessVendetta/Content/AI/Enemy/Basic/BT_BasicEnemy.uasset b/EndlessVendetta/Content/AI/Enemy/Basic/BT_BasicEnemy.uasset index e3aafec6..4a874ddc 100644 --- a/EndlessVendetta/Content/AI/Enemy/Basic/BT_BasicEnemy.uasset +++ b/EndlessVendetta/Content/AI/Enemy/Basic/BT_BasicEnemy.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:87f04b1ff54b8fac36ed5341491dcc9beb969400a57b4942ef44968b17fd0a02 -size 74567 +oid sha256:019e879ee15b4850fb9e601944cc2337663d20b4240b0cdf5006727321a0e496 +size 80128 diff --git a/EndlessVendetta/Content/__ExternalActors__/Levels/AITest/E/1M/A5VMSIPC1VU25T4W5AQYEC.uasset b/EndlessVendetta/Content/__ExternalActors__/Levels/AITest/E/1M/A5VMSIPC1VU25T4W5AQYEC.uasset new file mode 100644 index 00000000..d03d17aa --- /dev/null +++ b/EndlessVendetta/Content/__ExternalActors__/Levels/AITest/E/1M/A5VMSIPC1VU25T4W5AQYEC.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18a4d11545c9b24a0aa01f0c132535e10a3b1bbd483485e897179b21bd76fe5f +size 3383 diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.cpp new file mode 100644 index 00000000..7780b46a --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.cpp @@ -0,0 +1,47 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AI_RestrictedZone.h" + +#include "EndlessVendetta/EndlessVendettaCharacter.h" + + +// Sets default values +AAI_RestrictedZone::AAI_RestrictedZone() +{ + // 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; + BoxCollision = CreateDefaultSubobject(TEXT("BoxCollision")); +} + +// Called when the game starts or when spawned +void AAI_RestrictedZone::BeginPlay() +{ + Super::BeginPlay(); + BoxCollision->OnComponentBeginOverlap.AddDynamic(this, &AAI_RestrictedZone::OnBoxOverlapBegin); + BoxCollision->OnComponentEndOverlap.AddDynamic(this, &AAI_RestrictedZone::OnBoxOverlapEnd); +} + +void AAI_RestrictedZone::OnBoxOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) +{ + if (Cast(OtherActor)) + { + UE_LOG(LogTemp, Display, TEXT("Player entered restricted bounds")); + Cast(OtherActor)->IncrementRestrictedBoundsCount(); + } +} + +void AAI_RestrictedZone::OnBoxOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex) +{ + if (Cast(OtherActor)) + { + UE_LOG(LogTemp, Display, TEXT("Player left restricted bounds")); + Cast(OtherActor)->DecrementRestrictedBoundsCount(); + } +} + +// Called every frame +void AAI_RestrictedZone::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.h b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.h new file mode 100644 index 00000000..ca4cd298 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZone.h @@ -0,0 +1,34 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/BoxComponent.h" +#include "GameFramework/Actor.h" +#include "AI_RestrictedZone.generated.h" + +UCLASS() +class ENDLESSVENDETTA_API AAI_RestrictedZone : public AActor +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AAI_RestrictedZone(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + + UPROPERTY() + UBoxComponent* BoxCollision; + + UFUNCTION() + void OnBoxOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); + UFUNCTION() + void OnBoxOverlapEnd(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.cpp new file mode 100644 index 00000000..dff721b4 --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.cpp @@ -0,0 +1,27 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AI_RestrictedZoneModifier.h" + + +// Sets default values +AAI_RestrictedZoneModifier::AAI_RestrictedZoneModifier() +{ + // 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; + BoxCollision = CreateDefaultSubobject(TEXT("BoxCollision")); +} + +// Called when the game starts or when spawned +void AAI_RestrictedZoneModifier::BeginPlay() +{ + Super::BeginPlay(); + +} + +// Called every frame +void AAI_RestrictedZoneModifier::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.h b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.h new file mode 100644 index 00000000..b720c93b --- /dev/null +++ b/EndlessVendetta/Source/EndlessVendetta/AI/AI_RestrictedZoneModifier.h @@ -0,0 +1,28 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Components/BoxComponent.h" +#include "GameFramework/Actor.h" +#include "AI_RestrictedZoneModifier.generated.h" + +UCLASS() +class ENDLESSVENDETTA_API AAI_RestrictedZoneModifier : public AActor +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AAI_RestrictedZoneModifier(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + + UBoxComponent* BoxCollision; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; +}; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp index caccb861..f0acd139 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.cpp @@ -22,6 +22,11 @@ void AEnemyCharacter::BeginPlay() { Super::BeginPlay(); CharacterName = "Enemy"; + + if (AEndlessVendettaCharacter* PlayerCharacter = Cast(GetWorld()->GetFirstPlayerController()->GetPawn())) + { + PlayerCharacter->RestrictedAreaStatusChanged.AddUniqueDynamic(this, &AEnemyCharacter::SetIfPlayerIsInRestrictedArea); + } } void AEnemyCharacter::OnDeath() @@ -51,11 +56,12 @@ void AEnemyCharacter::SetAlertLevel(const int NewAlertLevel) const Cast(GetController())->GetBlackboardComponent()->SetValueAsInt("AlertLevel", NewAlertLevel); } -void AEnemyCharacter::SetLocalAlertLevel(int NewAlertLevel) const +void AEnemyCharacter::SetLocalAlertLevel(int NewAlertLevel) { - if (!IsValid(DelegatedControlHub)) return; if (!IsValid(GetController())) return; Cast(GetController())->GetBlackboardComponent()->SetValueAsBool("IsInvestigating", true); + if (NewAlertLevel >= 2) SetHostilityLevel(EHostilityLevel::Hostile); + if (!IsValid(DelegatedControlHub)) return; DelegatedControlHub->SetAlertLevel(NewAlertLevel); } @@ -99,3 +105,9 @@ void AEnemyCharacter::HuntPlayer(FVector PlayerLastKnownLocation) EquipWeapon(); Cast(GetController())->GetBlackboardComponent()->SetValueAsVector("LastKnownLocation", PlayerLastKnownLocation); } + +void AEnemyCharacter::SetIfPlayerIsInRestrictedArea(const bool bIsInRestrictedArea) +{ + if (!IsValid(GetController())) return; + Cast(GetController())->GetBlackboardComponent()->SetValueAsBool("PlayerIsInRestrictedBounds", bIsInRestrictedArea); +} diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h index d7577413..05776470 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/AI/EnemyCharacter.h @@ -41,7 +41,7 @@ public: virtual void Tick(float DeltaTime) override; UFUNCTION(BlueprintCallable) void SubscribeToGroupAIEvents(class AAIControlHub* ControlHub); - void SetLocalAlertLevel(int NewAlertLevel) const; + void SetLocalAlertLevel(int NewAlertLevel); UFUNCTION(BlueprintCallable) void SetHostilityLevel(EHostilityLevel NewHostilityLevel); virtual float TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser) override; @@ -67,4 +67,6 @@ private: FDelegateHandle HuntPlayerDelegateHandle; void SetAlertLevel(int NewAlertLevel) const; void HuntPlayer(FVector PlayerLastKnowLocation); + UFUNCTION() + void SetIfPlayerIsInRestrictedArea(bool bIsInRestrictedArea); }; diff --git a/EndlessVendetta/Source/EndlessVendetta/AI/Tasks/BTTask_SetLocalAlertLevel.cpp b/EndlessVendetta/Source/EndlessVendetta/AI/Tasks/BTTask_SetLocalAlertLevel.cpp index 3cd9990b..3aa25e00 100644 --- a/EndlessVendetta/Source/EndlessVendetta/AI/Tasks/BTTask_SetLocalAlertLevel.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/AI/Tasks/BTTask_SetLocalAlertLevel.cpp @@ -14,7 +14,7 @@ EBTNodeResult::Type UBTTask_SetLocalAlertLevel::ExecuteTask(UBehaviorTreeCompone { if (const AAI_EnemyController* const AIEnemyController = Cast(OwnerComp.GetAIOwner())) { - if (const AEnemyCharacter* const EnemyCharacter = Cast(AIEnemyController->GetPawn())) + if (AEnemyCharacter* const EnemyCharacter = Cast(AIEnemyController->GetPawn())) { EnemyCharacter->SetLocalAlertLevel(AlertLevel); diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp index 66473a96..fafa4e56 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.cpp @@ -47,13 +47,33 @@ AEndlessVendettaCharacter::AEndlessVendettaCharacter() Mesh1P->SetRelativeLocation(FVector(-30.f, 0.f, -150.f)); } +void AEndlessVendettaCharacter::IncrementRestrictedBoundsCount() +{ + RestrictedBoundsCount++; + if (RestrictedBoundsCount > 0) + { + bIsInRestrictedArea = true; + RestrictedAreaStatusChanged.Broadcast(true); + } +} + +void AEndlessVendettaCharacter::DecrementRestrictedBoundsCount() +{ + RestrictedBoundsCount--; + if (RestrictedBoundsCount <= 0) + { + bIsInRestrictedArea = false; + RestrictedAreaStatusChanged.Broadcast(false); + } +} + void AEndlessVendettaCharacter::BeginPlay() { // Call the base class Super::BeginPlay(); bIsCurrentlyHoldingWeapon = false; UEVGameInstance* GI = Cast(GetWorld()->GetGameInstance()); - if (IsValid(GI->MainSaveGameInstanceRef)) + if (IsValid(GI->MainSaveGameInstanceRef)) { PrimaryWeaponClass = GI->MainSaveGameInstanceRef->PrimaryWeaponClassSave; SecondaryWeaponClass = GI->MainSaveGameInstanceRef->SecondaryWeaponClassSave; @@ -378,7 +398,7 @@ void AEndlessVendettaCharacter::EquipPrimary() Cast(GetWorld()->GetAuthGameMode())->SendEvent("DeEquip", "Pri"); return; } - + if (IsValid(SecondaryWeapon)) EquipSecondary(); if (GadgetManager->IsValidReconGadget() && GadgetManager->IsReconEquipped() && !GadgetManager->TryToUnequipRecon()) return; @@ -477,7 +497,7 @@ void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) PrimaryWeaponClass = Outhit->GetClass(); if (IsValid(PrimaryWeapon)) { - if(bIsCurrentlyHoldingWeapon) + if (bIsCurrentlyHoldingWeapon) { PrimaryWeaponActor = GetWorld()->SpawnActor(PrimaryWeaponClass, spawnParams); UE_LOG(LogTemp, Warning, TEXT("PRIMARY WEAPON SPAWNING IN")); @@ -486,7 +506,7 @@ void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) } bIsWeaponPickedUp = true; UEVGameInstance* GI = Cast(GetGameInstance()); - if (IsValid(GI->MainSaveGameInstanceRef)) + if (IsValid(GI->MainSaveGameInstanceRef)) { GI->MainSaveGameInstanceRef->PrimaryWeaponClassSave = Outhit->GetClass(); UGameplayStatics::SaveGameToSlot(GI->MainSaveGameInstanceRef, "MainSave", 0); @@ -515,7 +535,7 @@ void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) { if (IsValid(SecondaryWeapon)) { - if(bIsCurrentlyHoldingWeapon) + if (bIsCurrentlyHoldingWeapon) { GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Blue, TEXT("bIsCurrentlyHoldingSecondaryCalled, trying to spawn secondary weapon actor")); SecondaryWeaponActor = GetWorld()->SpawnActor(SecondaryWeaponClass, spawnParams); @@ -525,14 +545,14 @@ void AEndlessVendettaCharacter::WeaponSwitcher(AActor* Outhit) } bIsWeaponPickedUp = true; SecondaryWeaponClass = Outhit->GetClass(); - + UEVGameInstance* GI = Cast(GetGameInstance()); - if (IsValid(GI->MainSaveGameInstanceRef)) + if (IsValid(GI->MainSaveGameInstanceRef)) { GI->MainSaveGameInstanceRef->SecondaryWeaponClassSave = Outhit->GetClass(); UGameplayStatics::SaveGameToSlot(GI->MainSaveGameInstanceRef, "MainSave", 0); } - + Outhit->Destroy(); EquipSecondary(); } diff --git a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h index cecf8f31..da45ae26 100644 --- a/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h +++ b/EndlessVendetta/Source/EndlessVendetta/EndlessVendettaCharacter.h @@ -127,14 +127,24 @@ public: void StopSecondaryWeaponADS(); UPROPERTY(BlueprintReadWrite) bool bIsInDialogue = false; + UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Stats") + bool bIsInRestrictedArea = false; + UFUNCTION(BlueprintCallable) + void IncrementRestrictedBoundsCount(); + UFUNCTION(BlueprintCallable) + void DecrementRestrictedBoundsCount(); + DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FRestrictedAreaStatusChangedSignature, bool, bIsInRestrictedArea); + + UPROPERTY(BlueprintAssignable, Category = "Restricted Area") + FRestrictedAreaStatusChangedSignature RestrictedAreaStatusChanged; protected: virtual void BeginPlay() override; virtual void Tick(float DeltaTime) override; bool InPauseMenu = false; - + UPROPERTY(EditDefaultsOnly, Category = "Gadget") TSubclassOf GadgetManagerClass; @@ -146,6 +156,9 @@ protected: UFUNCTION(BlueprintImplementableEvent) void PlayFadeScreen(); + UPROPERTY() + int RestrictedBoundsCount = 0; + public: AGadgetManager* GadgetManager; bool bIsReloading = false; @@ -234,6 +247,7 @@ protected: void StartedHoldingInteract(float Duration); UFUNCTION(BlueprintImplementableEvent) void StoppedHoldingInteract(); + protected: // Used by vault it plugin to run vaulting animations USkeletalMeshComponent* FP_SkeletalMesh = nullptr; @@ -282,9 +296,11 @@ private: UPROPERTY(EditDefaultsOnly, Category = "Hover Bike") TSubclassOf SpaceShipClass; ASpaceShip* SpaceShip; + protected: bool PlayerOnShip = false; void HoldInteract(); + public: void ExitShip(FTransform ExitLoc); void EnterShip(FTransform TakeoffLoc);