// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "Blaster/Character/BlasterCharacter.h" #include "Components/ActorComponent.h" #include "LagCompensationComponent.generated.h" USTRUCT(BlueprintType) struct FBoxInformation { GENERATED_BODY() UPROPERTY() FVector Location; UPROPERTY() FRotator Rotation; UPROPERTY() FVector BoxExtend; }; USTRUCT(BlueprintType) struct FFramePackage { GENERATED_BODY() UPROPERTY() float Time; UPROPERTY() TMap HitBoxInfo; UPROPERTY() ABlasterCharacter* Character; }; USTRUCT(BlueprintType) struct FServerSideRewindResult { GENERATED_BODY() UPROPERTY() bool bHitConfirmed; UPROPERTY() bool bHeadShot; }; USTRUCT(BlueprintType) struct FShotgunServerSideRewindResult { GENERATED_BODY() UPROPERTY() TMap Headshots; UPROPERTY() TMap BodyShots; }; UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class BLASTER_API ULagCompensationComponent : public UActorComponent { GENERATED_BODY() public: ULagCompensationComponent(); friend ABlasterCharacter; virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; void ShowFramePackage(const FFramePackage& Package, const FColor Color); // Hitscan FServerSideRewindResult ServerSideRewind( ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, float HitTime ); // Projectiles FServerSideRewindResult ProjectilServerSideRewind( ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, float HitTime ); // Shotgun UFUNCTION(Server, Reliable) void ShotgunServerScoreRequest( const TArray& HitCharacters, const FVector_NetQuantize& TraceStart, const TArray& HitLocations, float HitTime ); UFUNCTION(Server, Reliable) void ServerScoreRequest( ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize& HitLocation, float HitTime, AWeapon* DamageCauser ); UFUNCTION(Server, Reliable) void ProjectileServerScoreRequest( ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, float HitTime ); FShotgunServerSideRewindResult ShotgunServerSideRewind( const TArray& HitCharacters, const FVector_NetQuantize& TraceStart, const TArray& HitLocations, float HitTime ); protected: void SaveFramePackage(); void SaveFramePackage(FFramePackage& Package); FFramePackage InterpBetweenFrames(const FFramePackage& OlderFrame, const FFramePackage& YoungerFrame, float HitTime); void CacheBoxPositions(ABlasterCharacter* HitCharacter, FFramePackage& OutFramePackage); void MoveBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package); void ResetHitBoxes(ABlasterCharacter* HitCharacter, const FFramePackage& Package); void EnableCharacterMeshCollision(ABlasterCharacter* HitCharacter, ECollisionEnabled::Type CollisionEnabled); FFramePackage GetFrameToCheck(ABlasterCharacter* HitCharacter, float HitTime); // Hitscan FServerSideRewindResult ConfirmHit( const FFramePackage& Package, ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize HitLocation ); // Projectile FServerSideRewindResult ProjectileConfirmHit( const FFramePackage& Package, ABlasterCharacter* HitCharacter, const FVector_NetQuantize& TraceStart, const FVector_NetQuantize100& InitialVelocity, float HitTime ); // Shotgun FShotgunServerSideRewindResult ShotgunConfirmHit( const TArray& FramePackages, const FVector_NetQuantize& TraceStart, const TArray& HitLocations ); private: UPROPERTY() ABlasterCharacter* Character; UPROPERTY() ABlasterPlayerController* Controller; TDoubleLinkedList FrameHistory; UPROPERTY(EditAnywhere) float MaxRecordTime = 4.f; };