upload
This commit is contained in:
52
KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc
Normal file
52
KFGameContent/Classes/KFDT_Ballistic_BlastBrawlersShotgun.uc
Normal file
@ -0,0 +1,52 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_BlastBrawlersShotgun
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_BlastBrawlersShotgun extends KFDT_Ballistic_Shotgun
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
if( super.CanDismemberHitZone( InHitZoneName ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ( InHitZoneName )
|
||||
{
|
||||
case 'lupperarm':
|
||||
case 'rupperarm':
|
||||
case 'chest':
|
||||
case 'heart':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BloodSpread=0.4
|
||||
BloodScale=0.6
|
||||
|
||||
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-500
|
||||
KDeathVel=350
|
||||
//KDamageImpulse=350
|
||||
//KDeathUpKick=120
|
||||
//KDeathVel=10
|
||||
|
||||
StumblePower=12
|
||||
GunHitPower=12
|
||||
|
||||
OverrideImpactEffect=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Impact'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
|
||||
}
|
27
KFGameContent/Classes/KFDT_Ballistic_FAMAS_Rifle.uc
Normal file
27
KFGameContent/Classes/KFDT_Ballistic_FAMAS_Rifle.uc
Normal file
@ -0,0 +1,27 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_FAMAS_Rifle
|
||||
//=============================================================================
|
||||
// Damage type class for the FAMAS rifle
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_FAMAS_Rifle extends KFDT_Ballistic_AssaultRifle
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-300
|
||||
KDeathVel=100
|
||||
|
||||
StumblePower=12
|
||||
GunHitPower=0
|
||||
|
||||
WeaponDef=class'KFWeapDef_FAMAS'
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Commando'
|
||||
ModifierPerkList(1)=class'KFPerk_Support'
|
||||
}
|
47
KFGameContent/Classes/KFDT_Ballistic_FAMAS_Shotgun.uc
Normal file
47
KFGameContent/Classes/KFDT_Ballistic_FAMAS_Shotgun.uc
Normal file
@ -0,0 +1,47 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_FAMAS_Shotgun
|
||||
//=============================================================================
|
||||
// Damage type class for the FAMAS shotgun alt fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_FAMAS_Shotgun extends KFDT_Ballistic_Shotgun
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
if( super.CanDismemberHitZone( InHitZoneName ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ( InHitZoneName )
|
||||
{
|
||||
case 'lupperarm':
|
||||
case 'rupperarm':
|
||||
case 'chest':
|
||||
case 'heart':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BloodSpread=0.4
|
||||
BloodScale=0.6
|
||||
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=500
|
||||
KDeathVel=350
|
||||
|
||||
StumblePower=10
|
||||
GunHitPower=15
|
||||
|
||||
WeaponDef=class'KFWeapDef_FAMAS'
|
||||
}
|
26
KFGameContent/Classes/KFDT_Ballistic_HRG_BarrierRifle.uc
Normal file
26
KFGameContent/Classes/KFDT_Ballistic_HRG_BarrierRifle.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_BarrierRifle
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Ballistic_HRG_BarrierRifle extends KFDT_Ballistic_AssaultRifle
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-300
|
||||
KDeathVel=100
|
||||
|
||||
StumblePower=20
|
||||
GunHitPower=20
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BarrierRifle'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_SWAT'
|
||||
}
|
55
KFGameContent/Classes/KFDT_Ballistic_ThermiteBoreImpact.uc
Normal file
55
KFGameContent/Classes/KFDT_Ballistic_ThermiteBoreImpact.uc
Normal file
@ -0,0 +1,55 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_ThermiteBoreImpact
|
||||
//=============================================================================
|
||||
// Rocket impact damage type for the Thermite rocket launcher
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_ThermiteBoreImpact extends KFDT_Ballistic_Shell
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the burning damage over time
|
||||
var class<KFDamageType> BurnDamageType;
|
||||
|
||||
static simulated function bool CanDismemberHitZone(name InHitZoneName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static simulated function bool CanDismemberHitZoneWhileAlive(name InHitZoneName)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
|
||||
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
|
||||
{
|
||||
// Overriden to specific a different damage type to do the burn damage over
|
||||
// time. We do this so we don't get shotgun pellet impact sounds/fx during
|
||||
// the DOT burning.
|
||||
if ( default.BurnDamageType.default.DoT_Type != DOT_None )
|
||||
{
|
||||
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BurnDamageType);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=0
|
||||
KDeathUpKick=0
|
||||
KDeathVel=0
|
||||
|
||||
BurnPower=50
|
||||
KnockdownPower=50
|
||||
StumblePower=350
|
||||
GunHitPower=300
|
||||
|
||||
BurnDamageType=class'KFDT_Fire_ThermiteImpactDoT'
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_FireBug'
|
||||
|
||||
WeaponDef=class'KFWeapDef_ThermiteBore'
|
||||
}
|
24
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlers.uc
Normal file
24
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlers.uc
Normal file
@ -0,0 +1,24 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_BlastBrawlers
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_BlastBrawlers extends KFDT_Bludgeon
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=2500
|
||||
KDeathUpKick=500
|
||||
KDeathVel=400
|
||||
|
||||
MeleeHitPower=100
|
||||
StunPower=0
|
||||
StumblePower=0
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
|
||||
ModifierPerkList(0)=class'KFPerk_Support'
|
||||
}
|
25
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlersBash.uc
Normal file
25
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlersBash.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_BlastBrawlersBash
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_BlastBrawlersBash extends KFDT_Bludgeon
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3500
|
||||
KDeathUpKick=800
|
||||
KDeathVel=575
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=200
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
|
||||
ModifierPerkList(0)=class'KFPerk_Support'
|
||||
}
|
28
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlersHeavy.uc
Normal file
28
KFGameContent/Classes/KFDT_Bludgeon_BlastBrawlersHeavy.uc
Normal file
@ -0,0 +1,28 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_BlastBrawlersHeavy
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_BlastBrawlersHeavy extends KFDT_Bludgeon
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3500
|
||||
KDeathUpKick=800
|
||||
KDeathVel=575
|
||||
|
||||
KnockdownPower=75
|
||||
StunPower=0
|
||||
StumblePower=150
|
||||
MeleeHitPower=150
|
||||
EMPPower=0
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
|
||||
ModifierPerkList(0)=class'KFPerk_Support'
|
||||
|
||||
//OverrideImpactEffect=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_Static_Strikers_Impact'
|
||||
}
|
15
KFGameContent/Classes/KFDT_Bludgeon_FAMAS.uc
Normal file
15
KFGameContent/Classes/KFDT_Bludgeon_FAMAS.uc
Normal file
@ -0,0 +1,15 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_FAMAS
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Bludgeon_FAMAS extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_FAMAS'
|
||||
}
|
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_BarrierRifle.uc
Normal file
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_BarrierRifle.uc
Normal file
@ -0,0 +1,15 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_BarrierRifle
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2016 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Bludgeon_HRG_BarrierRifle extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_BarrierRifle'
|
||||
}
|
15
KFGameContent/Classes/KFDT_Bludgeon_ThermiteBore.uc
Normal file
15
KFGameContent/Classes/KFDT_Bludgeon_ThermiteBore.uc
Normal file
@ -0,0 +1,15 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_ThermiteBore
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Bludgeon_ThermiteBore extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_ThermiteBore'
|
||||
}
|
49
KFGameContent/Classes/KFDT_Explosive_Thermite.uc
Normal file
49
KFGameContent/Classes/KFDT_Explosive_Thermite.uc
Normal file
@ -0,0 +1,49 @@
|
||||
//=============================================================================
|
||||
// KFDT_Explosive_Thermite
|
||||
//=============================================================================
|
||||
// Explosive damage type for the Seal Squeal
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Explosive_Thermite extends KFDT_Fire
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the burning damage over time
|
||||
var class<KFDamageType> BurnDamageType;
|
||||
|
||||
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
|
||||
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
|
||||
{
|
||||
// Overriden to specific a different damage type to do the burn damage over
|
||||
// time. We do this so we don't get shotgun pellet impact sounds/fx during
|
||||
// the DOT burning.
|
||||
if ( default.BurnDamageType.default.DoT_Type != DOT_None )
|
||||
{
|
||||
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BurnDamageType);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bShouldSpawnPersistentBlood = true
|
||||
|
||||
// physics impact
|
||||
RadialDamageImpulse = 2000
|
||||
GibImpulseScale = 0.15
|
||||
KDeathUpKick = 1000
|
||||
KDeathVel = 300
|
||||
|
||||
KnockdownPower = 0
|
||||
BurnPower = 50
|
||||
StumblePower = 200
|
||||
|
||||
BurnDamageType=class'KFDT_Fire_ThermiteExplosionDoT'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0) = class'KFPerk_Firebug'
|
||||
|
||||
WeaponDef = class'KFWeapDef_ThermiteBore'
|
||||
}
|
33
KFGameContent/Classes/KFDT_Fire_Ground_ThermiteBore.uc
Normal file
33
KFGameContent/Classes/KFDT_Fire_Ground_ThermiteBore.uc
Normal file
@ -0,0 +1,33 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_Ground_ThermiteBore
|
||||
//=============================================================================
|
||||
// Damage type class for the thermite bore ground fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_Ground_ThermiteBore extends KFDT_Fire_Ground
|
||||
abstract;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bShouldSpawnPersistentBlood=false
|
||||
|
||||
// physics impact
|
||||
RadialDamageImpulse=0
|
||||
KDeathUpKick=0
|
||||
KDeathVel=0
|
||||
|
||||
KnockdownPower=0
|
||||
StumblePower=100
|
||||
BurnPower=10
|
||||
|
||||
// DOT
|
||||
DoT_Duration=3.0 //5.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.5 //0.2
|
||||
bIgnoreSelfInflictedScale=false
|
||||
|
||||
WeaponDef=class'KFWeapDef_ThermiteBore'
|
||||
}
|
42
KFGameContent/Classes/KFDT_Fire_ThermiteExplosionDoT.uc
Normal file
42
KFGameContent/Classes/KFDT_Fire_ThermiteExplosionDoT.uc
Normal file
@ -0,0 +1,42 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_ThermiteExplosionDoT
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by a thermite bore explosion
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_ThermiteExplosionDoT extends KFDT_Fire
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
static function int GetKillerDialogID()
|
||||
{
|
||||
return 86;//KILL_Fire
|
||||
}
|
||||
|
||||
static function int GetDamagerDialogID()
|
||||
{
|
||||
return 102;//DAMZ_Fire
|
||||
}
|
||||
|
||||
static function int GetDamageeDialogID()
|
||||
{
|
||||
return 116;//DAMP_Fire
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
WeaponDef=class'KFWeapDef_ThermiteBore'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=3.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.2
|
||||
|
||||
BurnPower=10
|
||||
|
||||
// Explosion DOT does not damage the instigator
|
||||
bNoInstigatorDamage=true
|
||||
}
|
40
KFGameContent/Classes/KFDT_Fire_ThermiteImpactDoT.uc
Normal file
40
KFGameContent/Classes/KFDT_Fire_ThermiteImpactDoT.uc
Normal file
@ -0,0 +1,40 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_ThermiteImpactDoT
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by a thermite bore projectile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_ThermiteImpactDoT extends KFDT_Fire
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
static function int GetKillerDialogID()
|
||||
{
|
||||
return 86;//KILL_Fire
|
||||
}
|
||||
|
||||
static function int GetDamagerDialogID()
|
||||
{
|
||||
return 102;//DAMZ_Fire
|
||||
}
|
||||
|
||||
static function int GetDamageeDialogID()
|
||||
{
|
||||
return 116;//DAMP_Fire
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
WeaponDef=class'KFWeapDef_ThermiteBore'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=3.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.2
|
||||
|
||||
BurnPower=10
|
||||
}
|
||||
|
30
KFGameContent/Classes/KFExplosion_Thermite.uc
Normal file
30
KFGameContent/Classes/KFExplosion_Thermite.uc
Normal file
@ -0,0 +1,30 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_Thermite
|
||||
//=============================================================================
|
||||
// Used by projectiles and kismet to spawn an explosion
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_Thermite extends KFExplosionActorLingering;
|
||||
|
||||
/** Replacement particles to play when hitting surfaces at different angles */
|
||||
var() ParticleSystem LoopingParticleEffectCeiling;
|
||||
var() ParticleSystem LoopingParticleEffectWall;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
Interval=0.5
|
||||
MaxTime=10
|
||||
|
||||
bDoFullDamage=true
|
||||
|
||||
LoopingParticleEffect=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_ground_fire_01'
|
||||
|
||||
LoopingParticleEffectCeiling=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_Ceiling_01'
|
||||
LoopingParticleEffectWall=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_Wall_01'
|
||||
|
||||
LoopStartEvent=AkEvent'WW_WEP_SA_Flamethrower.Play_WEP_SA_Flamethrower_Residual_Fire_Loop'
|
||||
LoopStopEvent=AkEvent'WW_WEP_SA_Flamethrower.Stop_WEP_SA_Flamethrower_Residual_Fire_Loop'
|
||||
}
|
@ -170,7 +170,7 @@ function bool TrySetNextWaveSpecial()
|
||||
|
||||
function WaveEnded(EWaveEndCondition WinCondition)
|
||||
{
|
||||
if(!bWaveStarted)
|
||||
if(!bWaveStarted && !MyKFGRI.bTraderIsOpen && WinCondition != WEC_TeamWipedOut)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -937,16 +937,19 @@ function ResetAllPickups()
|
||||
/** Overridden to scale the number of active pickups by wave */
|
||||
function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
|
||||
{
|
||||
if(NumPickups != 0)
|
||||
NumPickups *= (float(WaveNum) / float(WaveMax));
|
||||
|
||||
// make sure to have at least 1 ammo pickup in the level, and if it's wave 2 or later make sure there's
|
||||
// at least one weapon pickup. Also, we need to ensure if OverrideItemPickupModifier is set to 0 we really
|
||||
// don't want any item pickups.
|
||||
if( NumPickups == 0 && PickupList.Length > 0
|
||||
&& (WaveNum > 1
|
||||
|| KFPickupFactory_Ammo(PickupList[0]) != none
|
||||
|| (KFPickupFactory_Item(PickupList[0]) != none && (OutbreakEvent == none || OutbreakEvent.ActiveEvent.OverrideItemPickupModifier != 0))
|
||||
)
|
||||
)
|
||||
{
|
||||
NumPickups *= (float(WaveNum) / float(WaveMax));
|
||||
|
||||
// make sure to have at least 1 ammo pickup in the level, and if it's wave 2 or later make sure there's
|
||||
// at least one weapon pickup
|
||||
if( NumPickups == 0 && PickupList.Length > 0 && (WaveNum > 1 || KFPickupFactory_Ammo(PickupList[0]) != none) )
|
||||
{
|
||||
NumPickups = 1;
|
||||
}
|
||||
NumPickups = 1;
|
||||
}
|
||||
super.ResetPickups( PickupList, NumPickups );
|
||||
}
|
||||
@ -1117,8 +1120,10 @@ function WaveEnded(EWaveEndCondition WinCondition)
|
||||
local int i;
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
if(!bWaveStarted && !MyKFGRI.bTraderIsOpen)
|
||||
if(!bWaveStarted && !MyKFGRI.bTraderIsOpen && WinCondition != WEC_TeamWipedOut)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WorldInfo.NetMode == NM_DedicatedServer)
|
||||
{
|
||||
|
@ -65,6 +65,11 @@ event PreBeginPlay()
|
||||
super.PreBeginPlay();
|
||||
|
||||
OutbreakEvent.UpdateGRI();
|
||||
|
||||
if (Role == Role_Authority && MyKFGRI != none && OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
|
||||
{
|
||||
MyKFGRI.NotifyBrokenTrader();
|
||||
}
|
||||
}
|
||||
|
||||
function CreateOutbreakEvent()
|
||||
@ -136,6 +141,7 @@ function SetPickupItemList()
|
||||
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem)
|
||||
{
|
||||
for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx)
|
||||
@ -241,14 +247,18 @@ protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPa
|
||||
function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
|
||||
{
|
||||
local int i;
|
||||
local int j;
|
||||
local KFPlayerController KFPC;
|
||||
local KFPlayerReplicationInfo DamagerKFPRI;
|
||||
local array<DamageInfo> DamageHistory;
|
||||
local array<KFPlayerController> Attackers;
|
||||
local KFPawn_Human PawnHuman;
|
||||
|
||||
local KFGameInfo KFGI;
|
||||
|
||||
DamageHistory = MonsterPawn.DamageHistory;
|
||||
|
||||
|
||||
KFGI = KFGameInfo(WorldInfo.Game);
|
||||
|
||||
for ( i = 0; i < DamageHistory.Length; i++ )
|
||||
{
|
||||
if( DamageHistory[i].DamagerController != none
|
||||
@ -266,9 +276,30 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
|
||||
{
|
||||
PawnHuman = KFPawn_Human(KFPC.Pawn);
|
||||
Attackers.AddItem(KFPC);
|
||||
|
||||
/*
|
||||
Weekly event Aracnophobia (10):
|
||||
2 kind of heales: one for killing and another for killing by jumping on enemies.
|
||||
HealByAssistance is used for the latest, no need to add extra variables.
|
||||
*/
|
||||
if( KFPC == Killer && KFGI != none && KFGI.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled )
|
||||
{
|
||||
for (j = 0; j < DamageHistory[i].DamageTypes.Length; j++)
|
||||
{
|
||||
if (DamageHistory[i].DamageTypes[j] == class 'KFDT_GoompaStomp')
|
||||
{
|
||||
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
|
||||
return;
|
||||
}
|
||||
//
|
||||
|
||||
if( KFPC == Killer )
|
||||
{
|
||||
`Log("Heal by Kill: "$MonsterPawn.HealByKill);
|
||||
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
|
||||
|
||||
if( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none )
|
||||
@ -278,7 +309,6 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
|
||||
}
|
||||
else
|
||||
{
|
||||
`Log("Heal by Assistance: "$MonsterPawn.HealByAssistance);
|
||||
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
|
||||
}
|
||||
}
|
||||
@ -286,7 +316,6 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -482,6 +511,34 @@ function StartWave()
|
||||
SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave));
|
||||
}
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
|
||||
{
|
||||
OverridePickupList();
|
||||
}
|
||||
}
|
||||
|
||||
function bool OverridePickupList()
|
||||
{
|
||||
local KFPickupFactory PickupFactory;
|
||||
local KFPickupFactory_Item ItemFactory;
|
||||
local KFGameReplicationInfo_WeeklySurvival KFGRI_WS;
|
||||
|
||||
KFGRI_WS=KFGameReplicationInfo_WeeklySurvival(MyKFGRI);
|
||||
if (KFGRI_WS == none)
|
||||
return false;
|
||||
|
||||
foreach ItemPickups(PickupFactory)
|
||||
{
|
||||
ItemFactory = KFPickupFactory_Item(PickupFactory);
|
||||
|
||||
if (ItemFactory == none)
|
||||
continue;
|
||||
|
||||
KFGRI_WS.OverrideWeaponPickups(ItemFactory);
|
||||
ItemFactory.OverridePickup();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function EnableGlobalDamage()
|
||||
@ -614,8 +671,6 @@ function InitAllPickups()
|
||||
{
|
||||
NumWeaponPickups = ItemPickups.Length * (OutbreakEvent.ActiveEvent.OverrideItemPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideItemPickupModifier : DifficultyInfo.GetItemPickupModifier());
|
||||
NumAmmoPickups = AmmoPickups.Length * (OutbreakEvent.ActiveEvent.OverrideAmmoPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideAmmoPickupModifier : DifficultyInfo.GetAmmoPickupModifier());
|
||||
`log("OutbreakEvent.ActiveEvent.OverrideItemPickupModifier"@OutbreakEvent.ActiveEvent.OverrideItemPickupModifier);
|
||||
`log("NumWeaponPickups"@NumWeaponPickups);
|
||||
|
||||
`if(`__TW_SDK_)
|
||||
if( BaseMutator != none )
|
||||
@ -696,6 +751,7 @@ function class<KFPawn_Monster> GetAISpawnType(EAIType AIType)
|
||||
function bool AllowPrimaryWeapon(string ClassPath)
|
||||
{
|
||||
local STraderItem Item;
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none)
|
||||
{
|
||||
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
|
||||
@ -704,8 +760,8 @@ function bool AllowPrimaryWeapon(string ClassPath)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -788,6 +844,42 @@ function DoDeathExplosion(Pawn DeadPawn, KFGameExplosion ExplosionTemplate, clas
|
||||
}
|
||||
}
|
||||
|
||||
simulated function AddWeaponsFromSpawnList(KFPawn P)
|
||||
{
|
||||
local STraderItem Item;
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none || OutbreakEvent.ActiveEvent.bAddSpawnListToLoadout)
|
||||
{
|
||||
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
|
||||
{
|
||||
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(Item.WeaponDef.default.WeaponClassPath, class'Class')));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OverrideHumanDefaults(KFPawn_Human P)
|
||||
{
|
||||
if (OutbreakEvent.ActiveEvent.JumpZ >= 0.0f)
|
||||
{
|
||||
P.JumpZ = OutbreakEvent.ActiveEvent.JumpZ;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ModifyDamageGiven(out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC;
|
||||
local int Streak;
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bGoompaJumpEnabled)
|
||||
{
|
||||
KFPC = KFPlayerController_WeeklySurvival(DamageInstigator);
|
||||
if (KFPC != none)
|
||||
{
|
||||
Streak = KFPC.GoompaStreakBonus < KFPC.MaxGoompaStreak ? KFPC.GoompaStreakBonus : KFPC.MaxGoompaStreak;
|
||||
InDamage *= (1 + OutbreakEvent.ActiveEvent.GoompaStreakDamage * Streak);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
@ -9,6 +9,14 @@
|
||||
|
||||
class KFGameReplicationInfo_WeeklySurvival extends KFGameReplicationInfo;
|
||||
|
||||
struct SBrokeTraderPickupItem
|
||||
{
|
||||
/** Weapons available for spawning */
|
||||
var() array<class<KFWeaponDefinition> > WeaponClasses;
|
||||
};
|
||||
|
||||
var() array<SBrokeTraderPickupItem> BrokenTraderItemPickups;
|
||||
|
||||
simulated function array<int> GetKFSeqEventLevelLoadedIndices()
|
||||
{
|
||||
local array<int> ActivateIndices;
|
||||
@ -16,4 +24,262 @@ simulated function array<int> GetKFSeqEventLevelLoadedIndices()
|
||||
ActivateIndices[0] = 7;
|
||||
|
||||
return ActivateIndices;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OverrideWeaponPickups(out KFPickupFactory_Item ItemFactory)
|
||||
{
|
||||
local int Idx;
|
||||
local ItemPickup Pickup;
|
||||
|
||||
if (ItemFactory == none)
|
||||
return;
|
||||
|
||||
if ( BrokenTraderItemPickups.Length == 0 || WaveNum > BrokenTraderItemPickups.Length )
|
||||
return;
|
||||
|
||||
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
|
||||
|
||||
for(Idx = 0; Idx < BrokenTraderItemPickups[WaveNum-1].WeaponClasses.Length; Idx++)
|
||||
{
|
||||
Pickup.ItemClass = class<KFWeapon> (DynamicLoadObject(BrokenTraderItemPickups[WaveNum-1].WeaponClasses[Idx].default.WeaponClassPath, class'Class'));
|
||||
ItemFactory.ItemPickups.AddItem(Pickup);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function NotifyWaveStart()
|
||||
{
|
||||
local KFPickupFactory_Item ItemFactory;
|
||||
|
||||
if (WorldInfo.NetMode == NM_Client && bIsBrokenTrader)
|
||||
{
|
||||
foreach AllActors(class'KFPickupFactory_Item', ItemFactory)
|
||||
{
|
||||
OverrideWeaponPickups(ItemFactory);
|
||||
ItemFactory.SetPickupMesh();
|
||||
}
|
||||
}
|
||||
|
||||
super.NotifyWaveStart();
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
BrokenTraderItemPickups={(
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_9mmDual',
|
||||
class'KFGame.KFWeapDef_Crovel',
|
||||
class'KFGame.KFWeapDef_MB500',
|
||||
class'KFGame.KFWeapDef_MedicPistol',
|
||||
class'KFGame.KFWeapDef_HX25',
|
||||
class'KFGame.KFWeapDef_CaulkBurn',
|
||||
class'KFGame.KFWeapDef_Remington1858Dual',
|
||||
class'KFGame.KFWeapDef_Winchester1894',
|
||||
class'KFGame.KFWeapDef_MP7',
|
||||
class'KFGame.KFWeapDef_AR15'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_Nailgun',
|
||||
class'KFGame.KFWeapDef_Katana',
|
||||
class'KFGame.KFWeapDef_ChainBat',
|
||||
class'KFGame.KFWeapDef_FireAxe',
|
||||
class'KFGame.KFWeapDef_Bullpup',
|
||||
class'KFGame.KFWeapDef_Thompson',
|
||||
class'KFGame.KFWeapDef_DoubleBarrel',
|
||||
class'KFGame.KFWeapDef_HZ12',
|
||||
class'KFGame.KFWeapDef_DragonsBreath',
|
||||
class'KFGame.KFWeapDef_MedicSMG',
|
||||
class'KFGame.KFWeapDef_Healthrower_HRG',
|
||||
class'KFGame.KFWeapDef_M79',
|
||||
class'KFGame.KFWeapDef_FlareGunDual',
|
||||
class'KFGame.KFWeapDef_Mac10',
|
||||
class'KFGame.KFWeapDef_HRGScorcher',
|
||||
class'KFGame.KFWeapDef_Colt1911Dual',
|
||||
class'KFGame.KFWeapDef_HRGWinterbite',
|
||||
class'KFGame.KFWeapDef_CenterfireMB464',
|
||||
class'KFGame.KFWeapDef_Crossbow',
|
||||
class'KFGame.KFWeapDef_MP5RAS'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_Nailgun',
|
||||
class'KFGame.KFWeapDef_Katana',
|
||||
class'KFGame.KFWeapDef_ChainBat',
|
||||
class'KFGame.KFWeapDef_FireAxe',
|
||||
class'KFGame.KFWeapDef_Bullpup',
|
||||
class'KFGame.KFWeapDef_Thompson',
|
||||
class'KFGame.KFWeapDef_DoubleBarrel',
|
||||
class'KFGame.KFWeapDef_HZ12',
|
||||
class'KFGame.KFWeapDef_DragonsBreath',
|
||||
class'KFGame.KFWeapDef_MedicSMG',
|
||||
class'KFGame.KFWeapDef_Healthrower_HRG',
|
||||
class'KFGame.KFWeapDef_M79',
|
||||
class'KFGame.KFWeapDef_FlareGunDual',
|
||||
class'KFGame.KFWeapDef_Mac10',
|
||||
class'KFGame.KFWeapDef_HRGScorcher',
|
||||
class'KFGame.KFWeapDef_Colt1911Dual',
|
||||
class'KFGame.KFWeapDef_HRGWinterbite',
|
||||
class'KFGame.KFWeapDef_CenterfireMB464',
|
||||
class'KFGame.KFWeapDef_Crossbow',
|
||||
class'KFGame.KFWeapDef_MP5RAS'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_MedicBat',
|
||||
class'KFGame.KFWeapDef_Pulverizer',
|
||||
class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe',
|
||||
class'KFGame.KFWeapDef_AK12',
|
||||
class'KFGame.KFWeapDef_MKB42',
|
||||
class'KFGame.KFWeapDef_M16M203',
|
||||
class'KFGame.KFWeapDef_M4',
|
||||
class'KFGame.KFWeapDef_SW500Dual_HRG',
|
||||
class'KFGame.KFWeapDef_MedicShotgun',
|
||||
class'KFGame.KFWeapDef_Hemogoblin',
|
||||
class'KFGame.KFWeapDef_Mine_Reconstructor',
|
||||
class'KFGame.KFWeapDef_SealSqueal',
|
||||
class'KFGame.KFWeapDef_FlameThrower',
|
||||
class'KFGame.KFWeapDef_HRGIncendiaryRifle',
|
||||
class'KFGame.KFWeapDef_ChiappaRhinoDual',
|
||||
class'KFGame.KFWeapDef_DeagleDual',
|
||||
class'KFGame.KFWeapDef_M14EBR',
|
||||
class'KFGame.KFWeapDef_HRG_SonicGun',
|
||||
class'KFGame.KFWeapDef_MosinNagant',
|
||||
class'KFGame.KFWeapDef_P90',
|
||||
class'KFGame.KFWeapDef_Nailgun_HRG',
|
||||
class'KFGame.KFWeapDef_HK_UMP',
|
||||
class'KFGame.KFWeapDef_FreezeThrower',
|
||||
class'KFGame.KFWeapDef_HRG_Kaboomstick',
|
||||
class'KFGame.KFWeapDef_FAMAS'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_MedicBat',
|
||||
class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe',
|
||||
class'KFGame.KFWeapDef_M16M203',
|
||||
class'KFGame.KFWeapDef_M4',
|
||||
class'KFGame.KFWeapDef_MedicShotgun',
|
||||
class'KFGame.KFWeapDef_FlameThrower',
|
||||
class'KFGame.KFWeapDef_HRGIncendiaryRifle',
|
||||
class'KFGame.KFWeapDef_DeagleDual',
|
||||
class'KFGame.KFWeapDef_HRG_SonicGun',
|
||||
class'KFGame.KFWeapDef_MosinNagant',
|
||||
class'KFGame.KFWeapDef_HK_UMP',
|
||||
class'KFGame.KFWeapDef_FreezeThrower',
|
||||
class'KFGame.KFWeapDef_HRG_Kaboomstick',
|
||||
class'KFGame.KFWeapDef_FAMAS',
|
||||
class'KFGame.KFWeapDef_Eviscerator',
|
||||
class'KFGame.KFWeapDef_FNFal',
|
||||
class'KFGame.KFWeapDef_MedicRifle',
|
||||
class'KFGame.KFWeapDef_ElephantGun',
|
||||
class'KFGame.KFWeapDef_Seeker6',
|
||||
class'KFGame.KFWeapDef_HuskCannon',
|
||||
class'KFGame.KFWeapDef_SW500Dual',
|
||||
class'KFGame.KFWeapDef_Kriss',
|
||||
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_HRGTeslauncher',
|
||||
class'KFGame.KFWeapDef_Eviscerator',
|
||||
class'KFGame.KFWeapDef_MaceAndShield',
|
||||
class'KFGame.KFWeapDef_PowerGloves',
|
||||
class'KFGame.KFWeapDef_SCAR',
|
||||
class'KFGame.KFWeapDef_Stoner63A',
|
||||
class'KFGame.KFWeapDef_MedicRifle',
|
||||
class'KFGame.KFWeapDef_FNFal',
|
||||
class'KFGame.KFWeapDef_AA12',
|
||||
class'KFGame.KFWeapDef_ElephantGun',
|
||||
class'KFGame.KFWeapDef_Blunderbuss',
|
||||
class'KFGame.KFWeapDef_HRGIncision',
|
||||
class'KFGame.KFWeapDef_HRG_Vampire',
|
||||
class'KFGame.KFWeapDef_RPG7',
|
||||
class'KFGame.KFWeapDef_Seeker6',
|
||||
class'KFGame.KFWeapDef_HuskCannon',
|
||||
class'KFGame.KFWeapDef_MicrowaveGun',
|
||||
class'KFGame.KFWeapDef_SW500Dual',
|
||||
class'KFGame.KFWeapDef_AF2011Dual',
|
||||
class'KFGame.KFWeapDef_Pistol_DualG18',
|
||||
class'KFGame.KFWeapDef_RailGun',
|
||||
class'KFGame.KFWeapDef_G18',
|
||||
class'KFGame.KFWeapDef_Kriss',
|
||||
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
|
||||
class'KFGame.KFWeapDef_AbominationAxe',
|
||||
class'KFGame.KFWeapDef_Minigun',
|
||||
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
|
||||
class'KFGame.KFWeapDef_MicrowaveRifle',
|
||||
class'KFGame.KFWeapDef_CompoundBow',
|
||||
class'KFGame.KFWeapDef_M99',
|
||||
class'KFGame.KFWeapDef_LazerCutter',
|
||||
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
|
||||
class'KFGame.KFWeapDef_ThermiteBore',
|
||||
class'KFGame.KFWeapDef_HRG_BarrierRifle'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_HRGTeslauncher',
|
||||
class'KFGame.KFWeapDef_Eviscerator',
|
||||
class'KFGame.KFWeapDef_MaceAndShield',
|
||||
class'KFGame.KFWeapDef_PowerGloves',
|
||||
class'KFGame.KFWeapDef_SCAR',
|
||||
class'KFGame.KFWeapDef_Stoner63A',
|
||||
class'KFGame.KFWeapDef_MedicRifle',
|
||||
class'KFGame.KFWeapDef_FNFal',
|
||||
class'KFGame.KFWeapDef_AA12',
|
||||
class'KFGame.KFWeapDef_ElephantGun',
|
||||
class'KFGame.KFWeapDef_Blunderbuss',
|
||||
class'KFGame.KFWeapDef_HRGIncision',
|
||||
class'KFGame.KFWeapDef_HRG_Vampire',
|
||||
class'KFGame.KFWeapDef_RPG7',
|
||||
class'KFGame.KFWeapDef_Seeker6',
|
||||
class'KFGame.KFWeapDef_HuskCannon',
|
||||
class'KFGame.KFWeapDef_MicrowaveGun',
|
||||
class'KFGame.KFWeapDef_SW500Dual',
|
||||
class'KFGame.KFWeapDef_AF2011Dual',
|
||||
class'KFGame.KFWeapDef_Pistol_DualG18',
|
||||
class'KFGame.KFWeapDef_RailGun',
|
||||
class'KFGame.KFWeapDef_G18',
|
||||
class'KFGame.KFWeapDef_Kriss',
|
||||
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
|
||||
class'KFGame.KFWeapDef_AbominationAxe',
|
||||
class'KFGame.KFWeapDef_Minigun',
|
||||
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
|
||||
class'KFGame.KFWeapDef_MicrowaveRifle',
|
||||
class'KFGame.KFWeapDef_CompoundBow',
|
||||
class'KFGame.KFWeapDef_M99',
|
||||
class'KFGame.KFWeapDef_LazerCutter',
|
||||
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
|
||||
class'KFGame.KFWeapDef_ThermiteBore',
|
||||
class'KFGame.KFWeapDef_HRG_BarrierRifle'
|
||||
)}),
|
||||
(WeaponClasses={(
|
||||
class'KFGame.KFWeapDef_HRGTeslauncher',
|
||||
class'KFGame.KFWeapDef_Eviscerator',
|
||||
class'KFGame.KFWeapDef_MaceAndShield',
|
||||
class'KFGame.KFWeapDef_PowerGloves',
|
||||
class'KFGame.KFWeapDef_SCAR',
|
||||
class'KFGame.KFWeapDef_Stoner63A',
|
||||
class'KFGame.KFWeapDef_MedicRifle',
|
||||
class'KFGame.KFWeapDef_FNFal',
|
||||
class'KFGame.KFWeapDef_AA12',
|
||||
class'KFGame.KFWeapDef_ElephantGun',
|
||||
class'KFGame.KFWeapDef_Blunderbuss',
|
||||
class'KFGame.KFWeapDef_HRGIncision',
|
||||
class'KFGame.KFWeapDef_HRG_Vampire',
|
||||
class'KFGame.KFWeapDef_RPG7',
|
||||
class'KFGame.KFWeapDef_Seeker6',
|
||||
class'KFGame.KFWeapDef_HuskCannon',
|
||||
class'KFGame.KFWeapDef_MicrowaveGun',
|
||||
class'KFGame.KFWeapDef_SW500Dual',
|
||||
class'KFGame.KFWeapDef_AF2011Dual',
|
||||
class'KFGame.KFWeapDef_Pistol_DualG18',
|
||||
class'KFGame.KFWeapDef_RailGun',
|
||||
class'KFGame.KFWeapDef_G18',
|
||||
class'KFGame.KFWeapDef_Kriss',
|
||||
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
|
||||
class'KFGame.KFWeapDef_AbominationAxe',
|
||||
class'KFGame.KFWeapDef_Minigun',
|
||||
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
|
||||
class'KFGame.KFWeapDef_MicrowaveRifle',
|
||||
class'KFGame.KFWeapDef_CompoundBow',
|
||||
class'KFGame.KFWeapDef_M99',
|
||||
class'KFGame.KFWeapDef_LazerCutter',
|
||||
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
|
||||
class'KFGame.KFWeapDef_ThermiteBore',
|
||||
class'KFGame.KFWeapDef_HRG_BarrierRifle'
|
||||
)})
|
||||
)}
|
||||
}
|
||||
|
34
KFGameContent/Classes/KFMeleeHelperWeaponBlastBrawlers.uc
Normal file
34
KFGameContent/Classes/KFMeleeHelperWeaponBlastBrawlers.uc
Normal file
@ -0,0 +1,34 @@
|
||||
//=============================================================================
|
||||
// KFMeleeHelperWeaponBlastBrawlers
|
||||
//=============================================================================
|
||||
// Manages melee attack related functionality for 1st person weapons
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFMeleeHelperWeaponBlastBrawlers extends KFMeleeHelperWeapon
|
||||
config(Game);
|
||||
|
||||
event InitWorldTraceForHitboxCollision()
|
||||
{
|
||||
local KFWeap_HRG_BlastBrawlers BlastBrawlers;
|
||||
|
||||
BlastBrawlers = KFWeap_HRG_BlastBrawlers(Instigator.Weapon);
|
||||
if (BlastBrawlers != none)
|
||||
{
|
||||
BlastBrawlers.Shoot();
|
||||
}
|
||||
|
||||
super.InitWorldTraceForHitboxCollision();
|
||||
}
|
||||
|
||||
simulated function InitAttackSequence(EPawnOctant NewAtkDir, EMeleeAttackType NewAtkType)
|
||||
{
|
||||
super.InitAttackSequence(NewAtkDir, NewAtkType);
|
||||
NextAttackType = NewAtkType;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
@ -407,6 +407,115 @@ defaultproperties
|
||||
|
||||
)}
|
||||
|
||||
// Aracnophobia
|
||||
SetEvents[10]={(
|
||||
EventDifficulty=2, //1,
|
||||
GameLength=GL_Normal,
|
||||
SpawnRateMultiplier=0.75, //5.0,
|
||||
bHealAfterKill = true,
|
||||
bGoompaJumpEnabled = true,
|
||||
GoompaJumpDamage = 550, //300,
|
||||
GoompaStreakDamage = 0.1, //0.2,
|
||||
GoompaJumpImpulse = 600, //1000,
|
||||
GoompaStreakMax = 5,
|
||||
GoompaBonusDuration=8.0f, //10.0f,
|
||||
DoshOnKillGlobalModifier=1.0,
|
||||
SpawnWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.AracnophobiaWeeklySpawnList',
|
||||
bAddSpawnListToLoadout=true,
|
||||
WaveAICountScale=(0.6, 0.6, 0.6, 0.6, 0.6, 0.6),
|
||||
JumpZ=700.f, // 650.0 by default; -1 used for not overriding.
|
||||
/** HealByKill = Normal kill. HealByAssistance = Goomba stomping */
|
||||
ZedsToAdjust={(
|
||||
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler',HealthScale=10.0, HeadHealthScale=20.0, DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.7, HealByAssistance=10),
|
||||
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing',HealthScale=10.0,HeadHealthScale=20.0, DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.7, HealByAssistance=20)
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket',HealByAssistance=5),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealByAssistance=15),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealByAssistance=15),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealByAssistance=15),
|
||||
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealByAssistance=5)
|
||||
)},
|
||||
SpawnReplacementList={(
|
||||
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_Stalker,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_Husk,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
//(SpawnEntry=AT_Scrake,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
|
||||
//(SpawnEntry=AT_FleshPound,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
|
||||
//(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
|
||||
(SpawnEntry=AT_EliteClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_EliteGoreFast,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_EDAR_EMP,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_EDAR_Laser,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_EDAR_Rocket,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
|
||||
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=1.0)
|
||||
)}
|
||||
)}
|
||||
|
||||
// Broken Trader
|
||||
SetEvents[11]={(
|
||||
EventDifficulty=1,
|
||||
GameLength=GL_Normal,
|
||||
bSpawnWeaponListAffectsSecondaryWeapons=true,
|
||||
TraderWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.BrokenTraderWeeklyTraderList',
|
||||
PickupResetTime=PRS_Wave,
|
||||
bDisableTraders=false,
|
||||
DroppedItemLifespan=10.0f, // 300 default
|
||||
DoshOnKillGlobalModifier=0.2,
|
||||
//Pickup Notes for when you're modifying:
|
||||
// NumPickups = Actors * OverridePickupModifer * WavePickupModifier
|
||||
// Ex: 16 item pickups in the world
|
||||
// * 0.9 Pickup Modifier = 14
|
||||
// * 0.5 Current wave modifier = 7 expected to spawn
|
||||
//
|
||||
// Ex: 16 ammo pickups in the world
|
||||
// * 0.1 pickup modifier = 2
|
||||
// * 0.5 current wave modifier = 1 expected to spawn
|
||||
bUnlimitedWeaponPickups=true,
|
||||
OverrideItemPickupModifier=2.0,
|
||||
OverrideAmmoPickupModifier=0.8, //0.5,
|
||||
WaveItemPickupModifiers={(
|
||||
1.0, 1.0, 1.0, 1.0, 1.0
|
||||
)},
|
||||
WaveAmmoPickupModifiers={(
|
||||
0.5, 0.6, 0.7, 0.8, 0.9
|
||||
)},
|
||||
bUseOverrideAmmoRespawnTime=true,
|
||||
OverrideAmmoRespawnTime={(
|
||||
PlayersMod[0]=20.000000,
|
||||
PlayersMod[1]=20.000000,
|
||||
PlayersMod[2]=10.000000,
|
||||
PlayersMod[3]=10.000000,
|
||||
PlayersMod[4]=5.000000,
|
||||
PlayersMod[5]=5.000000,
|
||||
ModCap=1.000000
|
||||
)},
|
||||
bUseOverrideItemRespawnTime=true,
|
||||
OverrideItemRespawnTime={(
|
||||
PlayersMod[0]=10.000000,
|
||||
PlayersMod[1]=10.000000,
|
||||
PlayersMod[2]=5.000000,
|
||||
PlayersMod[3]=5.000000,
|
||||
PlayersMod[4]=2.000000,
|
||||
PlayersMod[5]=2.000000,
|
||||
ModCap=1.000000
|
||||
)}
|
||||
)}
|
||||
|
||||
|
||||
//Test events from here down. These don't end up in the regular rotation.
|
||||
|
@ -36,7 +36,13 @@ simulated function PlayHeadAsplode()
|
||||
/** Set our gib flag on the server, replicate it with bTearOff */
|
||||
function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLocation)
|
||||
{
|
||||
if( !bPlayedDeath && DamageType != class'KFSM_PlayerCrawler_Suicide'.default.SuicideDamageType )
|
||||
local KFGameInfo_WeeklySurvival KFGI_WS;
|
||||
|
||||
// Not exploding if we are in arachnophobia weekly.
|
||||
KFGI_WS = KFGameInfo_WeeklySurvival(WorldInfo.Game);
|
||||
|
||||
if( !bPlayedDeath && DamageType != class'KFSM_PlayerCrawler_Suicide'.default.SuicideDamageType &&
|
||||
(KFGI_WS == none|| !KFGI_WS.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled))
|
||||
{
|
||||
bShouldExplode = true;
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
|
||||
}
|
||||
}
|
||||
|
||||
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser)
|
||||
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser)
|
||||
{
|
||||
if (ShieldHealthPctByte == 0)
|
||||
{
|
||||
|
51
KFGameContent/Classes/KFPhysicsDamageByPawnVolume.uc
Normal file
51
KFGameContent/Classes/KFPhysicsDamageByPawnVolume.uc
Normal file
@ -0,0 +1,51 @@
|
||||
//=============================================================================
|
||||
// KFPhysicsDamageByPawnVolume
|
||||
//=============================================================================
|
||||
// PhysicsVolume are, by default, used for traps on all maps. This KFPhysicsDamageByPawnVolume
|
||||
// gives the ability to make different damage values for Humans and Monsters.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
// Roberto Moreno
|
||||
//=============================================================================
|
||||
class KFPhysicsDamageByPawnVolume extends PhysicsVolume
|
||||
placeable;
|
||||
|
||||
var() float DamagePerSecMultiplierForHuman;
|
||||
var() float DamagePerSecMultiplierForMonster;
|
||||
|
||||
function CausePainTo(Actor Other)
|
||||
{
|
||||
local float DamagePerSecModified;
|
||||
|
||||
DamagePerSecModified = DamagePerSec;
|
||||
|
||||
if (KFPawn_Human(Other) != None)
|
||||
{
|
||||
DamagePerSecModified *= DamagePerSecMultiplierForHuman;
|
||||
}
|
||||
else if (KFPawn_Monster(Other) != None)
|
||||
{
|
||||
DamagePerSecModified *= DamagePerSecMultiplierForMonster;
|
||||
}
|
||||
|
||||
if (DamagePerSecModified > 0)
|
||||
{
|
||||
if ( WorldInfo.bSoftKillZ && (Other.Physics != PHYS_Walking) )
|
||||
return;
|
||||
if ( (DamageType == None) || (DamageType == class'DamageType') )
|
||||
`log("No valid damagetype ("$DamageType$") specified for "$PathName(self));
|
||||
Other.TakeDamage(DamagePerSecModified*PainInterval, DamageInstigator, Location, vect(0,0,1), DamageType,, self);
|
||||
}
|
||||
else
|
||||
{
|
||||
Other.HealDamage(-DamagePerSecModified * PainInterval, DamageInstigator, DamageType);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
DamagePerSecMultiplierForHuman=1.0
|
||||
DamagePerSecMultiplierForMonster=1.0
|
||||
}
|
@ -234,9 +234,9 @@ defaultproperties
|
||||
|
||||
// Ice explosion
|
||||
Begin Object Class=KFGameExplosion Name=ExploTemplate0
|
||||
Damage=25
|
||||
DamageRadius=200
|
||||
DamageFalloffExponent=1.f
|
||||
Damage=75 //25
|
||||
DamageRadius=250 //200
|
||||
DamageFalloffExponent=0.5f //1.f
|
||||
DamageDelay=0.f
|
||||
|
||||
bIgnoreInstigator=false
|
||||
|
29
KFGameContent/Classes/KFProj_Bullet_BlastBrawlers.uc
Normal file
29
KFGameContent/Classes/KFProj_Bullet_BlastBrawlers.uc
Normal file
@ -0,0 +1,29 @@
|
||||
//=============================================================================
|
||||
// KFProj_Bullet_BlastBrawlers
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Bullet_BlastBrawlers extends KFProj_Bullet_Pellet
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MaxSpeed=7000.0
|
||||
Speed=7000.0
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
DamageRadius=0
|
||||
|
||||
ImpactEffects = KFImpactEffectInfo'WEP_HRG_BlastBrawlers_ARCH.HRG_BlastBrawler_Projectile_Impacts'
|
||||
ProjFlightTemplate=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Tracer_Instant'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Tracer_Instant'
|
||||
//ProjFlightTemplate=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Projectile'
|
||||
//ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Projectile'
|
||||
|
||||
AmbientSoundPlayEvent=none
|
||||
AmbientSoundStopEvent=none
|
||||
}
|
@ -11,13 +11,10 @@ class KFProj_Grenade_GravityImploder extends KFProj_BallisticExplosive
|
||||
/* Ensure it detonates */
|
||||
var float DetonationTime;
|
||||
var float VortexDuration;
|
||||
|
||||
var float VortexRadius;
|
||||
var float VortexImpulseStrength;
|
||||
var protected transient bool bVortexActive;
|
||||
|
||||
var protected RB_RadialImpulseComponent RadialImpulseComponent;
|
||||
|
||||
simulated state GrenadeState
|
||||
{
|
||||
simulated event BeginState(Name PrevStateName)
|
||||
@ -49,18 +46,25 @@ simulated state VortexState
|
||||
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
local float ImpulseModifier;
|
||||
local Actor Victim;
|
||||
local TraceHitInfo HitInfo;
|
||||
local FracturedStaticMeshActor FracActor;
|
||||
|
||||
if(bVortexActive && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
|
||||
{
|
||||
// ImpulseModifier = (bReduceGibImpulseOnTick) ? (1.0f - AccumulatedTime / Lifetime) : 1.0f;
|
||||
ImpulseModifier = 1.0f;
|
||||
|
||||
RadialImpulseComponent.ImpulseRadius = VortexRadius;
|
||||
RadialImpulseComponent.ImpulseStrength = VortexImpulseStrength * ImpulseModifier;
|
||||
RadialImpulseComponent.bVelChange = true;
|
||||
RadialImpulseComponent.ImpulseFalloff = RIF_Constant;
|
||||
RadialImpulseComponent.FireImpulse(Location);
|
||||
foreach CollidingActors(class'Actor', Victim, VortexRadius, Location, true,, HitInfo)
|
||||
{
|
||||
if (KFPawn_Human(Victim) == none && Victim.CollisionComponent != none && !Victim.bWorldGeometry)
|
||||
{
|
||||
Victim.CollisionComponent.AddRadialImpulse(Location, VortexRadius, VortexImpulseStrength, RIF_Constant, true);
|
||||
}
|
||||
|
||||
FracActor = FracturedStaticMeshActor(Victim);
|
||||
if (FracActor != none)
|
||||
{
|
||||
FracActor.BreakOffPartsInRadius(Location, VortexRadius, VortexImpulseStrength, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,9 +127,9 @@ defaultproperties
|
||||
ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile_ZEDTIME'
|
||||
|
||||
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
|
||||
//GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
|
||||
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
|
||||
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force'
|
||||
//AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force'
|
||||
|
||||
// Grenade explosion light
|
||||
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
||||
@ -179,10 +183,4 @@ defaultproperties
|
||||
VortexImpulseStrength=-100
|
||||
VortexDuration=0.5f
|
||||
bVortexActive=false
|
||||
|
||||
Begin Object Class=RB_RadialImpulseComponent Name=ImpulseComponent0
|
||||
End Object
|
||||
RadialImpulseComponent=ImpulseComponent0
|
||||
Components.Add(ImpulseComponent0)
|
||||
}
|
||||
|
||||
|
368
KFGameContent/Classes/KFProj_Rocket_ThermiteBore.uc
Normal file
368
KFGameContent/Classes/KFProj_Rocket_ThermiteBore.uc
Normal file
@ -0,0 +1,368 @@
|
||||
//=============================================================================
|
||||
// KFProj_Rocket_ThermiteBore
|
||||
//=============================================================================
|
||||
// Thermite Bore Rifle rocket launcher harpoon
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2012 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFProj_Rocket_ThermiteBore extends KFProjectile;
|
||||
|
||||
var float FuseTime;
|
||||
|
||||
/** This is the effect indicator that is played for the current user **/
|
||||
var(Projectile) ParticleSystem ProjIndicatorTemplate;
|
||||
var ParticleSystemComponent ProjIndicatorEffects;
|
||||
|
||||
var bool IndicatorActive;
|
||||
|
||||
/**
|
||||
Fire effects
|
||||
*/
|
||||
|
||||
var class<KFProjectile> ResidualFlameProjClass;
|
||||
|
||||
var int NumResidualFlames;
|
||||
|
||||
/** Cone Angle to determine residual flame directions */
|
||||
var float ResidualFlameHalfConeAngle;
|
||||
/** Impulse modiffier apply to residual forces*/
|
||||
var float ResidualFlameForceMultiplier;
|
||||
|
||||
simulated function TryActivateIndicator()
|
||||
{
|
||||
if(!IndicatorActive && Instigator != None)
|
||||
{
|
||||
IndicatorActive = true;
|
||||
|
||||
if(WorldInfo.NetMode == NM_Standalone || Instigator.Role == Role_AutonomousProxy ||
|
||||
(Instigator.Role == ROLE_Authority && WorldInfo.NetMode == NM_ListenServer && Instigator.IsLocallyControlled() ))
|
||||
{
|
||||
if( ProjIndicatorTemplate != None )
|
||||
{
|
||||
ProjIndicatorEffects = WorldInfo.MyEmitterPool.SpawnEmitterCustomLifetime(ProjIndicatorTemplate);
|
||||
}
|
||||
|
||||
if(ProjIndicatorEffects != None)
|
||||
{
|
||||
ProjIndicatorEffects.SetAbsolute(false, false, false);
|
||||
ProjIndicatorEffects.SetLODLevel(WorldInfo.bDropDetail ? 1 : 0);
|
||||
ProjIndicatorEffects.bUpdateComponentInTick = true;
|
||||
AttachComponent(ProjIndicatorEffects);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initial velocity and cook time
|
||||
*/
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
SetTimer(FuseTime, false, 'Timer_Detonate');
|
||||
}
|
||||
|
||||
AdjustCanDisintigrate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode after a certain amount of time
|
||||
*/
|
||||
function Timer_Detonate()
|
||||
{
|
||||
Detonate();
|
||||
}
|
||||
|
||||
/** Called when the owning instigator controller has left a game */
|
||||
simulated function OnInstigatorControllerLeft()
|
||||
{
|
||||
if( WorldInfo.NetMode != NM_Client )
|
||||
{
|
||||
SetTimer( 1.f + Rand(5) + fRand(), false, nameOf(Timer_Detonate) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trace down and get the location to spawn the explosion effects and decal
|
||||
*/
|
||||
simulated function GetExplodeEffectLocation(out vector HitLocation, out vector HitRotation, out Actor HitActor)
|
||||
{
|
||||
local vector EffectStartTrace, EffectEndTrace;
|
||||
local TraceHitInfo HitInfo;
|
||||
|
||||
EffectStartTrace = Location + vect(0,0,1) * 4.f;
|
||||
EffectEndTrace = EffectStartTrace - vect(0,0,1) * 32.f;
|
||||
|
||||
// Find where to put the decal
|
||||
HitActor = Trace(HitLocation, HitRotation, EffectEndTrace, EffectStartTrace, false,, HitInfo, TRACEFLAG_Bullet);
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
/** Used to check current status of StuckTo actor (to figure out if we should fall) */
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
super.Tick(DeltaTime);
|
||||
|
||||
StickHelper.Tick(DeltaTime);
|
||||
|
||||
if (!IsZero(Velocity))
|
||||
{
|
||||
SetRelativeRotation(rotator(Velocity));
|
||||
}
|
||||
|
||||
TryActivateIndicator();
|
||||
}
|
||||
|
||||
/** Causes charge to explode */
|
||||
function Detonate()
|
||||
{
|
||||
local KFWeap_RocketLauncher_ThermiteBore WeaponOwner;
|
||||
local vector ExplosionNormal;
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
WeaponOwner = KFWeap_RocketLauncher_ThermiteBore(Owner);
|
||||
if (WeaponOwner != none)
|
||||
{
|
||||
WeaponOwner.RemoveDeployedHarpoon(, self);
|
||||
}
|
||||
}
|
||||
|
||||
ExplosionNormal = vect(0,0,1) >> Rotation;
|
||||
Explode(Location, ExplosionNormal);
|
||||
}
|
||||
|
||||
simulated function Explode(vector HitLocation, vector HitNormal)
|
||||
{
|
||||
local vector HitVelocity;
|
||||
|
||||
HitVelocity = Velocity;
|
||||
|
||||
StickHelper.UnPin();
|
||||
super.Explode(HitLocation, HitNormal);
|
||||
|
||||
// Spawn fire projectiles
|
||||
if(Role < Role_Authority)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpawnResidualFlames(HitLocation, HitNormal, HitVelocity);
|
||||
SpawnResidualFlame(ResidualFlameProjClass, Location, HitVelocity);
|
||||
}
|
||||
|
||||
simulated function Disintegrate( rotator InDisintegrateEffectRotation )
|
||||
{
|
||||
local KFWeap_RocketLauncher_ThermiteBore WeaponOwner;
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
WeaponOwner = KFWeap_RocketLauncher_ThermiteBore(Owner);
|
||||
if (WeaponOwner != none)
|
||||
{
|
||||
WeaponOwner.RemoveDeployedHarpoon(, self);
|
||||
}
|
||||
}
|
||||
|
||||
super.Disintegrate(InDisintegrateEffectRotation);
|
||||
}
|
||||
|
||||
// for nukes && concussive force
|
||||
simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
class'KFPerk_Demolitionist'.static.PrepareExplosive(Instigator, self);
|
||||
|
||||
super.PrepareExplosionTemplate();
|
||||
}
|
||||
|
||||
simulated function SyncOriginalLocation()
|
||||
{
|
||||
// IMPORTANT NOTE: We aren't actually syncing to the original location (or calling the super).
|
||||
// We just want to receive the original location so we can do a trace between that location and
|
||||
// our current location to determine if we hit any zeds between those two locations.
|
||||
// KFII-45464
|
||||
|
||||
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)
|
||||
{
|
||||
StickHelper.TryStick(HitNormal, HitLocation, HitActor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated protected function StopSimulating()
|
||||
{
|
||||
super.StopSimulating();
|
||||
|
||||
if (ProjIndicatorEffects!=None)
|
||||
{
|
||||
ProjIndicatorEffects.DeactivateSystem();
|
||||
}
|
||||
}
|
||||
|
||||
/** 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 );
|
||||
HitVelDir = Normal( HitVelocity );
|
||||
|
||||
SpawnLoc = HitLocation + (HitNormal * 10.f);
|
||||
|
||||
// spawn random lingering fires (rather, projectiles that cause little fires)
|
||||
for( i = 0; i < NumResidualFlames; ++i )
|
||||
{
|
||||
|
||||
SpawnVel = CalculateResidualFlameVelocity( HitNormal, HitVelDir, HitVelMag );
|
||||
SpawnResidualFlame( ResidualFlameProjClass, SpawnLoc, SpawnVel );
|
||||
}
|
||||
}
|
||||
|
||||
function vector CalculateResidualFlameVelocity( vector HitNormal, vector HitVelDir, float HitVelMag )
|
||||
{
|
||||
local vector SpawnDir;
|
||||
|
||||
// apply some spread
|
||||
SpawnDir = VRandCone( HitNormal, ResidualFlameHalfConeAngle * DegToRad );
|
||||
/*
|
||||
// make HitVelDir parallel to contact surface by subtracting component parallel to HitNormal
|
||||
SpawnDir = SpawnDir + (-(SpawnDir dot HitNormal) * HitNormal);
|
||||
|
||||
// apply some more spread to get some of the flames to stick to the wall and others the ground beneath the wall
|
||||
// (makes it looks kind of smeared down the wall, like a real molotov)
|
||||
SpawnDir = VRandCone( SpawnDir, PI/4 );
|
||||
*/
|
||||
return SpawnDir * ResidualFlameForceMultiplier;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ProjFlightTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Harpoon_Projectile'
|
||||
ProjIndicatorTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Harpoon_Projectile_Indicator'
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
MaxSpeed=5000.0 //4000.0
|
||||
Speed=5000.0 //4000.0
|
||||
TerminalVelocity=5000 //4000
|
||||
|
||||
Physics=PHYS_Falling
|
||||
|
||||
TossZ=0 //150
|
||||
GravityScale=0.36 //0.5//0.7
|
||||
|
||||
GlassShatterType=FMGS_ShatterAll
|
||||
|
||||
bCollideComplex=true
|
||||
|
||||
bIgnoreFoliageTouch=true
|
||||
|
||||
bBlockedByInstigator=false
|
||||
bAlwaysReplicateExplosion=true
|
||||
|
||||
FuseTime=4.0
|
||||
|
||||
bNetTemporary=false
|
||||
NetPriority=5
|
||||
NetUpdateFrequency=200
|
||||
|
||||
bNoReplicationToInstigator=false
|
||||
bUseClientSideHitDetection=true
|
||||
bUpdateSimulatedPosition=true
|
||||
bSyncToOriginalLocation=true
|
||||
bSyncToThirdPersonMuzzleLocation=true
|
||||
|
||||
PinBoneIdx=INDEX_None
|
||||
|
||||
bCanBeDamaged=true
|
||||
bCanDisintegrate=true
|
||||
Begin Object Name=CollisionCylinder
|
||||
BlockNonZeroExtent=false
|
||||
// for siren scream
|
||||
CollideActors=true
|
||||
End Object
|
||||
|
||||
// explosion light
|
||||
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 // @todo: change me
|
||||
Damage=150 //250
|
||||
DamageRadius=500 //600
|
||||
DamageFalloffExponent=1.f
|
||||
DamageDelay=0.f
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Explosive_Thermite'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=200.0
|
||||
FracturePartVel=500.0
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_Thermite_ARCH.ThermiteHarpoon_Explosion'
|
||||
ExplosionSound=AkEvent'WW_WEP_SealSqueal.Play_WEP_SealSqueal_Shoot_Explode'
|
||||
|
||||
// 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'
|
||||
|
||||
bCanStick=true
|
||||
bCanPin=true
|
||||
Begin Object Class=KFProjectileStickHelper Name=StickHelper0
|
||||
End Object
|
||||
StickHelper=StickHelper0
|
||||
|
||||
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
|
||||
|
||||
ResidualFlameProjClass=class'KFProj_ThermiteSplash'
|
||||
NumResidualFlames=4 //it always spawn 1 more than this parameter, so 5
|
||||
|
||||
ResidualFlameHalfConeAngle=72
|
||||
ResidualFlameForceMultiplier=700f; //1000f;
|
||||
|
||||
}
|
110
KFGameContent/Classes/KFProj_ThermiteSplash.uc
Normal file
110
KFGameContent/Classes/KFProj_ThermiteSplash.uc
Normal file
@ -0,0 +1,110 @@
|
||||
//=============================================================================
|
||||
// KFProj_ThermiteSplash
|
||||
//=============================================================================
|
||||
// Projectile class for the thermite rocket launchers
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_ThermiteSplash extends KFProj_MolotovSplash;
|
||||
|
||||
/*
|
||||
simulated function Tick(float Delta)
|
||||
{
|
||||
super.Tick(Delta);
|
||||
|
||||
if (WorldInfo.NetMode != NM_Client && WorldInfo.NetMode != NM_Standalone)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Rotate towards velocity:
|
||||
if (VSizeSq(Velocity) > 0)
|
||||
{
|
||||
SetRotation(rotator(Normal(Velocity)));
|
||||
}
|
||||
}
|
||||
*/
|
||||
defaultproperties
|
||||
{
|
||||
Physics=PHYS_Falling
|
||||
|
||||
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
|
||||
|
||||
// network
|
||||
bNetTemporary=False
|
||||
bAlwaysReplicateExplosion=true
|
||||
AlwaysRelevantDistanceSquared=6250000 // 25m
|
||||
|
||||
// gameplay
|
||||
bBlockedByInstigator=false
|
||||
GlassShatterType=FMGS_ShatterNone
|
||||
|
||||
// audio
|
||||
bStopAmbientSoundOnExplode=false
|
||||
bAutoStartAmbientSound=true
|
||||
bAmbientSoundZedTimeOnly=false
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_SA_Flamethrower.Play_WEP_SA_Flamethrower_Residual_Fire_Loop'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_SA_Flamethrower.Stop_WEP_SA_Flamethrower_Residual_Fire_Loop'
|
||||
|
||||
Begin Object name=AmbientAkSoundComponent
|
||||
bStopWhenOwnerDestroyed=true
|
||||
bForceOcclusionUpdateInterval=true
|
||||
OcclusionUpdateInterval=0.25;
|
||||
End Object
|
||||
AmbientComponent=AmbientAkSoundComponent
|
||||
Components.Add(AmbientAkSoundComponent)
|
||||
|
||||
// light
|
||||
Begin Object Name=FlamePointLight
|
||||
LightColor=(R=245,G=190,B=140,A=255)
|
||||
Brightness=2.f
|
||||
Radius=300.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 Name=ExploTemplate0
|
||||
Damage=10
|
||||
DamageRadius=150
|
||||
DamageFalloffExponent=1.f
|
||||
DamageDelay=0.f
|
||||
// Don't burn the guy that tossed it, it's just too much damage with multiple fires, its almost guaranteed to kill the guy that tossed it
|
||||
bIgnoreInstigator=true
|
||||
|
||||
MomentumTransferScale=1
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Fire_Ground_ThermiteBore'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=0
|
||||
ExplosionEffects=KFImpactEffectInfo'wep_thermite_arch.Thermite_GroundFire'
|
||||
|
||||
bDirectionalExplosion=true
|
||||
|
||||
// Camera Shake
|
||||
CamShake=none
|
||||
|
||||
// Dynamic Light
|
||||
ExploLight=FlamePointLight
|
||||
ExploLightStartFadeOutTime=4.2
|
||||
ExploLightFadeOutTime=0.3
|
||||
End Object
|
||||
ExplosionTemplate=ExploTemplate0
|
||||
|
||||
ProjFlightTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_01'
|
||||
ExplosionActorClass=class'KFExplosion_Thermite'
|
||||
|
||||
AssociatedPerkClass=class'KFPerk_Firebug'
|
||||
|
||||
// Ground Fire Perk Skill Alternative FX
|
||||
AltExploEffects=KFImpactEffectInfo'WEP_Thermite_ARCH.GroundFire_Splash_Impacts'
|
||||
}
|
137
KFGameContent/Classes/KFSeasonalEventStats_Summer2021.uc
Normal file
137
KFGameContent/Classes/KFSeasonalEventStats_Summer2021.uc
Normal file
@ -0,0 +1,137 @@
|
||||
//=============================================================================
|
||||
// KFSeasonalEventStats_Summer2021
|
||||
//=============================================================================
|
||||
// Tracks event-specific challenges/accomplishments for Summer 2021
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFSeasonalEventStats_Summer2021 extends KFSeasonalEventStats;
|
||||
|
||||
var transient private const int ZedsStompRequired, LaserKillsRequired, JumpKillsRequired, EndlessWaveRequired;
|
||||
|
||||
private event Initialize(string MapName)
|
||||
{
|
||||
local string CapsMapName;
|
||||
CapsMapName = Caps(MapName);
|
||||
|
||||
bObjectiveIsValidForMap[0] = 1; // Stomp on 50 Zeds
|
||||
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Moonbase
|
||||
bObjectiveIsValidForMap[2] = 0; // Use the laser trap to kill 20 Zeds on Moonbase
|
||||
bObjectiveIsValidForMap[3] = 0; // Kill 300 Zeds while jumping in the air on Moonbase
|
||||
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Moonbase
|
||||
|
||||
if (CapsMapName == "KF-MOONBASE")
|
||||
{
|
||||
bObjectiveIsValidForMap[1] = 1;
|
||||
bObjectiveIsValidForMap[2] = 1;
|
||||
bObjectiveIsValidForMap[3] = 1;
|
||||
bObjectiveIsValidForMap[4] = 1;
|
||||
}
|
||||
|
||||
SetSeasonalEventStatsMax(ZedsStompRequired, 0, LaserKillsRequired, JumpKillsRequired, 0);
|
||||
}
|
||||
|
||||
private event GrantEventItems()
|
||||
{
|
||||
if (Outer.IsEventObjectiveComplete(0) &&
|
||||
Outer.IsEventObjectiveComplete(1) &&
|
||||
Outer.IsEventObjectiveComplete(2) &&
|
||||
Outer.IsEventObjectiveComplete(3) &&
|
||||
Outer.IsEventObjectiveComplete(4))
|
||||
{
|
||||
// @TODO: Set Proper Reward ID
|
||||
//
|
||||
GrantEventItem(8844);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
|
||||
{
|
||||
// Moonbase weekly
|
||||
if (bObjectiveIsValidForMap[1] != 0)
|
||||
{
|
||||
if (GameClass == class'KFGameInfo_WeeklySurvival')
|
||||
{
|
||||
FinishedObjective(SEI_Summer, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
|
||||
{
|
||||
local int ObjIdx;
|
||||
local KFPlayerController KFPC;
|
||||
local KFPawn_Human KFP;
|
||||
|
||||
// Laser Kills
|
||||
ObjIdx = 2;
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (ClassIsChildOf(DT, class'KFDT_EMPTrap'))
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= LaserKillsRequired)
|
||||
{
|
||||
FinishedObjective(SEI_SUMMER, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjIdx = 3;
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
KFPC = Outer.MyKFPC;
|
||||
if (KFPC != none)
|
||||
{
|
||||
KFP = KFPawn_Human(KFPC.Pawn);
|
||||
if (KFP != none && KFP.Physics == PHYS_Falling)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= JumpKillsRequired)
|
||||
{
|
||||
FinishedObjective(SEI_SUMMER, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnHitGiven(class<DamageType> DT)
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 0;
|
||||
|
||||
// Stomps
|
||||
if (ClassIsChildOf(DT, class'DmgType_Crushed'))
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= ZedsStompRequired)
|
||||
{
|
||||
FinishedObjective(SEI_SUMMER, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
|
||||
{
|
||||
local int ObjIdx;
|
||||
|
||||
// Waves in Endless hard
|
||||
ObjIdx = 4;
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
|
||||
{
|
||||
FinishedObjective(SEI_Summer, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ZedsStompRequired=50
|
||||
LaserKillsRequired=20
|
||||
JumpKillsRequired=300
|
||||
EndlessWaveRequired=15
|
||||
}
|
231
KFGameContent/Classes/KFWeapAttach_FAMAS.uc
Normal file
231
KFGameContent/Classes/KFWeapAttach_FAMAS.uc
Normal file
@ -0,0 +1,231 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_FAMAS
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_FAMAS extends KFWeaponAttachment;
|
||||
|
||||
const SecondaryFireAnim = 'Shoot_Secondary';
|
||||
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
|
||||
const SecondaryFireAnimLast = 'Shoot_Secondary_Last';
|
||||
const SecondaryFireIronAnimLast = 'Shoot_Secondary_Iron_Last';
|
||||
const SecondaryFireBodyAnim = 'ADD_Shoot_Secondary';
|
||||
const SecondaryFireBodyAnimCH = 'ADD_Shoot_Secondary_CH';
|
||||
const SecondaryFireBodyAnimIron = 'ADD_Shoot_Secondary_Iron';
|
||||
const SecondaryReloadAnimEmpty = 'Reload_Secondary_Empty';
|
||||
const SecondaryReloadAnimHalf = 'Reload_Secondary_Half';
|
||||
const SecondaryReloadAnimEliteEmpty = 'Reload_Secondary_Elite_Empty';
|
||||
const SecondaryReloadAnimEliteHalf = 'Reload_Secondary_Elite_Half';
|
||||
const ShotgunMuzzleSocket = 'ShotgunMuzzleFlash';
|
||||
|
||||
var protected transient KFMuzzleFlash ShotgunMuzzleFlash;
|
||||
|
||||
|
||||
/** Play a 3rd person reload animation */
|
||||
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
|
||||
{
|
||||
local name AnimName;
|
||||
|
||||
if(NewWeaponState == WEP_ReloadSecondary || NewWeaponState == WEP_ReloadSecondary_Elite)
|
||||
{
|
||||
switch (NewWeaponState)
|
||||
{
|
||||
case WEP_ReloadSecondary:
|
||||
AnimName = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryReloadAnimEmpty : SecondaryReloadAnimHalf;
|
||||
break;
|
||||
case WEP_ReloadSecondary_Elite:
|
||||
AnimName = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryReloadAnimEliteEmpty : SecondaryReloadAnimEliteHalf;
|
||||
break;
|
||||
}
|
||||
|
||||
PlayCharacterMeshAnim(P, AnimName, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.PlayReloadMagazineAnim(NewWeaponState, P);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function CauseMuzzleFlash(byte FiringMode)
|
||||
{
|
||||
if ( FiringMode == 1 ) // AltFire
|
||||
{
|
||||
if (ShotgunMuzzleFlash == None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if (ShotgunMuzzleFlash != None )
|
||||
{
|
||||
ShotgunMuzzleFlash.CauseMuzzleFlash(FiringMode);
|
||||
if ( ShotgunMuzzleFlash.bAutoActivateShellEject )
|
||||
{
|
||||
ShotgunMuzzleFlash.CauseShellEject();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.CauseMuzzleFlash(FiringMode);
|
||||
}
|
||||
}
|
||||
|
||||
/** Added second weapon */
|
||||
simulated function AttachMuzzleFlash()
|
||||
{
|
||||
Super.AttachMuzzleFlash();
|
||||
|
||||
if ( WeapMesh != none && ShotgunMuzzleFlash == None )
|
||||
{
|
||||
ShotgunMuzzleFlash = new(self) Class'KFMuzzleFlash'(class'KFWeap_AssaultRifle_FAMAS'.default.ShotgunMuzzleFlashTemplate);
|
||||
ShotgunMuzzleFlash.AttachMuzzleFlash(WeapMesh, ShotgunMuzzleSocket,);
|
||||
}
|
||||
}
|
||||
|
||||
/** Plays fire animation on weapon mesh */
|
||||
simulated function PlayFireAnim(KFPawn P)
|
||||
{
|
||||
local float Duration;
|
||||
local name Anim;
|
||||
local KFPawn OwnerPawn;
|
||||
|
||||
OwnerPawn = KFPawn(Owner);
|
||||
|
||||
if ( Instigator.bIsWalking ) // IronSight anims
|
||||
{
|
||||
if (OwnerPawn.FiringMode == 0) // DEFAULT FIRE MODE (Rifle)
|
||||
{
|
||||
Anim = WeaponIronFireAnim;
|
||||
}
|
||||
else if (OwnerPawn.FiringMode == 1) // ALT FIRE MODE (Shotgun)
|
||||
{
|
||||
// Anim = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryFireIronAnimLast : SecondaryFireIronAnim;
|
||||
Anim = SecondaryFireIronAnim;
|
||||
|
||||
}
|
||||
}
|
||||
else // Normal anims
|
||||
{
|
||||
if (Pawn(Owner).FiringMode == 0) // DEFAULT FIRE MODE (Rifle)
|
||||
{
|
||||
Anim = WeaponFireAnim;
|
||||
}
|
||||
else if (Pawn(Owner).FiringMode == 1) // ALT FIRE MODE (Shotgun)
|
||||
{
|
||||
// Anim = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryFireAnimLast : SecondaryFireAnim;
|
||||
Anim = SecondaryFireAnim;
|
||||
}
|
||||
}
|
||||
|
||||
Duration = WeapMesh.GetAnimLength( Anim );
|
||||
WeapMesh.PlayAnim( Anim, Duration / ThirdPersonAnimRate,, true );
|
||||
}
|
||||
|
||||
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
|
||||
{
|
||||
local EAnimSlotStance AnimType;
|
||||
|
||||
if (P.FiringMode == 1) // AltFire
|
||||
{
|
||||
SpawnTracer(GetAltMuzzleLocation(), HitLocation);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 )
|
||||
{
|
||||
PlayFireAnim(P);
|
||||
}
|
||||
|
||||
if( P.IsDoingSpecialMove() && P.SpecialMoves[P.SpecialMove].bAllowFireAnims )
|
||||
{
|
||||
AnimType = EAS_Additive;
|
||||
}
|
||||
else
|
||||
{
|
||||
AnimType = EAS_FullBody;
|
||||
}
|
||||
|
||||
// Character shoot anims
|
||||
if ( !P.IsDoingSpecialMove() || AnimType == EAS_Additive )
|
||||
{
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Plays fire animation on pawn */
|
||||
simulated function PlayPawnFireAnim( KFPawn P, EAnimSlotStance AnimType )
|
||||
{
|
||||
if (P.FiringMode == 0)
|
||||
{
|
||||
super.PlayPawnFireAnim(P, AnimType);
|
||||
}
|
||||
else if (P.FiringMode == 1)
|
||||
{
|
||||
if ( P.bIsCrouched )
|
||||
{
|
||||
P.PlayBodyAnim(SecondaryFireBodyAnimCH, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
|
||||
}
|
||||
else if ( P.bIsWalking )
|
||||
{
|
||||
P.PlayBodyAnim(SecondaryFireBodyAnimIron, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
P.PlayBodyAnim(SecondaryFireBodyAnim, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function vector GetAltMuzzleLocation(optional byte MuzzleID)
|
||||
{
|
||||
local vector SocketLocation;
|
||||
|
||||
if (ShotgunMuzzleFlash == None && MuzzleFlashTemplate != None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if( ShotgunMuzzleFlash != none )
|
||||
{
|
||||
WeapMesh.GetSocketWorldLocationAndRotation(ShotgunMuzzleFlash.GetSocketName(), SocketLocation);
|
||||
return SocketLocation;
|
||||
}
|
||||
|
||||
return Super.GetMuzzleLocation(MuzzleID);
|
||||
}
|
||||
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
|
||||
}
|
102
KFGameContent/Classes/KFWeapAttach_HRG_BarrierRifle.uc
Normal file
102
KFGameContent/Classes/KFWeapAttach_HRG_BarrierRifle.uc
Normal file
@ -0,0 +1,102 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_HRG_BarrierRifle
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_HRG_BarrierRifle extends KFWeaponAttachment;
|
||||
|
||||
`define BARRIERRIFLE_MIC_SHIELD_INDEX 0
|
||||
|
||||
/** Indicates wheter we are activating/deactivating the shield fx */
|
||||
var protected transient bool bActivatingShield;
|
||||
var protected transient float FXDelta;
|
||||
var protected transient float ShieldFXDuration;
|
||||
var protected transient float OverlayDelta;
|
||||
var protected transient float OverlayMax;
|
||||
var protected transient float OverlayMin;
|
||||
var protected transient float ShieldBlockVFXDuration;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
if ( WorldInfo.NetMode == NM_DedicatedServer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ShieldFXDuration = class'KFWeap_HRG_BarrierRifle'.default.ShieldFXDuration;
|
||||
OverlayMax = class'KFWeap_HRG_BarrierRifle'.default.RedOverlayMax;
|
||||
OverlayMin = class'KFWeap_HRG_BarrierRifle'.default.RedOverlayMin;
|
||||
ShieldBlockVFXDuration = class'KFWeap_HRG_BarrierRifle'.default.ShieldBlockVFXDuration;
|
||||
|
||||
UpdateShieldFXValue(0.0f);
|
||||
}
|
||||
|
||||
simulated function UpdateShieldFXValue(float Value)
|
||||
{
|
||||
if ( WeaponMIC == None && WeapMesh != None )
|
||||
{
|
||||
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`BARRIERRIFLE_MIC_SHIELD_INDEX);
|
||||
}
|
||||
|
||||
WeaponMIC.SetScalarParameterValue('Opacity', Value);
|
||||
}
|
||||
|
||||
unreliable client function SetShieldActive(bool bActive)
|
||||
{
|
||||
bActivatingShield = bActive;
|
||||
}
|
||||
|
||||
/** Special event added for weap attachments. Free for use */
|
||||
function OnSpecialEvent(int Arg)
|
||||
{
|
||||
if (Arg < 2)
|
||||
{
|
||||
SetShieldActive(Arg == 1 ? True : False);
|
||||
}
|
||||
else if (Arg == 3)
|
||||
{
|
||||
UpdateShieldBlockVFX(OverlayMax);
|
||||
OverlayDelta = OverlayMax;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function UpdateShieldBlockVFX(float Value)
|
||||
{
|
||||
if ( WeaponMIC == None && WeapMesh != None )
|
||||
{
|
||||
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`BARRIERRIFLE_MIC_SHIELD_INDEX);
|
||||
}
|
||||
WeaponMIC.SetScalarParameterValue('RedOverlay', Value);
|
||||
}
|
||||
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
// Update Shield visuals
|
||||
if (bActivatingShield && FXDelta < class'KFWeap_HRG_BarrierRifle'.default.ShieldFXDuration)
|
||||
{
|
||||
FXDelta = FMin(FXDelta + DeltaTime, ShieldFXDuration);
|
||||
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
|
||||
}
|
||||
else if (!bActivatingShield && FXDelta > 0.0f)
|
||||
{
|
||||
FXDelta = FMax(FXDelta - DeltaTime, 0.0f);
|
||||
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
|
||||
}
|
||||
|
||||
if (OverlayDelta > 0.0f)
|
||||
{
|
||||
OverlayDelta = FMax(OverlayDelta - DeltaTime, OverlayMin);
|
||||
UpdateShieldBlockVFX(OverlayMax * (OverlayDelta / ShieldBlockVFXDuration));
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
OverlayDelta=0.0f
|
||||
}
|
142
KFGameContent/Classes/KFWeapAttach_HRG_BlastBrawlers.uc
Normal file
142
KFGameContent/Classes/KFWeapAttach_HRG_BlastBrawlers.uc
Normal file
@ -0,0 +1,142 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_HRG_BlastBrawlers
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapAttach_HRG_BlastBrawlers extends KFWeapAttach_DualBase;
|
||||
|
||||
var protected transient bool bUsingLeftWeapon;
|
||||
var protected transient name ReloadAnimName;
|
||||
var protected transient float ReloadAnimRateMod;
|
||||
|
||||
/** Overrides to prevent weapon animation */
|
||||
simulated function PlayWeaponFireAnim();
|
||||
|
||||
/** Caching reload anim name */
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
ReloadAnimName = class'KFWeap_HRG_BlastBrawlers'.default.ReloadAnimation;
|
||||
ReloadAnimRateMod = class'KFWeap_HRG_BlastBrawlers'.default.ReloadAnimRateModifier;
|
||||
}
|
||||
|
||||
/** Overriding to avoid interrupting meleen anims with fire anims */
|
||||
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
|
||||
{
|
||||
SpawnTracer(GetMuzzleLocation(), HitLocation);
|
||||
|
||||
// Effects below this point are culled based on visibility and distance
|
||||
if ( !ActorEffectIsRelevant(P, false, MaxFireEffectDistance) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CauseMuzzleFlash(P.FiringMode);
|
||||
P.LastWeaponFireTime = -1.f;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated function vector GetMuzzleLocation(optional byte MuzzleID)
|
||||
{
|
||||
local vector SocketLocation;
|
||||
|
||||
if ( bUsingLeftWeapon)
|
||||
{
|
||||
if (LeftMuzzleFlash == None && MuzzleFlashTemplate != None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if( LeftMuzzleFlash != none )
|
||||
{
|
||||
LeftWeapMesh.GetSocketWorldLocationAndRotation(LeftMuzzleFlash.GetSocketName(), SocketLocation);
|
||||
return SocketLocation;
|
||||
}
|
||||
}
|
||||
|
||||
return Super.GetMuzzleLocation(MuzzleID);
|
||||
}
|
||||
|
||||
/** Added second weapon */
|
||||
simulated function CauseMuzzleFlash(byte FiringMode)
|
||||
{
|
||||
if ( bUsingLeftWeapon )
|
||||
{
|
||||
if (LeftMuzzleFlash == None && MuzzleFlashTemplate != None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if (LeftMuzzleFlash != None )
|
||||
{
|
||||
LeftMuzzleFlash.CauseMuzzleFlash(FiringMode);
|
||||
if ( LeftMuzzleFlash.bAutoActivateShellEject )
|
||||
{
|
||||
LeftMuzzleFlash.CauseShellEject();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.CauseMuzzleFlash(FiringMode);
|
||||
bUsingLeftWeapon = true;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function UpdateThirdPersonWeaponAction(EWeaponState NewWeaponState, KFPawn P, byte ThirdPersonAnimRateByte )
|
||||
{
|
||||
// Reset
|
||||
bUsingLeftWeapon=false;
|
||||
super.UpdateThirdPersonWeaponAction(NewWeaponState, P, ThirdPersonAnimRateByte);
|
||||
}
|
||||
|
||||
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
|
||||
{
|
||||
PlayCharacterMeshAnim(P, ReloadAnimNAme, true);
|
||||
}
|
||||
|
||||
simulated function PlayWeaponMeshAnim(name AnimName, AnimNodeSlot SyncNode, bool bLoop)
|
||||
{
|
||||
local float Duration;
|
||||
|
||||
/** Only reload animation could be played */
|
||||
if ( !IsAnimationValid(AnimName) )
|
||||
return;
|
||||
|
||||
// Weapon shoot anims
|
||||
if( !bWeapMeshIsPawnMesh )
|
||||
{
|
||||
Duration = WeapMesh.GetAnimLength(AnimName);
|
||||
|
||||
if (AnimName == ReloadAnimName)
|
||||
{
|
||||
Duration *= ReloadAnimRateMod;
|
||||
}
|
||||
|
||||
WeapMesh.PlayAnim(AnimName, Duration / ThirdPersonAnimRate, bLoop);
|
||||
|
||||
// syncronize this with the character anim
|
||||
if ( SyncNode != None )
|
||||
{
|
||||
bSynchronizeWeaponAnim = true;
|
||||
SyncPawnNode = SyncNode;
|
||||
SyncAnimName = AnimName;
|
||||
bSyncAnimCheckRelevance = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function bool IsAnimationValid(name AnimName)
|
||||
{
|
||||
return AnimName == ReloadAnimName;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bUsingLeftWeapon=false
|
||||
}
|
682
KFGameContent/Classes/KFWeap_AssaultRifle_FAMAS.uc
Normal file
682
KFGameContent/Classes/KFWeap_AssaultRifle_FAMAS.uc
Normal file
@ -0,0 +1,682 @@
|
||||
//=============================================================================
|
||||
// KFWeap_AssaultRifle_FAMAS
|
||||
//=============================================================================
|
||||
// FAMAS assault rifle with an extra of shotgun. Better than in MGS!
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_AssaultRifle_FAMAS extends KFWeap_ScopedBase;
|
||||
|
||||
var (Positioning) vector SecondaryFireOffset;
|
||||
|
||||
const SecondaryFireAnim = 'Shoot_Secondary';
|
||||
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
|
||||
const SecondaryFireAnimLast = 'Shoot_Secondary_Last';
|
||||
const SecondaryFireIronAnimLast = 'Shoot_Secondary_Iron_Last';
|
||||
const SecondaryReloadAnimEmpty = 'Reload_Secondary_Empty';
|
||||
const SecondaryReloadAnimHalf = 'Reload_Secondary_Half';
|
||||
const SecondaryReloadAnimEliteEmpty = 'Reload_Secondary_Elite_Empty';
|
||||
const SecondaryReloadAnimEliteHalf = 'Reload_Secondary_Elite_Half';
|
||||
const ShotgunMuzzleSocket = 'ShotgunMuzzleFlash';
|
||||
|
||||
/** Animation to play when the weapon is fired in burst mode with 2 rounds left */
|
||||
var(Animations) const editconst name BurstFire2RdAnim;
|
||||
var(Animations) const editconst name BurstFire2RdSightedAnim;
|
||||
/** Animation to play when the weapon is fired in burst fire mode for 3 rounds*/
|
||||
var(Animations) const editconst name BurstFire3RdAnim;
|
||||
var(Animations) const editconst name BurstFire3RdSightedAnim;
|
||||
|
||||
var transient KFMuzzleFlash ShotgunMuzzleFlash;
|
||||
var() KFMuzzleFlash ShotgunMuzzleFlashTemplate;
|
||||
|
||||
// Used on the server to keep track of grenades
|
||||
var int ServerTotalAltAmmo;
|
||||
|
||||
var transient bool bCanceledAltAutoReload;
|
||||
var transient int BurstAmountBegin;
|
||||
|
||||
var protected const float AltFireRecoilScale;
|
||||
|
||||
static simulated event EFilterTypeUI GetTraderFilter()
|
||||
{
|
||||
return FT_Assault;
|
||||
}
|
||||
|
||||
static simulated event EFilterTypeUI GetAltTraderFilter()
|
||||
{
|
||||
return FT_Explosive;
|
||||
}
|
||||
|
||||
/** Instead of switch fire mode use as immediate alt fire */
|
||||
simulated function AltFireMode()
|
||||
{
|
||||
if ( !Instigator.IsLocallyControlled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (bCanceledAltAutoReload)
|
||||
{
|
||||
bCanceledAltAutoReload = false;
|
||||
TryToAltReload(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// StartFire - StopFire called from KFPlayerInput
|
||||
StartFire(ALTFIRE_FIREMODE);
|
||||
}
|
||||
|
||||
simulated function BeginFire( Byte FireModeNum )
|
||||
{
|
||||
local bool bStoredAutoReload;
|
||||
|
||||
// We are trying to reload the weapon but the primary ammo in already at full capacity
|
||||
if ( FireModeNum == RELOAD_FIREMODE && !CanReload() )
|
||||
{
|
||||
// Store the current state of bCanceledAltAutoReload in case its not possible to do the reload
|
||||
bStoredAutoReload = bCanceledAltAutoReload;
|
||||
bCanceledAltAutoReload = false;
|
||||
|
||||
if(CanAltAutoReload(false))
|
||||
{
|
||||
TryToAltReload(false);
|
||||
return;
|
||||
}
|
||||
|
||||
bCanceledAltAutoReload = bStoredAutoReload;
|
||||
}
|
||||
|
||||
super.BeginFire( FireModeNum );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes ammo counts, when weapon is spawned.
|
||||
*/
|
||||
function InitializeAmmo()
|
||||
{
|
||||
Super.InitializeAmmo();
|
||||
|
||||
// Add Secondary ammo to our secondary spare ammo count both of these are important, in order to allow dropping the weapon to function properly.
|
||||
SpareAmmoCount[1] = Min(SpareAmmoCount[1] + InitialSpareMags[1] * default.MagazineCapacity[1], GetMaxAmmoAmount(1) - AmmoCount[1]);
|
||||
ServerTotalAltAmmo += SpareAmmoCount[1];
|
||||
|
||||
// Make sure the server doesn't get extra shots on listen servers.
|
||||
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
|
||||
{
|
||||
ServerTotalAltAmmo += AmmoCount[1];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Weapon::ConsumeAmmo
|
||||
*/
|
||||
simulated function ConsumeAmmo( byte FireModeNum )
|
||||
{
|
||||
local byte AmmoType;
|
||||
local bool bNoInfiniteAmmo;
|
||||
local int OldAmmoCount;
|
||||
|
||||
if(UsesSecondaryAmmo() && FireModeNum == ALTFIRE_FIREMODE && Role == ROLE_Authority && !Instigator.IsLocallyControlled())
|
||||
{
|
||||
AmmoType = GetAmmoType(FireModeNum);
|
||||
|
||||
OldAmmoCount = AmmoCount[AmmoType];
|
||||
Super.ConsumeAmmo(FireModeNum);
|
||||
|
||||
bNoInfiniteAmmo = (OldAmmoCount - AmmoCount[AmmoType]) > 0 || AmmoCount[AmmoType] == 0;
|
||||
if ( bNoInfiniteAmmo )
|
||||
{
|
||||
ServerTotalAltAmmo--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.ConsumeAmmo(FireModeNum);
|
||||
}
|
||||
}
|
||||
|
||||
/** Make sure user can't fire infinitely if they cheat to get infinite ammo locally. */
|
||||
simulated event bool HasAmmo( byte FireModeNum, optional int Amount=1 )
|
||||
{
|
||||
local byte AmmoType;
|
||||
|
||||
AmmoType = GetAmmoType(FireModeNum);
|
||||
|
||||
if(AmmoType == 1 && Role == ROLE_Authority && UsesSecondaryAmmo() && !Instigator.IsLocallyControlled())
|
||||
{
|
||||
if(ServerTotalAltAmmo <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return Super.HasAmmo(FireModeNum, Amount );
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden so any grenades added will go to the spare ammo and no the clip.
|
||||
*/
|
||||
function int AddSecondaryAmmo(int Amount)
|
||||
{
|
||||
local int OldAmmo;
|
||||
|
||||
// If we can't accept spare ammo, then abort
|
||||
if( !CanRefillSecondaryAmmo() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
|
||||
{
|
||||
OldAmmo = ServerTotalAltAmmo;
|
||||
|
||||
ServerTotalAltAmmo = Min(ServerTotalAltAmmo + Amount, GetMaxAmmoAmount(1));
|
||||
ClientGiveSecondaryAmmo(Amount);
|
||||
return ServerTotalAltAmmo - OldAmmo;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldAmmo = SpareAmmoCount[1];
|
||||
ClientGiveSecondaryAmmo(Amount);
|
||||
return SpareAmmoCount[1] - OldAmmo;
|
||||
}
|
||||
}
|
||||
|
||||
/** Give client specified amount of ammo (used player picks up ammo on the server) */
|
||||
reliable client function ClientGiveSecondaryAmmo(byte Amount)
|
||||
{
|
||||
SpareAmmoCount[1] = Min(SpareAmmoCount[1] + Amount, GetMaxAmmoAmount(1) - AmmoCount[1]);
|
||||
TryToAltReload(true);
|
||||
}
|
||||
|
||||
function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon )
|
||||
{
|
||||
local KFWeap_AssaultRifle_FAMAS Weap;
|
||||
|
||||
Super.SetOriginalValuesFromPickup(PickedUpWeapon);
|
||||
|
||||
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
|
||||
{
|
||||
Weap = KFWeap_AssaultRifle_FAMAS(PickedUpWeapon);
|
||||
ServerTotalAltAmmo = Weap.ServerTotalAltAmmo;
|
||||
SpareAmmoCount[1] = ServerTotalAltAmmo - AmmoCount[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're locally controlled, don't bother using ServerTotalAltAmmo.
|
||||
SpareAmmoCount[1] = PickedUpWeapon.SpareAmmoCount[1];
|
||||
}
|
||||
}
|
||||
|
||||
simulated state WeaponBurstFiring
|
||||
{
|
||||
simulated event BeginState(Name PreviousStateName)
|
||||
{
|
||||
BurstAmountBegin = GetBurstAmount();
|
||||
Super.BeginState(PreviousStateName);
|
||||
}
|
||||
|
||||
simulated function name GetWeaponFireAnim(byte FireModeNum)
|
||||
{
|
||||
// only do one burst animation instead of a burst animation per shot
|
||||
// since burst amount gets reduced after each shot, this will only play the one animation based on the number of shots in the burst fire
|
||||
if (BurstAmount == BurstAmountBegin)
|
||||
{
|
||||
if (BurstAmount == 3)
|
||||
{
|
||||
if (bUsingSights)
|
||||
{
|
||||
return BurstFire3RdSightedAnim;
|
||||
}
|
||||
return BurstFire3RdAnim;
|
||||
}
|
||||
else if (BurstAmount == 2)
|
||||
{
|
||||
if (bUsingSights)
|
||||
{
|
||||
return BurstFire2RdSightedAnim;
|
||||
}
|
||||
return BurstFire2RdAnim;
|
||||
}
|
||||
else
|
||||
{
|
||||
return super.GetWeaponFireAnim(FireModeNum);
|
||||
}
|
||||
}
|
||||
|
||||
// will not play any animation
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
simulated state FiringSecondaryState extends WeaponFiring
|
||||
{
|
||||
// Overriden to not call FireAmmunition right at the start of the state
|
||||
simulated event BeginState( Name PreviousStateName )
|
||||
{
|
||||
Super.BeginState(PreviousStateName);
|
||||
NotifyBeginState();
|
||||
}
|
||||
|
||||
simulated function EndState(Name NextStateName)
|
||||
{
|
||||
Super.EndState(NextStateName);
|
||||
NotifyEndState();
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the world location for spawning the visual effects
|
||||
* Overridden to use a special offset for using the shotgun
|
||||
*/
|
||||
simulated event vector GetMuzzleLoc()
|
||||
{
|
||||
local vector MuzzleLocation;
|
||||
|
||||
// swap fireoffset temporarily
|
||||
FireOffset = SecondaryFireOffset;
|
||||
MuzzleLocation = Global.GetMuzzleLoc();
|
||||
FireOffset = default.FireOffset;
|
||||
|
||||
return MuzzleLocation;
|
||||
}
|
||||
|
||||
/** Get whether we should play the reload anim as well or not */
|
||||
simulated function name GetWeaponFireAnim(byte FireModeNum)
|
||||
{
|
||||
if (AmmoCount[FireModeNum] > 0)
|
||||
{
|
||||
return bUsingSights ? SecondaryFireIronAnim : SecondaryFireAnim;
|
||||
}
|
||||
return bUsingSights ? SecondaryFireIronAnimLast : SecondaryFireAnimLast;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't allow secondary fire to make a primary fire shell particle come out of the gun.
|
||||
*/
|
||||
simulated function CauseMuzzleFlash(byte FireModeNum)
|
||||
{
|
||||
if(FireModeNum == ALTFIRE_FIREMODE)
|
||||
{
|
||||
if (ShotgunMuzzleFlash == None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if (ShotgunMuzzleFlash != none)
|
||||
{
|
||||
ShotgunMuzzleFlash.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
|
||||
if ( ShotgunMuzzleFlash.bAutoActivateShellEject )
|
||||
{
|
||||
ShotgunMuzzleFlash.CauseShellEject();
|
||||
SetShellEjectsToForeground();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function AttachMuzzleFlash()
|
||||
{
|
||||
super.AttachMuzzleFlash();
|
||||
|
||||
if ( MySkelMesh != none )
|
||||
{
|
||||
if (ShotgunMuzzleFlashTemplate != None)
|
||||
{
|
||||
ShotgunMuzzleFlash = new(self) Class'KFMuzzleFlash'(ShotgunMuzzleFlashTemplate);
|
||||
ShotgunMuzzleFlash.AttachMuzzleFlash(MySkelMesh, ShotgunMuzzleSocket,);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State Reloading
|
||||
* This is the default Reloading State. It's performed on both the client and the server.
|
||||
*********************************************************************************************/
|
||||
|
||||
/** Do not allow alternate fire to tell the weapon to reload. Alt reload occurs in a separate codepath */
|
||||
simulated function bool ShouldAutoReload(byte FireModeNum)
|
||||
{
|
||||
if(FireModeNum == ALTFIRE_FIREMODE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Super.ShouldAutoReload(FireModeNum);
|
||||
}
|
||||
|
||||
/** Called on local player when reload starts and replicated to server */
|
||||
simulated function SendToAltReload()
|
||||
{
|
||||
ReloadAmountLeft = MagazineCapacity[1] - AmmoCount[1];
|
||||
GotoState('AltReloading');
|
||||
if ( Role < ROLE_Authority )
|
||||
{
|
||||
ServerSendToAltReload();
|
||||
}
|
||||
}
|
||||
|
||||
/** Called from client when reload starts */
|
||||
reliable server function ServerSendToAltReload()
|
||||
{
|
||||
ReloadAmountLeft = MagazineCapacity[1] - AmmoCount[1];
|
||||
GotoState('AltReloading');
|
||||
}
|
||||
|
||||
/**
|
||||
* State Reloading
|
||||
* State the weapon is in when it is being reloaded (current magazine replaced with a new one, related animations and effects played).
|
||||
*/
|
||||
simulated state AltReloading extends Reloading
|
||||
{
|
||||
ignores ForceReload, ShouldAutoReload, AllowSprinting;
|
||||
|
||||
simulated function byte GetWeaponStateId()
|
||||
{
|
||||
local KFPerk Perk;
|
||||
local bool bTacticalReload;
|
||||
|
||||
Perk = GetPerk();
|
||||
bTacticalReload = (Perk != None && Perk.GetUsingTactialReload(self));
|
||||
|
||||
return (bTacticalReload ? WEP_ReloadSecondary_Elite : WEP_ReloadSecondary);
|
||||
}
|
||||
|
||||
simulated event BeginState(Name PreviousStateName)
|
||||
{
|
||||
super.BeginState(PreviousStateName);
|
||||
bCanceledAltAutoReload = true;
|
||||
}
|
||||
|
||||
// Overridding super so we don't call functions we don't want to call.
|
||||
simulated function EndState(Name NextStateName)
|
||||
{
|
||||
ClearZedTimeResist();
|
||||
ClearTimer(nameof(ReloadStatusTimer));
|
||||
ClearTimer(nameof(ReloadAmmoTimer));
|
||||
|
||||
CheckBoltLockPostReload();
|
||||
NotifyEndState();
|
||||
|
||||
`DialogManager.PlayAmmoDialog( KFPawn(Instigator), float(SpareAmmoCount[1]) / float(GetMaxAmmoAmount(1)) );
|
||||
}
|
||||
|
||||
// Overridding super so when this reload is called directly after normal reload state there
|
||||
// are not complications resulting from back to back reloads.
|
||||
simulated event ReplicatedEvent(name VarName)
|
||||
{
|
||||
Global.ReplicatedEvent(Varname);
|
||||
}
|
||||
|
||||
/** Make sure we can inturrupt secondary reload with anything. */
|
||||
simulated function bool CanOverrideMagReload(byte FireModeNum)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Returns animation to play based on reload type and status */
|
||||
simulated function name GetReloadAnimName( bool bTacticalReload )
|
||||
{
|
||||
// magazine relaod
|
||||
if ( AmmoCount[1] > 0 )
|
||||
{
|
||||
return (bTacticalReload) ? SecondaryReloadAnimEliteHalf : SecondaryReloadAnimHalf;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bTacticalReload) ? SecondaryReloadAnimEliteEmpty : SecondaryReloadAnimEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function PerformReload(optional byte FireModeNum)
|
||||
{
|
||||
Global.PerformReload(ALTFIRE_FIREMODE);
|
||||
|
||||
if(Instigator.IsLocallyControlled() && Role < ROLE_Authority)
|
||||
{
|
||||
ServerSetAltAmmoCount(AmmoCount[1]);
|
||||
}
|
||||
|
||||
bCanceledAltAutoReload = false;
|
||||
}
|
||||
|
||||
simulated function EReloadStatus GetNextReloadStatus(optional byte FireModeNum)
|
||||
{
|
||||
return Global.GetNextReloadStatus(ALTFIRE_FIREMODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reliable server function ServerSetAltAmmoCount(byte Amount)
|
||||
{
|
||||
AmmoCount[1] = Amount;
|
||||
}
|
||||
|
||||
/** Allow reloads for primary weapon to be interupted by firing secondary weapon. */
|
||||
simulated function bool CanOverrideMagReload(byte FireModeNum)
|
||||
{
|
||||
if(FireModeNum == ALTFIRE_FIREMODE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Super.CanOverrideMagReload(FireModeNum);
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State Active
|
||||
* Try to get weapon to automatically reload secondary fire types when it can.
|
||||
*********************************************************************************************/
|
||||
simulated state Active
|
||||
{
|
||||
/** Initialize the weapon as being active and ready to go. */
|
||||
simulated event BeginState(Name PreviousStateName)
|
||||
{
|
||||
// do this last so the above code happens before any state changes
|
||||
Super.BeginState(PreviousStateName);
|
||||
|
||||
// If nothing happened, try to reload
|
||||
TryToAltReload(true);
|
||||
}
|
||||
}
|
||||
|
||||
/** Network: Local Player */
|
||||
simulated function bool CanAltAutoReload(bool bIsAuto)
|
||||
{
|
||||
if ( !Instigator.IsLocallyControlled() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!UsesSecondaryAmmo())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the weapon wants to fire its primary weapon, and it can fire, do not allow weapon to automatically alt reload
|
||||
if(PendingFire(DEFAULT_FIREMODE) && HasAmmo(DEFAULT_FIREMODE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!CanReload(ALTFIRE_FIREMODE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bIsAuto && AmmoCount[1] > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bCanceledAltAutoReload)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated function TryToAltReload(bool bIsAuto)
|
||||
{
|
||||
if ((IsInState('Active') || IsInState('WeaponSprinting')) && CanAltAutoReload(bIsAuto))
|
||||
{
|
||||
SendToAltReload();
|
||||
}
|
||||
}
|
||||
|
||||
simulated function int GetSecondaryAmmoForHUD()
|
||||
{
|
||||
return AmmoCount[1];
|
||||
}
|
||||
|
||||
simulated function int GetSecondarySpareAmmoForHUD()
|
||||
{
|
||||
return SpareAmmoCount[1];
|
||||
}
|
||||
|
||||
simulated function ModifyRecoil( out float CurrentRecoilModifier )
|
||||
{
|
||||
if( CurrentFireMode == ALTFIRE_FIREMODE )
|
||||
{
|
||||
CurrentRecoilModifier *= AltFireRecoilScale;
|
||||
}
|
||||
|
||||
super.ModifyRecoil( CurrentRecoilModifier );
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bCanRefillSecondaryAmmo = true;
|
||||
|
||||
// Content
|
||||
PackageKey="Famas"
|
||||
FirstPersonMeshName="wep_1p_famas_mesh.Wep_1stP_Famas_Rig"
|
||||
FirstPersonAnimSetNames(0)="wep_1p_famas_anim.Wep_1stP_Famas_Anim"
|
||||
PickupMeshName="WEP_3P_Famas_MESH.WEP_Famas_Pickup"
|
||||
AttachmentArchetypeName="Wep_Famas_ARCH.Wep_Famas_3P"
|
||||
MuzzleFlashTemplateName="wep_famas_arch.Wep_Famas_MuzzleFlash"
|
||||
ShotgunMuzzleFlashTemplate=KFMuzzleFlash'wep_famas_arch.Wep_Famas_Shotgun_MuzzleFlash'
|
||||
|
||||
// Scope Render
|
||||
// 2D scene capture
|
||||
Begin Object Name=SceneCapture2DComponent0
|
||||
TextureTarget=TextureRenderTarget2D'Wep_Mat_Lib.WEP_ScopeLense_Target'
|
||||
FieldOfView=12.5 // "2.0X" = 25.0(our real world FOV determinant)/2.0
|
||||
End Object
|
||||
|
||||
ScopedSensitivityMod = 8.0
|
||||
ScopeLenseMICTemplate = MaterialInstanceConstant'WEP_1P_FNFAL_MAT.WEP_1P_FNFAL_Scope_MAT'
|
||||
ScopeMICIndex = 2
|
||||
|
||||
// FOV
|
||||
MeshFov=65
|
||||
MeshIronSightFOV=60 //45
|
||||
PlayerIronSightFOV=70
|
||||
|
||||
// Depth of field
|
||||
DOF_BlendInSpeed=3.0
|
||||
DOF_FG_FocalRadius=0
|
||||
DOF_FG_MaxNearBlurSize=3.5
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=22.0,Y=9.f,Z=-2.f)
|
||||
IronSightPosition=(X=0,Y=0,Z=0)
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=24
|
||||
SpareAmmoCapacity[0]=240
|
||||
InitialSpareMags[0]=3
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Shotgun Ammo
|
||||
MagazineCapacity[1]=6
|
||||
SpareAmmoCapacity[1]=36 //42
|
||||
InitialSpareMags[1]=1
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=100 //125 //200 //120
|
||||
minRecoilPitch=75 //100 //150 //70
|
||||
maxRecoilYaw=40 //80
|
||||
minRecoilYaw=-40 //-80
|
||||
RecoilRate=0.085
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=900
|
||||
RecoilMinPitchLimit=65035
|
||||
RecoilISMaxYawLimit=75
|
||||
RecoilISMinYawLimit=65460
|
||||
RecoilISMaxPitchLimit=375
|
||||
RecoilISMinPitchLimit=65460
|
||||
RecoilViewRotationScale=0.25
|
||||
IronSightMeshFOVCompensationScale=1.7
|
||||
HippedRecoilModifier=2.0 //1.5
|
||||
|
||||
// Inventory / Grouping
|
||||
InventorySize=6
|
||||
GroupPriority=80 //75
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_Famas_TEX.UI_WeaponSelect_Famas'
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletBurst'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponBurstFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_FAMAS_Rifle'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.0667 // 900 RPM
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=35.0
|
||||
Spread(DEFAULT_FIREMODE)=0.005 //0.0085
|
||||
BurstAmount=3
|
||||
BurstFire2RdAnim=Shoot_Burst2
|
||||
BurstFire3RdAnim=Shoot_Burst
|
||||
BurstFire2RdSightedAnim=Shoot_Burst2_Iron
|
||||
BurstFire3RdSightedAnim=Shoot_Burst_Iron
|
||||
FireOffset=(X=30,Y=4.5,Z=-5)
|
||||
SecondaryFireOffset=(X=20.f,Y=4.5,Z=-7.f)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=FiringSecondaryState
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_Pellet'
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_FAMAS_Shotgun'
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=25.0
|
||||
PenetrationPower(DEFAULT_FIREMODE)=2.0
|
||||
FireInterval(ALTFIRE_FIREMODE)=+1.2 //0.5 //0.7 //85 RPM
|
||||
NumPellets(ALTFIRE_FIREMODE)=6
|
||||
Spread(ALTFIRE_FIREMODE)=0.12 //0.07
|
||||
SecondaryAmmoTexture=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_FAMAS'
|
||||
InstantHitDamage(BASH_FIREMODE)=26
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Fire_1P')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Handling_DryFire'
|
||||
|
||||
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Fire_1P')
|
||||
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Handling_DryFire'
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Commando'
|
||||
AssociatedPerkClasses(1)=class'KFPerk_Support'
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Damage1, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
|
||||
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.25f), (Stat=EWUS_Damage1, Scale=1.25f), (Stat=EWUS_Weight, Add=2)))
|
||||
|
||||
bUsesSecondaryAmmoAltHUD=true
|
||||
AltFireRecoilScale = 4.5 //4.0 //2.5
|
||||
}
|
@ -1142,7 +1142,7 @@ defaultproperties
|
||||
BonesToLockOnEmpty=(RW_Magazine1, RW_BatteryContactLeft, RW_BatteryContactRight)
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.2f), (Stat=EWUS_Damage1, Scale=1.2f), (Stat=EWUS_Weight, Add=1)))
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.0f), (Stat=EWUS_Damage1, Scale=1.0f), (Stat=EWUS_Weight, Add=0)))
|
||||
|
||||
MuzzleFlashEffectL1=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_01'
|
||||
MuzzleFlashEffectL2=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_02'
|
||||
|
@ -727,9 +727,9 @@ defaultproperties
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=1
|
||||
SpareAmmoCapacity[0]=30
|
||||
InitialSpareMags[0]=10
|
||||
AmmoPickupScale[0]=3.0 // 3 arrows
|
||||
SpareAmmoCapacity[0]=35 //30
|
||||
InitialSpareMags[0]=11 //10
|
||||
AmmoPickupScale[0]=4.0 //3.0
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=200
|
||||
|
731
KFGameContent/Classes/KFWeap_HRG_BarrierRifle.uc
Normal file
731
KFGameContent/Classes/KFWeap_HRG_BarrierRifle.uc
Normal file
@ -0,0 +1,731 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_BarrierRifle
|
||||
//=============================================================================
|
||||
// A modified version of the Stoner63A rifle.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeap_HRG_BarrierRifle extends KFWeap_LMG_Stoner63A;
|
||||
|
||||
`define BARRIERRIFLE_MIC_SHIELD_INDEX 4
|
||||
|
||||
/** Amount of shield charge that is consumed per second */
|
||||
var (Shield) float ShieldConsumptionPerSecond;
|
||||
|
||||
/** Amount of shield chared that is recharged per second */
|
||||
var (Shield) float ShieldRechargePerSecond;
|
||||
|
||||
/** Cooldown to apply after the shield is destroyed */
|
||||
var (Shield) float CooldownAfterShieldDepleted;
|
||||
|
||||
/** Cooldown to apply after the shield depleted the charge */
|
||||
var (Shield) float CooldownAfterShieldDestroyed;
|
||||
|
||||
/** VFX and SFX for blocking damage */
|
||||
var (Shield) AkBaseSoundObject BlockSound;
|
||||
var (Shield) ParticleSystem BlockParticleSystem;
|
||||
var (Shield) name BlockEffectsSocketName;
|
||||
|
||||
/** Blocking information per damage type */
|
||||
var (Shield) array<BlockEffectInfo> BlockDamageTypes;
|
||||
|
||||
/** Modifier applied to the damage received by the character */
|
||||
var (Shield) float BlockDamageModifier;
|
||||
|
||||
/** Modifier applied to the damager that will affect the shield charge */
|
||||
var (Shield) float ShieldDamageAbsorbtionModifier;
|
||||
|
||||
/** Angle to block with the shield */
|
||||
var (Shield) float BlockingAngle;
|
||||
|
||||
/** Turn ON/OFF VFX duration */
|
||||
var (Shield) float ShieldFXDuration;
|
||||
|
||||
/** Shield Block VFX duration */
|
||||
var (Shield) float ShieldBlockVFXDuration;
|
||||
|
||||
/** Is shield active */
|
||||
var protected transient bool bIsShieldActive;
|
||||
|
||||
/** Was shield charge depleted */
|
||||
var protected transient bool bWasShieldDepleted;
|
||||
|
||||
/** Was the shield destroyed */
|
||||
var protected transient bool bWasShielDestroyed;
|
||||
|
||||
/** Self explanatory */
|
||||
var protected transient bool bCanRechargeShield;
|
||||
|
||||
/** float containing the shield charge to not be lost in the next frame
|
||||
due to int conversion.
|
||||
*/
|
||||
var protected transient float ShieldRechargeIncrement;
|
||||
var protected transient float ShieldConsumptionIncrement;
|
||||
|
||||
/** Cos of the blocking angle (Rads) */
|
||||
var protected transient float BlockingAngleCos;
|
||||
|
||||
/** Wether the timer for activating the shield has expired (using the fire interval) */
|
||||
var protected transient bool bShieldActionAvailable;
|
||||
|
||||
/** Indicates wheter we are activating/deactivating the shield fx */
|
||||
var protected bool bActivatingShield;
|
||||
var protected bool bDeactivatingShield;
|
||||
var protected transient float FXDelta;
|
||||
|
||||
var transient float RedOverlayMax;
|
||||
var transient float RedOverlayMin;
|
||||
var protected transient float OverlayDelta;
|
||||
|
||||
var WeaponFireSndInfo ShieldActivateSound;
|
||||
var WeaponFireSndInfo ShieldDeactivateSound;
|
||||
var (Shield) AkBaseSoundObject ShieldEndSound;
|
||||
|
||||
var repnotify byte ShieldAmmo;
|
||||
|
||||
replication
|
||||
{
|
||||
if (bNetDirty && Role == ROLE_Authority)
|
||||
bActivatingShield, bDeactivatingShield;
|
||||
|
||||
if (bNetDirty && Role == ROLE_Authority && bAllowClientAmmoTracking)
|
||||
ShieldAmmo;
|
||||
}
|
||||
|
||||
simulated event ReplicatedEvent(name VarName)
|
||||
{
|
||||
if (VarName == nameof(ShieldAmmo))
|
||||
{
|
||||
AmmoCount[ALTFIRE_FIREMODE] = ShieldAmmo;
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.ReplicatedEvent(VarName);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
super.PostBeginPlay();
|
||||
BlockingAngleCos = cos((BlockingAngle / 2.f) * DegToRad);
|
||||
}
|
||||
|
||||
simulated function Activate()
|
||||
{
|
||||
super.Activate();
|
||||
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer)
|
||||
{
|
||||
UpdateShieldFXValue(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function UpdateShieldFXValue(float Value)
|
||||
{
|
||||
if( WeaponMICs.Length > `BARRIERRIFLE_MIC_SHIELD_INDEX )
|
||||
{
|
||||
WeaponMICs[`BARRIERRIFLE_MIC_SHIELD_INDEX].SetScalarParameterValue('Opacity', Value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of a toggle, just immediately fire alternate fire.
|
||||
*/
|
||||
simulated function AltFireMode()
|
||||
{
|
||||
// LocalPlayer Only
|
||||
if ( !Instigator.IsLocallyControlled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( Role < Role_Authority )
|
||||
{
|
||||
// if we're a client, synchronize server
|
||||
UseShield();
|
||||
}
|
||||
|
||||
CustomFire();
|
||||
}
|
||||
|
||||
reliable server function UseShield()
|
||||
{
|
||||
CustomFire();
|
||||
}
|
||||
|
||||
/** Shield deploying */
|
||||
simulated function CustomFire()
|
||||
{
|
||||
if (bWasShieldDepleted || bWasShielDestroyed || !bShieldActionAvailable || AmmoCount[ALTFIRE_FIREMODE] == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bIsShieldActive ? DeactivateShield() : ActivateShield();
|
||||
bIsShieldActive = !bIsShieldActive;
|
||||
|
||||
bShieldActionAvailable = false;
|
||||
}
|
||||
|
||||
simulated function ActivateShield()
|
||||
{
|
||||
PlaySoundBase(ShieldActivateSound.FirstPersonCue);
|
||||
bActivatingShield = true;
|
||||
bDeactivatingShield = false;
|
||||
bNetDirty = true;
|
||||
NotifyShieldActive(true);
|
||||
SetTimer(FireInterval[ALTFIRE_FIREMODE], false, nameof(ShieldActivationCompleted));
|
||||
}
|
||||
|
||||
simulated function DeactivateShield()
|
||||
{
|
||||
PlaySoundBase(ShieldDeactivateSound.FirstPersonCue);
|
||||
bDeactivatingShield = true;
|
||||
bActivatingShield = false;
|
||||
bCanRechargeShield = false;
|
||||
bNetDirty=true;
|
||||
NotifyShieldActive(false);
|
||||
SetTimer(FireInterval[ALTFIRE_FIREMODE], false, nameof(ShieldDeactivatedTimerCompleted));
|
||||
}
|
||||
|
||||
simulated function ShieldActivationCompleted()
|
||||
{
|
||||
bShieldActionAvailable = true;
|
||||
}
|
||||
|
||||
simulated function ShieldDeactivatedTimerCompleted()
|
||||
{
|
||||
bShieldActionAvailable = true;
|
||||
bCanRechargeShield = true;
|
||||
}
|
||||
|
||||
/** Update shield charge - client and server */
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
// Update Shield visuals
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer)
|
||||
{
|
||||
if (bActivatingShield && FXDelta < ShieldFXDuration)
|
||||
{
|
||||
FXDelta = FMin(FXDelta + DeltaTime, ShieldFXDuration);
|
||||
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
|
||||
if (FXDelta == ShieldFXDuration)
|
||||
{
|
||||
bActivatingShield = false;
|
||||
}
|
||||
}
|
||||
else if (bDeactivatingShield && FXDelta > 0.0f)
|
||||
{
|
||||
FXDelta = FMax(FXDelta - DeltaTime, 0.0f);
|
||||
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
|
||||
if (FXDelta == 0.0f)
|
||||
{
|
||||
bDeactivatingShield = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OverlayDelta > RedOverlayMin)
|
||||
{
|
||||
OverlayDelta = FMax(OverlayDelta - DeltaTime, RedOverlayMin);
|
||||
UpdateShieldBlockVFX(RedOverlayMax * (OverlayDelta / ShieldBlockVFXDuration));
|
||||
}
|
||||
|
||||
if ( Role == Role_Authority )
|
||||
{
|
||||
// If shield is active it needs to consume charge, otherwise it recharges itself.
|
||||
if (bIsShieldActive)
|
||||
{
|
||||
ConsumeShield(DeltaTime);
|
||||
}
|
||||
else if (bCanRechargeShield && AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE])
|
||||
{
|
||||
RechargeShield(DeltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
Super.Tick(DeltaTime);
|
||||
}
|
||||
|
||||
simulated function ConsumeShield(float DeltaTime)
|
||||
{
|
||||
local int Charge;
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
ShieldRechargeIncrement = 0.0f;
|
||||
|
||||
ShieldConsumptionIncrement += ShieldConsumptionPerSecond * DeltaTime;
|
||||
|
||||
if (ShieldConsumptionIncrement >= 1.0f && AmmoCount[ALTFIRE_FIREMODE] > 0)
|
||||
{
|
||||
Charge = int(ShieldConsumptionIncrement);
|
||||
AmmoCount[ALTFIRE_FIREMODE] = Max(AmmoCount[ALTFIRE_FIREMODE] - Charge, 0);
|
||||
ShieldConsumptionIncrement -= Charge;
|
||||
|
||||
ShieldAmmo = AmmoCount[ALTFIRE_FIREMODE];
|
||||
|
||||
if (AmmoCount[ALTFIRE_FIREMODE] == 0)
|
||||
{
|
||||
OnShieldDepleted();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function RechargeShield(float DeltaTime)
|
||||
{
|
||||
local int Charge;
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
ShieldConsumptionIncrement = 0.0f;
|
||||
ShieldRechargeIncrement += ShieldRechargePerSecond * DeltaTime;
|
||||
if (ShieldRechargeIncrement >= 1.0f && AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE])
|
||||
{
|
||||
Charge = int(ShieldRechargeIncrement);
|
||||
AmmoCount[ALTFIRE_FIREMODE] = Min(AmmoCount[ALTFIRE_FIREMODE] + Charge, MagazineCapacity[ALTFIRE_FIREMODE]);
|
||||
ShieldRechargeIncrement -= Charge;
|
||||
|
||||
ShieldAmmo = AmmoCount[ALTFIRE_FIREMODE];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Shield consumed all the charge by itself */
|
||||
simulated function OnShieldDepleted()
|
||||
{
|
||||
bWasShieldDepleted = true;
|
||||
bActivatingShield = false;
|
||||
bDeactivatingShield = true;
|
||||
bCanRechargeShield = false;
|
||||
bIsShieldActive = false;
|
||||
ShieldAmmo = 0;
|
||||
bNetDirty = true;
|
||||
NotifyShieldActive(false);
|
||||
PlaySoundBase(ShieldEndSound);
|
||||
SetTimer(CooldownAfterShieldDepleted, false, nameof(ShieldRepletedTimerCompleted));
|
||||
}
|
||||
|
||||
simulated function ShieldRepletedTimerCompleted()
|
||||
{
|
||||
bWasShieldDepleted = false;
|
||||
bCanRechargeShield = true;
|
||||
}
|
||||
|
||||
/** Shield was destroyed by attacks */
|
||||
simulated function OnShieldDestroyed()
|
||||
{
|
||||
bWasShielDestroyed = true;
|
||||
bActivatingShield = false;
|
||||
bDeactivatingShield = true;
|
||||
bCanRechargeShield = false;
|
||||
bIsShieldActive = false;
|
||||
ShieldAmmo = 0;
|
||||
bNetDirty = true;
|
||||
NotifyShieldActive(false);
|
||||
PlaySoundBase(ShieldEndSound);
|
||||
SetTimer(CooldownAfterShieldDestroyed, false, nameof(ShieldDestroyedTimerCompleted));
|
||||
}
|
||||
|
||||
simulated function ShieldDestroyedTimerCompleted()
|
||||
{
|
||||
bWasShielDestroyed = false;
|
||||
bCanRechargeShield = true;
|
||||
}
|
||||
|
||||
/** Update HUD ammo icon for shield */
|
||||
simulated function int GetSecondaryAmmoForHUD()
|
||||
{
|
||||
return AmmoCount[ALTFIRE_FIREMODE];
|
||||
}
|
||||
|
||||
simulated function ShieldAbsorbDamage(int DamageBase)
|
||||
{
|
||||
local int Damage;
|
||||
// Use the carried shield reduction by time
|
||||
ShieldConsumptionIncrement += DamageBase*ShieldDamageAbsorbtionModifier;
|
||||
Damage = int(ShieldConsumptionIncrement);
|
||||
AmmoCount[ALTFIRE_FIREMODE] = Max(AmmoCount[ALTFIRE_FIREMODE] - Damage, 0);
|
||||
ShieldConsumptionIncrement -= Damage;
|
||||
|
||||
// Check if shield is destroyed.
|
||||
if (AmmoCount[ALTFIRE_FIREMODE] == 0)
|
||||
{
|
||||
OnShieldDestroyed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reduce the damage received and apply it to the shield
|
||||
*/
|
||||
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
|
||||
{
|
||||
local KFPerk InstigatorPerk;
|
||||
local byte BlockTypeIndex;
|
||||
local float DmgCauserDot;
|
||||
|
||||
if (!bIsShieldActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't apply block effects for teammates
|
||||
if (Instigator.IsSameTeam(DamageCauser.Instigator))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CanBlockDamageType(DamageType, BlockTypeIndex))
|
||||
{
|
||||
if (ClassIsChildOf(DamageCauser.class, class'Projectile'))
|
||||
{
|
||||
// Projectile might be beyond/behind player, resulting in bad dot
|
||||
// Projectile won't have a velocity to check against, either
|
||||
// Assume velocity is the vector between projectile and instigator
|
||||
DmgCauserDot = Normal(DamageCauser.Instigator.Location - DamageCauser.Location) dot vector(Instigator.Rotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
DmgCauserDot = Normal(DamageCauser.Location - Instigator.Location) dot vector(Instigator.Rotation);
|
||||
}
|
||||
|
||||
if (DmgCauserDot > BlockingAngleCos)
|
||||
{
|
||||
ShieldAbsorbDamage(InDamage);
|
||||
InDamage *= BlockDamageModifier;
|
||||
|
||||
ClientPlayBlockEffects(BlockTypeIndex);
|
||||
NotifyShieldBlockActive(true);
|
||||
SetTimer(0.1f, false, nameof(ResetShieldBlockVFX));
|
||||
|
||||
InstigatorPerk = GetPerk();
|
||||
if (InstigatorPerk != none)
|
||||
{
|
||||
InstigatorPerk.SetSuccessfullBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Only DT added to BlockDamageTypes can be blocked. Check if the current one is in the list. */
|
||||
function bool CanBlockDamageType(class<DamageType> DamageType, optional out byte out_Idx)
|
||||
{
|
||||
local int Idx;
|
||||
|
||||
for (Idx = 0; Idx < BlockDamageTypes.length; ++Idx)
|
||||
{
|
||||
if (ClassIsChildOf(DamageType, BlockDamageTypes[Idx].DmgType))
|
||||
{
|
||||
out_Idx = Idx;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
out_Idx = INDEX_NONE;
|
||||
return false;
|
||||
}
|
||||
|
||||
unreliable client function ClientPlayBlockEffects(optional byte BlockDTIndex=255)
|
||||
{
|
||||
local AkBaseSoundObject Sound;
|
||||
local ParticleSystem PSTemplate;
|
||||
|
||||
GetBlockEffects(BlockDTIndex, Sound, PSTemplate);
|
||||
PlayLocalBlockEffects(Sound, PSTemplate);
|
||||
UpdateShieldBlockVFX(RedOverlayMax);
|
||||
OverlayDelta = ShieldBlockVFXDuration;
|
||||
}
|
||||
|
||||
/** Called on the client when successfully block/parry an attack */
|
||||
simulated function PlayLocalBlockEffects(AKBaseSoundObject Sound, ParticleSystem PSTemplate)
|
||||
{
|
||||
local vector Loc;
|
||||
local rotator Rot;
|
||||
local ParticleSystemComponent PSC;
|
||||
|
||||
if (Sound != None)
|
||||
{
|
||||
PlaySoundBase(Sound, true);
|
||||
}
|
||||
|
||||
if (PSTemplate != None)
|
||||
{
|
||||
if (MySkelMesh.GetSocketWorldLocationAndRotation(BlockEffectsSocketName, Loc, Rot))
|
||||
{
|
||||
PSC = WorldInfo.MyEmitterPool.SpawnEmitter(PSTemplate, Loc, Rot);
|
||||
PSC.SetDepthPriorityGroup(SDPG_Foreground);
|
||||
}
|
||||
else
|
||||
{
|
||||
`log(self@GetFuncName()@"missing BlockEffects Socket!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns sound and particle system overrides using index into BlockDamageTypes array */
|
||||
simulated function GetBlockEffects(byte BlockDTIndex, out AKBaseSoundObject outSound, out ParticleSystem outParticleSys)
|
||||
{
|
||||
outSound = BlockSound;
|
||||
outParticleSys = BlockParticleSystem;
|
||||
|
||||
if (BlockDTIndex != 255)
|
||||
{
|
||||
if (BlockDamageTypes[BlockDTIndex].BlockSound != None)
|
||||
{
|
||||
outSound = BlockDamageTypes[BlockDTIndex].BlockSound;
|
||||
}
|
||||
if (BlockDamageTypes[BlockDTIndex].BlockParticleSys != None)
|
||||
{
|
||||
outParticleSys = BlockDamageTypes[BlockDTIndex].BlockParticleSys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Should replicate to 3P to show the shield effects
|
||||
*/
|
||||
simulated function NotifyShieldActive(bool bActive)
|
||||
{
|
||||
local KFPawn KFP;
|
||||
|
||||
if (WorldInfo.NetMode != NM_Client)
|
||||
{
|
||||
KFP = KFPawn(Instigator);
|
||||
KFP.OnWeaponSpecialAction(bActive ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function NotifyShieldBlockActive(bool bActive)
|
||||
{
|
||||
local KFPawn KFP;
|
||||
|
||||
if (WorldInfo.NetMode != NM_Client)
|
||||
{
|
||||
KFP = KFPawn(Instigator);
|
||||
KFP.OnWeaponSpecialAction(bActive ? 3 : 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State WeaponEquipping
|
||||
* The Weapon is in this state while transitioning from Inactive to Active state.
|
||||
* Typically, the weapon will remain in this state while its selection animation is being played.
|
||||
* While in this state, the weapon cannot be fired.
|
||||
*********************************************************************************************/
|
||||
|
||||
simulated state WeaponEquipping
|
||||
{
|
||||
simulated function BeginState(Name PreviousStateName)
|
||||
{
|
||||
bShieldActionAvailable = true;
|
||||
super.BeginState(PreviousStateName);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State WeaponPuttingDown
|
||||
* Putting down weapon in favor of a new one.
|
||||
* Weapon is transitioning to the Inactive state.
|
||||
*********************************************************************************************/
|
||||
|
||||
simulated state WeaponPuttingDown
|
||||
{
|
||||
simulated event EndState(Name NextStateName)
|
||||
{
|
||||
UpdateShieldFXValue(0.0f);
|
||||
|
||||
// Reset Values
|
||||
bIsShieldActive = false;
|
||||
bWasShieldDepleted = false;
|
||||
bWasShielDestroyed = false;
|
||||
bCanRechargeShield = true;
|
||||
bShieldActionAvailable = false;
|
||||
bActivatingShield = false;
|
||||
bDeactivatingShield = false;
|
||||
FXDelta = 0.0f;
|
||||
bNetDirty=true;
|
||||
|
||||
super.EndState(NextStateName);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function UpdateShieldBlockVFX(float Value)
|
||||
{
|
||||
if( WeaponMICs.Length > `BARRIERRIFLE_MIC_SHIELD_INDEX )
|
||||
{
|
||||
WeaponMICs[`BARRIERRIFLE_MIC_SHIELD_INDEX].SetScalarParameterValue('RedOverlay', Value);
|
||||
}
|
||||
}
|
||||
|
||||
function ResetShieldBlockVFX()
|
||||
{
|
||||
NotifyShieldBlockActive(false);
|
||||
}
|
||||
|
||||
/** Shield doesn't count as ammo for purposes of inventory management (e.g. switching) */
|
||||
simulated function bool HasAnyAmmo()
|
||||
{
|
||||
return AmmoCount[0] > 0 || SpareAmmoCount[0] > 0;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Shooting Animations
|
||||
FireSightedAnims[0]=Shoot_Iron
|
||||
FireSightedAnims[1]=Shoot_Iron2
|
||||
FireSightedAnims[2]=Shoot_Iron3
|
||||
|
||||
// FOV
|
||||
MeshFOV=75
|
||||
MeshIronSightFOV=35
|
||||
PlayerIronSightFOV=70
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=85
|
||||
DOF_FG_MaxNearBlurSize=2.5
|
||||
|
||||
// Content
|
||||
PackageKey="HRG_BarrierRifle"
|
||||
FirstPersonMeshName="WEP_1P_HRG_BarrierRifle_MESH.WEP_1stP_HRG_BarrielRifle_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_HRG_BarrierRifle_ANIM.Wep_1stP_HRG_BarrierRifle_Anim"
|
||||
PickupMeshName="WEP_3P_HRG_BarrierRifle_MESH.Wep_3rdP_HRG_BarrierRifle_Pickup"
|
||||
AttachmentArchetypeName="WEP_HRG_BarrierRifle_ARCH.Wep_HRG_BarrierRifle_3P"
|
||||
MuzzleFlashTemplateName="WEP_HRG_BarrierRifle_ARCH.Wep_HRG_BarrierRifle_MuzzleFlash"
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=4.0,Y=8,Z=-4)
|
||||
IronSightPosition=(X=8.5,Y=0,Z=0)
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=60
|
||||
SpareAmmoCapacity[0]=540 //480
|
||||
InitialSpareMags[0]=2
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Shield "Ammo"
|
||||
MagazineCapacity[1]=100
|
||||
SpareAmmoCapacity[1]=0
|
||||
bCanRefillSecondaryAmmo=false
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=110 //120
|
||||
minRecoilPitch=70 //70
|
||||
maxRecoilYaw=80 //130
|
||||
minRecoilYaw=-80 //-130
|
||||
RecoilRate=0.045 //0.08
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=900
|
||||
RecoilMinPitchLimit=65035
|
||||
RecoilISMaxYawLimit=75
|
||||
RecoilISMinYawLimit=65460
|
||||
RecoilISMaxPitchLimit=375
|
||||
RecoilISMinPitchLimit=65460
|
||||
RecoilViewRotationScale=0.4 //0.25
|
||||
IronSightMeshFOVCompensationScale=2.3
|
||||
HippedRecoilModifier=1.5
|
||||
//WalkingRecoilModifier=1.1
|
||||
//JoggingRecoilModifier=1.2
|
||||
|
||||
// Inventory / Grouping
|
||||
InventorySize=7
|
||||
GroupPriority=125
|
||||
WeaponSelectTexture=Texture2D'wep_ui_hrg_barrierrifle_tex.UI_WeaponSelect_HRG_BarrierRifle'
|
||||
AssociatedPerkClasses(0)=class'KFPerk_SWAT'
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_BarrierRifle'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.066 // 900 RPM
|
||||
Spread(DEFAULT_FIREMODE)=0.025 //0.0085
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=33.0 //35.0
|
||||
FireOffset=(X=30,Y=4.5,Z=-5)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
|
||||
AmmoCost(ALTFIRE_FIREMODE)=0
|
||||
FireInterval(ALTFIRE_FIREMODE)=0.01f
|
||||
SecondaryAmmoTexture=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_BarrierRifle'
|
||||
InstantHitDamage(BASH_FIREMODE)=26
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_3P_Loop', FirstPersonCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_1P_Loop')
|
||||
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_3P_EndLoop', FirstPersonCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_1P_EndLoop')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_L85A2.Play_WEP_SA_L85A2_Handling_DryFire'
|
||||
EjectedShellForegroundDuration=0.8f
|
||||
|
||||
// Advanced (High RPM) Fire Effects
|
||||
bLoopingFireAnim(DEFAULT_FIREMODE)=true
|
||||
bLoopingFireSnd(DEFAULT_FIREMODE)=true
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
// Ammo belt
|
||||
AmmoBeltBulletBonePrefix="RW_Bullets"
|
||||
NumAmmoBeltBullets=14
|
||||
LastAmmoCount=-1
|
||||
|
||||
bIsShieldActive=false
|
||||
bWasShieldDepleted=false
|
||||
bWasShielDestroyed=false
|
||||
bCanRechargeShield=true
|
||||
ShieldRechargeIncrement=0.0f;
|
||||
ShieldConsumptionIncrement=0.0f
|
||||
|
||||
ShieldConsumptionPerSecond=3.0f //10.0f
|
||||
ShieldRechargePerSecond=8.0f //10.0f //15.0f
|
||||
CooldownAfterShieldDepleted=3.0f //3.0f
|
||||
CooldownAfterShieldDestroyed=3.0f //5.0f
|
||||
|
||||
ShieldActivateSound=(DefaultCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_On', FirstPersonCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_On')
|
||||
ShieldDeactivateSound=(DefaultCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Off', FirstPersonCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Off')
|
||||
ShieldEndSound=AKEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_End';
|
||||
|
||||
BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'
|
||||
BlockParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Block_melee_01'
|
||||
BlockEffectsSocketName=BlockEffect
|
||||
|
||||
RedOverlayMax=1.0f
|
||||
RedOverlayMin=0.0f
|
||||
OverlayDelta=0.0f
|
||||
ShieldBlockVFXDuration=0.5f
|
||||
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Bludgeon', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Slashing', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Fire_HuskFireball', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Fire_HuskFlamethrower'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_BloatPuke'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_EvilDAR_Rocket', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_EvilDAR_Laser', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_DAR_EMPBlast', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Ballistic_PatMinigun', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Explosive_PatMissile', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_Ballistic_HansAK12', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_EMP_MatriarchTeslaBlast', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_EMP_MatriarchPlasmaCannon'))
|
||||
BlockDamageTypes.Add((DmgType=class'KFDT_FleshpoundKing_ChestBeam'))
|
||||
BlockDamageModifier=0.3f //0.4f
|
||||
ShieldDamageAbsorbtionModifier=1.2f //0.8f //0.8 = equal to base damage
|
||||
BlockingAngle=180.f // Adjust with visuals.
|
||||
bShieldActionAvailable=true
|
||||
bActivatingShield=false
|
||||
bDeactivatingShield=false
|
||||
FXDelta=0.0f
|
||||
ShieldFXDuration=0.15f
|
||||
bAllowClientAmmoTracking=true
|
||||
NumBloodMapMaterials=5
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.0f), (Stat=EWUS_Weight, Add=0)))
|
||||
}
|
482
KFGameContent/Classes/KFWeap_HRG_BlastBrawlers.uc
Normal file
482
KFGameContent/Classes/KFWeap_HRG_BlastBrawlers.uc
Normal file
@ -0,0 +1,482 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_BlastBrawlers
|
||||
//=============================================================================
|
||||
// Power gloves and shotgun, all in one.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeap_HRG_BlastBrawlers extends KFWeap_Blunt_PowerGloves;
|
||||
|
||||
var name ReloadAnimation;
|
||||
var float ReloadAnimRateModifier;
|
||||
var float ReloadAnimRateModifierElite;
|
||||
|
||||
var protected transient bool bWaitingForSecondShot;
|
||||
var protected transient int NumAttacks;
|
||||
|
||||
/** A muzzle flash instance for left weapon */
|
||||
var KFMuzzleFlash LeftMuzzleFlash;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
super.PreBeginPlay();
|
||||
}
|
||||
|
||||
simulated function Shoot()
|
||||
{
|
||||
// LocalPlayer Only
|
||||
if ( !Instigator.IsLocallyControlled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( Role < Role_Authority )
|
||||
{
|
||||
// if we're a client, synchronize server
|
||||
ServerShoot();
|
||||
}
|
||||
|
||||
ProcessShoot();
|
||||
}
|
||||
|
||||
/**
|
||||
Each attack shoots twice, once with the right and left fists.
|
||||
Ammo is decremented after the second shot.
|
||||
*/
|
||||
reliable server function bool ServerShoot()
|
||||
{
|
||||
return ProcessShoot();
|
||||
}
|
||||
|
||||
simulated function bool ProcessShoot()
|
||||
{
|
||||
// Shooting only happens when default firing
|
||||
if(CurrentFireMode != DEFAULT_FIREMODE)
|
||||
return false;
|
||||
|
||||
CustomFire();
|
||||
|
||||
if (!bWaitingForSecondShot)
|
||||
{
|
||||
// AmmoCount[DEFAULT_FIREMODE] = Max(AmmoCount[DEFAULT_FIREMODE] - 1, 0);
|
||||
DecrementAmmo();
|
||||
}
|
||||
|
||||
bWaitingForSecondShot = !bWaitingForSecondShot;
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated function DecrementAmmo()
|
||||
{
|
||||
AmmoCount[DEFAULT_FIREMODE] = Max(AmmoCount[DEFAULT_FIREMODE] - 1, 0);
|
||||
}
|
||||
|
||||
simulated state Active
|
||||
{
|
||||
/**
|
||||
* Called from Weapon:Active.BeginState when HasAnyAmmo (which is overridden above) returns false.
|
||||
*/
|
||||
simulated function WeaponEmpty()
|
||||
{
|
||||
local int i;
|
||||
|
||||
// Copied from Weapon:Active.BeginState where HasAnyAmmo returns true.
|
||||
// Basically, pretend the weapon isn't empty in this case.
|
||||
for (i=0; i<GetPendingFireLength(); i++)
|
||||
{
|
||||
if (PendingFire(i))
|
||||
{
|
||||
BeginFire(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static simulated event bool UsesAmmo()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated function CustomFire()
|
||||
{
|
||||
local byte CachedFireMode;
|
||||
|
||||
CachedFireMode = CurrentFireMode;
|
||||
CurrentFireMode = CUSTOM_FIREMODE;
|
||||
|
||||
ProjectileFire();
|
||||
|
||||
// Let the accuracy tracking system know that we fired
|
||||
HandleWeaponShotTaken(CurrentFireMode);
|
||||
|
||||
NotifyWeaponFired(CurrentFireMode);
|
||||
|
||||
// Play fire effects now (don't wait for WeaponFired to replicate)
|
||||
PlayFireEffects(CurrentFireMode, vect(0, 0, 0));
|
||||
|
||||
CurrentFireMode = CachedFireMode;
|
||||
}
|
||||
|
||||
/** Overriden for the Tight Choke perk */
|
||||
simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
|
||||
{
|
||||
local KFPerk InstigatorPerk;
|
||||
|
||||
if (CurrentFireMode == CUSTOM_FIREMODE)
|
||||
{
|
||||
InstigatorPerk = GetPerk();
|
||||
if (InstigatorPerk != none)
|
||||
{
|
||||
Spread[CurrentFireMode] = default.Spread[CurrentFireMode] * InstigatorPerk.GetTightChokeModifier();
|
||||
}
|
||||
}
|
||||
|
||||
return super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir);
|
||||
}
|
||||
|
||||
/** Override for not playing animations (even if noanimation is set it interrupts the melee ones.) */
|
||||
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
|
||||
{
|
||||
// If we have stopped the looping fire sound to play single fire sounds for zed time
|
||||
// start the looping sound back up again when the time is back above zed time speed
|
||||
if( FireModeNum < bLoopingFireSnd.Length && bLoopingFireSnd[FireModeNum] && !bPlayingLoopingFireSnd )
|
||||
{
|
||||
StartLoopingFireSound(FireModeNum);
|
||||
}
|
||||
|
||||
PlayFiringSound(CurrentFireMode);
|
||||
|
||||
if( Instigator != none )
|
||||
{
|
||||
if( Instigator.IsLocallyControlled() )
|
||||
{
|
||||
if( Instigator.IsFirstPerson() )
|
||||
{
|
||||
// Start muzzle flash effect
|
||||
CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
|
||||
ShakeView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Weapon::StartFire
|
||||
*/
|
||||
simulated function StartFire(byte FireModeNum)
|
||||
{
|
||||
// can't start fire because it's in an uninterruptible state
|
||||
if (StartFireDisabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (FireModeNum == DEFAULT_FIREMODE)
|
||||
{
|
||||
if(AmmoCount[DEFAULT_FIREMODE] > 0)
|
||||
{
|
||||
StartMeleeFire(FireModeNum, DIR_FORWARD, ATK_Normal);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.StartFire(RELOAD_FIREMODE);
|
||||
// If not cleared, it will loop the animation.
|
||||
ClearPendingFire(RELOAD_FIREMODE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
super.StartFire(FireModeNum);
|
||||
}
|
||||
|
||||
/** Avoiding reload anim to interrupt combo */
|
||||
simulated state MeleeChainAttacking
|
||||
{
|
||||
simulated function BeginState(Name PrevStateName)
|
||||
{
|
||||
local KFPerk InstigatorPerk;
|
||||
|
||||
if( CurrentFireMode == DEFAULT_FIREMODE )
|
||||
{
|
||||
StartFireDisabled = true;
|
||||
bWaitingForSecondShot = false;
|
||||
NumAttacks = 0;
|
||||
}
|
||||
|
||||
InstigatorPerk = GetPerk();
|
||||
if (InstigatorPerk != none)
|
||||
{
|
||||
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
|
||||
}
|
||||
|
||||
super.BeginState( PrevStateName );
|
||||
}
|
||||
|
||||
simulated function EndState(Name NextStateName)
|
||||
{
|
||||
super.EndState(NextStateName);
|
||||
if( CurrentFireMode == DEFAULT_FIREMODE )
|
||||
{
|
||||
StartFireDisabled = false;
|
||||
}
|
||||
|
||||
ClearZedTimeResist();
|
||||
}
|
||||
|
||||
simulated function bool ShouldContinueMelee(optional int ChainCount)
|
||||
{
|
||||
if ( CurrentFireMode == DEFAULT_FIREMODE )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return super.ShouldContinueMelee(ChainCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on a client, this function Attaches the WeaponAttachment
|
||||
* to the Mesh.
|
||||
*
|
||||
* Overridden to attach LeftMuzzleFlash
|
||||
*/
|
||||
simulated function AttachMuzzleFlash()
|
||||
{
|
||||
super.AttachMuzzleFlash();
|
||||
|
||||
if ( MySkelMesh != none )
|
||||
{
|
||||
if (MuzzleFlashTemplate != None)
|
||||
{
|
||||
LeftMuzzleFlash = new(self) Class'KFMuzzleFlash'(MuzzleFlashTemplate);
|
||||
LeftMuzzleFlash.AttachMuzzleFlash(MySkelMesh, 'MuzzleFlash_L');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes the muzzle flash to turn on and setup a time to
|
||||
* turn it back off again.
|
||||
*
|
||||
* Overridden to cause left weapon flash
|
||||
*/
|
||||
simulated function CauseMuzzleFlash(byte FireModeNum)
|
||||
{
|
||||
if( MuzzleFlash == None || LeftMuzzleFlash == None )
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if( bWaitingForSecondShot )
|
||||
{
|
||||
if (MuzzleFlash != None )
|
||||
{
|
||||
// Not ejecting shells for this weapon.
|
||||
MuzzleFlash.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( LeftMuzzleFlash != None )
|
||||
{
|
||||
// Not ejecting shells for this weapon.
|
||||
LeftMuzzleFlash.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove/Detach the muzzle flash components
|
||||
*/
|
||||
simulated function DetachMuzzleFlash()
|
||||
{
|
||||
super.DetachMuzzleFlash();
|
||||
|
||||
if (MySkelMesh != none && LeftMuzzleFlash != None)
|
||||
{
|
||||
LeftMuzzleFlash.DetachMuzzleFlash(MySkelMesh);
|
||||
LeftMuzzleFlash = None;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust the FOV for the first person weapon and arms.
|
||||
*/
|
||||
simulated event SetFOV( float NewFOV )
|
||||
{
|
||||
super.SetFOV( NewFOV );
|
||||
|
||||
if( LeftMuzzleFlash != none )
|
||||
{
|
||||
LeftMuzzleFlash.SetFOV( NewFOV );
|
||||
}
|
||||
}
|
||||
|
||||
simulated function StopFireEffects(byte FireModeNum)
|
||||
{
|
||||
super.StopFireEffects( FireModeNum );
|
||||
|
||||
if (LeftMuzzleFlash != None)
|
||||
{
|
||||
LeftMuzzleFlash.StopMuzzleFlash();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if weapon can potentially be reloaded */
|
||||
simulated function bool CanReload(optional byte FireModeNum)
|
||||
{
|
||||
if ( FiringStatesArray[RELOAD_FIREMODE] == 'WeaponUpkeep' )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( FireModeNum == CUSTOM_FIREMODE)
|
||||
{
|
||||
FireModeNum = DEFAULT_FIREMODE;
|
||||
}
|
||||
|
||||
return Super.CanReload(FireModeNum);
|
||||
}
|
||||
|
||||
simulated function name GetReloadAnimName( bool bTacticalReload )
|
||||
{
|
||||
return ReloadAnimation;
|
||||
}
|
||||
|
||||
/** No diferent states */
|
||||
simulated function EReloadStatus GetNextReloadStatus(optional byte FireModeNum)
|
||||
{
|
||||
switch ( ReloadStatus )
|
||||
{
|
||||
case RS_None: //drop
|
||||
case RS_Reloading:
|
||||
if ( HasSpareAmmo(FiremodeNum) && ReloadAmountLeft > 0 )
|
||||
{
|
||||
return RS_Reloading;
|
||||
}
|
||||
}
|
||||
|
||||
return RS_Complete;
|
||||
}
|
||||
|
||||
/** Returns an anim rate scale for reloading */
|
||||
simulated function float GetReloadRateScale()
|
||||
{
|
||||
local float Modifier;
|
||||
|
||||
Modifier = UseTacticalReload() ? ReloadAnimRateModifierElite : ReloadAnimRateModifier;
|
||||
|
||||
return super.GetReloadRateScale() * Modifier;
|
||||
}
|
||||
|
||||
simulated function bool HasAnyAmmo()
|
||||
{
|
||||
return AmmoCount[0] != 0 && SpareAmmoCount[0] != 0;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Content
|
||||
PackageKey="HRG_BlastBrawlers"
|
||||
FirstPersonMeshName="WEP_1P_HRG_BlastBrawlers_MESH.WEP_1stP_HRG_Blast_Brawlers_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_HRG_BlastBrawlers_ANIM.WEP_1P_HRG_BlastBrawlers_ANIM"
|
||||
PickupMeshName="WEP_3P_HRG_BlastBrawlers_MESH.Wep_HRG_Blast_Brawlers_Pickup"
|
||||
AttachmentArchetypeName="WEP_HRG_BlastBrawlers_ARCH.Wep_HRG_BlastBrawlers_3P"
|
||||
MuzzleFlashTemplateName="WEP_HRG_BlastBrawlers_ARCH.Wep_HRG_BlastBrawler_MuzzleFlash"
|
||||
|
||||
Begin Object Class=KFMeleeHelperWeaponBlastBrawlers Name=MeleeHelper_0
|
||||
MaxHitRange=230 //150 //190
|
||||
// Override automatic hitbox creation (advanced)
|
||||
HitboxChain.Add((BoneOffset=(Y=+3,Z=150)))
|
||||
HitboxChain.Add((BoneOffset=(Y=-3,Z=130)))
|
||||
HitboxChain.Add((BoneOffset=(Y=+3,Z=110)))
|
||||
HitboxChain.Add((BoneOffset=(Y=-3,Z=90)))
|
||||
HitboxChain.Add((BoneOffset=(Y=+3,Z=70)))
|
||||
HitboxChain.Add((BoneOffset=(Y=-3,Z=50)))
|
||||
HitboxChain.Add((BoneOffset=(Y=+3,Z=30)))
|
||||
HitboxChain.Add((BoneOffset=(Z=10)))
|
||||
HitboxChain.Add((BoneOffset=(Z=-10)))
|
||||
WorldImpactEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Blunted_melee_impact'
|
||||
// modified combo sequences
|
||||
bAllowMeleeToFracture=false
|
||||
bUseDirectionalMelee=true
|
||||
bHasChainAttacks=false
|
||||
MeleeImpactCamShakeScale=0.035f //0.4
|
||||
ChainSequence_F=()
|
||||
ChainSequence_B=()
|
||||
ChainSequence_L=()
|
||||
ChainSequence_R=()
|
||||
End Object
|
||||
MeleeAttackHelper=MeleeHelper_0
|
||||
|
||||
// FOV
|
||||
//MeshFOV=95
|
||||
|
||||
// Shotgun Ammo
|
||||
MagazineCapacity[0]=4 //3
|
||||
SpareAmmoCapacity[0]=36 //28
|
||||
InitialSpareMags[0]=2
|
||||
AmmoPickupScale[0]=1.5 //2.0
|
||||
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
bNoMagazine=false
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=20,Y=0,Z=0)
|
||||
|
||||
// Inventory
|
||||
GroupPriority=110
|
||||
InventorySize=9 //7
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_HRG_BlastBrawlers_TEX.UI_WeaponSelect_HRG_BlastBrawlers'
|
||||
|
||||
FireModeIconPaths(CUSTOM_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
FiringStatesArray(CUSTOM_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(CUSTOM_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(CUSTOM_FIREMODE)=class'KFProj_Bullet_BlastBrawlers'
|
||||
FireInterval(CUSTOM_FIREMODE)=0.1f
|
||||
InstantHitDamageTypes(CUSTOM_FIREMODE)=class'KFDT_Ballistic_BlastBrawlersShotgun'
|
||||
InstantHitDamage(CUSTOM_FIREMODE)=36.0 //30.0
|
||||
AmmoCost(CUSTOM_FIREMODE)=0
|
||||
NumPellets(CUSTOM_FIREMODE)=5
|
||||
Spread(CUSTOM_FIREMODE)=0.1 //0.15
|
||||
WeaponFireSnd(CUSTOM_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_BlastBrawlers.Play_WEP_HRG_BlastBrawlers_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_BlastBrawlers.Play_WEP_HRG_BlastBrawlers_Shoot_1P')
|
||||
InstantHitMomentum(CUSTOM_FIREMODE)=1.0
|
||||
PenetrationDamageReductionCurve(CUSTOM_FIREMODE)=(Points=((InVal=0.f,OutVal=0.f),(InVal=1.f, OutVal=1.f)))
|
||||
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=50
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlers'
|
||||
|
||||
FireModeIconPaths(HEAVY_ATK_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BluntMelee'
|
||||
InstantHitDamage(HEAVY_ATK_FIREMODE)=200 //175
|
||||
InstantHitDamageTypes(HEAVY_ATK_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlersHeavy'
|
||||
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlersBash'
|
||||
InstantHitDamage(BASH_FIREMODE)=100
|
||||
|
||||
FiringStatesArray(RELOAD_FIREMODE)=Reloading
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Support'
|
||||
|
||||
// Block Sounds
|
||||
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Crovel'
|
||||
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
|
||||
|
||||
ParryStrength=5
|
||||
ParryDamageMitigationPercent=0.40
|
||||
BlockDamageMitigation=0.40
|
||||
|
||||
bWaitingForSecondShot = false
|
||||
NumAttacks = 0
|
||||
|
||||
bAllowClientAmmoTracking=false
|
||||
|
||||
ReloadAnimation = "Atk_B"
|
||||
ReloadAnimRateModifier = 1.6f
|
||||
ReloadAnimRateModifierElite = 1.0f; //0.5f;
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Damage1, Scale=1.125f), (Stat=EWUS_Damage2, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
|
||||
}
|
@ -42,7 +42,7 @@ simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optio
|
||||
defaultproperties
|
||||
{
|
||||
//Healing
|
||||
HealAmount=20
|
||||
HealAmount=25 //20
|
||||
HealFullRechargeSeconds=10
|
||||
|
||||
// Inventory / Grouping
|
||||
@ -84,7 +84,7 @@ defaultproperties
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=7
|
||||
SpareAmmoCapacity[0]=98
|
||||
SpareAmmoCapacity[0]=112 //98
|
||||
InitialSpareMags[0]=4
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
@ -119,7 +119,7 @@ defaultproperties
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Hemogoblin'
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=100.0
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=120.0 //100.0
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Hemogoblin'
|
||||
FireInterval(DEFAULT_FIREMODE)=0.25
|
||||
PenetrationPower(DEFAULT_FIREMODE)=0.0 //2.0
|
||||
|
324
KFGameContent/Classes/KFWeap_RocketLauncher_ThermiteBore.uc
Normal file
324
KFGameContent/Classes/KFWeap_RocketLauncher_ThermiteBore.uc
Normal file
@ -0,0 +1,324 @@
|
||||
//=============================================================================
|
||||
// KFWeap_RocketLauncher_ThermiteBore
|
||||
//=============================================================================
|
||||
// Impale, burn, repeat
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_RocketLauncher_ThermiteBore extends KFWeap_GrenadeLauncher_Base;
|
||||
|
||||
/** List of spawned harpoons (will be detonated oldest to youngest) */
|
||||
var array<KFProj_Rocket_ThermiteBore> DeployedHarpoons;
|
||||
|
||||
/** Same as DeployedHarpoons.Length, but replicated because harpoons are only tracked on server */
|
||||
var int NumDeployedHarpoons;
|
||||
|
||||
/** Reduction for the amount of damage dealt to the weapon owner (including damage by the explosion) */
|
||||
var float SelfDamageReductionValue;
|
||||
|
||||
var(Animations) const editconst name DetonateAnim;
|
||||
var(Animations) const editconst name DetonateAnimLast;
|
||||
var(Animations) const editconst name DetonateAnimIron;
|
||||
var(Animations) const editconst name DetonateAnimIronLast;
|
||||
|
||||
replication
|
||||
{
|
||||
if( bNetDirty )
|
||||
NumDeployedHarpoons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle between DEFAULT and ALTFIRE
|
||||
*/
|
||||
simulated function AltFireMode()
|
||||
{
|
||||
// skip super
|
||||
|
||||
if (!Instigator.IsLocallyControlled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartFire(ALTFIRE_FIREMODE);
|
||||
}
|
||||
|
||||
/** Overridded to add spawned charge to list of spawned charges */
|
||||
simulated function Projectile ProjectileFire()
|
||||
{
|
||||
local Projectile P;
|
||||
local KFProj_Rocket_ThermiteBore Harpoon;
|
||||
|
||||
P = super.ProjectileFire();
|
||||
|
||||
Harpoon = KFProj_Rocket_ThermiteBore(P);
|
||||
if (Harpoon != none)
|
||||
{
|
||||
DeployedHarpoons.AddItem(Harpoon);
|
||||
NumDeployedHarpoons = DeployedHarpoons.Length;
|
||||
bForceNetUpdate = true;
|
||||
}
|
||||
|
||||
return P;
|
||||
}
|
||||
|
||||
/** Returns animation to play based on reload type and status */
|
||||
simulated function name GetReloadAnimName(bool bTacticalReload)
|
||||
{
|
||||
// magazine relaod
|
||||
if (AmmoCount[0] > 0)
|
||||
{
|
||||
return (bTacticalReload) ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bTacticalReload) ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim;
|
||||
}
|
||||
}
|
||||
|
||||
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
|
||||
{
|
||||
super.AdjustDamage(InDamage, DamageType, DamageCauser);
|
||||
|
||||
if (Instigator != none && DamageCauser != none && DamageCauser.Instigator == Instigator)
|
||||
{
|
||||
InDamage *= SelfDamageReductionValue;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State WeaponDetonating
|
||||
* The weapon is in this state while detonating a charge
|
||||
*********************************************************************************************/
|
||||
|
||||
simulated function GotoActiveState();
|
||||
|
||||
simulated state WeaponDetonating
|
||||
{
|
||||
ignores AllowSprinting;
|
||||
|
||||
simulated event BeginState( name PreviousStateName )
|
||||
{
|
||||
PrepareAndDetonate();
|
||||
}
|
||||
|
||||
simulated function GotoActiveState()
|
||||
{
|
||||
GotoState('Active');
|
||||
}
|
||||
}
|
||||
|
||||
// GrenadeLaunchers determine ShouldPlayFireLast based on the spare ammo
|
||||
// overriding to use the base KFWeapon version since that uses the current ammo in the mag
|
||||
simulated function bool ShouldPlayFireLast(byte FireModeNum)
|
||||
{
|
||||
return Super(KFWeapon).ShouldPlayFireLast(FireModeNum);
|
||||
}
|
||||
|
||||
simulated function PrepareAndDetonate()
|
||||
{
|
||||
local name SelectedAnim;
|
||||
local float AnimDuration;
|
||||
local bool bInSprintState;
|
||||
|
||||
// choose the detonate animation based on whether it is in ironsights and whether it is the last harpoon
|
||||
if (bUsingSights)
|
||||
{
|
||||
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? DetonateAnimIronLast : DetonateAnimIron;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? DetonateAnimLast : DetonateAnim;
|
||||
}
|
||||
|
||||
AnimDuration = MySkelMesh.GetAnimLength(SelectedAnim);
|
||||
bInSprintState = IsInState('WeaponSprinting');
|
||||
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer)
|
||||
{
|
||||
if (bInSprintState)
|
||||
{
|
||||
AnimDuration *= 0.25f;
|
||||
PlayAnimation(SelectedAnim, AnimDuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayAnimation(SelectedAnim);
|
||||
}
|
||||
}
|
||||
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
Detonate();
|
||||
}
|
||||
|
||||
//AnimDuration value here representes the ALTFIRE FireInterval
|
||||
AnimDuration = 0.75f; //1.f;
|
||||
if (bInSprintState)
|
||||
{
|
||||
SetTimer(AnimDuration * 0.8f, false, nameof(PlaySprintStart));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetTimer(AnimDuration * 0.5f, false, nameof(GotoActiveState));
|
||||
}
|
||||
}
|
||||
|
||||
/** Detonates all the harpoons */
|
||||
simulated function Detonate()
|
||||
{
|
||||
local int i;
|
||||
|
||||
// auto switch weapon when out of ammo and after detonating the last deployed charge
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
for (i = DeployedHarpoons.Length - 1; i >= 0; i--)
|
||||
{
|
||||
DeployedHarpoons[i].Detonate();
|
||||
}
|
||||
|
||||
if (!HasAnyAmmo() && NumDeployedHarpoons == 0)
|
||||
{
|
||||
if (CanSwitchWeapons())
|
||||
{
|
||||
Instigator.Controller.ClientSwitchToBestWeapon(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Removes a charge from the list using either an index or an actor and updates NumDeployedHarpoons */
|
||||
function RemoveDeployedHarpoon(optional int HarpoonIndex = INDEX_NONE, optional Actor HarpoonActor)
|
||||
{
|
||||
if (HarpoonIndex == INDEX_NONE)
|
||||
{
|
||||
if (HarpoonActor != none)
|
||||
{
|
||||
HarpoonIndex = DeployedHarpoons.Find(HarpoonActor);
|
||||
}
|
||||
}
|
||||
|
||||
if (HarpoonIndex != INDEX_NONE)
|
||||
{
|
||||
DeployedHarpoons.Remove(HarpoonIndex, 1);
|
||||
NumDeployedHarpoons = DeployedHarpoons.Length;
|
||||
bForceNetUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Allow reloads for primary weapon to be interupted by firing secondary weapon. */
|
||||
simulated function bool CanOverrideMagReload(byte FireModeNum)
|
||||
{
|
||||
if(FireModeNum == ALTFIRE_FIREMODE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return Super.CanOverrideMagReload(FireModeNum);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Content
|
||||
PackageKey="Thermite"
|
||||
FirstPersonMeshName="wep_1p_thermite_mesh.WEP_1stP_Thermite_Rig"
|
||||
FirstPersonAnimSetNames(0)="wep_1p_thermite_anim.WEP_1stP_Thermite_Anim"
|
||||
PickupMeshName="WEP_3P_Thermite_MESH.WEP_Thermite_Pickup" //@TODO: Replace me
|
||||
AttachmentArchetypeName="wep_thermite_arch.Wep_Thermite_3P"
|
||||
MuzzleFlashTemplateName="wep_thermite_arch.Wep_Thermite_MuzzleFlash" //@TODO: Replace me
|
||||
|
||||
// Inventory / Grouping
|
||||
InventorySize=7
|
||||
GroupPriority=100
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_Thermite_TEX.UI_WeaponSelect_Thermite'
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Firebug'
|
||||
|
||||
// FOV
|
||||
MeshFOV=75
|
||||
MeshIronSightFOV=40
|
||||
PlayerIronSightFOV=65
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=50
|
||||
DOF_FG_MaxNearBlurSize=3.5
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=6
|
||||
SpareAmmoCapacity[0]=36 //42
|
||||
InitialSpareMags[0]=1
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=11.0,Y=8,Z=-2)
|
||||
IronSightPosition=(X=10,Y=0,Z=0)
|
||||
|
||||
// AI warning system
|
||||
bWarnAIWhenAiming=true
|
||||
AimWarningDelay=(X=0.4f, Y=0.8f)
|
||||
AimWarningCooldown=0.0f
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=500
|
||||
minRecoilPitch=400
|
||||
maxRecoilYaw=150
|
||||
minRecoilYaw=-150
|
||||
RecoilRate=0.08
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=1250
|
||||
RecoilMinPitchLimit=64785
|
||||
RecoilISMaxYawLimit=50
|
||||
RecoilISMinYawLimit=65485
|
||||
RecoilISMaxPitchLimit=500
|
||||
RecoilISMinPitchLimit=65485
|
||||
RecoilViewRotationScale=0.6
|
||||
IronSightMeshFOVCompensationScale=1.5
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Rocket_ThermiteBore'
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=150
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_ThermiteBoreImpact'
|
||||
FireInterval(DEFAULT_FIREMODE)=0.8 //100 RPM
|
||||
Spread(DEFAULT_FIREMODE)=0
|
||||
PenetrationPower(DEFAULT_FIREMODE)=0
|
||||
FireOffset=(X=25,Y=3.0,Z=-2.5)
|
||||
|
||||
// ALTFIRE_FIREMODE (remote detonate)
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponDetonating
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
|
||||
AmmoCost(ALTFIRE_FIREMODE)=0
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_ThermiteBore'
|
||||
InstantHitDamage(BASH_FIREMODE)=26
|
||||
|
||||
// Custom animations
|
||||
FireSightedAnims=(Shoot_Iron)
|
||||
BonesToLockOnEmpty=(RW_Exhaust, RW_BoltAssembly1, RW_BoltAssembly2, RW_BoltAssembly3)
|
||||
bHasFireLastAnims=true
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_1P')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Dry_Fire'
|
||||
EjectedShellForegroundDuration=1.5f
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
|
||||
|
||||
SelfDamageReductionValue=0.05f //0.25f
|
||||
|
||||
DetonateAnim=Alt_Fire
|
||||
DetonateAnimLast=Alt_Fire_Last
|
||||
DetonateAnimIron=Alt_Fire_Iron
|
||||
DetonateAnimIronLast=Alt_Fire_Iron_Last
|
||||
}
|
Reference in New Issue
Block a user