Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- SWeapon.h HEADER FILE BELOW THIS!!
- // Fill out your copyright notice in the Description page of Project Settings.
- #pragma once
- #include "CoreMinimal.h"
- #include "GameFramework/Actor.h"
- #include "SWeapon.generated.h"
- class USkeletalMeshComponent;
- class UDamageType;
- class UParticleSystem;
- // Contains information of a single hitscan weapon linetrace.
- USTRUCT()
- struct FHitScanTrace
- {
- GENERATED_BODY()
- public:
- UPROPERTY()
- TEnumAsByte<EPhysicalSurface> SurfaceType;
- UPROPERTY()
- FVector_NetQuantize TraceTo;
- };
- UCLASS()
- class COOPGAME_API ASWeapon : public AActor
- {
- GENERATED_BODY()
- public:
- // Sets default values for this actor's properties
- ASWeapon();
- protected:
- virtual void BeginPlay() override;
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
- USkeletalMeshComponent* MeshComp;
- void PlayFireEffects(FVector TraceEnd);
- void PlayImpactEffects(EPhysicalSurface SurfaceType, FVector ImpactPoint);
- UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- TSubclassOf<UDamageType> DamageType;
- UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- FName MuzzleSocketName;
- UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- FName TracerTargetName;
- UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- UParticleSystem* MuzzleEffect;
- UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- UParticleSystem* DefaultImpactEffect;
- UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- UParticleSystem* FleshImpactEffect;
- UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Weapon")
- UParticleSystem* TracerEffect;
- UPROPERTY(EditDefaultsOnly, Category = "Weapon")
- TSubclassOf<UCameraShake> FireCamShake;
- UPROPERTY(EditDefaultsOnly, Category = "Weapon")
- float BaseDamage;
- void Fire();
- UFUNCTION(Server, Reliable, WithValidation)
- void ServerFire();
- FTimerHandle TimerHandle_TimeBetweenShots;
- float LastFireTime;
- /* RPM - Bullets per minute fired by weapon */
- UPROPERTY(EditDefaultsOnly, Category = "Weapon")
- float RateOfFire;
- // Derived from ROF
- float TimeBetweenShots;
- UPROPERTY(ReplicatedUsing = OnRep_HitScanTrace)
- FHitScanTrace HitScanTrace;
- UFUNCTION()
- void OnRep_HitScanTrace();
- public:
- void StartFire();
- void StopFire();
- };
- .
- .
- .
- .
- .
- SWeapon.h STOPS HERE !! SWeapon.cpp IS BELOW HERE !!
- .
- .
- .
- .
- .
- // Fill out your copyright notice in the Description page of Project Settings.
- #include "SWeapon.h"
- #include "DrawDebugHelpers.h"
- #include "Kismet/GameplayStatics.h"
- #include "Particles/ParticleSystem.h"
- #include "Components/SkeletalMeshComponent.h"
- #include "Particles/ParticleSystemComponent.h"
- #include "PhysicalMaterials/PhysicalMaterial.h"
- #include "CoopGame.h"
- #include "TimerManager.h"
- #include "Net/UnrealNetwork.h"
- static int32 DebugWeaponDrawing = 0;
- FAutoConsoleVariableRef CVARDebugWeaponDrawing(TEXT("COOP.DebugWeapons"), DebugWeaponDrawing, TEXT("Draw Debug Lines for Weapons"), ECVF_Cheat);
- // Sets default values
- ASWeapon::ASWeapon()
- {
- MeshComp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("MeshComp"));
- RootComponent = MeshComp;
- MuzzleSocketName = "MuzzleSocket";
- TracerTargetName = "Target";
- BaseDamage = 20.0f;
- RateOfFire = 600;
- SetReplicates(true);
- }
- void ASWeapon::BeginPlay()
- {
- Super::BeginPlay();
- TimeBetweenShots = 60 / RateOfFire;
- }
- void ASWeapon::Fire()
- {
- // Trace the world, from pawn eyes to crosshair location
- if (Role < ROLE_Authority)
- {
- ServerFire();
- return;
- }
- AActor* MyOwner = GetOwner();
- if (MyOwner)
- {
- FVector EyeLocation;
- FRotator EyeRotation;
- MyOwner->GetActorEyesViewPoint(EyeLocation, EyeRotation);
- FVector ShotDirection = EyeRotation.Vector();
- FVector TraceEnd = EyeLocation + (ShotDirection * 10000);
- FCollisionQueryParams QueryParams;
- QueryParams.AddIgnoredActor(MyOwner);
- QueryParams.AddIgnoredActor(this);
- QueryParams.bTraceComplex = true;
- QueryParams.bReturnPhysicalMaterial = true;
- // Particle "Target" Parameter
- FVector TracerEndPoint = TraceEnd;
- EPhysicalSurface SurfaceType = SurfaceType_Default;
- FHitResult Hit;
- if (GetWorld()->LineTraceSingleByChannel(Hit, EyeLocation, TraceEnd, COLLISION_WEAPON, QueryParams))
- {
- // Blocking hit! Process damage
- AActor * HitActor = Hit.GetActor();
- SurfaceType = UPhysicalMaterial::DetermineSurfaceType(Hit.PhysMaterial.Get());
- float ActualDamage = BaseDamage;
- if (SurfaceType == SURFACE_FLESHVULNERABLE)
- {
- ActualDamage *= 4.0f;
- }
- UGameplayStatics::ApplyPointDamage(HitActor, ActualDamage, ShotDirection, Hit, MyOwner->GetInstigatorController(), this, DamageType);
- PlayImpactEffects(SurfaceType, Hit.ImpactPoint);
- TracerEndPoint = Hit.ImpactPoint;
- }
- if (DebugWeaponDrawing > 0)
- {
- DrawDebugLine(GetWorld(), EyeLocation, TraceEnd, FColor::White, false, 1.0f, 0, 1.0f);
- }
- PlayFireEffects(TracerEndPoint);
- if (Role == ROLE_Authority)
- {
- HitScanTrace.TraceTo = TracerEndPoint;
- HitScanTrace.SurfaceType = SurfaceType;
- }
- LastFireTime = GetWorld()->TimeSeconds;
- }
- }
- void ASWeapon::ServerFire_Implementation()
- {
- Fire();
- }
- bool ASWeapon::ServerFire_Validate()
- {
- return true;
- }
- void ASWeapon::OnRep_HitScanTrace()
- {
- // Play cosmetic FX
- PlayFireEffects(HitScanTrace.TraceTo);
- PlayImpactEffects(HitScanTrace.SurfaceType, HitScanTrace.TraceTo);
- }
- void ASWeapon::StartFire()
- {
- float FirstDelay = FMath::Max(LastFireTime + TimeBetweenShots - GetWorld()->TimeSeconds, 0.0f);
- GetWorldTimerManager().SetTimer(TimerHandle_TimeBetweenShots, this, &ASWeapon::Fire, TimeBetweenShots, true, FirstDelay);
- }
- void ASWeapon::StopFire()
- {
- GetWorldTimerManager().ClearTimer(TimerHandle_TimeBetweenShots);
- }
- void ASWeapon::PlayFireEffects(FVector TraceEnd)
- {
- if (MuzzleEffect)
- {
- UGameplayStatics::SpawnEmitterAttached(MuzzleEffect, MeshComp, MuzzleSocketName);
- }
- if (TracerEffect)
- {
- FVector MuzzleLocation = MeshComp->GetSocketLocation(MuzzleSocketName);
- UParticleSystemComponent* TracerComp = UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), TracerEffect, MuzzleLocation);
- if (TracerComp)
- {
- TracerComp->SetVectorParameter(TracerTargetName, TraceEnd);
- }
- }
- APawn* MyOwner = Cast<APawn>(GetOwner());
- if (MyOwner)
- {
- APlayerController* PC = Cast<APlayerController>(MyOwner->GetController());
- if (PC)
- {
- PC->ClientPlayCameraShake(FireCamShake);
- }
- }
- }
- void ASWeapon::PlayImpactEffects(EPhysicalSurface SurfaceType, FVector ImpactPoint)
- {
- UParticleSystem* SelectedEffect = nullptr;
- switch (SurfaceType)
- {
- case SURFACE_FLESHDEFAULT:
- case SURFACE_FLESHVULNERABLE:
- SelectedEffect = FleshImpactEffect;
- break;
- default:
- SelectedEffect = DefaultImpactEffect;
- break;
- }
- if (SelectedEffect)
- {
- FVector MuzzleLocation = MeshComp->GetSocketLocation(MuzzleSocketName);
- FVector ShotDirection = ImpactPoint - MuzzleLocation;
- ShotDirection.Normalize();
- UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), SelectedEffect, ImpactPoint, ShotDirection.Rotation());
- }
- }
- void ASWeapon::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
- {
- Super::GetLifetimeReplicatedProps(OutLifetimeProps);
- DOREPLIFETIME_CONDITION(ASWeapon, HitScanTrace, COND_SkipOwner);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement