diff --git a/Config/Game/Hero1_Attributes.csv b/Config/Game/Hero1_Attributes.csv index 991383f..5bfe2f1 100644 --- a/Config/Game/Hero1_Attributes.csv +++ b/Config/Game/Hero1_Attributes.csv @@ -1,3 +1,6 @@ ---,1.000000 MaxStamina,1000.000000 -StaminaRegen,10.000000 +StaminaRegen,2.000000 +MaxHealth,1000.000000 +HealthRegen,0.100000 +BaseDamage,100.000000 diff --git a/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset b/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset index d0a59fa..f6d90ba 100644 Binary files a/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset and b/Content/Characters/Hero1/Attributes/CT_Hero1_Attributes.uasset differ diff --git a/Content/__ExternalActors__/Maps/L_Default/E/HA/CXMK7W9FIGA0C2MR0GYXOO.uasset b/Content/__ExternalActors__/Maps/L_Default/E/HA/CXMK7W9FIGA0C2MR0GYXOO.uasset index c0417af..f3d86f0 100644 Binary files a/Content/__ExternalActors__/Maps/L_Default/E/HA/CXMK7W9FIGA0C2MR0GYXOO.uasset and b/Content/__ExternalActors__/Maps/L_Default/E/HA/CXMK7W9FIGA0C2MR0GYXOO.uasset differ diff --git a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp index ecb5bdb..a28eeae 100644 --- a/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp +++ b/Plugins/CogAbility/Source/CogAbility/Private/CogAbilityWindow_Cheats.cpp @@ -98,13 +98,22 @@ void FCogAbilityWindow_Cheats::TryReapplyCheats() TArray Targets { LocalPawn }; - for (const FString& AppliedCheatName : Config->AppliedCheats) + for (int32 i = Config->AppliedCheats.Num() - 1; i >= 0; i--) { + const FString& AppliedCheatName = Config->AppliedCheats[i]; + if (const FCogAbilityCheat* Cheat = Asset->PersistentEffects.FindByPredicate( [AppliedCheatName](const FCogAbilityCheat& Cheat) { return Cheat.Name == AppliedCheatName; })) { Replicator->ApplyCheat(LocalPawn, Targets, *Cheat); } + else + { + //----------------------------------------------------- + // This cheat doesn't exist anymore. We can remove it. + //----------------------------------------------------- + Config->AppliedCheats.RemoveAt(i); + } } bHasReappliedCheats = true; @@ -166,30 +175,33 @@ void FCogAbilityWindow_Cheats::RenderContent() ImGui::TableNextRow(); ImGui::TableNextColumn(); - bool bHasChanged = false; int Index = 0; for (const FCogAbilityCheat& CheatEffect : Asset->PersistentEffects) { ImGui::PushID(Index); - bHasChanged |= AddCheat(ControlledActor, SelectedActor, CheatEffect, true); + AddCheat(ControlledActor, SelectedActor, CheatEffect, true); ImGui::PopID(); Index++; } - //---------------------------------------------------------------- - // When a persistent cheat has been changed, update the applied - // cheats string array to be saved in the config later - //---------------------------------------------------------------- - if (bHasChanged && SelectedActor == ControlledActor) + //---------------------------------------------------------------------------- + // Update the config of applied cheat to reapply them on the next launch. + // We do not updated them only when the the user input is pressed because + // the state of the cheat is lagging when connected to a server. + // So we check if the array should be updated all the time. + //---------------------------------------------------------------------------- + if (SelectedActor == ControlledActor) { - Config->AppliedCheats.Empty(); - for (const FCogAbilityCheat& CheatEffect : Asset->PersistentEffects) { if (ACogAbilityReplicator::IsCheatActive(SelectedActor, CheatEffect)) { - Config->AppliedCheats.Add(CheatEffect.Name); + Config->AppliedCheats.AddUnique(CheatEffect.Name); + } + else + { + Config->AppliedCheats.Remove(CheatEffect.Name); } } } diff --git a/Source/CogSample/CogSamplePlayerController.cpp b/Source/CogSample/CogSamplePlayerController.cpp index 6f46c35..c5e3eb1 100644 --- a/Source/CogSample/CogSamplePlayerController.cpp +++ b/Source/CogSample/CogSamplePlayerController.cpp @@ -4,6 +4,7 @@ #include "CogSampleDefines.h" #include "CogSampleCharacter.h" #include "CogSampleLogCategories.h" +#include "CogSampleProjectileComponent.h" #include "CogSampleTargetAcquisition.h" #include "GameFramework/PlayerState.h" #include "Net/UnrealNetwork.h" @@ -205,7 +206,14 @@ void ACogSamplePlayerController::Server_SetTarget_Implementation(AActor* Value) } //-------------------------------------------------------------------------------------------------------------------------- -const ACogSamplePlayerController* ACogSamplePlayerController::GetFirstLocalPlayerController(UObject* WorldContextObject) +const ACogSamplePlayerController* ACogSamplePlayerController::GetFirstLocalPlayerControllerConst(UObject* WorldContextObject) +{ + const ACogSamplePlayerController* PlayerController = GetFirstLocalPlayerController(WorldContextObject); + return PlayerController; +} + +//-------------------------------------------------------------------------------------------------------------------------- +ACogSamplePlayerController* ACogSamplePlayerController::GetFirstLocalPlayerController(UObject* WorldContextObject) { UWorld* const World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull); if (World == nullptr) @@ -231,3 +239,11 @@ float ACogSamplePlayerController::GetClientLag() const return HalfPingInSeconds; } +//-------------------------------------------------------------------------------------------------------------------------- +void ACogSamplePlayerController::Server_ProjectileHit_Implementation(UCogSampleProjectileComponent* Projectile, const FHitResult& HitResult) +{ + if (Projectile != nullptr) + { + Projectile->Server_Hit(HitResult); + } +} \ No newline at end of file diff --git a/Source/CogSample/CogSamplePlayerController.h b/Source/CogSample/CogSamplePlayerController.h index a4be124..b6f54a4 100644 --- a/Source/CogSample/CogSamplePlayerController.h +++ b/Source/CogSample/CogSamplePlayerController.h @@ -25,7 +25,9 @@ class ACogSamplePlayerController public: - static const ACogSamplePlayerController* GetFirstLocalPlayerController(UObject* WorldContextObject); + static const ACogSamplePlayerController* GetFirstLocalPlayerControllerConst(UObject* WorldContextObject); + + static ACogSamplePlayerController* GetFirstLocalPlayerController(UObject* WorldContextObject); ACogSamplePlayerController(); @@ -67,6 +69,12 @@ public: UPROPERTY() TArray SpawnPredictions; + //---------------------------------------------------------------------------------------------------------------------- + // Projectile Hit + //---------------------------------------------------------------------------------------------------------------------- + UFUNCTION(Reliable, Server) + void Server_ProjectileHit(UCogSampleProjectileComponent* Projectile, const FHitResult& HitResult); + private: //---------------------------------------------------------------------------------------------------------------------- diff --git a/Source/CogSample/CogSampleProjectileComponent.cpp b/Source/CogSample/CogSampleProjectileComponent.cpp index 7733684..5c21cb4 100644 --- a/Source/CogSample/CogSampleProjectileComponent.cpp +++ b/Source/CogSample/CogSampleProjectileComponent.cpp @@ -52,6 +52,8 @@ // // One client could be made responsible to detect hits received by a specific NPC. // +//-------------------------------------------------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------------------------------------------------- UCogSampleProjectileComponent::UCogSampleProjectileComponent(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) @@ -81,6 +83,7 @@ void UCogSampleProjectileComponent::BeginPlay() Creator = UCogSampleFunctionLibrary_Gameplay::GetCreator(GetOwner()); SpawnPrediction = GetOwner()->FindComponentByClass(); + LocalPlayerController = ACogSamplePlayerController::GetFirstLocalPlayerController(this); COG_LOG_OBJECT(LogCogProjectile, ELogVerbosity::Verbose, Creator.Get(), TEXT("Projectile:%s | Role:%s | IsActive:%d"), *GetNameSafe(GetOwner()), *GetRoleName(), IsActive()); @@ -107,6 +110,12 @@ void UCogSampleProjectileComponent::BeginPlay() } } +//-------------------------------------------------------------------------------------------------------------------------- +void UCogSampleProjectileComponent::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + Super::EndPlay(EndPlayReason); +} + //-------------------------------------------------------------------------------------------------------------------------- void UCogSampleProjectileComponent::Activate(bool bReset) { @@ -146,9 +155,9 @@ void UCogSampleProjectileComponent::Activate(bool bReset) //-------------------------------------------------------------------------- if (GetOwner()->GetLocalRole() != ROLE_Authority) { - if (const ACogSamplePlayerController* Controller = ACogSamplePlayerController::GetFirstLocalPlayerController(this)) + if (LocalPlayerController != nullptr) { - Catchup(Controller->GetClientLag()); + Catchup(LocalPlayerController->GetClientLag()); } } @@ -510,6 +519,13 @@ void UCogSampleProjectileComponent::Hit_Implementation(const FHitResult& HitResu DrawDebugHitResult(HitResult); #endif //ENABLE_COG + if (LocalPlayerController == nullptr) + { + return; + } + + LocalPlayerController->Server_ProjectileHit(this, HitResult); + Server_Hit(HitResult); } @@ -525,7 +541,7 @@ FString UCogSampleProjectileComponent::GetRoleName() const } //-------------------------------------------------------------------------------------------------------------------------- -void UCogSampleProjectileComponent::Server_Hit_Implementation(const FHitResult& HitResult) +void UCogSampleProjectileComponent::Server_Hit(const FHitResult& HitResult) { COG_LOG_OBJECT(LogCogProjectile, ELogVerbosity::Verbose, Creator.Get(), TEXT("Projectile:%s | Role:%s | Other:%s | Comp:%s | Bone:%s"), *GetNameSafe(GetOwner()), diff --git a/Source/CogSample/CogSampleProjectileComponent.h b/Source/CogSample/CogSampleProjectileComponent.h index c3a775b..587edc5 100644 --- a/Source/CogSample/CogSampleProjectileComponent.h +++ b/Source/CogSample/CogSampleProjectileComponent.h @@ -53,12 +53,15 @@ public: virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction); virtual void Activate(bool bReset) override; virtual void StopSimulating(const FHitResult& HitResult) override; + virtual void Server_Hit(const FHitResult& Hit); UFUNCTION(BlueprintCallable) void ClearHitActors(); @@ -79,8 +82,6 @@ protected: virtual void TryHit(const FHitResult& Hit); - UFUNCTION(Server, Reliable) - virtual void Server_Hit(const FHitResult& Hit); UFUNCTION() virtual void OnCollisionOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool IsFromSweep, const FHitResult& SweepHit); @@ -129,6 +130,9 @@ protected: UPROPERTY(Replicated) FVector ServerSpawnVelocity = FVector::ZeroVector; + UPROPERTY() + TWeakObjectPtr LocalPlayerController = nullptr; + /** Re-entrancy guard */ bool IsAlreadyProcessingAnOverlap = false;