diff --git a/Source/Blaster/Character/BlasterCharacter.h b/Source/Blaster/Character/BlasterCharacter.h index c08d3e4..f9424d4 100644 --- a/Source/Blaster/Character/BlasterCharacter.h +++ b/Source/Blaster/Character/BlasterCharacter.h @@ -301,4 +301,5 @@ public: FORCEINLINE UAnimMontage* GetReloadMontage() const { return ReloadMontage; } FORCEINLINE UStaticMeshComponent* GetAttachedGrenade() const { return AttachedGrenade; } bool IsLocallyReloading(); + FORCEINLINE ULagCompensationComponent* GetLagCompensation() const { return LagCompensation; } }; diff --git a/Source/Blaster/Components/LagCompensationComponent.cpp b/Source/Blaster/Components/LagCompensationComponent.cpp index 575a8bf..bc90b6a 100644 --- a/Source/Blaster/Components/LagCompensationComponent.cpp +++ b/Source/Blaster/Components/LagCompensationComponent.cpp @@ -50,6 +50,61 @@ void ULagCompensationComponent::ShowFramePackage(const FFramePackage& Package, c } } +void ULagCompensationComponent::ServerSideRewind(ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, + float HitTime) +{ + bool bReturn = HitCharacter == nullptr || + HitCharacter->GetLagCompensation() == nullptr || + HitCharacter->GetLagCompensation()->FrameHistory.GetHead() == nullptr || + HitCharacter->GetLagCompensation()->FrameHistory.GetTail() == nullptr; + + if (bReturn) return; + + // Frame package that we check to verify a hit + FFramePackage FrameToSheck; + bool bShouldInterpolate = true; + + const TDoubleLinkedList& History = HitCharacter->GetLagCompensation()->FrameHistory; + const float OldestHistoryTime = History.GetTail()->GetValue().Time; + const float NewestHistoryTime = History.GetHead()->GetValue().Time; + if (OldestHistoryTime > HitTime) + { + // Too far back, too laggy to do SSR + return; + } + if (OldestHistoryTime == HitTime) + { + FrameToSheck = History.GetTail()->GetValue(); + bShouldInterpolate = false; + } + if (NewestHistoryTime <= HitTime) + { + FrameToSheck = History.GetHead()->GetValue(); + bShouldInterpolate = false; + } + auto Younger = History.GetHead(); + auto Older = History.GetHead(); + while (Older->GetValue().Time > HitTime) + { + if (Older->GetNextNode() == nullptr) break; + Older = Older->GetNextNode(); + if (Older->GetValue().Time > HitTime) + { + Younger = Older; + } + } + if (Older->GetValue().Time == HitTime) + { + FrameToSheck = Older->GetValue(); + bShouldInterpolate = false; + } + + if (bShouldInterpolate) // Why not just check if FrameToCheck == nullptr? + { + // Interpolate between Younger and Older + } +} + void ULagCompensationComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) { Super::TickComponent(DeltaTime, TickType, ThisTickFunction); diff --git a/Source/Blaster/Components/LagCompensationComponent.h b/Source/Blaster/Components/LagCompensationComponent.h index 46eefb3..ee821b3 100644 --- a/Source/Blaster/Components/LagCompensationComponent.h +++ b/Source/Blaster/Components/LagCompensationComponent.h @@ -43,6 +43,7 @@ public: friend ABlasterCharacter; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; void ShowFramePackage(const FFramePackage& Package, const FColor Color); + void ServerSideRewind(class ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, float HitTime); protected: virtual void BeginPlay() override;