1
0
KF2-Dev-Scripts/KFGameContent/Classes/KFWeapAttach_HRG_Vampire.uc
2020-12-13 18:09:05 +03:00

497 lines
14 KiB
Ucode

//=============================================================================
// KFWeapAttach_HRG_Vampire
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_Vampire extends KFWeapAttach_SprayBase;
var transient ParticleSystemComponent ChargingPSC;
var transient ParticleSystemComponent ChargedPSC;
var ParticleSystem ChargingEffect;
var ParticleSystem ChargedEffect;
var ParticleSystem BloodStolenEffect;
var bool bIsCharging;
var bool bIsFullyCharged;
var bool bIsChargeEffectsActive;
var bool bIsBloodParticlesEffectActive;
var bool bIsDisabledSprayVisualAndMesh;
var repnotify float StartFireTime;
var int ChargeLevel;
var float FXScalingFactorByCharge;
var float ChargeRTPC;
var KFPawn_Monster oZedCurrentlyBeingSprayed;
var KFPawn_Monster oZedPreviouslyBeingSprayed;
var KFWeap_HRG_Vampire Weapon;
var KFEmit_DirectionalPath BloodStolenParticles[15];
var int NumBloodStolenParticlesForPool;
var transient float BloodStolenControlTime;
var float RateUpdateDestinationBloodParticles;
var transient float UpdateDestinationBloodParticlesTime;
var class<KFProj_BloodSplash> BloodSplashClass;
var bool bHasToStopDoingFireAnim;
var bool bHasToStopDoingFireAnimB;
/** Blood Particles */
var(BloodParticles) float SpeedBloodParticles;
var(BloodParticles) float SpawnRateBloodParticles;
var(BloodParticles) float SpeedBloodParticles_3P;
var(BloodParticles) float SpawnRateBloodParticles_3P;
var(BloodParticles) float HalfAngleSpawnCone;
var(BloodParticles) float CurveTurnRateUntilDestinationFinal;
var(BloodParticles) float CurveTurnRateUntilDestinationMidPoint;
var(BloodParticles) float LimitDistanceFinalPoint;
var(BloodParticles) float LimitDistanceMidPoint;
simulated function PostBeginPlay()
{
local int Index;
super.PostBeginPlay();
UpdateDestinationBloodParticlesTime = RateUpdateDestinationBloodParticles;
for( Index = (NumBloodStolenParticlesForPool - 1) ; Index >= 0 ; Index-- )
{
BloodStolenParticles[Index] = Spawn(class'KFEmit_DirectionalPath');
BloodStolenParticles[Index].DeactivateEmitter();
BloodStolenParticles[Index].SetTemplate(BloodStolenEffect, true);
}
}
simulated function StartFire()
{
StartFireTime = WorldInfo.TimeSeconds;
bIsCharging = false;
bIsFullyCharged = false;
bIsDisabledSprayVisualAndMesh = false;
if (ChargingPSC == none)
{
ChargingPSC = new(self) class'ParticleSystemComponent';
if (WeapMesh != none)
{
WeapMesh.AttachComponentToSocket(ChargingPSC, 'MuzzleFlash');
}
else
{
AttachComponent(ChargingPSC);
}
ChargingPSC.SetTemplate(ChargingEffect);
}
if (ChargedPSC == none)
{
ChargedPSC = new(self) class'ParticleSystemComponent';
if (WeapMesh != none)
{
WeapMesh.AttachComponentToSocket(ChargedPSC, 'MuzzleFlash');
}
else
{
AttachComponent(ChargedPSC);
}
ChargedPSC.SetTemplate(ChargedEffect);
}
ChargingPSC.SetActive( false );
ChargedPSC.SetActive( false );
}
simulated event Tick(float DeltaTime)
{
local int Index;
local vector MuzzleFlashSocketLocation, BloodParticlesMidPointSocketLocation;
local KFEmit_DirectionalPath EmitterToRemove;
local vector VectorParameterParticle;
local vector ChargePercentageVector;
local Rotator DestinationRotation, BloodParticlesMidPointSocketRotation;
local vector BloodSplashVelocity;
if(bIsChargeEffectsActive)
{
if(bIsCharging)
{
ChargingPSC.SetActive( true, true );
ChargePercentageVector.X = ChargeRTPC;
ChargePercentageVector.Y = ChargeRTPC;
ChargePercentageVector.Z = ChargeRTPC;
ChargingPSC.SetVectorParameter( name("BlobCharge"), ChargePercentageVector);
}
if(bIsFullyCharged)
{
ChargedPSC.SetActive( true, true );
ChargingPSC.SetFloatParameter( name("InflateBlob"), ChargeRTPC);
}
}
if (bIsDisabledSprayVisualAndMesh)
{
TurnOffFireSpray();
ActiveFlameSpray.CleanupEndFire();
}
//Spawning blood particles if conditions met
if (bIsBloodParticlesEffectActive)
{
if(oZedCurrentlyBeingSprayed != none && oZedCurrentlyBeingSprayed.IsAliveAndWell())
{
CreateBloodParticle(DeltaTime, oZedCurrentlyBeingSprayed);
}
}
// Updating blood stolen particles FX destination position
UpdateDestinationBloodParticlesTime -= DeltaTime;
if (UpdateDestinationBloodParticlesTime <= 0)
{
UpdateDestinationBloodParticlesTime = RateUpdateDestinationBloodParticles;
if( WeapMesh != none )
{
GetFlameSocketLocAndRot(MuzzleFlashSocketLocation, DestinationRotation);
WeapMesh.GetSocketWorldLocationAndRotation('BloodParticlesMidPoint', BloodParticlesMidPointSocketLocation, BloodParticlesMidPointSocketRotation);
}
for( Index = (NumBloodStolenParticlesForPool - 1) ; Index >= 0 ; Index-- )
{
if(!BloodStolenParticles[Index].IsEnabled || BloodStolenParticles[Index] == None)
{
continue;
}
if( BloodStolenParticles[Index].bReachDestinationFinal )
{
EmitterToRemove = BloodStolenParticles[Index];
//BloodStolenParticles.Remove(Index, 1);
EmitterToRemove.DeactivateEmitter();
}
else
{
if (BloodStolenParticles[Index].ParticleSystemComponent != None)
{
VectorParameterParticle.X = WorldInfo.TimeDilation;
VectorParameterParticle.Y = WorldInfo.TimeDilation;
VectorParameterParticle.Z = WorldInfo.TimeDilation;
BloodStolenParticles[Index].ParticleSystemComponent.SetVectorParameter( name("ZedtimeScale"), VectorParameterParticle );
}
BloodStolenParticles[Index].UpdateDestination( MuzzleFlashSocketLocation, BloodParticlesMidPointSocketLocation );
if (FRand() > 0.47)
{
BloodSplashVelocity.x = 0;
BloodSplashVelocity.y = RandRange(-100, 100);
BloodSplashVelocity.z = -200;
SpawnBloodSplash(BloodSplashClass, BloodStolenParticles[Index].Location, BloodSplashVelocity);
}
}
}
}
Super.Tick(DeltaTime);
}
simulated function FirstPersonFireEffects(Weapon W, vector HitLocation)
{
super.FirstPersonFireEffects(W, HitLocation);
}
simulated function bool ThirdPersonFireEffects(vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local EAnimSlotStance AnimType;
local bool bResult;
bIsChargeEffectsActive = true;
bIsBloodParticlesEffectActive = true;
//bResult = Super(KFWeaponAttachment).ThirdPersonFireEffects(HitLocation,P,ThirdPersonAnimRateByte);
SpawnTracer(GetMuzzleLocation(), HitLocation);
// Effects below this point are culled based on visibility and distance
if ( !ActorEffectIsRelevant(P, false, MaxFireEffectDistance) )
{
return false;
}
DecodeThirdPersonAnimRate( ThirdPersonAnimRateByte );
// Weapon shoot anims
if( !bWeapMeshIsPawnMesh && bHasToStopDoingFireAnim == false )
{
PlayWeaponFireAnim();
bHasToStopDoingFireAnim = true;
}
if( P.IsDoingSpecialMove() && P.SpecialMoves[P.SpecialMove].bAllowFireAnims )
{
AnimType = EAS_Additive;
}
else
{
AnimType = EAS_FullBody;
}
// Character shoot anims
if ( !P.IsDoingSpecialMove() || AnimType == EAS_Additive )
{
if(!bHasToStopDoingFireAnimB)
{
bHasToStopDoingFireAnimB = true;
PlayPawnFireAnim( P, AnimType );
}
// interrupt other weapon action anims (e.g. Reload)
if( !P.IsDoingSpecialMove() )
{
P.StopBodyAnim(P.bIsCrouched ? EAS_CH_UpperBody : EAS_UpperBody, 0.1f);
}
if ( OnWeaponStateChanged != None )
{
OnWeaponStateChanged(true);
}
}
CauseMuzzleFlash(P.FiringMode);
// Wider effect distances for fire spray. Called on Instigator to go beyond the weapon mesh cull distance
if ( P.FiringMode != 1 && P.ActorEffectIsRelevant(P, false, 15000, 2000) && !bIsDisabledSprayVisualAndMesh )
{
TurnOnFireSpray();
bResult = true;
}
return bResult;
}
simulated function StopThirdPersonFireEffects(optional bool bForce)
{
Super.StopThirdPersonFireEffects(bForce);
bIsChargeEffectsActive = false;
bIsBloodParticlesEffectActive = false;
RemoveAllBloodParticles();
bIsDisabledSprayVisualAndMesh = false;
if (ChargingPSC != none)
{
ChargingPSC.SetActive(false);
}
if (ChargedPSC != none)
{
ChargedPSC.SetActive(false);
}
bHasToStopDoingFireAnim = false;
bHasToStopDoingFireAnimB = false;
}
simulated function CauseMuzzleFlash(byte FiringMode)
{
if (MuzzleFlash == None && MuzzleFlashTemplate != None)
{
AttachMuzzleFlash();
}
Super.CauseMuzzleFlash(FiringMode);
}
simulated protected function TurnOnPilot()
{
Super.TurnOnPilot();
if( FlamePool[0] != None && KFSprayActor_HRG_Vampire(FlamePool[0]) != None && KFSprayActor_HRG_Vampire(FlamePool[0]).OwnerWeapon == None)
{
KFSprayActor_HRG_Vampire(FlamePool[0]).OwnerWeapon = KFWeap_HRG_Vampire(KFPawn_Human(Instigator).MyKFWeapon);
}
if( FlamePool[1] != None && KFSprayActor_HRG_Vampire(FlamePool[1]) != None && KFSprayActor_HRG_Vampire(FlamePool[1]).OwnerWeapon == None)
{
KFSprayActor_HRG_Vampire(FlamePool[1]).OwnerWeapon = KFWeap_HRG_Vampire(KFPawn_Human(Instigator).MyKFWeapon);
}
}
simulated function CreateBloodParticle(float DeltaTime, KFPawn_Monster Monster)
{
Local KFEmit_DirectionalPath Emitter;
local vector DestinationLocation, MonsterLocation, BloodParticlesMidPointSocketLocation;
local Rotator DestinationRotation, BloodParticlesMidPointSocketRotation;
local vector BloodSplashVelocity;
local int Index;
if( BloodStolenControlTime > 0 )
{
BloodStolenControlTime -= DeltaTime;
return;
}
Emitter = none;
for( Index = (NumBloodStolenParticlesForPool - 1) ; Index >= 0 ; Index-- )
{
if(BloodStolenParticles[Index].IsEnabled == false)
{
//`log("I gave the emitter");
Emitter = BloodStolenParticles[Index];
break;
}
}
if(Emitter == none)
{
//`log("NO EMITTER");
return;
}
if( WeapMesh != none && WeapMesh.SkeletalMesh != none)
{
GetFlameSocketLocAndRot(DestinationLocation, DestinationRotation);
WeapMesh.GetSocketWorldLocationAndRotation('BloodParticlesMidPoint', BloodParticlesMidPointSocketLocation, BloodParticlesMidPointSocketRotation);
}
BloodStolenControlTime += SpawnRateBloodParticles_3P;
MonsterLocation = ActiveFlameSpray.GetLastContactPositionMeshHit();
if (IsZero(MonsterLocation))
{
Monster.Mesh.GetBoneLocation('Spine1');
}
if(MonsterLocation == vect(0,0,0))
{
MonsterLocation = Monster.Location + vect(0,0,20);
}
if (FRand() > 0.4)
{
BloodSplashVelocity = BloodParticlesMidPointSocketLocation - MonsterLocation;
BloodSplashVelocity = VRandCone(vect(0,0,-1), PI / 5) * 100;
SpawnBloodSplash(BloodSplashClass, MonsterLocation, BloodSplashVelocity);
}
//Emitter = Spawn(class'KFEmit_DirectionalPath',,, MonsterLocation);
Emitter.ParticleSpeed = SpeedBloodParticles_3P;
Emitter.RateTickCheckHasReached = 0.2;
//BloodStolenParticles.AddItem(Emitter);
Emitter.SetLocation(MonsterLocation);
Emitter.SetDestination(DestinationLocation, BloodParticlesMidPointSocketLocation, 20, 20, 50, 50, 0);
Emitter.ActivateEmitter();
//Emitter.isEnabled = true;
}
simulated function SetChargePercentage(float ChargePercentage)
{
ChargeRTPC = ChargePercentage;
bIsCharging = false;
bIsFullyCharged = false;
if (ChargeRTPC >= 0.0)
{
bIsCharging = true;
}
if (ChargeRTPC >= 1.0)
{
bIsFullyCharged = true;
}
}
simulated function SetZedCurrentlyBeingSprayed(KFPawn_Monster ZedCurrentlyBeingSprayed)
{
oZedPreviouslyBeingSprayed = oZedCurrentlyBeingSprayed;
oZedCurrentlyBeingSprayed = ZedCurrentlyBeingSprayed;
}
simulated function DisableSprayVisualAndMesh()
{
bIsDisabledSprayVisualAndMesh = true;
}
function SpawnBloodSplash( class<KFProj_BloodSplash> SpawnClass, vector SpawnLoc, vector SpawnVel )
{
local TraceHitInfo HitInfo;
local vector HitLocation, HitRotation;
local KFGoreManager GoreManager;
// Grab the gore manager
GoreManager = KFGoreManager(WorldInfo.MyGoreEffectManager);
if (GoreManager == none || oZedCurrentlyBeingSprayed == none)
{
return;
}
//EffectStartTrace = Location + vect(0,0,1) * 4.f;
//EffectEndTrace = EffectStartTrace - vect(0,0,1) * 32.f;
// Find where to put the decal
Trace(HitLocation, HitRotation, SpawnLoc + SpawnVel * 32.f, SpawnLoc, false,, HitInfo, TRACEFLAG_Bullet);
//DrawDebugLine(SpawnLoc,SpawnLoc + SpawnVel * 32.f,0,255,0,TRUE);
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitRotation) )
{
HitRotation = vect(0,0,1);
}
//Put the decals
GoreManager.LeaveABloodSplatterDecal(oZedCurrentlyBeingSprayed, HitLocation, HitRotation);
//GoreManager. LeaveAPersistentBloodSplat(HitLocation, HitNormal, 1.0);
if (oZedCurrentlyBeingSprayed != none)
{
GoreManager.CausePersistentBlood(oZedCurrentlyBeingSprayed, class'KFDamageType', HitLocation, vect(0,0,-1), 0, false, false);
}
}
simulated function RemoveAllBloodParticles()
{
local int Index;
local KFEmit_DirectionalPath EmitterToRemove;
for( Index = (NumBloodStolenParticlesForPool - 1) ; Index >= 0 ; Index-- )
{
EmitterToRemove = BloodStolenParticles[Index];
//BloodStolenParticles.Remove(Index, 1);
EmitterToRemove.DeactivateEmitter();
}
}
defaultproperties
{
ChargeRTPC=0
bIsChargeEffectsActive=false
bIsBloodParticlesEffectActive=false
bIsDisabledSprayVisualAndMesh=false
MuzzleFlashTemplate=KFMuzzleFlash'WEP_HRG_Vampire_Arch.Wep_HRG_Vampire_MuzzleFlash_3P'
ChargingEffect=ParticleSystem'WEP_HRG_Vampire_EMIT.FX_HRG_Vampire_BlobCharge_3P_01'
ChargedEffect=ParticleSystem'WEP_HRG_Vampire_EMIT.FX_HRG_Vampire_FullCharge'
BloodStolenEffect=ParticleSystem'WEP_HRG_Vampire_EMIT.FX_HRG_Vampire_BloodStolen_3P'
BloodSplashClass=KFProj_BloodSplash
RateUpdateDestinationBloodParticles = 0.7
NumBloodStolenParticlesForPool = 15;
}