From 053c56f37c7cd0eb440d584d0766ec3cc196a1ee Mon Sep 17 00:00:00 2001 From: HappyTanuki Date: Wed, 25 Oct 2023 02:40:51 +0900 Subject: [PATCH] =?UTF-8?q?=ED=98=B8-=EB=B0=8D=20=EA=B3=B5=EA=B2=A9=20?= =?UTF-8?q?=EB=B0=8F=20=EC=84=A0=ED=83=9D=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BP_DefaultPlayerCharacter.uasset | 4 +- .../Bp_DefaultplayerController.uasset | 4 +- Content/Blueprints/DefaultClass.uasset | 3 - .../UI/NameBar_UI/NameBar_UI.uasset | 4 +- Content/Character/Lb/BP_Lb.uasset | 4 +- Content/Character/Lb/BaseArrow.uasset | 4 +- .../Character/Monster/Knight/BP_Knignt.uasset | 4 +- Content/Effect/AliumQ/Knife1.uasset | 3 + Content/Effect/CC.uasset | 3 + Content/Effect/dust.uasset | 3 + Content/Effect/tnt.uasset | 3 + Content/Maps/DevMap.umap | 4 +- .../ApDamage.cpp => DamageType/APDamage.cpp} | 2 +- .../ApDamage.h => DamageType/APDamage.h} | 4 +- Source/Promether/DamageType/HomingAttack.cpp | 45 ++++++ Source/Promether/DamageType/HomingAttack.h | 30 ++++ Source/Promether/DefaultAIController.cpp | 33 +++++ Source/Promether/DefaultAIController.h | 21 +++ .../PlayerGeneric/DefaultPlayerCharacter.cpp | 132 ++++++++++-------- .../PlayerGeneric/DefaultPlayerCharacter.h | 15 +- .../PlayerGeneric/DefaultPlayerController.cpp | 88 ++++++------ .../PlayerGeneric/DefaultPlayerController.h | 4 +- .../PlayerGeneric/DefaultPlayerState.cpp | 37 ++++- .../PlayerGeneric/DefaultPlayerState.h | 26 +++- Source/Promether/PrometherEnum.h | 1 + 25 files changed, 347 insertions(+), 134 deletions(-) delete mode 100644 Content/Blueprints/DefaultClass.uasset create mode 100644 Content/Effect/AliumQ/Knife1.uasset create mode 100644 Content/Effect/CC.uasset create mode 100644 Content/Effect/dust.uasset create mode 100644 Content/Effect/tnt.uasset rename Source/Promether/{Private/DamageType/ApDamage.cpp => DamageType/APDamage.cpp} (71%) rename Source/Promether/{Public/DamageType/ApDamage.h => DamageType/APDamage.h} (71%) create mode 100644 Source/Promether/DamageType/HomingAttack.cpp create mode 100644 Source/Promether/DamageType/HomingAttack.h create mode 100644 Source/Promether/DefaultAIController.cpp create mode 100644 Source/Promether/DefaultAIController.h diff --git a/Content/Blueprints/BP_DefaultPlayerCharacter.uasset b/Content/Blueprints/BP_DefaultPlayerCharacter.uasset index a90b7f8..8b8a483 100644 --- a/Content/Blueprints/BP_DefaultPlayerCharacter.uasset +++ b/Content/Blueprints/BP_DefaultPlayerCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:76bef1350b78a2de3894e927a1e7f2ff7a52e4654c1d7415598e0b87b2cfa71d -size 143280 +oid sha256:e8c82415960d0b58adbb46faa76b95711bf913a53aab55b722faaf06b86922c0 +size 142183 diff --git a/Content/Blueprints/Bp_DefaultplayerController.uasset b/Content/Blueprints/Bp_DefaultplayerController.uasset index 0836b9f..2fe18a0 100644 --- a/Content/Blueprints/Bp_DefaultplayerController.uasset +++ b/Content/Blueprints/Bp_DefaultplayerController.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d0d423051a6f4d915aac51bc5d985a8dc9d8348989d42cec8599d4cdf75adc47 -size 40051 +oid sha256:a702d41d5005141962ad11a235ecb3f13398ef0b3c9630de3003610d8a600e62 +size 12861 diff --git a/Content/Blueprints/DefaultClass.uasset b/Content/Blueprints/DefaultClass.uasset deleted file mode 100644 index e1a4511..0000000 --- a/Content/Blueprints/DefaultClass.uasset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e8a0c4c04da4fc8856f04a18c5f5a97ec2d366bd739d928d1a2f43fd9dd9831 -size 12732 diff --git a/Content/Blueprints/UI/NameBar_UI/NameBar_UI.uasset b/Content/Blueprints/UI/NameBar_UI/NameBar_UI.uasset index 49ee2d1..bbe456e 100644 --- a/Content/Blueprints/UI/NameBar_UI/NameBar_UI.uasset +++ b/Content/Blueprints/UI/NameBar_UI/NameBar_UI.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0aa427e46f1151c85266dcc8175c349f2dba4971635ebb051b051005b61840bb -size 78485 +oid sha256:95ff3173214888843cc310bd0246f36ee5c3e72356588bc16792ec06b01ae6c8 +size 81747 diff --git a/Content/Character/Lb/BP_Lb.uasset b/Content/Character/Lb/BP_Lb.uasset index bc43cbc..1b62c08 100644 --- a/Content/Character/Lb/BP_Lb.uasset +++ b/Content/Character/Lb/BP_Lb.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fa93d860707521412a2f3a6b3fee76d97c58f0156f0ee975a75e8dfab645e08 -size 265764 +oid sha256:16d4e7f5452d5488c98bc4e94b56349548b16a61f01ce0c00368e5995140de27 +size 252367 diff --git a/Content/Character/Lb/BaseArrow.uasset b/Content/Character/Lb/BaseArrow.uasset index 52cfa4f..3a2827a 100644 --- a/Content/Character/Lb/BaseArrow.uasset +++ b/Content/Character/Lb/BaseArrow.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:96e1888de2d20e53511527fb610e55c59b40f61a3aa4a9bea218147626e753e8 -size 109007 +oid sha256:ea4d2c8a04a158e685627b6e63d8fa7313be56de4843f685a712a220455f0abe +size 91881 diff --git a/Content/Character/Monster/Knight/BP_Knignt.uasset b/Content/Character/Monster/Knight/BP_Knignt.uasset index 346b2dd..6714f7f 100644 --- a/Content/Character/Monster/Knight/BP_Knignt.uasset +++ b/Content/Character/Monster/Knight/BP_Knignt.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:25322dfc3f4a1072aa4244c6c2d45efd6c15b12d19abdbc720f1acc7525b5b36 -size 63703 +oid sha256:029169f9c794e0c6869f700a7635795faa0c50a018589e8e534d2b5a76ba83eb +size 65976 diff --git a/Content/Effect/AliumQ/Knife1.uasset b/Content/Effect/AliumQ/Knife1.uasset new file mode 100644 index 0000000..cd7de68 --- /dev/null +++ b/Content/Effect/AliumQ/Knife1.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:61e889e853480031a870a8627a4d6c4de77a541dda93b39aae022befbd2801db +size 295484 diff --git a/Content/Effect/CC.uasset b/Content/Effect/CC.uasset new file mode 100644 index 0000000..b034c8b --- /dev/null +++ b/Content/Effect/CC.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8e1f53ef1caf6952425675f5a542af654a8f61eb5aba7c18da678c6799a74fec +size 73954 diff --git a/Content/Effect/dust.uasset b/Content/Effect/dust.uasset new file mode 100644 index 0000000..72b4cf0 --- /dev/null +++ b/Content/Effect/dust.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce231ed8a4ee66c55e32527d3b35b9c75e7617f1d349a9ad72737b33ea36c99d +size 47039 diff --git a/Content/Effect/tnt.uasset b/Content/Effect/tnt.uasset new file mode 100644 index 0000000..08fabdb --- /dev/null +++ b/Content/Effect/tnt.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f509cf5e1734fb8eb06305bf48506f5e7ee993ce3663071c57c1cf3294081777 +size 20120 diff --git a/Content/Maps/DevMap.umap b/Content/Maps/DevMap.umap index 952e43e..a5d345e 100644 --- a/Content/Maps/DevMap.umap +++ b/Content/Maps/DevMap.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:255fdaf829cf0a99ff91e2261f5f1f2a57dbb538ffac5acdcc7d58de9eb0d76b -size 179055 +oid sha256:2c428dbf2880f96f770e8809675a3cd8b28f1106e572dc4d6db45061e46fccc1 +size 179947 diff --git a/Source/Promether/Private/DamageType/ApDamage.cpp b/Source/Promether/DamageType/APDamage.cpp similarity index 71% rename from Source/Promether/Private/DamageType/ApDamage.cpp rename to Source/Promether/DamageType/APDamage.cpp index 186bc18..7029a18 100644 --- a/Source/Promether/Private/DamageType/ApDamage.cpp +++ b/Source/Promether/DamageType/APDamage.cpp @@ -1,5 +1,5 @@ // Fill out your copyright notice in the Description page of Project Settings. -#include "DamageType/ApDamage.h" +#include "APDamage.h" diff --git a/Source/Promether/Public/DamageType/ApDamage.h b/Source/Promether/DamageType/APDamage.h similarity index 71% rename from Source/Promether/Public/DamageType/ApDamage.h rename to Source/Promether/DamageType/APDamage.h index b8a6718..81ed8f7 100644 --- a/Source/Promether/Public/DamageType/ApDamage.h +++ b/Source/Promether/DamageType/APDamage.h @@ -4,13 +4,13 @@ #include "CoreMinimal.h" #include "GameFramework/DamageType.h" -#include "ApDamage.generated.h" +#include "APDamage.generated.h" /** * */ UCLASS() -class PROMETHER_API UApDamage : public UDamageType +class PROMETHER_API UAPDamage : public UDamageType { GENERATED_BODY() diff --git a/Source/Promether/DamageType/HomingAttack.cpp b/Source/Promether/DamageType/HomingAttack.cpp new file mode 100644 index 0000000..9948809 --- /dev/null +++ b/Source/Promether/DamageType/HomingAttack.cpp @@ -0,0 +1,45 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "HomingAttack.h" +#include "../PlayerGeneric/DefaultPlayerCharacter.h" +#include "../PlayerGeneric/DefaultPlayerState.h" +#include "Kismet/KismetMathLibrary.h" + +// Sets default values +AHomingAttack::AHomingAttack() +{ + // 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; + ProjectileMovement = CreateDefaultSubobject(TEXT("ProjectileMovement")); + ProjectileMovement->InitialSpeed = 200; + ProjectileMovement->MaxSpeed = 200; + ProjectileMovement->ProjectileGravityScale = 0; + ProjectileMovement->bIsHomingProjectile = true; + ProjectileMovement->HomingAccelerationMagnitude = 200; + ProjectileMovement->Velocity = { 0, 0, 0 }; + ProjectileMovement->bRotationFollowsVelocity = true; +} + +// Called when the game starts or when spawned +void AHomingAttack::BeginPlay() +{ + Super::BeginPlay(); + + ADefaultPlayerState* State = Cast(GetOwner())->GetPlayerState(); + if (!State) return; + if (!State->GetCurrentAttackTarget()) + { + UE_LOG(LogTemp, Error, TEXT("No Target")); + return; + } + + ProjectileMovement->HomingTargetComponent = State->GetCurrentAttackTarget()->GetRootComponent(); +} + +// Called every frame +void AHomingAttack::Tick(float DeltaTime) +{ + Super::Tick(DeltaTime); +} + diff --git a/Source/Promether/DamageType/HomingAttack.h b/Source/Promether/DamageType/HomingAttack.h new file mode 100644 index 0000000..c9f0d07 --- /dev/null +++ b/Source/Promether/DamageType/HomingAttack.h @@ -0,0 +1,30 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "GameFramework/Actor.h" +#include "GameFramework/ProjectileMovementComponent.h" +#include "HomingAttack.generated.h" + +UCLASS() +class PROMETHER_API AHomingAttack : public AActor +{ + GENERATED_BODY() + +public: + // Sets default values for this actor's properties + AHomingAttack(); + +protected: + // Called when the game starts or when spawned + virtual void BeginPlay() override; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + UProjectileMovementComponent* ProjectileMovement; + +public: + // Called every frame + virtual void Tick(float DeltaTime) override; + +}; diff --git a/Source/Promether/DefaultAIController.cpp b/Source/Promether/DefaultAIController.cpp new file mode 100644 index 0000000..5f680d8 --- /dev/null +++ b/Source/Promether/DefaultAIController.cpp @@ -0,0 +1,33 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "DefaultAIController.h" +#include "PlayerGeneric/DefaultPlayerState.h" +#include "PlayerGeneric/DefaultPlayerCharacter.h" + +ADefaultAIController::ADefaultAIController() +{ + bWantsPlayerState = true; +} + +void ADefaultAIController::OnPossess(APawn* aPawn) +{ + //debug + FString MyName = aPawn->GetName(); + + ADefaultPlayerState* MyPlayerState = GetPlayerState(); + if (!MyPlayerState) return; + + ADefaultPlayerCharacter* ControlledPawn = Cast(aPawn); + if (!ControlledPawn) return; + + ControlledPawn->SetPlayerState(MyPlayerState); + + TArray DefaultStatsValue; + TArray CooldownDurationValue; + + ControlledPawn->DefaultStats.GenerateValueArray(DefaultStatsValue); + ControlledPawn->CooldownDuration.GenerateValueArray(CooldownDurationValue); + + MyPlayerState->InitPlayerStats(DefaultStatsValue, CooldownDurationValue); +} \ No newline at end of file diff --git a/Source/Promether/DefaultAIController.h b/Source/Promether/DefaultAIController.h new file mode 100644 index 0000000..96b9d01 --- /dev/null +++ b/Source/Promether/DefaultAIController.h @@ -0,0 +1,21 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "AIController.h" +#include "DefaultAIController.generated.h" + +/** + * + */ +UCLASS() +class PROMETHER_API ADefaultAIController : public AAIController +{ + GENERATED_BODY() + +public: + ADefaultAIController(); + void OnPossess(APawn* aPawn) override; + +}; diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.cpp b/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.cpp index d77f526..b29cbfa 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.cpp +++ b/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.cpp @@ -3,8 +3,10 @@ #include "DefaultPlayerCharacter.h" #include "DefaultPlayerState.h" +#include "../DefaultAIController.h" #include "Engine/DamageEvents.h" #include "Kismet/GameplayStatics.h" +#include "Components/CapsuleComponent.h" ADefaultPlayerCharacter::ADefaultPlayerCharacter() { @@ -13,6 +15,9 @@ ADefaultPlayerCharacter::ADefaultPlayerCharacter() SetCanBeDamaged(true); bUseControllerRotationYaw = false; + AIControllerClass = ADefaultAIController::StaticClass(); + AutoPossessAI = EAutoPossessAI::PlacedInWorldOrSpawned; + CameraSpringArm = CreateDefaultSubobject(TEXT("SpringArm")); CameraSpringArm->SetRelativeLocationAndRotation(FVector(0.0f, 0.0f, 0.0f), FRotator(-45.0f, 0.0f, 0.0f)); CameraSpringArm->SetAbsolute(false, true, true); @@ -49,14 +54,13 @@ void ADefaultPlayerCharacter::Tick(float DeltaTime) */ } - - void ADefaultPlayerCharacter::Attack_Implementation() { - NetMulticast_Attack(); + Client_Attack(); + BP_Attack(); } -void ADefaultPlayerCharacter::NetMulticast_Attack_Implementation() +void ADefaultPlayerCharacter::Client_Attack_Implementation() { BP_Attack(); } @@ -65,68 +69,62 @@ float ADefaultPlayerCharacter::TakeDamage_Implementation(float DamageAmount, str { float ReturnValue = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser); - if (HasAuthority()) + ADefaultPlayerState* State = GetPlayerState(); + if (!State) return ReturnValue; + + if (!Cast(DamageCauser)) return ReturnValue; + + ADefaultPlayerState* AttackerState = Cast(DamageCauser)->GetPlayerState(); + if (!AttackerState) return ReturnValue; + + float ADDamageMultiplier = 0; + float APDamageMultiplier = 0; + + if (State->Stats[(uint8)EStats::Armor] >= 0) + ADDamageMultiplier = 100 / (100 + State->Stats[(uint8)EStats::Armor]); + else + ADDamageMultiplier = 2 - 100 / (100 - State->Stats[(uint8)EStats::Armor]); + + if (State->Stats[(uint8)EStats::MagicResistance] >= 0) + APDamageMultiplier = 100 / (100 + State->Stats[(uint8)EStats::MagicResistance]); + else + APDamageMultiplier = 2 - 100 / (100 - State->Stats[(uint8)EStats::MagicResistance]); + + + UE_LOG(LogTemp, Warning, TEXT("%s : ADDamageMultiplier : %f CalculatedDamage : %f"), *DamageCauser->GetName(), ADDamageMultiplier, DamageAmount * ADDamageMultiplier); + UE_LOG(LogTemp, Warning, TEXT("%s : APDamageMultiplier : %f CalculatedDamage : %f"), *DamageCauser->GetName(), APDamageMultiplier, DamageAmount * APDamageMultiplier); + + float UpdatedHealth = 0; + + if (Cast(DamageEvent.DamageTypeClass->GetDefaultObject())) { - UE_LOG(LogTemp, Warning, TEXT("TakeDamage Called On Server")); + UE_LOG(LogTemp, Warning, TEXT("DamageType : BaseAttack")); + + UpdatedHealth = State->Stats[(uint8)EStats::Health] - AttackerState->Stats[(uint8)EStats::AttackDamage] * ADDamageMultiplier; + } + else if (Cast(DamageEvent.DamageTypeClass->GetDefaultObject())) + { + UE_LOG(LogTemp, Warning, TEXT("DamageType : APDamage")); + + UpdatedHealth = State->Stats[(uint8)EStats::Health] - AttackerState->Stats[(uint8)EStats::AbilityPower] * APDamageMultiplier; + } + + if (UpdatedHealth < 0 || UpdatedHealth < 0.1 ) + { + State->Stats[(uint8)EStats::Health] = 0; + Server_PerformDead(); + Client_PerformDead(); } else { - UE_LOG(LogTemp, Warning, TEXT("TakeDamage Called On Client")); + State->Stats[(uint8)EStats::Health] = UpdatedHealth; } - if (HasAuthority()) - { - if (ADefaultPlayerState* MyState = this->GetInstigatorController()->GetPlayerState()) - { - if (ADefaultPlayerState* EventInstigatorState = EventInstigator->GetPlayerState()) - { - float ADDamageMultiplier = 0; - float APDamageMultiplier = 0; + UE_LOG(LogTemp, Warning, TEXT("Current Health : %f"), State->Stats[(uint8)EStats::Health]); - if (MyState->Stats[(uint8)EStats::Armor] >= 0) - ADDamageMultiplier = 100 / (100 + MyState->Stats[(uint8)EStats::Armor]); - else - ADDamageMultiplier = 2 - 100 / (100 - MyState->Stats[(uint8)EStats::Armor]); - - if (MyState->Stats[(uint8)EStats::MagicResistance] >= 0) - APDamageMultiplier = 100 / (100 + MyState->Stats[(uint8)EStats::MagicResistance]); - else - APDamageMultiplier = 2 - 100 / (100 - MyState->Stats[(uint8)EStats::MagicResistance]); - - - UE_LOG(LogTemp, Warning, TEXT("%s : ADDamageMultiplier : %f CalculatedDamage : %f"), *DamageCauser->GetName(), ADDamageMultiplier, DamageAmount * ADDamageMultiplier); - UE_LOG(LogTemp, Warning, TEXT("%s : APDamageMultiplier : %f CalculatedDamage : %f"), *DamageCauser->GetName(), APDamageMultiplier, DamageAmount * APDamageMultiplier); - - if (Cast(DamageEvent.DamageTypeClass->GetDefaultObject())) - { - UE_LOG(LogTemp, Warning, TEXT("DamageType : BaseAttack")); - - float UpdatedHealth = MyState->Stats[(uint8)EStats::Health] - EventInstigatorState->Stats[(uint8)EStats::AttackDamage] * ADDamageMultiplier; - if (UpdatedHealth < 0) - { - MyState->Stats[(uint8)EStats::Health] = 0; - } - else - { - MyState->Stats[(uint8)EStats::Health] = UpdatedHealth; - } - - UE_LOG(LogTemp, Warning, TEXT("Current Health : %f"), MyState->Stats[(uint8)EStats::Health]); - } - - } - } - - return ReturnValue; - } - else - { - return -1.0f; - } + return ReturnValue; } - - void ADefaultPlayerCharacter::Skill1_Implementation() { NetMulticast_Skill1(); @@ -206,3 +204,23 @@ void ADefaultPlayerCharacter::NetMulticast_Skill7_Implementation() { BP_Skill7(); } + +void ADefaultPlayerCharacter::PerformDead() +{ + ADefaultPlayerState* State = GetPlayerState(); + if (!State) return; + + State->SetState(ECharacterState::Dead); + GetCapsuleComponent()->SetGenerateOverlapEvents(false); + GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision); +} + +void ADefaultPlayerCharacter::Server_PerformDead_Implementation() +{ + PerformDead(); +} + +void ADefaultPlayerCharacter::Client_PerformDead_Implementation() +{ + PerformDead(); +} diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.h b/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.h index 0aac52a..b5773d2 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.h +++ b/Source/Promether/PlayerGeneric/DefaultPlayerCharacter.h @@ -22,12 +22,13 @@ public: virtual void Tick(float DeltaTime) override; UFUNCTION(BlueprintCallable, Server, Reliable) - void Attack(); + void Attack(); //Override me UFUNCTION(BlueprintImplementableEvent) - void BP_Attack(); - UFUNCTION(NetMulticast, Reliable) - void NetMulticast_Attack(); + void BP_Attack(); + UFUNCTION(Client, Reliable) + void Client_Attack(); + UFUNCTION(BlueprintNativeEvent) float TakeDamage( float Damage, struct FDamageEvent const& DamageEvent, @@ -35,7 +36,13 @@ public: AActor* DamageCauser ) override; + void PerformDead(); + UFUNCTION(Client, Reliable) + void Client_PerformDead(); + + UFUNCTION(Server, Reliable) + void Server_PerformDead(); UFUNCTION(BlueprintCallable, Server, Reliable) diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerController.cpp b/Source/Promether/PlayerGeneric/DefaultPlayerController.cpp index 0cc4b57..a5c9f98 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerController.cpp +++ b/Source/Promether/PlayerGeneric/DefaultPlayerController.cpp @@ -105,7 +105,7 @@ void ADefaultPlayerController::Server_SpawnPlayerCamera_Implementation() void ADefaultPlayerController::SetACharacterOutlineColor(ACharacter* Target, bool Visible) { - if (HasAuthority()) return; + if (!Target) return; ADefaultPlayerState* State = Target->GetPlayerState(); if (!State) @@ -405,47 +405,50 @@ void ADefaultPlayerController::Bomb() void ADefaultPlayerController::ObjectSelect() { + ADefaultPlayerState* State = GetPlayerState(); + if (!State) return; + FHitResult HitResult; TArray> ObjectTypes; - ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldStatic)); ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn)); GetHitResultUnderCursorForObjects(ObjectTypes, true, HitResult); ACharacter* HitObject = Cast(HitResult.GetActor()); - if (!HitObject) return; - UE_LOG(LogTemp, Warning, TEXT("%s"), *HitObject->GetName()); - SetACharacterOutlineColor(HitObject, true); + if (!HitObject) + { + SetACharacterOutlineColor(Cast(State->GetPreviousAttackTarget()), false); + State->SetPreviousAttackTarget(nullptr); + State->SetCurrentAttackTarget(nullptr); + return; + } + + if (State->GetPreviousAttackTarget() != HitResult.GetActor()) + { + SetACharacterOutlineColor(Cast(State->GetPreviousAttackTarget()), false); + + State->SetPreviousAttackTarget(HitResult.GetActor()); + State->SetCurrentAttackTarget(HitResult.GetActor()); + + SetACharacterOutlineColor(HitObject, true); + } + + UE_LOG(LogTemp, Warning, TEXT("%s"), *State->GetCurrentAttackTarget()->GetName()); + + FString Name = HitResult.GetActor()->GetName(); + APlayerState* TargetState = Cast(HitResult.GetActor())->GetPlayerState(); } - void ADefaultPlayerController::Move() { EndAttack(); - FHitResult HitResult; - TArray> ObjectTypes; - ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldStatic)); - ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn)); - - GetHitResultUnderCursorForObjects(ObjectTypes, true, HitResult); - ACharacter* HitCharacter = Cast(HitResult.GetActor()); //¿ÀºêÁ§Æ®¸¦ °¡Á®¿Í HitCharactor¿¡ ÀúÀå<<ÃßÈÄ Àû ij¸¯ÅÍÀ϶§¸¸ ÀúÀåÀ¸·Î º¯°æÇؾßÇÔ - HitTarget = HitResult.GetActor(); - - UE_LOG(LogTemp, Warning, TEXT("%s"), *HitResult.GetActor()->GetName()); - - if (HitResult.GetActor() != GetPawn()) //Áö±ÝÀº HitObject°¡ nullÀÌ ¾Æ´Ò °æ¿ì Attack()À» ½ÇÇàÇÏ´Â ÄÚµåÁö¸¸, HitObject°¡ Àû ij¸¯ÅÍÀÏ ¶§ ½ÇÇàÀ¸·Î º¯°æÇؾßÇÔ + ObjectSelect(); + + if (GetPlayerState()->GetCurrentAttackTarget() != GetPawn() && + Cast(GetPlayerState()->GetCurrentAttackTarget())) //º»ÀÎÀÌ ¾Æ´Ï°í °ø°ÝÀÌ °¡´ÉÇÑ ´ë»ó(ÀûÀÌµç ¾Æ±ºÀ̵ç)ÀÏ ¶§ { - if (!GetPlayerState()->Stats[(uint8)EStats::Attackable] == 0) - return; - if (!HitCharacter) - { - FVector Destination = GetMouseHitLocation(); - GetPlayerState()->SetState(ECharacterState::Moving); - SimpleMoveToLocation(this, Destination); - this->MoveToLocation(Destination); - return; - } + if (!GetPlayerState()->Stats[(uint8)EStats::Attackable] == 0) return; BeginAttack(); //HitObject¸¦ ´ë»óÀ¸·Î BeginAttack ½ÇÇà } else @@ -500,7 +503,10 @@ void ADefaultPlayerController::Multicast_StopMove_Implementation() FVector ADefaultPlayerController::GetMouseHitLocation() { FHitResult HitResult; - GetHitResultUnderCursor(ECollisionChannel::ECC_Visibility, true, HitResult); + TArray> ObjectTypes; + ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldStatic)); + + GetHitResultUnderCursorForObjects(ObjectTypes, true, HitResult); HitResult.Location.Z = 0; //UE_LOG(LogTemp, Warning, TEXT("Client%d MoveTo : (%f, %f)"), GPlayInEditorID, HitResult.Location.X, HitResult.Location.Y); @@ -629,39 +635,36 @@ void ADefaultPlayerController::OnMoveCompleted(FAIRequestID RequestID, const FPa GetPlayerState()->SetState(ECharacterState::Idle); } -FTimerHandle TimerHandle; - void ADefaultPlayerController::BeginAttack() { - GetWorldTimerManager().SetTimer(TimerHandle, this, &ADefaultPlayerController::RepeatedAttack, 0.1f, true); + GetWorldTimerManager().SetTimer(TimerHandle, this, &ADefaultPlayerController::RepeatedAttack, 0.1f, true); } void ADefaultPlayerController::EndAttack() { - GetWorldTimerManager().ClearTimer(TimerHandle); } void ADefaultPlayerController::RepeatedAttack() { - if (!GetPlayerState()->Stats[(uint8)EStats::Attackable] == 0) - return; Attack(); } - - void ADefaultPlayerController::Attack() { - + if (!GetPlayerState()->Stats[(uint8)EStats::Attackable] == 0) + return; + float MinDistance = GetPlayerState()->Stats[(uint8)EStats:: AttackRange]; - FVector Destination = HitTarget->GetActorLocation(); // HitObjectÀÇ À§Ä¡¸¦ ¸ñÀûÁö·Î ¼³Á¤ + + if (!GetPlayerState()->GetCurrentAttackTarget()) return; + + FVector Destination = GetPlayerState()->GetCurrentAttackTarget()->GetActorLocation(); // HitObjectÀÇ À§Ä¡¸¦ ¸ñÀûÁö·Î ¼³Á¤ if (FVector::Dist(Destination, GetPawn()->GetActorLocation()) <= MinDistance) { if ((GetPlayerState()->CooldownDuration[(uint8)CooldownType::Attack] != 0)) return; - FVector Location = GetPawn()->GetActorLocation(); Location.X = 0; @@ -671,7 +674,6 @@ void ADefaultPlayerController::Attack() Multicast_SetRotation(Destination); Server_SetRotation(Destination); - UE_LOG(LogTemp, Warning, TEXT("Attack")); GetPlayerState()->SetState(ECharacterState::Attack); @@ -681,12 +683,8 @@ void ADefaultPlayerController::Attack() { GetPlayerState()->SetState(ECharacterState::Moving); SimpleMoveToLocation(this, Destination); - - - this->MoveToLocation(Destination); } - SetTarget(); } void ADefaultPlayerController::MoveToLocation_Implementation(FVector Location) diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerController.h b/Source/Promether/PlayerGeneric/DefaultPlayerController.h index eb66315..711ffdd 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerController.h +++ b/Source/Promether/PlayerGeneric/DefaultPlayerController.h @@ -77,9 +77,7 @@ public: UPROPERTY(BlueprintReadWrite) float MouseClickInterval; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Actor") - AActor* HitTarget; - + FTimerHandle TimerHandle; private: UPROPERTY(EditAnywhere, Category = "Input") diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp b/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp index 1159af6..2ab440b 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp +++ b/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp @@ -22,8 +22,10 @@ void ADefaultPlayerState::GetLifetimeReplicatedProps(TArray& DOREPLIFETIME(ADefaultPlayerState, State); DOREPLIFETIME(ADefaultPlayerState, AttackType); - //DOREPLIFETIME(ADefaultPlayerState, StatusEffectObject); DOREPLIFETIME(ADefaultPlayerState, PlayerCamera); + + DOREPLIFETIME(ADefaultPlayerState, CurrentAttackTarget); + DOREPLIFETIME(ADefaultPlayerState, PreviousAttackTarget); } void ADefaultPlayerState::InitPlayerStats_Implementation(const TArray& StatsValue, const TArray& CooldownDurationValue) @@ -33,7 +35,6 @@ void ADefaultPlayerState::InitPlayerStats_Implementation(const TArray& St CooldownDuration.Append(CooldownDurationValue); MaxCooldownDuration.Append(CooldownDurationValue); - for (float Value : StatsValue) { UE_LOG(LogTemp, Warning, TEXT("Values: %f"), Value); @@ -64,3 +65,35 @@ int32 ADefaultPlayerState::GetCharacterLevel() const { return int32(); } + +void ADefaultPlayerState::SetCurrentAttackTarget(AActor* Target) +{ + Server_SetCurrentAttackTarget(Target); + Client_SetCurrentAttackTarget(Target); +} + +void ADefaultPlayerState::Server_SetCurrentAttackTarget_Implementation(AActor* Target) +{ + CurrentAttackTarget = Target; +} + +void ADefaultPlayerState::Client_SetCurrentAttackTarget_Implementation(AActor* Target) +{ + CurrentAttackTarget = Target; +} + +void ADefaultPlayerState::SetPreviousAttackTarget(AActor* Target) +{ + Server_SetPreviousAttackTarget(Target); + Client_SetPreviousAttackTarget(Target); +} + +void ADefaultPlayerState::Server_SetPreviousAttackTarget_Implementation(AActor* Target) +{ + PreviousAttackTarget = Target; +} + +void ADefaultPlayerState::Client_SetPreviousAttackTarget_Implementation(AActor* Target) +{ + PreviousAttackTarget = Target; +} diff --git a/Source/Promether/PlayerGeneric/DefaultPlayerState.h b/Source/Promether/PlayerGeneric/DefaultPlayerState.h index 117cc17..a37ea68 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerState.h +++ b/Source/Promether/PlayerGeneric/DefaultPlayerState.h @@ -62,6 +62,23 @@ public: UFUNCTION(BlueprintCallable) int32 GetCharacterLevel() const; + + UFUNCTION(BlueprintCallable) + AActor* GetCurrentAttackTarget() const { return CurrentAttackTarget; }; + UFUNCTION(BlueprintCallable) + AActor* GetPreviousAttackTarget() const { return PreviousAttackTarget; }; + + void SetCurrentAttackTarget(AActor* Target); + UFUNCTION(Server, Reliable) + void Server_SetCurrentAttackTarget(AActor* Target); + UFUNCTION(Client, Reliable) + void Client_SetCurrentAttackTarget(AActor* Target); + + void SetPreviousAttackTarget(AActor* Target); + UFUNCTION(Server, Reliable) + void Server_SetPreviousAttackTarget(AActor* Target); + UFUNCTION(Client, Reliable) + void Client_SetPreviousAttackTarget(AActor* Target); UPROPERTY(Replicated, Transient, EditAnywhere, BlueprintReadWrite) TArray Stats; @@ -73,6 +90,7 @@ public: UPROPERTY(Replicated, Transient, BlueprintReadWrite) TArray MaxCooldownDuration; + private: UPROPERTY(Replicated, Transient) UClass* CharacterBPRef; @@ -84,9 +102,11 @@ private: UPROPERTY(Replicated, Transient) CooldownType AttackType; - //UPROPERTY(Replicated, Transient) - //TMap StatusEffectObject; - UPROPERTY(Replicated, Transient) AActor* PlayerCamera; + + UPROPERTY(Replicated, Transient) + AActor* CurrentAttackTarget; + UPROPERTY(Replicated, Transient) + AActor* PreviousAttackTarget; }; diff --git a/Source/Promether/PrometherEnum.h b/Source/Promether/PrometherEnum.h index 610758b..4fa82db 100644 --- a/Source/Promether/PrometherEnum.h +++ b/Source/Promether/PrometherEnum.h @@ -2,6 +2,7 @@ #include "CoreMinimal.h" #include "DamageType/BaseAttack.h" +#include "DamageType/APDamage.h" UENUM(BlueprintType) enum class CharacterType : uint8