diff --git a/Content/Maps/warmup.umap b/Content/Maps/warmup.umap index 31a398cc0..83891e21a 100644 Binary files a/Content/Maps/warmup.umap and b/Content/Maps/warmup.umap differ diff --git a/Content/Physicals/PM_Character.uasset b/Content/Physicals/PM_Character.uasset index 31d004a0a..abe52c0ec 100644 Binary files a/Content/Physicals/PM_Character.uasset and b/Content/Physicals/PM_Character.uasset differ diff --git a/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.cpp b/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.cpp index a7b1ca6a8..6f629b4bc 100644 --- a/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.cpp +++ b/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.cpp @@ -10,25 +10,82 @@ UCloud9PhysicalMaterial::UCloud9PhysicalMaterial() FirearmDecalSize = {8.0f, 8.0, 8.0f}; FirearmDecalRotationMin = 0.0f; FirearmDecalRotationMax = 180.0f; -} -UMaterialInterface* UCloud9PhysicalMaterial::GetRandomFirearmDecal() const { return GetRandomItem(FirearmDecals); } + FirearmBackgroundDecalSize = {8.0f, 64.0, 64.0f}; + FirearmBackgroundDecalOffsetMin = -50.0f; + FirearmBackgroundDecalOffsetMax = 50.0f; + FirearmBackgroundDecalRotationMin = 0.0f; + FirearmBackgroundDecalRotationMax = 180.0f; + FirearmBackgroundDecalProbability = 0.5f; + FirearmBackgroundDecalMaxDistance = 200.0f; -UNiagaraSystem* UCloud9PhysicalMaterial::GetRandomFirearmSquib() const { return GetRandomItem(FirearmEffects); } + GrenadeDecalSize = {8.0f, 8.0f, 8.0f}; + MeleeDecalSize = {8.0f, 8.0f, 8.0f}; +} -FVector UCloud9PhysicalMaterial::GetFirearmDecalSize() const { return FirearmDecalSize; } +bool IsVertical(FVector Normal) +{ + return FMath::IsNearlyEqual(Normal.Z, 1.0f, 0.1f); +} -FRotator UCloud9PhysicalMaterial::GetFirearmDecalRotation(FVector Normal) const +FRotator GetNormalSurfaceRotation(FVector Normal, float Roll) { constexpr float DecalVPitch = 90.0f; constexpr float DecalVRoll = -180.0f; constexpr float DecalHYaw = 90.0f; constexpr float DecalHRoll = -90.0; + let Corrective = IsVertical(Normal) + ? FRotator{DecalVPitch, Roll, DecalVRoll} + : FRotator{Roll, DecalHYaw, DecalHRoll}; + + return Normal.Rotation() + Corrective; +} + +UMaterialInterface* UCloud9PhysicalMaterial::GetRandomFirearmDecal() const { return GetRandomItem(FirearmDecals); } + +FVector UCloud9PhysicalMaterial::GetFirearmDecalSize() const { return FirearmDecalSize; } + +FRotator UCloud9PhysicalMaterial::GetFirearmDecalRotation(FVector Normal) const +{ let RandomRotation = FMath::RandRange(FirearmDecalRotationMin, FirearmDecalRotationMax); - let BaseRotation = Normal.Rotation(); - let CorrectiveRotation = FMath::IsNearlyEqual(Normal.Z, 1.0f, 0.1f) - ? FRotator{DecalVPitch, RandomRotation, DecalVRoll} - : FRotator{RandomRotation, DecalHYaw, DecalHRoll}; - return BaseRotation + CorrectiveRotation; + return GetNormalSurfaceRotation(Normal, RandomRotation); +} + +UMaterialInterface* UCloud9PhysicalMaterial::GetRandomBackgroundDecal() const +{ + return GetRandomItem(FirearmBackgroundDecals); +} + +FVector UCloud9PhysicalMaterial::GetBackgroundDecalSize() const +{ + return FirearmBackgroundDecalSize; +} + +FVector UCloud9PhysicalMaterial::GetBackgroundDecalLocation(FVector Location, FVector Normal) const +{ + let OffsetH = FMath::RandRange(FirearmBackgroundDecalOffsetMin, FirearmBackgroundDecalOffsetMax); + let OffsetV = FMath::RandRange(FirearmBackgroundDecalOffsetMin, FirearmBackgroundDecalOffsetMax); + return IsVertical(Normal) + ? FVector{Location.X + OffsetH, Location.Y + OffsetV, Location.Z} + : FVector{Location.X + OffsetH, Location.Y, Location.Z + OffsetV}; +} + +FRotator UCloud9PhysicalMaterial::GetBackgroundDecalRotation(FVector Normal) const +{ + let RandomRotation = FMath::RandRange(FirearmBackgroundDecalRotationMin, FirearmBackgroundDecalRotationMax); + return GetNormalSurfaceRotation(Normal, RandomRotation); } + + +float UCloud9PhysicalMaterial::GetBackgroundDecalMaxDistance() const +{ + return FirearmBackgroundDecalMaxDistance; +} + +bool UCloud9PhysicalMaterial::TestBackgroundDecalProbability() const +{ + return FMath::RandRange(0.0f, 1.0f) < FirearmBackgroundDecalProbability; +} + +UNiagaraSystem* UCloud9PhysicalMaterial::GetRandomFirearmSquib() const { return GetRandomItem(FirearmEffects); } diff --git a/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.h b/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.h index 4fc4da332..6dd892f5b 100644 --- a/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.h +++ b/Source/Cloud9/Physicals/Cloud9PhysicalMaterial.h @@ -20,35 +20,83 @@ class CLOUD9_API UCloud9PhysicalMaterial : public UPhysicalMaterial UMaterialInterface* GetRandomFirearmDecal() const; UNiagaraSystem* GetRandomFirearmSquib() const; + UMaterialInterface* GetRandomBackgroundDecal() const; + FVector GetBackgroundDecalSize() const; + FVector GetBackgroundDecalLocation(FVector Location, FVector Normal) const; + FRotator GetBackgroundDecalRotation(FVector Normal) const; + float GetBackgroundDecalMaxDistance() const; + bool TestBackgroundDecalProbability() const; + FVector GetFirearmDecalSize() const; FRotator GetFirearmDecalRotation(FVector Normal) const; protected: - UPROPERTY(EditDefaultsOnly, Category=Decal) + UPROPERTY(EditDefaultsOnly, Category="Firearm Hit Decal") TSet FirearmDecals; - UPROPERTY(EditDefaultsOnly, Category=Decal) + UPROPERTY(EditDefaultsOnly, Category="Firearm Hit Decal") FVector FirearmDecalSize; - UPROPERTY(EditDefaultsOnly, Category=Decal, meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) + UPROPERTY(EditDefaultsOnly, Category="Firearm Hit Decal", + meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) float FirearmDecalRotationMin; - UPROPERTY(EditDefaultsOnly, Category=Decal, meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) + UPROPERTY(EditDefaultsOnly, Category="Firearm Hit Decal", + meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) float FirearmDecalRotationMax; - UPROPERTY(EditDefaultsOnly, Category=Effect) + UPROPERTY(EditDefaultsOnly, Category="Firearm Hit Effect") TSet FirearmEffects; - UPROPERTY(EditDefaultsOnly, Category=Decal) + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal") + TSet FirearmBackgroundDecals; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal") + FVector FirearmBackgroundDecalSize; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="-100", UIMax="100", ClampMin="-100", ClampMax="100")) + float FirearmBackgroundDecalOffsetMin; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="-100", UIMax="100", ClampMin="-100", ClampMax="100")) + float FirearmBackgroundDecalOffsetMax; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) + float FirearmBackgroundDecalRotationMin; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="-180", UIMax="180", ClampMin="-180", ClampMax="180")) + float FirearmBackgroundDecalRotationMax; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="0", UIMax="1.0", ClampMin="0", ClampMax="1.0")) + float FirearmBackgroundDecalProbability; + + UPROPERTY(EditDefaultsOnly, Category="Firearm Background Decal", + meta=(UIMin="0", UIMax="1000", ClampMin="0", ClampMax="1000")) + float FirearmBackgroundDecalMaxDistance; + + + UPROPERTY(EditDefaultsOnly, Category="Grenade Hit Decal") TSet GrenadeDecals; - UPROPERTY(EditDefaultsOnly, Category=Effect) + UPROPERTY(EditDefaultsOnly, Category="Grenade Hit Decal") + FVector GrenadeDecalSize; + + UPROPERTY(EditDefaultsOnly, Category="Grenade Hit Effect") TSet GrenadeEffects; - UPROPERTY(EditDefaultsOnly, Category=Decal) + + UPROPERTY(EditDefaultsOnly, Category="Melee Hit Decal") TSet MeleeDecals; - UPROPERTY(EditDefaultsOnly, Category=Effect) + UPROPERTY(EditDefaultsOnly, Category="Melee Hit Decal") + FVector MeleeDecalSize; + + UPROPERTY(EditDefaultsOnly, Category="Melee Hit Effect") TSet MeleeEffects; private: diff --git a/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp b/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp index 4ad86ee57..6d78b093c 100644 --- a/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp +++ b/Source/Cloud9/Weapon/Classes/Cloud9WeaponFirearm.cpp @@ -468,10 +468,10 @@ EFirearmFireStatus ACloud9WeaponFirearm::Fire( true); } - if (let FirearmDecalMaterial = PhysicalMaterial->GetRandomFirearmDecal(); IsValid(FirearmDecalMaterial)) + if (let HitDecal = PhysicalMaterial->GetRandomFirearmDecal(); IsValid(HitDecal)) { GetWorld() | EUWorld::SpawnDecal{ - .Material = FirearmDecalMaterial, + .Material = HitDecal, .DecalSize = PhysicalMaterial->GetFirearmDecalSize(), .Location = LineHit.Location, .Rotator = PhysicalMaterial->GetFirearmDecalRotation(LineHit.Normal), @@ -479,6 +479,49 @@ EFirearmFireStatus ACloud9WeaponFirearm::Fire( .Instigator = Character }; } + + if (let BackgroundDecal = PhysicalMaterial->GetRandomBackgroundDecal(); IsValid(BackgroundDecal)) + { + if (PhysicalMaterial->TestBackgroundDecalProbability()) + { + var BackgroundCollisionParams = FCollisionQueryParams::DefaultQueryParam; + BackgroundCollisionParams.AddIgnoredActor(DamagedActor); + + let StartBackgroundLocation = LineHit.Location; + let EndBackgroundLocation = FMath::Lerp( + FVector{StartBackgroundLocation}, + StartBackgroundLocation + Direction, + PhysicalMaterial->GetBackgroundDecalMaxDistance()); + + FHitResult BackgroundHit; + let IsBackgroundHit = GetWorld()->LineTraceSingleByChannel( + BackgroundHit, + StartBackgroundLocation, + EndBackgroundLocation, + TRACE_CHANNEL, + BackgroundCollisionParams); + + if (IsBackgroundHit) + { + let BackgroundActor = LineHit.Actor.Get(); + if (not IsValid(BackgroundActor)) + { + log(Error, "[Weapon='%s'] Background actor is invalid on hit", *GetName()); + return EFirearmFireStatus::Success; + } + + GetWorld() | EUWorld::SpawnDecal{ + .Material = BackgroundDecal, + .DecalSize = PhysicalMaterial->GetBackgroundDecalSize(), + .Location = PhysicalMaterial->GetBackgroundDecalLocation( + BackgroundHit.Location, BackgroundHit.Normal), + .Rotator = PhysicalMaterial->GetBackgroundDecalRotation(BackgroundHit.Normal), + .Owner = BackgroundActor, + .Instigator = Character + }; + } + } + } } }