diff --git a/Content/Maps/BlasterMap.umap b/Content/Maps/BlasterMap.umap index ce5b2f6..6e1a06c 100644 Binary files a/Content/Maps/BlasterMap.umap and b/Content/Maps/BlasterMap.umap differ diff --git a/Source/Blaster/Components/LagCompensationComponent.cpp b/Source/Blaster/Components/LagCompensationComponent.cpp index 1fe8cbf..32c48b9 100644 --- a/Source/Blaster/Components/LagCompensationComponent.cpp +++ b/Source/Blaster/Components/LagCompensationComponent.cpp @@ -3,7 +3,9 @@ #include "LagCompensationComponent.h" +#include "Blaster/Weapon/Weapon.h" #include "Components/BoxComponent.h" +#include "Kismet/GameplayStatics.h" ULagCompensationComponent::ULagCompensationComponent() { @@ -16,6 +18,24 @@ void ULagCompensationComponent::BeginPlay() } +void ULagCompensationComponent::ServerScoreRequest_Implementation(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, + const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser) +{ + const FServerSideRewindResult Confirm = ServerSideRewind(HitCharacter, TraceStart, HitLocation, HitTime); + + if (Character && HitCharacter && DamageCauser && Confirm.bHitConfirmed) + { + + UGameplayStatics::ApplyDamage( + HitCharacter, + DamageCauser->GetDamage(), + Character->Controller, + DamageCauser, + UDamageType::StaticClass() + ); + } +} + void ULagCompensationComponent::SaveFramePackage(FFramePackage& Package) { Character = Character == nullptr ? Cast(GetOwner()) : Character; @@ -116,11 +136,11 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics); return FServerSideRewindResult{ true, false }; } - - ResetHitBoxes(HitCharacter, CurrentFrame); - EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics); - return FServerSideRewindResult{ false, false }; } + + ResetHitBoxes(HitCharacter, CurrentFrame); + EnableCharacterMeshCollision(HitCharacter, ECollisionEnabled::QueryAndPhysics); + return FServerSideRewindResult{ false, false }; } void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage) @@ -258,6 +278,12 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); + SaveFramePackage(); +} + +void ULagCompensationComponent::SaveFramePackage() +{ + if (Character == nullptr || !Character->HasAuthority()) return; if (FrameHistory.Num() <= 1) { FFramePackage ThisFrame; @@ -270,12 +296,11 @@ void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickTy while (HistoryLength > MaxRecordTime) { FrameHistory.RemoveNode(FrameHistory.GetTail()); - HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time; + HistoryLength = FrameHistory.GetHead()->GetValue().Time - FrameHistory.GetTail()->GetValue().Time; } FFramePackage ThisFrame; SaveFramePackage(ThisFrame); FrameHistory.AddHead(ThisFrame); - ShowFramePackage(ThisFrame, FColor::Red); + // ShowFramePackage(ThisFrame, FColor::Red); } -} - +} \ No newline at end of file diff --git a/Source/Blaster/Components/LagCompensationComponent.h b/Source/Blaster/Components/LagCompensationComponent.h index e47b753..f0c7361 100644 --- a/Source/Blaster/Components/LagCompensationComponent.h +++ b/Source/Blaster/Components/LagCompensationComponent.h @@ -56,9 +56,18 @@ public: virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; void ShowFramePackage(const FFramePackage& Package, const FColor Color); FServerSideRewindResult ServerSideRewind(class ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, float HitTime); - + + UFUNCTION(Server, Reliable) + void ServerScoreRequest( + ABlasterCharacter* HitCharacter, + const FVector_NetQuantize& TraceStart, + const FVector_NetQuantize& HitLocation, + float HitTime, + class AWeapon* DamageCauser + ); protected: virtual void BeginPlay() override; + void SaveFramePackage(); void SaveFramePackage(FFramePackage& Package); FFramePackage InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime); FServerSideRewindResult ConfirmHit(const FFramePackage& Package, ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize HitLocation); diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.cpp b/Source/Blaster/PlayerController/BlasterPlayerController.cpp index 5d04a09..9d9db60 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.cpp +++ b/Source/Blaster/PlayerController/BlasterPlayerController.cpp @@ -468,7 +468,8 @@ void ABlasterPlayerController::ServerRequestServerTime_Implementation(float Time void ABlasterPlayerController::ClientReportServerTime_Implementation(float TimeOfClientRequest, float TimeServerReceivedClientRequest) { float RoundTripTime = GetWorld()->GetTimeSeconds() - TimeOfClientRequest; - float CurrentServerTime = TimeServerReceivedClientRequest + 0.5f * RoundTripTime; + SingleTripTime = 0.5f * RoundTripTime; + float CurrentServerTime = TimeServerReceivedClientRequest + SingleTripTime; ClientServerDelta = CurrentServerTime - GetWorld()->GetTimeSeconds(); } diff --git a/Source/Blaster/PlayerController/BlasterPlayerController.h b/Source/Blaster/PlayerController/BlasterPlayerController.h index 4dd6a0e..2b744f5 100644 --- a/Source/Blaster/PlayerController/BlasterPlayerController.h +++ b/Source/Blaster/PlayerController/BlasterPlayerController.h @@ -44,6 +44,8 @@ public: void OnMatchStateSet(FName State); void HandleCooldown(); + + float SingleTripTime = 0.f; protected: diff --git a/Source/Blaster/Weapon/HitScanWeapon.cpp b/Source/Blaster/Weapon/HitScanWeapon.cpp index 7d483ed..cca2925 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.cpp +++ b/Source/Blaster/Weapon/HitScanWeapon.cpp @@ -4,6 +4,8 @@ #include "HitScanWeapon.h" #include "Blaster/Character/BlasterCharacter.h" +#include "Blaster/Components/LagCompensationComponent.h" +#include "Blaster/PlayerController/BlasterPlayerController.h" #include "Engine/SkeletalMeshSocket.h" #include "Kismet/GameplayStatics.h" #include "Particles/ParticleSystemComponent.h" @@ -26,15 +28,34 @@ void AHitScanWeapon::Fire(const FVector& HitTarget) WeaponTraceHit(Start, HitTarget, FireHit); ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); - if (BlasterCharacter && HasAuthority() && InstigatorController) + if (BlasterCharacter && InstigatorController) { - UGameplayStatics::ApplyDamage( - BlasterCharacter, - Damage, - InstigatorController, - this, - UDamageType::StaticClass() - ); + if (HasAuthority() && !bUseServerSideRewind) + { + UGameplayStatics::ApplyDamage( + BlasterCharacter, + Damage, + InstigatorController, + this, + UDamageType::StaticClass() + ); + } + else if (!HasAuthority() && bUseServerSideRewind) + { + OwnerCharacter = OwnerCharacter == nullptr ? Cast(OwnerPawn) : OwnerCharacter; + OwnerController = OwnerController == nullptr ? Cast(InstigatorController) : OwnerController; + + if (OwnerCharacter && OwnerController && OwnerCharacter->GetLagCompensation()) + { + OwnerCharacter->GetLagCompensation()->ServerScoreRequest( + BlasterCharacter, + Start, + HitTarget, + OwnerController->GetServerTime() - OwnerController->SingleTripTime, + this + ); + } + } } if (ImpactParticles) { diff --git a/Source/Blaster/Weapon/HitScanWeapon.h b/Source/Blaster/Weapon/HitScanWeapon.h index 8a65489..6478199 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.h +++ b/Source/Blaster/Weapon/HitScanWeapon.h @@ -26,9 +26,6 @@ protected: UPROPERTY(EditAnywhere) USoundCue* HitSound; - UPROPERTY(EditAnywhere) - float Damage = 20.f; - private: UPROPERTY(EditAnywhere) diff --git a/Source/Blaster/Weapon/Weapon.h b/Source/Blaster/Weapon/Weapon.h index 0679316..12f4049 100644 --- a/Source/Blaster/Weapon/Weapon.h +++ b/Source/Blaster/Weapon/Weapon.h @@ -124,6 +124,18 @@ protected: UPROPERTY(EditAnywhere, Category = "Weapon Scatter") float SphereRadius = 75.f; + UPROPERTY(EditAnywhere) + float Damage = 20.f; + + UPROPERTY(EditAnywhere) + bool bUseServerSideRewind = false; + + UPROPERTY() + class ABlasterCharacter* OwnerCharacter; + + UPROPERTY() + class ABlasterPlayerController* OwnerController; + private: UPROPERTY(VisibleAnywhere, Category = "Weapon Properties") USkeletalMeshComponent* WeaponMesh; @@ -164,12 +176,6 @@ private: // Incremented in SpendRound(), decremented in ClientUpdateAmmo() int32 Sequence = 0; - UPROPERTY() - class ABlasterCharacter* OwnerCharacter; - - UPROPERTY() - class ABlasterPlayerController* OwnerController; - UPROPERTY(EditAnywhere) EWeaponType WeaponType; @@ -184,7 +190,8 @@ public: FORCEINLINE int32 GetMagCapacity() const { return MagCapacity; } bool IsEmpty(); bool IsFull(); - + FORCEINLINE float GetDamage() const { return Damage; } + // Convenience methods for WeaponType FORCEINLINE bool IsPistol() const { return WeaponType == EWeaponType::EWT_Pistol; } FORCEINLINE bool IsSMG() const { return WeaponType == EWeaponType::EWT_SubmachineGun; }