410 lines
11 KiB
Ucode
410 lines
11 KiB
Ucode
//=============================================================================
|
|
// KFWeapAttach_LazerCutter
|
|
//=============================================================================
|
|
//
|
|
//=============================================================================
|
|
// Killing Floor 2
|
|
// Copyright (C) 2017 Tripwire Interactive LLC
|
|
//=============================================================================
|
|
class KFWeapAttach_LazerCutter extends KFWeapAttach_SprayBase;
|
|
|
|
/** When the beam started charging*/
|
|
var float StartFireTime;
|
|
/** The amount of time spent charging*/
|
|
var float ChargeTime;
|
|
/** Whether the beam is at max charge*/
|
|
var bool bIsFullyCharged;
|
|
/** Whether the beam is currently charging*/
|
|
var bool bIsCharging;
|
|
|
|
var transient ParticleSystemComponent ChargingPSC;
|
|
var ParticleSystem ChargingEffect;
|
|
|
|
/** Muzzle flash effects per level */
|
|
var const ParticleSystem MuzzleFlashEffectL1;
|
|
var const ParticleSystem MuzzleFlashEffectL2;
|
|
var const ParticleSystem MuzzleFlashEffectL3;
|
|
|
|
/** Color for the weapon center when charging/firing*/
|
|
var LinearColor DefaultFireModeColor;
|
|
var LinearColor EnergyColorL0;
|
|
var LinearColor EnergyColorL1;
|
|
var LinearColor EnergyColorL2;
|
|
var LinearColor EnergyColorL3;
|
|
|
|
/** Extra materials on the laser cutter*/
|
|
var int WeaponMaterialCount;
|
|
var array<MaterialInstanceConstant> WeaponMICs;
|
|
|
|
/** Names of the charging/firing animations specific to the laser cutter*/
|
|
const WeaponChargeAnim = 'Charge_Beam';
|
|
const WeaponBeamAnim = 'Shoot_Beam';
|
|
|
|
const PawnChargeAnim = 'ADD_Charge_Beam';
|
|
const PawnChargeAnimCrouch = 'ADD_CH_Charge_Beam';
|
|
const PawnChargeAnimIron = 'ADD_Iron_Charge_Beam';
|
|
const PawnBeamAnim = 'ADD_Shoot_Beam';
|
|
const PawnBeamAnimCrouch = 'ADD_CH_Shoot_Beam';
|
|
const PawnBeamAnimIron = 'ADD_Iron_Shoot_Beam';
|
|
|
|
/** Used to gate the beam firing muzzle flash to only play once after the beam starts */
|
|
var bool bPlayMuzzleFlash;
|
|
|
|
simulated function PlayWeaponFireAnim()
|
|
{
|
|
local float Duration;
|
|
|
|
if (bIsCharging) // charging the lazer
|
|
{
|
|
Duration = WeapMesh.GetAnimLength(WeaponChargeAnim);
|
|
WeapMesh.PlayAnim(WeaponChargeAnim, Duration / ThirdPersonAnimRate, true, false);
|
|
}
|
|
else if (Instigator.FiringMode == 6) // firing the lazer
|
|
{
|
|
Duration = WeapMesh.GetAnimLength(WeaponBeamAnim);
|
|
WeapMesh.PlayAnim(WeaponBeamAnim, Duration / ThirdPersonAnimRate, , false);
|
|
}
|
|
else
|
|
{
|
|
super.PlayWeaponFireAnim();
|
|
}
|
|
}
|
|
|
|
/** Plays fire animation on pawn */
|
|
simulated function PlayPawnFireAnim(KFPawn P, EAnimSlotStance AnimType)
|
|
{
|
|
if (bIsCharging) // charging the lazer
|
|
{
|
|
if (P.bIsCrouched)
|
|
{
|
|
P.PlayBodyAnim(PawnChargeAnimCrouch, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime, true,false);
|
|
}
|
|
else if (P.bIsWalking)
|
|
{
|
|
P.PlayBodyAnim(PawnChargeAnimIron, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime, true, false);
|
|
}
|
|
else
|
|
{
|
|
P.PlayBodyAnim(PawnChargeAnim, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime, true, false);
|
|
}
|
|
}
|
|
else if (Instigator.FiringMode == 6) // firing the lazer
|
|
{
|
|
if (P.bIsCrouched)
|
|
{
|
|
P.PlayBodyAnim(PawnBeamAnimCrouch, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime,, false);
|
|
}
|
|
else if (P.bIsWalking)
|
|
{
|
|
P.PlayBodyAnim(PawnBeamAnimIron, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime,, false);
|
|
}
|
|
else
|
|
{
|
|
P.PlayBodyAnim(PawnBeamAnim, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime,, false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
super.PlayPawnFireAnim(P, AnimType);
|
|
}
|
|
}
|
|
|
|
simulated function StartFire()
|
|
{
|
|
StartFireTime = WorldInfo.TimeSeconds;
|
|
ChargeTime = 0.0f;
|
|
|
|
// start the beam charging
|
|
bIsFullyCharged = false;
|
|
bIsCharging = true;
|
|
|
|
// setup and play the beam charge particle system
|
|
if (ChargingPSC == none)
|
|
{
|
|
ChargingPSC = new(self) class'ParticleSystemComponent';
|
|
|
|
if (WeapMesh != none)
|
|
{
|
|
WeapMesh.AttachComponentToSocket(ChargingPSC, 'MuzzleFlash');
|
|
}
|
|
else
|
|
{
|
|
AttachComponent(ChargingPSC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ChargingPSC.ActivateSystem();
|
|
}
|
|
|
|
if (ChargingPSC != none)
|
|
{
|
|
ChargingPSC.SetTemplate(ChargingEffect);
|
|
}
|
|
}
|
|
|
|
/** Spawn tracer effects for this weapon */
|
|
simulated function SpawnTracer(vector EffectLocation, vector HitLocation)
|
|
{
|
|
local ParticleSystemComponent E;
|
|
local vector Dir;
|
|
local float DistSQ;
|
|
local float TracerDuration;
|
|
local KFTracerInfo TracerInfo;
|
|
|
|
if ( Instigator == None || Instigator.FiringMode >= TracerInfos.Length )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// only show tracers for the full auto mode (not the laser charge/firing)
|
|
if (Instigator.FiringMode != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// since the tracers only happen in full-auto mode, make sure this isn't set to charging
|
|
bIsCharging = false;
|
|
ChargeTime = 0.0f;
|
|
|
|
TracerInfo = TracerInfos[Instigator.FiringMode];
|
|
if( ((`NotInZedTime(self) && TracerInfo.bDoTracerDuringNormalTime)
|
|
|| (`IsInZedTime(self) && TracerInfo.bDoTracerDuringZedTime))
|
|
&& TracerInfo.TracerTemplate != none )
|
|
{
|
|
Dir = HitLocation - EffectLocation;
|
|
DistSQ = VSizeSq(Dir);
|
|
if ( DistSQ > TracerInfo.MinTracerEffectDistanceSquared )
|
|
{
|
|
// Lifetime scales based on the distance from the impact point. Subtract a frame so it doesn't clip.
|
|
TracerDuration = fMin( (Sqrt(DistSQ) - 100.f) / TracerInfo.TracerVelocity, 1.f );
|
|
if( TracerDuration > 0.f )
|
|
{
|
|
E = WorldInfo.MyEmitterPool.SpawnEmitter( TracerInfo.TracerTemplate, EffectLocation, rotator(Dir) );
|
|
E.SetVectorParameter('Shotend', HitLocation);
|
|
E.SetFloatParameter( 'Tracer_Lifetime', TracerDuration );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
simulated function SetBeamColor(int ChargeLevel)
|
|
{
|
|
local LinearColor BeamColor;
|
|
local int i;
|
|
|
|
// create the reset of the weapon material instances if they don't already exist
|
|
if (WeaponMICs.Length == 0)
|
|
{
|
|
for (i = 1; i < WeaponMaterialCount; i++)
|
|
{
|
|
WeaponMICs.AddItem(WeapMesh.CreateAndSetMaterialInstanceConstant(i));
|
|
}
|
|
}
|
|
|
|
// always the default firemode color if in that state
|
|
if (Instigator.FiringMode == 0)
|
|
{
|
|
BeamColor = DefaultFireModeColor;
|
|
}
|
|
else
|
|
{
|
|
switch (ChargeLevel)
|
|
{
|
|
case 3:
|
|
BeamColor = EnergyColorL3;
|
|
break;
|
|
case 2:
|
|
BeamColor = EnergyColorL2;
|
|
break;
|
|
case 1:
|
|
BeamColor = EnergyColorL1;
|
|
break;
|
|
default:
|
|
BeamColor = EnergyColorL0;
|
|
break;
|
|
}
|
|
}
|
|
// set the beam color based on the charge level
|
|
WeaponMIC.SetVectorParameterValue('Energy_Color', BeamColor);
|
|
for (i = 0; i < WeaponMICs.Length; i++)
|
|
{
|
|
WeaponMICs[i].SetVectorParameterValue('Energy_Color', BeamColor);
|
|
}
|
|
}
|
|
|
|
simulated event Tick(float DeltaTime)
|
|
{
|
|
// if the beam is charging, reset the charge time
|
|
if (bIsCharging && !bIsFullyCharged)
|
|
{
|
|
ChargeTime = WorldInfo.TimeSeconds - StartFireTime;
|
|
}
|
|
|
|
// if the beam has just reached max charge level
|
|
if (bIsCharging && !bIsFullyCharged && GetChargeFXLevel() == class'KFWeap_AssaultRifle_LazerCutter'.default.MaxChargeLevel)
|
|
{
|
|
bIsFullyCharged = true;
|
|
}
|
|
|
|
if (bIsCharging)
|
|
{
|
|
SetBeamColor(GetChargeFXLevel());
|
|
}
|
|
// the default firemode now has a separate color
|
|
else if (Instigator.FiringMode == 0)
|
|
{
|
|
SetBeamColor(0);
|
|
}
|
|
|
|
Super.Tick(DeltaTime);
|
|
}
|
|
|
|
simulated function bool ThirdPersonFireEffects(vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte)
|
|
{
|
|
local bool bResult;
|
|
|
|
// Overriding the KFWeapAttach_SprayBase portion of this function, so call the base Super directly
|
|
bResult = Super(KFWeaponAttachment).ThirdPersonFireEffects(HitLocation, P, ThirdPersonAnimRateByte);
|
|
|
|
// Lazer fire mode turns on the spray
|
|
// CUSTOM_FIREMODE == 6
|
|
if (P.FiringMode == 6 && P.ActorEffectIsRelevant(P, false, 15000, 2000))
|
|
{
|
|
if (!bFireSpraying)
|
|
{
|
|
// play the muzzle flash on the first flash
|
|
bPlayMuzzleFlash = true;
|
|
}
|
|
|
|
// turn off the charging effect
|
|
if (ChargingPSC != none)
|
|
{
|
|
ChargingPSC.DeactivateSystem();
|
|
}
|
|
|
|
TurnOnFireSpray();
|
|
|
|
// no longer charging now that it's firing the beam
|
|
bIsCharging = false;
|
|
bResult = true;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
// stop looping weapon anim states or longer animations trying to play out their duration
|
|
simulated function ResetAnimationState()
|
|
{
|
|
local KFPawn P;
|
|
|
|
P = KFPawn(Instigator);
|
|
if (P != None)
|
|
{
|
|
P.StopBodyAnim(EAS_FullBody, 0.1f);
|
|
}
|
|
|
|
InterruptWeaponAnim();
|
|
}
|
|
|
|
simulated function StopThirdPersonFireEffects(optional bool bForce)
|
|
{
|
|
if (bFireSpraying)
|
|
{
|
|
ResetAnimationState();
|
|
}
|
|
|
|
// beam is over, return to default color
|
|
SetBeamColor(0);
|
|
|
|
Super.StopThirdPersonFireEffects(bForce);
|
|
}
|
|
|
|
simulated function FirstPersonFireEffects(Weapon W, vector HitLocation)
|
|
{
|
|
super.FirstPersonFireEffects(W, HitLocation);
|
|
|
|
if (Instigator.FiringMode == 6)
|
|
{
|
|
bIsCharging = false;
|
|
}
|
|
|
|
if (ChargingPSC != none)
|
|
{
|
|
ChargingPSC.DeactivateSystem();
|
|
}
|
|
}
|
|
|
|
simulated function CauseMuzzleFlash(byte FiringMode)
|
|
{
|
|
// ALTFIRE_FIREMODE == 1, used for the charging state
|
|
if (FiringMode != 1)
|
|
{
|
|
// if firing the charge mode, set the muzzle flash based on the charge level
|
|
if (FiringMode == 6)
|
|
{
|
|
if (MuzzleFlash == None && MuzzleFlashTemplate != None)
|
|
{
|
|
AttachMuzzleFlash();
|
|
}
|
|
|
|
if (bPlayMuzzleFlash)
|
|
{
|
|
switch (GetChargeFXLevel())
|
|
{
|
|
case 0:
|
|
case 1:
|
|
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleFlashEffectL1;
|
|
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleFlashEffectL1);
|
|
break;
|
|
case 2:
|
|
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleFlashEffectL2;
|
|
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleFlashEffectL2);
|
|
break;
|
|
case 3:
|
|
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleFlashEffectL3;
|
|
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleFlashEffectL3);
|
|
break;
|
|
}
|
|
|
|
bPlayMuzzleFlash = false;
|
|
// setting to 0 so that the muzzle flash doesn't get turned off based on a timer
|
|
MuzzleFlash.MuzzleFlash.Duration = 0.0f;
|
|
super.CauseMuzzleFlash(FiringMode);
|
|
}
|
|
}
|
|
// otherwise use the default
|
|
else
|
|
{
|
|
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleFlashTemplate.MuzzleFlash.ParticleSystemTemplate;
|
|
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleFlashTemplate.MuzzleFlash.ParticleSystemTemplate);
|
|
MuzzleFlash.MuzzleFlash.Duration = MuzzleFlashTemplate.MuzzleFlash.Duration;
|
|
super.CauseMuzzleFlash(FiringMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
function int GetChargeFXLevel()
|
|
{
|
|
return Min(ChargeTime / class'KFWeap_AssaultRifle_LazerCutter'.default.ChargeTimePerLevel, class'KFWeap_AssaultRifle_LazerCutter'.default.MaxChargeLevel);
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
PilotLightPlayEvent=AkEvent'WW_WEP_Lazer_Cutter.Play_WEP_LazerCutter_Idle_LP'
|
|
PilotLightStopEvent=AkEvent'WW_WEP_Lazer_Cutter.Stop_WEP_LazerCutter_Idle_LP'
|
|
|
|
MuzzleFlashEffectL1=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_01'
|
|
MuzzleFlashEffectL2=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_02'
|
|
MuzzleFlashEffectL3=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_03'
|
|
ChargingEffect=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Charge_00'
|
|
|
|
DefaultFireModeColor=(R=5.f,G=1.f,B=20.f)
|
|
EnergyColorL0=(R=5.f,G=1.f,B=20.f)
|
|
EnergyColorL1=(R=20.f,G=5.f,B=200.f)
|
|
EnergyColorL2=(R=5.f,G=25.f,B=200.f)
|
|
EnergyColorL3=(R=20.f,G=50.f,B=200.f)
|
|
|
|
WeaponMaterialCount=5;
|
|
}
|