diff --git a/Content/Blueprints/BP_DefaultPlayerCharacter.uasset b/Content/Blueprints/BP_DefaultPlayerCharacter.uasset index 058671a..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:a60e63bc838c1fd6ab5b6da880fe6f21e9ab4d182041e686aa0f127ae046c34b -size 155340 +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/Character/Lb/BaseArrow.uasset b/Content/Character/Lb/BaseArrow.uasset index a496143..c186582 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:c8beb8766ceef4bb5225c66ccd7b08e7580038c3d84b04787d7fe550a1f60133 -size 144276 +oid sha256:e5bc4ed8926ea90e98dc27a6bf0768f7f2f6dc4a344a85c132e6427331c979a3 +size 90927 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/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 3b4914f..ea57948 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) @@ -331,22 +331,22 @@ void ADefaultPlayerController::Skill3() void ADefaultPlayerController::Skill4Triggered() { - if (GetPlayerState()->Stats[(uint8)EStats::charging] == 1)//Â÷Áö°¡ 1(false)ÀÏ ¶§ + if (GetPlayerState()->Stats[(uint8)EStats::charging] == 1)//������ 1(false)�� �� { if (!GetPlayerState()->Stats[(uint8)EStats::Skillusable] == 0) return; if (!(GetPlayerState()->Stats[(uint8)EStats::Mana] >= GetPlayerState()->Stats[(uint8)EStats::Skill4Cost])) return; GetPlayerState()->Stats[(uint8)EStats::Mana] -= GetPlayerState()->Stats[(uint8)EStats::Skill4Cost]; - GetPlayerState()->Stats[(uint8)EStats::charging] = 0;// ¼öÄ¡¸¦ °è»êÇϰí charge¸¦ true(0)·Î º¯°æ + GetPlayerState()->Stats[(uint8)EStats::charging] = 0;// ��ġ�� ����ϰ� charge�� true(0)�� ���� } - else if (GetPlayerState()->Stats[(uint8)EStats::charging] == 2) //Â÷Áö°¡ 2(never)ÀÏ ¶§ + else if (GetPlayerState()->Stats[(uint8)EStats::charging] == 2) //������ 2(never)�� �� { if (!GetPlayerState()->Stats[(uint8)EStats::Skillusable] == 0) return; if (!(GetPlayerState()->Stats[(uint8)EStats::Mana] >= GetPlayerState()->Stats[(uint8)EStats::Skill4Cost])) return; - GetPlayerState()->Stats[(uint8)EStats::Mana] -= GetPlayerState()->Stats[(uint8)EStats::Skill4Cost]; // ±×³É ¼öÄ¡ °è»ê¸¸ ½ÇÇà + GetPlayerState()->Stats[(uint8)EStats::Mana] -= GetPlayerState()->Stats[(uint8)EStats::Skill4Cost]; // �׳� ��ġ ��길 ���� } EndAttack(); GetPlayerState()->Stats[(uint8)EStats::Attackable] = 1; @@ -405,48 +405,51 @@ 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] == 1) - return; - if (!HitCharacter) - { - FVector Destination = GetMouseHitLocation(); - GetPlayerState()->SetState(ECharacterState::Moving); - SimpleMoveToLocation(this, Destination); - this->MoveToLocation(Destination); - return; - } - BeginAttack(); //HitObject¸¦ ´ë»óÀ¸·Î BeginAttack ½ÇÇà + if (!GetPlayerState()->Stats[(uint8)EStats::Attackable] == 0) return; + BeginAttack(); //HitObject�� ������� BeginAttack ���� } else { @@ -467,7 +470,7 @@ void ADefaultPlayerController::Multicast_SetRotation_Implementation(FVector Mous FRotator NewRotation = (MouseHitLocation - Location).Rotation(); - // ¸¸¾à XÃàÀ» °íÁ¤ÇÏ°í ½Í´Ù¸é ¾Æ·¡¿Í °°ÀÌ ÇØ´ç °ªÀ» ¼³Á¤ÇÕ´Ï´Ù. + // ���� X���� �����ϰ� �ʹٸ� �Ʒ��� ���� �ش� ���� �����մϴ�. NewRotation.Pitch = 0; @@ -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..5e96ac2 100644 --- a/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp +++ b/Source/Promether/PlayerGeneric/DefaultPlayerState.cpp @@ -6,6 +6,8 @@ ADefaultPlayerState::ADefaultPlayerState() CharacterBPRef = nullptr;; Team = TeamType::Null; State = ECharacterState::Idle; + + NetUpdateFrequency = 100.0f; } void ADefaultPlayerState::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const @@ -22,8 +24,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 +37,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 +67,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 8b7f54e..acd408e 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