diff --git a/Content/Maps/BlasterMap.umap b/Content/Maps/BlasterMap.umap index 6e1a06c..0a0b90c 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 08f0eeb..2945c27 100644 --- a/Source/Blaster/Components/LagCompensationComponent.cpp +++ b/Source/Blaster/Components/LagCompensationComponent.cpp @@ -119,11 +119,11 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag HeadBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly); HeadBox->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); - FHitResult ConfirmHitResult; const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f; UWorld* World = GetWorld(); if (World) { + FHitResult ConfirmHitResult; World->LineTraceSingleByChannel( ConfirmHitResult, TraceStart, @@ -168,6 +168,120 @@ FServerSideRewindResult ULagCompensationComponent::ConfirmHit(const FFramePackag return FServerSideRewindResult{ false, false }; } + +FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(const TArray& FramePackages, + const FVector_NetQuantize& TraceStart, const TArray& HitLocations) +{ + for (auto& Frame : FramePackages) + { + if (Frame.Character == nullptr) return FShotgunServerSideRewindResult(); + } + + FShotgunServerSideRewindResult ShotgunResult; + + TArray CurrentFrames; + for (auto& Frame : FramePackages) + { + FFramePackage CurrentFrame; + CurrentFrame.Character = Frame.Character; + CacheBoxPositions(Frame.Character, CurrentFrame); + MoveBoxes(Frame.Character, Frame); + EnableCharacterMeshCollision(Frame.Character, ECollisionEnabled::NoCollision); + CurrentFrames.Add(CurrentFrame); + } + + for (auto& Frame : FramePackages) + { + // Enable collision for the head first + UBoxComponent* HeadBox = Frame.Character->HitCollisionBoxes[FName("head")]; + HeadBox->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + HeadBox->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); + } + + UWorld* World = GetWorld(); + + // Check for headshots + for (auto& HitLocation : HitLocations) + { + const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f; + if (World) + { + FHitResult ConfirmHitResult; + World->LineTraceSingleByChannel( + ConfirmHitResult, + TraceStart, + TraceEnd, + ECC_Visibility + ); + + ABlasterCharacter* BlasterCharacter = Cast(ConfirmHitResult.GetActor()); + if (BlasterCharacter) + { + if (ShotgunResult.Headshots.Contains(BlasterCharacter)) + { + ShotgunResult.Headshots[BlasterCharacter]++; + } + else + { + ShotgunResult.Headshots.Emplace(BlasterCharacter, 1); + } + } + } + } + + // Enable collision for all boxes, then disable for head box + for (auto& Frame :FramePackages) + { + for (auto& HitBoxPair : Frame.Character->HitCollisionBoxes) + { + if (HitBoxPair.Value != nullptr) + { + HitBoxPair.Value->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + HitBoxPair.Value->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); + } + } + UBoxComponent* HeadBox = Frame.Character->HitCollisionBoxes[FName("head")]; + HeadBox->SetCollisionEnabled(ECollisionEnabled::NoCollision); + } + + // Check for body shots + for (auto& HitLocation : HitLocations) + { + const FVector TraceEnd = TraceStart + (HitLocation - TraceStart) * 1.25f; + if (World) + { + FHitResult ConfirmHitResult; + World->LineTraceSingleByChannel( + ConfirmHitResult, + TraceStart, + TraceEnd, + ECC_Visibility + ); + + ABlasterCharacter* BlasterCharacter = Cast(ConfirmHitResult.GetActor()); + if (BlasterCharacter) + { + if (ShotgunResult.BodyShots.Contains(BlasterCharacter)) + { + ShotgunResult.BodyShots[BlasterCharacter]++; + } + else + { + ShotgunResult.BodyShots.Emplace(BlasterCharacter, 1); + } + } + } + } + + for (auto& CurrentFrame : CurrentFrames) + { + ResetHitBoxes(CurrentFrame.Character, CurrentFrame); + EnableCharacterMeshCollision(CurrentFrame.Character, ECollisionEnabled::QueryAndPhysics); + } + + return ShotgunResult; +} + void ULagCompensationComponent::CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage) { if (HitCharacter == nullptr) return; @@ -249,13 +363,7 @@ FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunServerSideRewin FramesToCheck.Add(GetFrameToCheck(HitCharacter, HitTime)); } - return FShotgunServerSideRewindResult(); -} - -FShotgunServerSideRewindResult ULagCompensationComponent::ShotgunConfirmHit(const TArray& FramePackages, - const FVector_NetQuantize& TraceStart, const TArray& HitLocations) -{ - + return ShotgunConfirmHit(FramesToCheck, TraceStart, HitLocations); } FFramePackage ULagCompensationComponent::GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime)