284 lines
9.0 KiB
Ucode
284 lines
9.0 KiB
Ucode
//=============================================================================
|
|
// KFProj_BrokenFlare_HRGScorcher
|
|
//=============================================================================
|
|
// Shotgun pellet class for the HRG Scorcher
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2020 Tripwire Interactive LLC
|
|
// Roberto Moreno (Saber Interactive)
|
|
//=============================================================================
|
|
|
|
class KFProj_BrokenFlare_HRGScorcher extends KFProjectile
|
|
hidedropdown;
|
|
|
|
/** Speed when residual flames are dropped during projectile flight */
|
|
var vector SpeedDirectionResidualFlames;
|
|
|
|
/** Amount of residual flames to drop during flight
|
|
* This is the max number, if the projectile is interrupted before reaching the max, the left residual numbers will NOT be spawned.
|
|
* This value can NOT be 0 or 1.
|
|
*/
|
|
var int AmountResidualFlamesDuringFlight;
|
|
|
|
/** Time delay until starting to drop residual flames during flight (should NOT be greater than Lifespan)*/
|
|
var float TimeDelayStartDroppingResidualFlames;
|
|
|
|
/** Class for spawning residual flames **/
|
|
var class<KFProjectile> ResidualFlameProjClass;
|
|
|
|
/** Number of lingering flames to spawn when projectile hits environment or a pawn before reaching max
|
|
* Note: one flame will always spawn in the place or pawn hit.
|
|
*/
|
|
var() int AmountResidualFlamesInExplosion;
|
|
|
|
/** Magnitude to multiply velocity computed for residual flames in explosion */
|
|
var float MagnitudeVelocityResidualFlamesInExplosion;
|
|
|
|
/** Offset added to the final velocity computed for residual flames in explosion */
|
|
var vector OffsetVelocityResidualFlamesInExplosion;
|
|
|
|
/** (Computed) Last Velocity from Explode() */
|
|
var vector LastVelocity;
|
|
|
|
/** (Computed) Time between residual flames drops */
|
|
var float IntervalDroppingResidualFlames;
|
|
|
|
/** Same as Lifespan (but using TimeAlive we assure projectile follows same flow as an explosion) */
|
|
var float TimeAlive;
|
|
|
|
simulated protected function StopSimulating()
|
|
{
|
|
if (Instigator != none && Instigator.Role == ROLE_Authority)
|
|
{
|
|
ClearTimer(nameof(Timer_SpawningResidualFlamesDuringFlight));
|
|
ClearTimer(nameof(Timer_StartSpawningResidualFlamesDuringFlight));
|
|
}
|
|
ClearTimer(nameof(Timer_Shutdown));
|
|
|
|
super.StopSimulating();
|
|
}
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
//Subtract a bit (0.005) from TimeAlive to not match last cycle of the timer with time the projectile has to disappear (causing last flame not to drop then)
|
|
//Subtract 1 from AmountResidualFlamesDuringFlight because the first flame will be spawned manually at the start of the timer.
|
|
IntervalDroppingResidualFlames=((TimeAlive - 0.005) - TimeDelayStartDroppingResidualFlames)/(AmountResidualFlamesDuringFlight - 1);
|
|
if (Instigator != none && Instigator.Role == ROLE_Authority)
|
|
{
|
|
SetTimer(TimeDelayStartDroppingResidualFlames, false, nameof(Timer_StartSpawningResidualFlamesDuringFlight));
|
|
}
|
|
SetTimer(TimeAlive, false, nameof(Timer_Shutdown));
|
|
|
|
super.PostBeginPlay();
|
|
}
|
|
|
|
simulated function Init(vector Direction)
|
|
{
|
|
super.Init(Direction);
|
|
SpeedDirectionResidualFlames = Velocity/5;
|
|
}
|
|
|
|
/** Timer to spawn residual flames while projectile is flying */
|
|
simulated function Timer_SpawningResidualFlamesDuringFlight()
|
|
{
|
|
SpawnResidualFlame(ResidualFlameProjClass, Location, SpeedDirectionResidualFlames);
|
|
}
|
|
|
|
/** Timer to act as offset to start spawning residual flames during flight (in order to avoid dropping flames to close to player) */
|
|
simulated function Timer_StartSpawningResidualFlamesDuringFlight()
|
|
{
|
|
SpawnResidualFlame(ResidualFlameProjClass, Location, SpeedDirectionResidualFlames);
|
|
SetTimer(IntervalDroppingResidualFlames, true, nameof(Timer_SpawningResidualFlamesDuringFlight));
|
|
}
|
|
|
|
/** Timer until calling Shutdown */
|
|
simulated function Timer_Shutdown()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
/** Spawn several projectiles that explode and linger on impact */
|
|
function SpawnResidualFlames (vector HitLocation, vector HitNormal, vector HitVelocity)
|
|
{
|
|
local int i;
|
|
local vector HitVelDir;
|
|
local float HitVelMag;
|
|
local vector SpawnLoc, SpawnVel;
|
|
|
|
HitVelMag = VSize (HitVelocity)*MagnitudeVelocityResidualFlamesInExplosion;
|
|
HitVelDir = Normal (HitVelocity);
|
|
|
|
SpawnLoc = HitLocation + (HitNormal * 10.f);
|
|
|
|
// spawn random lingering fires (rather, projectiles that cause little fires)
|
|
for( i = 0; i < AmountResidualFlamesInExplosion; ++i )
|
|
{
|
|
SpawnVel = CalculateResidualFlameVelocity( HitNormal, HitVelDir, HitVelMag );
|
|
SpawnVel = SpawnVel + OffsetVelocityResidualFlamesInExplosion;
|
|
SpawnResidualFlame( ResidualFlameProjClass, SpawnLoc, SpawnVel );
|
|
}
|
|
}
|
|
|
|
/** Spawn several projectiles that explode and linger on impact on explosion and one projectile to explode where this projectile hit */
|
|
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
|
|
{
|
|
local bool bDoExplosion;
|
|
|
|
if (bHasDisintegrated)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bDoExplosion = !bHasExploded && Instigator.Role == ROLE_Authority;
|
|
|
|
if (bDoExplosion)
|
|
{
|
|
SpawnResidualFlames (HitLocation, HitNormal, LastVelocity);
|
|
SpawnResidualFlame (ResidualFlameProjClass, Location, LastVelocity);
|
|
}
|
|
|
|
super.TriggerExplosion(HitLocation, HitNormal, HitActor);
|
|
}
|
|
|
|
|
|
simulated function Explode (vector HitLocation, vector HitNormal)
|
|
{
|
|
LastVelocity = Velocity;
|
|
super.Explode (HitLocation, HitNormal);
|
|
}
|
|
|
|
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
|
|
{
|
|
ProcessBulletTouch(Other, HitLocation, HitNormal);
|
|
super.ProcessTouch(Other, HitLocation, HitNormal);
|
|
}
|
|
|
|
simulated function SpawnFlightEffects()
|
|
{
|
|
super.SpawnFlightEffects();
|
|
|
|
if (ProjEffects != None)
|
|
{
|
|
ProjEffects.SetFloatParameter( 'FlareLifetime', LifeSpan );
|
|
}
|
|
}
|
|
|
|
simulated function SyncOriginalLocation()
|
|
{
|
|
local Actor HitActor;
|
|
local vector HitLocation, HitNormal;
|
|
local TraceHitInfo HitInfo;
|
|
|
|
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
|
|
{
|
|
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
|
|
if (HitActor != none)
|
|
{
|
|
Explode(HitLocation, HitNormal);
|
|
}
|
|
}
|
|
|
|
Super.SyncOriginalLocation();
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
Physics=PHYS_Falling
|
|
|
|
MaxSpeed=7000.0
|
|
Speed=3000.0 //7000.0
|
|
TerminalVelocity=7000.0
|
|
|
|
bWarnAIWhenFired=true
|
|
|
|
bCollideActors=true
|
|
bCollideComplex=true
|
|
|
|
DamageRadius=0
|
|
GravityScale=0.4 //0.5 //1.0
|
|
TossZ=0
|
|
TimeDelayStartDroppingResidualFlames=0.005 //0.05
|
|
TimeAlive=0.5//0.6 //0.2
|
|
ProjEffectsFadeOutDuration=5.0
|
|
AmountResidualFlamesDuringFlight=8 //10
|
|
SpeedDirectionResidualFlames=(X=0, Y=0, Z=0)
|
|
AmountResidualFlamesInExplosion=3
|
|
MagnitudeVelocityResidualFlamesInExplosion=0.5
|
|
OffsetVelocityResidualFlamesInExplosion=(X=0, Y=0, Z=200)
|
|
bNoReplicationToInstigator=false
|
|
|
|
Begin Object Class=PointLightComponent Name=PointLight0
|
|
//LightColor=(R=252,G=218,B=171,A=255)
|
|
LightColor=(R=250,G=25,B=80,A=255)
|
|
Brightness=0.5f
|
|
Radius=500.f
|
|
FalloffExponent=10.f
|
|
CastShadows=False
|
|
CastStaticShadows=FALSE
|
|
CastDynamicShadows=False
|
|
bCastPerObjectShadows=false
|
|
bEnabled=true
|
|
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
|
End Object
|
|
ProjFlightLight=PointLight0
|
|
|
|
|
|
ResidualFlameProjClass=class'KFProj_BrokenFlare_HRGScorcherSplash'
|
|
//ProjFlightTemplateZedTime=ParticleSystem'WEP_DragonsBreath_EMIT.Tracer.FX_DragonsBreath_Tracer_ZEDTime'
|
|
|
|
ProjFlightTemplate=ParticleSystem'WEP_HRGScorcher_Pistol_EMIT.FX_HRGScorcher_Projectile_01_ALT'
|
|
|
|
AssociatedPerkClass=class'KFPerk_Firebug'
|
|
|
|
// Light during explosion
|
|
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
|
LightColor=(R=252,G=218,B=171,A=255)
|
|
Brightness=4.f
|
|
Radius=2000.f
|
|
FalloffExponent=10.f
|
|
CastShadows=False
|
|
CastStaticShadows=FALSE
|
|
CastDynamicShadows=False
|
|
bCastPerObjectShadows=false
|
|
bEnabled=FALSE
|
|
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
|
End Object
|
|
|
|
// Explosion
|
|
Begin Object Class=KFGameExplosion Name=ExploTemplate0
|
|
Damage=0
|
|
DamageRadius=500
|
|
DamageFalloffExponent=1.f
|
|
DamageDelay=0.f
|
|
|
|
bIgnoreInstigator=false
|
|
|
|
MomentumTransferScale=0
|
|
|
|
// Damage Effects
|
|
MyDamageType=class'KFDT_Fire_HRGScorcherDoT'
|
|
KnockDownStrength=0
|
|
FractureMeshRadius=200.0
|
|
FracturePartVel=500.0
|
|
ExplosionEffects=KFImpactEffectInfo'WEP_HRGScorcher_Pistol_ARCH.HRGScorcher_Pistol_Grenade_Explosion'
|
|
ExplosionSound=AkEvent'WW_WEP_HRG_Scorcher.Play_WEP_HRG_Scorcher_AltFire_Explosion'
|
|
|
|
// Dynamic Light
|
|
ExploLight=ExplosionPointLight
|
|
ExploLightStartFadeOutTime=0.0
|
|
ExploLightFadeOutTime=0.2
|
|
|
|
// Camera Shake
|
|
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
|
|
CamShakeInnerRadius=200
|
|
CamShakeOuterRadius=900
|
|
CamShakeFalloff=1.5f
|
|
bOrientCameraShakeTowardsEpicenter=true
|
|
End Object
|
|
ExplosionTemplate=ExploTemplate0
|
|
ExplosionActorClass=class'KFExplosionActor'
|
|
|
|
bDamageDestructiblesOnTouch=true
|
|
}
|
|
|