//============================================================================= // KFWeap_HRG_EMP_ArcGenerator //============================================================================= // A gun that zaps zeds //============================================================================= // Killing Floor 2 // Copyright (C) 2015 Tripwire Interactive LLC // FFerrando @ saber3d //============================================================================= /* Default firemode: -max number of secondary arcs -secondary arcs max range -main beam max range -aiming speed reduction Alt firemode: -projectile speed -projectile max range -zapTick (time between zaps) -max number of Zeds zapped -zap max range */ class KFWeap_HRG_EMP_ArcGenerator extends KFWeap_FlameBase; Replication { if(role == role_authority && bNetDirty) oZedCurrentlyBeingSprayed, MaxNumberOfZedsZapped, MaxDistanceToBeZapped, ZapInterval, ChainDamage; } /** Shoot animation to play when shooting secondary fire */ var(Animations) const editconst name FireHeavyAnim; /** Shoot animation to play when shooting secondary fire last shot */ var(Animations) const editconst name FireLastHeavyAnim; /** Shoot animation to play when shooting secondary fire last shot when aiming */ var(Animations) const editconst name FireLastHeavySightedAnim; /** Alt-fire explosion template */ var() GameExplosion ExplosionTemplate; /**************************** HRG SPRAY STUFF*/ struct BeamAttachedToActor { var ParticleSystemComponent oBeam; var KFPawn_Monster oAttachedZed; }; var array vRecentlyZappedActors; var array vAuxDeletionArrayChainedActors; var array vActiveBeamEffects; var array vAuxDeletionArray; var repnotify KFPawn_Monster oZedCurrentlyBeingSprayed; var ParticleSystem BeamPSCTemplate; var string EmitterPoolClassPath; var EmitterPool vBeamEffects; var int MaxNumberOfZedsZapped; var int MaxDistanceToBeZapped; var float ZapInterval; var int ChainDamage; /*********************** */ /** Handle one-hand fire anims */ simulated function name GetWeaponFireAnim(byte FireModeNum) { local bool bPlayFireLast; bPlayFireLast = ShouldPlayFireLast(FireModeNum); if ( bUsingSights ) { if( bPlayFireLast ) { if ( FireModeNum == ALTFIRE_FIREMODE ) { return FireLastHeavySightedAnim; } else { return FireLastSightedAnim; } } else { return FireSightedAnims[FireModeNum]; } } else { if( bPlayFireLast ) { if ( FireModeNum == ALTFIRE_FIREMODE ) { return FireLastHeavyAnim; } else { return FireLastAnim; } } else { if ( FireModeNum == ALTFIRE_FIREMODE ) { return FireHeavyAnim; } else { return FireAnim; } } } } /** * Instead of a toggle, just immediately fire alternate fire. */ simulated function AltFireMode() { // LocalPlayer Only if ( !Instigator.IsLocallyControlled() ) { return; } StartFire(ALTFIRE_FIREMODE); } /** Disable auto-reload for alt-fire */ simulated function bool ShouldAutoReload(byte FireModeNum) { local bool bRequestReload; bRequestReload = Super.ShouldAutoReload(FireModeNum); // Must be completely empty for auto-reload or auto-switch if ( FireModeNum == ALTFIRE_FIREMODE && AmmoCount[0] > 0 ) { bPendingAutoSwitchOnDryFire = false; return false; } return bRequestReload; } static simulated event EFilterTypeUI GetTraderFilter() { return FT_Electric; } simulated function StartPilotSound() { if( Instigator != none && Instigator.IsLocallyControlled() && Instigator.IsFirstPerson() ) { //PostAkEventOnBone(PilotLightPlayEvent, PilotLightSocketName, true, true); } } /** * Stops playing looping Pilot light sound */ simulated function StopPilotSound() { //PostAkEventOnBone(PilotLightStopEvent, PilotLightSocketName, true, true); } /********************************************************************** *********************************************************************** */ simulated function ReplicatedEvent(name VarName) { if(VarName == nameof(oZedCurrentlyBeingSprayed)) { if(role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { if(oZedCurrentlyBeingSprayed == none) { SprayEnded(); } } } } simulated function ChangeMaterial() { // Removed from base class /*local int i, Idx; if( BarrelHeat != LastBarrelHeat ) { for( i = 0; i < WeaponMICs.Length; ++i ) { if( WeaponMICs[i] != none ) { WeaponMICs[i].SetScalarParameterValue('Glow_Intensity', BarrelHeat); } } }*/ } simulated protected function TurnOnPilot() { Super.TurnOnPilot(); if( FlamePool[0] != None ) { KFSprayActor_ArcGenerator(FlamePool[0]).OwnerWeapon = self; MaxNumberOfZedsZapped=KFSprayActor_ArcGenerator(FlamePool[0]).MaxNumberOfZedsZapped; MaxDistanceToBeZapped=KFSprayActor_ArcGenerator(FlamePool[0]).MaxDistanceToBeZapped; ZapInterval=KFSprayActor_ArcGenerator(FlamePool[0]).ZapInterval; ChainDamage=KFSprayActor_ArcGenerator(FlamePool[0]).ChainDamage; } if( FlamePool[1] != None ) { KFSprayActor_ArcGenerator(FlamePool[1]).OwnerWeapon = self; } } simulated function float FlameHeatCalc() { //hack in order to make the arc gen always glow LastBarrelHeat = 1.0f; return 1.0f; } simulated event PostBeginPlay() { local class PoolClass; super.PostBeginPlay(); PoolClass = class(DynamicLoadObject(EmitterPoolClassPath, class'Class')); if (PoolClass != None) { vBeamEffects = Spawn(PoolClass, self,, vect(0,0,0), rot(0,0,0)); } } /*************************************** PARTICLE SYSTEM POOL AND ATTACHMENT MANAGEMENT ***************************************/ /** We so we detach the Component once we are done playing it **/ simulated function OnBeamEffectFinished( ParticleSystemComponent PSC ) { PSC.DeactivateSystem(); EndPSC(PSC); } //returns the position of the effect in the array, otherwise, -1 simulated function int SpawnBeam(Actor _OriginActor, Actor _DestinationActor) { local ParticleSystemComponent BeamPSC; local BeamAttachedToActor BeamAttachedInfo; local int i; //if actor is dupped in active beams, not chain again this to another beam for(i = 0; i < vActiveBeamEffects.Length; i++) { if(vActiveBeamEffects[i].oAttachedZed == _DestinationActor) { return -1; } } BeamPSC = vBeamEffects.SpawnEmitterCustomLifetime(BeamPSCTemplate); if(BeamPSC != none) { BeamPSC.SetBeamSourcePoint(0, _OriginActor.Location, 0); BeamPSC.SetBeamTargetPoint(0, _DestinationActor.Location, 0); BeamPSC.SetKillOnDeactivate(0, true); BeamPSC.SetAbsolute(false, false, false); BeamPSC.bUpdateComponentInTick = true; BeamAttachedInfo.oBeam = BeamPSC; BeamAttachedInfo.oAttachedZed = KFPawn_Monster(_DestinationActor); if(role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { BeamPSC.SetActive(true); AttachComponent(BeamPSC); } BeamAttachedInfo.oBeam.SetActive(true); vActiveBeamEffects.AddItem(BeamAttachedInfo); return vActiveBeamEffects.Length - 1; } else { } return -1; } simulated function MarkBeamToDeactivate(BeamAttachedToActor _BeamData) { vAuxDeletionArray.AddItem(_BeamData); } simulated function MarkZedToUnchain(DamagedActorInfo _DamageActorInfo) { vAuxDeletionArrayChainedActors.AddItem(_DamageActorInfo); } simulated function BeamAttachedToActor GetBeamFromActor(Actor _Actor) { local int i; for(i = 0; i < vActiveBeamEffects.Length; i++) { if(vActiveBeamEffects[i].oAttachedZed == _Actor) { return vActiveBeamEffects[i]; } } } simulated function DeactivateBeam(Actor _ChainedActor) { local int i; for(i = 0; i < vActiveBeamEffects.Length; i++) { if(vActiveBeamEffects[i].oAttachedZed == _ChainedActor) { OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); vActiveBeamEffects.RemoveItem(vActiveBeamEffects[i]); break; } } } simulated function EndPSC(ParticleSystemComponent _Value) { /*if(vCachedBeamEffects.Length < MaxNumberOfZedsZapped) { vCachedBeamEffects.AddItem(_Value); }*/ _Value.KillParticlesForced(); vBeamEffects.OnParticleSystemFinished(_Value); DetachComponent(_Value); } /*************************************** END PARTICLE SYSTEM POOL AND ATTACHMENT MANAGEMENT ***************************************/ /*************************************** CHAIN LOGIC FUNCTIONS ***************************************/ simulated function SetCurrentSprayedZed(KFPawn_Monster _Monster) { if(role == role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { oZedCurrentlyBeingSprayed = _Monster; bNetDirty=true; } } //returns true if it has successfully chained the zed, false otherwise (ex: dupe zed in the array) function bool ChainZed(Actor _ZedToChain) { local DamagedActorInfo NewActorInfo; local int i; for (i = vRecentlyZappedActors.Length - 1; i >= 0; i--) { //remove everything if pawn died or interval is greater than the time its supposed to be in here; if(vRecentlyZappedActors[i].HitActor == _ZedToChain) { return false; } } NewActorInfo.HitActor = _ZedToChain; NewActorInfo.HitTime = WorldInfo.TimeSeconds; vRecentlyZappedActors.AddItem(NewActorInfo); return true; } function UnchainZed(DamagedActorInfo _ZedToUnchain) { vRecentlyZappedActors.RemoveItem(_ZedToUnchain); } function bool CheckRecentlyZapped(Actor _ActorToCheck) { local int i; local bool bZapedRecently; bZapedRecently = false; for (i = vRecentlyZappedActors.Length - 1; i >= 0; i--) { if (vRecentlyZappedActors[i].HitActor == _ActorToCheck) { //`Warn("FOUND ACTOR. WorldInfo.TimeSeconds = " $(WorldInfo.TimeSeconds)$ ""); //`Warn("FOUND ACTOR. vRecentlyZappedActors[i].HitTime = " $(vRecentlyZappedActors[i].HitTime)$ ""); //`Warn("FOUND ACTOR. INTERVAL = " $(WorldInfo.TimeSeconds - vRecentlyZappedActors[i].HitTime)$ ""); // Only damage at a specified rate, so return if it's too soon if ((WorldInfo.TimeSeconds - vRecentlyZappedActors[i].HitTime) < ZapInterval) { bZapedRecently = true; } break; } } return bZapedRecently; } function UpdateLastHitTimeForActor(Actor _ActorToCheck) { local int i; for (i = vRecentlyZappedActors.Length - 1; i >= 0; i--) { if (vRecentlyZappedActors[i].HitActor == _ActorToCheck) { //`Warn("SETTING TIME: " $WorldInfo.TimeSeconds$ ""); vRecentlyZappedActors[i].HitTime = WorldInfo.TimeSeconds; break; } } } simulated function ChainNearZeds(Actor _TouchActor) { local KFPawn_Monster oMonsterPawn; //`Warn("ChainNearZeds(Actor _TouchActor)"); //we get all pawns from the world to check them foreach WorldInfo.AllPawns( class'KFPawn_Monster', oMonsterPawn ) { //if its alive and its not the main sprayed monster if( oMonsterPawn.IsAliveAndWell() && oMonsterPawn != _TouchActor) { //if its close enough to be zapped if( VSizeSQ(oMonsterPawn.Location - _TouchActor.Location) < Square(MaxDistanceToBeZapped) ) { if(vActiveBeamEffects.Length < MaxNumberOfZedsZapped) { //if we have nothing in between if(FastTrace(_TouchActor.Location, oMonsterPawn.Location, vect(0,0,0)) == false) { continue; } if(_TouchActor.IsA('KFPawn_Monster')) { if(role == role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { ChainZed(oMonsterPawn); } SpawnBeam(_TouchActor, oMonsterPawn); } } else { break; } } } } } /*************************************** CHAIN LOGIC FUNCTIONS END ***************************************/ simulated event Tick(float DeltaTime) { local int i; local vector BeamStartPoint, BeamEndPoint; Super.Tick(DeltaTime); if(oZedCurrentlyBeingSprayed != none) { //if we have space for one more zed to chain, we try to chain one zed if(vActiveBeamEffects.Length < MaxNumberOfZedsZapped && !CheckRecentlyZapped(oZedCurrentlyBeingSprayed)) { ChainNearZeds(oZedCurrentlyBeingSprayed); } //`Warn(vActiveBeamEffects.Length); //check current beams for (i = vActiveBeamEffects.Length - 1; i >= 0; i--) { //if a current beam has gone out of sight (we have a wall in between for example), remove the beam and continue to next beam if(FastTrace(vActiveBeamEffects[i].oAttachedZed.Location, oZedCurrentlyBeingSprayed.Location, vect(0,0,0)) == false) { //OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); MarkBeamToDeactivate(GetBeamFromActor(vRecentlyZappedActors[i].HitActor)); continue; } //if its not near enough to stay zapped, we break the chain if (VSizeSQ(vActiveBeamEffects[i].oAttachedZed.Location - oZedCurrentlyBeingSprayed.Location) < Square(MaxDistanceToBeZapped)) { //if has been recently damaged, do not take damage again until the fire rate tells us if( !CheckRecentlyZapped(vActiveBeamEffects[i].oAttachedZed)) { //take damage if(vActiveBeamEffects[i].oAttachedZed.IsAliveAndWell()) { if(role == role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { ChainedZapDamageFunction(vActiveBeamEffects[i].oAttachedZed, oZedCurrentlyBeingSprayed); UpdateLastHitTimeForActor(vActiveBeamEffects[i].oAttachedZed); } if(role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { //`warn(vActiveBeamEffects[i].oAttachedZed.Location); BeamStartPoint = oZedCurrentlyBeingSprayed.Mesh.GetBoneLocation('Spine1'); BeamEndPoint = vActiveBeamEffects[i].oAttachedZed.Mesh.GetBoneLocation('Spine1'); if(BeamStartPoint == vect(0,0,0)) BeamStartPoint = oZedCurrentlyBeingSprayed.Location; if(BeamEndPoint == vect(0,0,0)) BeamEndPoint = vActiveBeamEffects[i].oAttachedZed.Location; vActiveBeamEffects[i].oBeam.SetBeamSourcePoint(0, BeamStartPoint, 0); vActiveBeamEffects[i].oBeam.SetBeamTargetPoint(0, BeamEndPoint, 0); } if(!vActiveBeamEffects[i].oAttachedZed.IsAliveAndWell()) { //OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); MarkBeamToDeactivate(GetBeamFromActor(vActiveBeamEffects[i].oAttachedZed)); } } } } else { //OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); if(role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) MarkBeamToDeactivate(GetBeamFromActor(vActiveBeamEffects[i].oAttachedZed)); } } } if(oZedCurrentlyBeingSprayed == none && (role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone)) { for(i = 0; i < vActiveBeamEffects.Length; i++) { OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); } vActiveBeamEffects.Remove(0, vActiveBeamEffects.Length); } else if(oZedCurrentlyBeingSprayed != none && (role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone)) { `log(vActiveBeamEffects.Length); for(i = 0; i < vActiveBeamEffects.Length; i++) { if(!vActiveBeamEffects[i].oAttachedZed.IsAliveAndWell()) { //OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); MarkBeamToDeactivate(GetBeamFromActor(vActiveBeamEffects[i].oAttachedZed)); } } for(i = 0; i < vAuxDeletionArray.Length; i++) { OnBeamEffectFinished(vAuxDeletionArray[i].oBeam); vAuxDeletionArray.RemoveItem(vAuxDeletionArray[i]); } } if(role == role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { for (i = vRecentlyZappedActors.Length - 1; i >= 0; i--) { //remove everything if pawn died if(vRecentlyZappedActors[i].HitActor == none ) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); //UnchainZed(vRecentlyZappedActors[i]); MarkZedToUnchain(vRecentlyZappedActors[i]); } //remove everything if pawn died if(!KFPawn_Monster(vRecentlyZappedActors[i].HitActor).IsAliveAndWell()) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); //UnchainZed(vRecentlyZappedActors[i]); MarkZedToUnchain(vRecentlyZappedActors[i]); } //remove if interval is greater than the time its supposed to be in here; if(((WorldInfo.TimeSeconds - vRecentlyZappedActors[i].HitTime) > 1.f)) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); //UnchainZed(vRecentlyZappedActors[i]); MarkZedToUnchain(vRecentlyZappedActors[i]); } } for(i = 0; i < vAuxDeletionArrayChainedActors.Length; i++) { UnchainZed(vAuxDeletionArrayChainedActors[i]); } vAuxDeletionArrayChainedActors.Remove(0, vAuxDeletionArrayChainedActors.Length); } /*if(role != role_authority || WorldInfo.NetMode == NM_ListenServer || WorldInfo.NetMode == NM_StandAlone) { for (i = vRecentlyZappedActors.Length - 1; i >= 0; i--) { //remove everything if pawn died if(vRecentlyZappedActors[i].HitActor == none ) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); MarkZedToUnchain(vRecentlyZappedActors[i]); } //remove everything if pawn died if(!KFPawn_Monster(vRecentlyZappedActors[i].HitActor).IsAliveAndWell()) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); MarkZedToUnchain(vRecentlyZappedActors[i]); } //remove if interval is greater than the time its supposed to be in here; if(((WorldInfo.TimeSeconds - vRecentlyZappedActors[i].HitTime) > 1.f)) { DeactivateBeam(vRecentlyZappedActors[i].HitActor); MarkZedToUnchain(vRecentlyZappedActors[i]); } } }*/ } /** Notification that a direct impact has occurred. */ event ProcessDirectImpact() { if( KFPlayer != none ) { KFPlayer.AddShotsHit(1); } } function ChainedZapDamageFunction(Actor _TouchActor, Actor _OriginActor) { local vector Momentum; local TraceHitInfo HitInfo; local Pawn TouchPawn; local int TotalDamage; if (_OriginActor != none) { Momentum = _TouchActor.Location - _OriginActor.Location; } //Momentum *= (MomentumScale / DistToHitActor); if (ChainDamage > 0) { TouchPawn = Pawn(_TouchActor); // Let script know that we hit something if (TouchPawn != none) { ProcessDirectImpact(); } //`Warn("["$WorldInfo.TimeSeconds$"] Damaging "$_TouchActor.Name$" for "$ChainDamage$", Dist: "$VSize(_TouchActor.Location - _OriginActor.Location)); TotalDamage = ChainDamage * GetUpgradeDamageMod(); _TouchActor.TakeDamage(TotalDamage, KFPlayer, _TouchActor.Location, Momentum, class'KFDT_EMP_ArcGenerator_DefaultFiremodeZapDamage', HitInfo, self); } } simulated function SprayEnded() { local int i; /*for (i = 0; i < vActiveBeamEffects.Length - 1; i++) { DeactivateBeam(vActiveBeamEffects[i].oAttachedZed); }*/ //`Warn(vActiveBeamEffects.Length); for(i = 0; i < vActiveBeamEffects.Length; i++) { OnBeamEffectFinished(vActiveBeamEffects[i].oBeam); } vActiveBeamEffects.Remove(0, vActiveBeamEffects.Length); } /********************************************************************************** */ defaultproperties { FlameSprayArchetype=KFSprayActor_ArcGenerator'WEP_HRG_ArcGenerator_ARCH.WEP_HRG_ArcGenerator_Spray' // Shooting Animations bHasFireLastAnims=true FireSightedAnims[0]=Shoot FireSightedAnims[1]=Shoot_Heavy_Iron FireLastHeavySightedAnim=Shoot_Heavy_Iron_Last FireHeavyAnim=Shoot_Heavy FireLastHeavyAnim=Shoot_Heavy_Last // FOV MeshIronSightFOV=52 PlayerIronSightFOV=80 // Zooming/Position IronSightPosition=(X=3,Y=0,Z=0) PlayerViewOffset=(X=5.0,Y=9,Z=-3) // Depth of field DOF_FG_FocalRadius=150 DOF_FG_MaxNearBlurSize=1 // Content PackageKey="HRG_ArcGenerator" FirstPersonMeshName="WEP_1P_HRG_ArcGenerator_MESH.Wep_1stP_HRG_ArcGenerator_Rig" FirstPersonAnimSetNames(0)="WEP_1p_HRG_ArcGenerator_ANIM.WEP_1p_HRG_ArcGenerator_ANIM" PickupMeshName="WEP_3P_HRG_ArcGenerator_MESH.Wep_HRG_ArcGenerator_Pickup" AttachmentArchetypeName="WEP_HRG_ArcGenerator_ARCH.HRG_ArcGenerator_3P" MuzzleFlashTemplateName="WEP_HRG_ArcGenerator_ARCH.Wep_HRG_ArcGenerator_MuzzleFlash" // Ammo MagazineCapacity[0]=90 //100 SpareAmmoCapacity[0]=450 //500 InitialSpareMags[0]=0 AmmoPickupScale[0]=0.5 bCanBeReloaded=true bReloadFromMagazine=true // Recoil maxRecoilPitch=150 minRecoilPitch=115 maxRecoilYaw=115 minRecoilYaw=-115 RecoilRate=0.085 RecoilMaxYawLimit=500 RecoilMinYawLimit=65034 RecoilMaxPitchLimit=900 RecoilMinPitchLimit=65035 RecoilISMaxYawLimit=75 RecoilISMinYawLimit=65460 RecoilISMaxPitchLimit=375 RecoilISMinPitchLimit=65460 RecoilViewRotationScale=0.25 IronSightMeshFOVCompensationScale=1.5 HippedRecoilModifier=1.5 // Inventory InventorySize=9 //10 GroupPriority=100 WeaponSelectTexture=Texture2D'WEP_UI_HRG_ArcGenerator_TEX.UI_WeaponSelect_HRG_ArcGenerator' // DEFAULT_FIREMODE FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity' FiringStatesArray(DEFAULT_FIREMODE)=SprayingFire WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Custom FireInterval(DEFAULT_FIREMODE)=+0.1//+0.07 // 850 RPM MinAmmoConsumed=2 //3 FireOffset=(X=30,Y=4.5,Z=-5) // ALT_FIREMODE WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile Spread(ALTFIRE_FIREMODE) = 0.0085 FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_ArcGeneratorSphereBlast' FireInterval(ALTFIRE_FIREMODE)=+1.0 //+0.223 //269 RPMs AmmoCost(ALTFIRE_FIREMODE)=15 PenetrationPower(ALTFIRE_FIREMODE)=40.0 //10.0 InstantHitDamage(ALTFIRE_FIREMODE)=220 //180 //185 //200 InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_EMP_ArcGeneratorSphereImpact' // BASH_FIREMODE InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_ArcGenerator' InstantHitDamage(BASH_FIREMODE)=26 // Fire Effects WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_Fire_3P_Loop', FirstPersonCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_Fire_1P_Loop') WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_AltFire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_AltFire_1P') WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_Fire_3P_LoopEnd', FirstPersonCue=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_Fire_1P_LoopEnd') //@todo: add akevents when we have them WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_Microwave_Gun.Play_SA_MicrowaveGun_DryFire' WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_Microwave_Gun.Play_SA_MicrowaveGun_DryFire' PilotLightPlayEvent=AkEvent'WW_WEP_HRG_ArcGenerator.Play_HRG_ArcGenerator_PilotLight_Loop' PilotLightStopEvent=AkEvent'WW_WEP_HRG_ArcGenerator.Stop_HRG_ArcGenerator_PilotLight_Loop' // Advanced (High RPM) Fire Effects bLoopingFireAnim(DEFAULT_FIREMODE)=true bLoopingFireSnd(DEFAULT_FIREMODE)=true SingleFireSoundIndex=FIREMODE_NONE // Attachments bHasIronSights=true bHasFlashlight=false AssociatedPerkClasses(0)=class'KFPerk_Survivalist' BonesToLockOnEmpty=(RW_Handle1, RW_BatteryCylinder1, RW_BatteryCylinder2, RW_LeftArmSpinner, RW_RightArmSpinner, RW_LockEngager2, RW_LockEngager1) // AI Warning bWarnAIWhenFiring=true MaxAIWarningDistSQ=2250000 // Weapon Upgrade stat boosts //WeaponUpgrades[1]=(IncrementDamage=1.15f,IncrementWeight=1) WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1))) BeamPSCTemplate = ParticleSystem'WEP_HRG_ArcGenerator_EMIT.FX_Beam_Test' EmitterPoolClassPath="Engine.EmitterPool" oZedCurrentlyBeingSprayed=none; MaxNumberOfZedsZapped=3 MaxDistanceToBeZapped=2500 ZapInterval=0.07 ChainDamage=5; bAlwaysRelevant = true bOnlyRelevantToOwner = false }