1
0
This commit is contained in:
2023-09-21 22:31:11 +03:00
parent ef3db8a926
commit ce182019df
167 changed files with 5429 additions and 659 deletions

View File

@ -1698,11 +1698,12 @@ function DoFleeFrom( actor FleeFrom,
optional float FleeDuration,
optional float FleeDistance,
optional bool bShouldStopAtGoal=false,
optional bool bFromFear=false )
optional bool bFromFear=false,
optional bool bUseRandomDirection=false )
{
if( !bFromFear || !MyPatPawn.bInFleeAndHealMode )
{
super.DoFleeFrom( FleeFrom, FleeDuration, FleeDistance, bShouldStopAtGoal, bFromFear );
super.DoFleeFrom( FleeFrom, FleeDuration, FleeDistance, bShouldStopAtGoal, bFromFear, bUseRandomDirection );
}
}

View File

@ -19,6 +19,7 @@ var private bool bFound;
protected event TriggerDestroyedEvent( Controller EventInstigator )
{
local KFMapInfo KFMI;
local KFPlayerController KFPC;
super.TriggerDestroyedEvent( EventInstigator );
@ -27,6 +28,12 @@ protected event TriggerDestroyedEvent( Controller EventInstigator )
{
bFound = true;
KFMI.OnCollectibleFound( self, EventInstigator );
KFPC = KFPlayerController(EventInstigator);
If (KFPC != none)
{
KFPC.AddCollectibleFound(KFMI.CollectiblesToFind);
}
}
// Used on network to tell clients who join late that this collectible is destroyed

View File

@ -30,36 +30,6 @@ static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
/**
* Allows medic perk to add poison damage
* @return: None if toxic skill is not available
*/
static function class<KFDamageType> GetMedicToxicDmgType( out int out_Damage, optional Controller InstigatedBy )
{
local KFPerk InstigatorPerk;
InstigatorPerk = KFPlayerController(InstigatedBy).GetPerk();
if( InstigatorPerk == none || (!InstigatorPerk.IsToxicDmgActive() && !InstigatorPerk.IsZedativeActive()) )
{
return None;
}
InstigatorPerk.ModifyToxicDmg( out_Damage );
return InstigatorPerk.GetToxicDmgTypeClass();
}
defaultproperties
{
KDamageImpulse=1000

View File

@ -40,18 +40,6 @@ static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
GoreDamageGroup=DGT_Shotgun

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFDT_Ballistic_HRG_93R
//=============================================================================
// Base pistol damage type
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_93R extends KFDT_Ballistic_Handgun
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
KnockdownPower=12
StumblePower=0
GunHitPower=10
WeaponDef=class'KFWeapDef_HRG_93R'
}

View File

@ -89,17 +89,6 @@ static function PlayImpactHitEffects(KFPawn P, vector HitLocation, vector HitDir
/** 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 )
{
local class<KFDamageType> ToxicDT;
local int ToxicDamageTaken;
ToxicDamageTaken = DamageTaken;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( ToxicDamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(ToxicDamageTaken, InstigatedBy, ToxicDT);
}
// potential for two DoTs if DoT_Type is set
if (default.BleedDamageType.default.DoT_Type != DOT_None)
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BleedDamageType);

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFDT_Ballistic_MG3
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_MG3 extends KFDT_Ballistic_AssaultRifle
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=10
GunHitPower=50
WeaponDef=class'KFWeapDef_MG3'
//Perk
ModifierPerkList(0)=class'KFPerk_Commando'
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFDT_Ballistic_MG3_Alt
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_MG3_Alt extends KFDT_Ballistic_AssaultRifle
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=10
GunHitPower=50
WeaponDef=class'KFWeapDef_MG3'
//Perk
ModifierPerkList(0)=class'KFPerk_Commando'
}

View File

@ -11,18 +11,6 @@ class KFDT_Ballistic_MedicRifleGrenadeLauncher extends KFDT_Ballistic_AssaultRif
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=900
@ -32,7 +20,6 @@ defaultproperties
StumblePower=10
GunHitPower=45
WeaponDef=class'KFWeapDef_MedicRifleGrenadeLauncher'
//Perk

View File

@ -28,18 +28,6 @@ static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=2000

View File

@ -10,18 +10,6 @@ class KFDT_Ballistic_ParasiteImplanterAlt extends KFDT_Toxic
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KnockdownPower=30

View File

@ -12,19 +12,6 @@ class KFDT_Ballistic_Pistol_Medic extends KFDT_Ballistic_Handgun
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=900

View File

@ -12,18 +12,6 @@ class KFDT_Ballistic_SMG_Medic extends KFDT_Ballistic_Submachinegun
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=900

View File

@ -31,18 +31,6 @@ static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
BloodSpread=0.4

View File

@ -10,18 +10,6 @@
class KFDT_Bleeding_HRG_Vampire_BloodSuck extends KFDT_Bleeding
abstract;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
//physics

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Bludgeon_HRG_93R
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_HRG_93R extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
//defaults
WeaponDef=class'KFWeapDef_HRG_93R'
}

View File

@ -0,0 +1,15 @@
//=============================================================================
// KFDT_Bludgeon_MG3
//=============================================================================
// Killing Floor 2
// Copyright (C) 2016 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_MG3 extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
//defaults
WeaponDef=class'KFWeapDef_MG3'
}

View File

@ -12,7 +12,51 @@ class KFDT_Dart_Toxic extends KFDT_Toxic
abstract
hidedropdown;
/** Called when damage is dealt to apply additional instant damage */
static function ModifyInstantDamage( KFPawn Victim, out int DamageTaken, optional Controller InstigatedBy )
{
class'KFDT_Dart_Toxic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
}
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Dart_Toxic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
/**
* Allows medic perk to add poison damage
*/
static function class<KFDamageType> GetMedicToxicDmgType( out int out_Damage, optional Controller InstigatedBy )
{
local KFPerk InstigatorPerk;
InstigatorPerk = KFPlayerController(InstigatedBy).GetPerk();
if( InstigatorPerk == none || (!InstigatorPerk.IsToxicDmgActive() && !InstigatorPerk.IsZedativeActive()) )
{
return None;
}
InstigatorPerk.ModifyToxicDmg( out_Damage );
return InstigatorPerk.GetToxicDmgTypeClass();
}
defaultproperties
{
WeaponDef=class'KFWeapDef_Healer'
DoT_Type=DOT_None
DoT_Duration=0.0
DoT_Interval=0.0
DoT_DamageScale=0.0
PoisonPower=0.f
}

View File

@ -11,18 +11,6 @@ class KFDT_Piercing_HRG_Vampire_CrystalSpike extends KFDT_Piercing
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=1500

View File

@ -11,18 +11,6 @@ class KFDT_Piercing_KnifeStab_FieldMedic extends KFDT_Piercing_KnifeStab
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
ModifierPerkList(0)=class'KFPerk_FieldMedic'

View File

@ -12,18 +12,6 @@ class KFDT_Slashing_KnifeHeavy_Medic extends KFDT_Slashing_KnifeHeavy
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
MeleeHitPower=113

View File

@ -12,18 +12,6 @@ class KFDT_Slashing_Knife_Medic extends KFDT_Slashing_Knife
abstract
hidedropdown;
/** 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
GunHitPower=44

View File

@ -12,26 +12,11 @@ class KFDT_Toxic_MineReconstructorImpact extends KFDT_Ballistic_Shell
abstract
hidedropdown;
static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
//override dot as the impact has no dot

View File

@ -12,26 +12,11 @@ class KFDT_Toxic_MineReconstructorImpactHeavy extends KFDT_Ballistic_Shell
abstract
hidedropdown;
static simulated function bool CanDismemberHitZone( 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 )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
//override dot as the impact has no dot
@ -39,7 +24,6 @@ defaultproperties
EffectGroup=FXG_Toxic
MicrowavePower=50;
PoisonPower=60;
StumblePower=340;

View File

@ -506,7 +506,7 @@ function ReduceDamage(out int Damage, Pawn Injured, Controller InstigatedBy, vec
function StartOutbreakRound(int OutbreakIdx)
{
OutbreakEvent.SetActiveEvent(OutbreakIdx);
OutbreakEvent.SetActiveEvent(OutbreakIdx, self);
OutbreakEvent.UpdateGRI();
OutbreakEvent.SetWorldInfoOverrides();

View File

@ -50,6 +50,9 @@ var protected bool bGunGamePlayerOnLastGun;
var transient array<KFBarmwichBonfireVolume> BonfireVolumes;
// Trader Time modifier for Castle Volter map in the last round
var float CastleVolterTraderModifier;
/** Whether this game mode should play music from the get-go (lobby) */
static function bool ShouldPlayMusicAtStart()
{
@ -926,6 +929,7 @@ function StartWave()
WaveStarted();
MyKFGRI.NotifyWaveStart();
MyKFGRI.AIRemaining = SpawnManager.WaveTotalAI;
MyKFGRI.WaveTotalAICount = SpawnManager.WaveTotalAI;
@ -1469,7 +1473,17 @@ function DoTraderTimeCleanup();
/** Handle functionality for opening trader */
function OpenTrader()
{
MyKFGRI.OpenTrader(TimeBetweenWaves);
local int UpdatedTimeBetweenWaves;
UpdatedTimeBetweenWaves = TimeBetweenWaves;
// In castle volter the trader needs to have a special time
if (WorldInfo.GetMapName(true) == "KF-CastleVolter" && WaveNum == (WaveMax - 1) )
{
UpdatedTimeBetweenWaves = UpdatedTimeBetweenWaves * CastleVolterTraderModifier;
}
MyKFGRI.OpenTrader(UpdatedTimeBetweenWaves);
NotifyTraderOpened();
}
@ -1924,7 +1938,8 @@ DefaultProperties
MaxGameDifficulty=3
bWaveStarted=false
bGunGamePlayerOnLastGun=false
CastleVolterTraderModifier = 1.0f;
ObjectiveSpawnDelay=5
SpawnManagerClasses(0)=class'KFGame.KFAISpawnManager_Short'
@ -1962,6 +1977,7 @@ DefaultProperties
AIClassList(AT_EDAR_EMP)=class'KFGameContent.KFPawn_ZedDAR_Emp'
AIClassList(AT_EDAR_Laser)=class'KFGameContent.KFPawn_ZedDAR_Laser'
AIClassList(AT_EDAR_Rocket)=class'KFGameContent.KFPawn_ZedDAR_Rocket'
AIClassList(AT_HansClot)=class'KFGameContent.KFPawn_ZedHansClot'
NonSpawnAIClassList(0)=class'KFGameContent.KFPawn_ZedBloatKingSubspawn'

File diff suppressed because it is too large Load Diff

View File

@ -68,7 +68,9 @@ function ChooseNextObjective(int NextWaveNum)
if (IsContaminationMode() == false)
{
super.ChooseNextObjective(NextWaveNum);
super.ChooseNextObjective(NextWaveNum);
return;
}
KFMI = KFMapInfo(WorldInfo.GetMapInfo());

View File

@ -200,6 +200,11 @@ simulated function bool CanActivateObjectiveByWeekly()
{
if (KFGameInfo(WorldInfo.Game).OutbreakEvent != none)
{
if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bBossRushMode)
{
return false;
}
if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bGunGameMode)
{
return false;
@ -209,18 +214,33 @@ simulated function bool CanActivateObjectiveByWeekly()
{
return false;
}
if (KFGameInfo(WorldInfo.Game).OutbreakEvent.ActiveEvent.bBountyHunt)
{
return false;
}
}
}
else
{
if (KFGameReplicationInfo(WorldInfo.GRI) != none && KFGameReplicationInfo(WorldInfo.GRI).bIsWeeklyMode)
{
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 14)
{
return false;
}
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 16)
{
return false;
}
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 17)
{
return false;
}
if (KFGameReplicationInfo(WorldInfo.GRI).CurrentWeeklyIndex == 20)
{
return false;
}

View File

@ -1247,9 +1247,183 @@ defaultproperties
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedDAR_Rocket'),PercentChance=0.2)
)}
)}
// Bounty Hunt
SetEvents[20]={(
EventDifficulty=2,
GameLength=GL_Normal,
OverrideAmmoPickupModifier=2.0f,
WaveAICountScale=(0.8f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f), // This is per player-count, if more players than slots uses last value
bBountyHunt=true,
BountyHuntExtraDosh=200,
// Navigation parameters
BountyHuntNeedsToSeePlayerToTriggerFlee=false, //DEFAULT: false
BountyHuntTimeBetweenFlee=10.f, //DEFAULT: 10f // (seconds) Time the Flee AI Order is active
BountyHuntTimeBetweenAttack=12.f, //DEFAULT 12f // (seconds) Seconds between a new Attack Order can be issued using proximity to any player (BountyHuntDistancePlayerAttack)
BountyHuntTimeCanCancelAttack=1f, //DEFAULT 5.f // (seconds) Seconds after Attack is issued we can cancel it (to flee if the distance BountyHuntDistancePlayerMinFlee is okay)
BountyHuntDistancePlayerMinFirstFlee=2000.f, //DEFAULT 100f // (cm) Minimal Distance between Player and Zed when Zed decides to Flee first time (then we block crossing Blocking Volumes)
BountyHuntDistancePlayerMinFlee=2000.f, //DEFAULT 1000f // (cm) Minimal Distance between Player and Zed when Zed decides to Flee
BountyHuntDistancePlayerMaxFlee=20000.f, // DEFAULT 2200F // (cm) Distance between Player and Zed when Zed stops Fleeing (use to cancel a Flee)
BountyHuntDistancePlayerAttack=80.f, // DEFAULT 400f // (cm) Distance between Player and Zed when Zed decides to Attack
// BZ stat parameters
BountyHuntSpecialZedBuffHealthRatio=0.1f, // EXTRA 10% health for all Bounty Zeds
BountyHuntSpecialZedBuffAfflictionResistance=5f, // EXTRA 500% affliction resistance for all Bounty Zeds
HeadshotDamageMultiplier=0.25f,
BountyHuntMaxCoexistingZeds=3,
BountyHuntLastLevelStillUsesCoexistingZeds=false,
BountyHuntUseGradualSpawn=false,
BountyHuntGame=
{(
BountyHuntDataWaves= // Amount of Zeds is TOTAL, NOT NumberOfZeds per player
{(
(Wave=1
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=1)
, (NumberOfPlayers=2, NumberOfZeds=2)
, (NumberOfPlayers=3, NumberOfZeds=3)
, (NumberOfPlayers=4, NumberOfZeds=4)
, (NumberOfPlayers=5, NumberOfZeds=5)
, (NumberOfPlayers=6, NumberOfZeds=5)
)}),
(Wave=2
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=2)
, (NumberOfPlayers=2, NumberOfZeds=3)
, (NumberOfPlayers=3, NumberOfZeds=4)
, (NumberOfPlayers=4, NumberOfZeds=5)
, (NumberOfPlayers=5, NumberOfZeds=6)
, (NumberOfPlayers=6, NumberOfZeds=6)
)}),
(Wave=3
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=3)
, (NumberOfPlayers=2, NumberOfZeds=4)
, (NumberOfPlayers=3, NumberOfZeds=5)
, (NumberOfPlayers=4, NumberOfZeds=6)
, (NumberOfPlayers=5, NumberOfZeds=7)
, (NumberOfPlayers=6, NumberOfZeds=7)
)}),
(Wave=4
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=3)
, (NumberOfPlayers=2, NumberOfZeds=5)
, (NumberOfPlayers=3, NumberOfZeds=6)
, (NumberOfPlayers=4, NumberOfZeds=7)
, (NumberOfPlayers=5, NumberOfZeds=7)
, (NumberOfPlayers=6, NumberOfZeds=8)
)}),
(Wave=5
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=4)
, (NumberOfPlayers=2, NumberOfZeds=6)
, (NumberOfPlayers=3, NumberOfZeds=7)
, (NumberOfPlayers=4, NumberOfZeds=8)
, (NumberOfPlayers=5, NumberOfZeds=8)
, (NumberOfPlayers=6, NumberOfZeds=8)
)}),
(Wave=6
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=5)
, (NumberOfPlayers=2, NumberOfZeds=7)
, (NumberOfPlayers=3, NumberOfZeds=8)
, (NumberOfPlayers=4, NumberOfZeds=9)
, (NumberOfPlayers=5, NumberOfZeds=9)
, (NumberOfPlayers=6, NumberOfZeds=9)
)}),
(Wave=7
, BountyHuntWavePerPlayerZed =
{(
(NumberOfPlayers=1, NumberOfZeds=6)
, (NumberOfPlayers=2, NumberOfZeds=8)
, (NumberOfPlayers=3, NumberOfZeds=9)
, (NumberOfPlayers=4, NumberOfZeds=10)
, (NumberOfPlayers=5, NumberOfZeds=12)
, (NumberOfPlayers=6, NumberOfZeds=12)
)})
)},
// Zed Stats progression related to remaining AI zeds
BountyHuntZedAndProgression=
{(
( ZedType=class'KFGameContent.KFPawn_ZedGorefastDualBlade',
BountyHuntSpecialZedPerWave =
{(
(Wave=2), (Wave=3), (Wave=4), (Wave=5)
)},
BountyHuntZedProgression =
{(
(RemainingZedRatio=1.f, HealthBuffRatio=1f, DamageBuffRatio=0.f), // +100% H // +0% DMG
(RemainingZedRatio=0.75f, HealthBuffRatio=1.5f, DamageBuffRatio=0.1f), // +150% H // +10% DMG
(RemainingZedRatio=0.5f, HealthBuffRatio=2f, DamageBuffRatio=0.2f), // +200% H / +20% DMG
(RemainingZedRatio=0.3f, HealthBuffRatio=2.5f, DamageBuffRatio=0.3f), // +250% H // +30% DMG
(RemainingZedRatio=0.1f, HealthBuffRatio=3f, DamageBuffRatio=3.f) // +300%H // +300% DMG
)}
),
( ZedType=class'KFGameContent.KFPawn_ZedClot_AlphaKing',
BountyHuntSpecialZedPerWave =
{(
(Wave=1), (Wave=3)
)},
BountyHuntZedProgression =
{(
(RemainingZedRatio=1.f, HealthBuffRatio=5f, DamageBuffRatio=0.f), // +500% H // +0% DMG
(RemainingZedRatio=0.75f, HealthBuffRatio=5.1f, DamageBuffRatio=0.1f), // +510% H // +10% DMG
(RemainingZedRatio=0.5f, HealthBuffRatio=5.2f, DamageBuffRatio=0.2f), // +520% H / +20% DMG
(RemainingZedRatio=0.3f, HealthBuffRatio=5.3f, DamageBuffRatio=0.5f), // +530% H // +50% DMG
(RemainingZedRatio=0.1f, HealthBuffRatio=5.5f, DamageBuffRatio=3.f) // +550% H // +300% DMG
)}
),
( ZedType=class'KFGameContent.KFPawn_ZedFleshpoundMini',
BountyHuntSpecialZedPerWave =
{(
(Wave=6), (Wave=7)
)},
BountyHuntZedProgression =
{(
(RemainingZedRatio=1.f, HealthBuffRatio=0.f, DamageBuffRatio=0.f), // +0% H // +0% DMG
(RemainingZedRatio=0.75f, HealthBuffRatio=0.0f, DamageBuffRatio=0.01f), // +0% H // +1% DMG
(RemainingZedRatio=0.5f, HealthBuffRatio=0.0f, DamageBuffRatio=0.02f), // +0% H // +2% DMG
(RemainingZedRatio=0.3f, HealthBuffRatio=0.01f, DamageBuffRatio=0.03f), // +1% H // +3% DMG
(RemainingZedRatio=0.1f, HealthBuffRatio=0.05f, DamageBuffRatio=0.1f) // +5% H // +10% DMG
)}
),
( ZedType=class'KFGameContent.KFPawn_ZedScrake',
BountyHuntSpecialZedPerWave =
{(
(Wave=4), (Wave=5), (Wave=6), (Wave=7)
)},
BountyHuntZedProgression =
{(
(RemainingZedRatio=1.f, HealthBuffRatio=0.01f, DamageBuffRatio=0.f), // +1% H // +0% DMG
(RemainingZedRatio=0.75f, HealthBuffRatio=0.02f, DamageBuffRatio=0.05f), // +2% H // +5% DMG
(RemainingZedRatio=0.5f, HealthBuffRatio=0.03f, DamageBuffRatio=0.05f), // +3% H // +5% DMG
(RemainingZedRatio=0.3f, HealthBuffRatio=0.04f, DamageBuffRatio=0.05f), // +4% H // +5% DMG
(RemainingZedRatio=0.1f, HealthBuffRatio=0.05f, DamageBuffRatio=0.25f) // +5% H // +25% DMG
)}
)
)},
BountyHuntDosh=
{(
(NumberOfPlayers=1, Dosh=300, DoshNoAssist=250),
(NumberOfPlayers=2, Dosh=250, DoshNoAssist=200),
(NumberOfPlayers=3, Dosh=200, DoshNoAssist=150),
(NumberOfPlayers=4, Dosh=150, DoshNoAssist=100),
(NumberOfPlayers=5, Dosh=130, DoshNoAssist=80),
(NumberOfPlayers=6, Dosh=130, DoshNoAssist=80)
)}
)}
)}
//Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8

View File

@ -497,6 +497,55 @@ simulated state TargetSearch
}
}
simulated function bool TargetValidWithGeometry(Actor Target, vector MuzzleLoc, vector ReferencePosition)
{
local vector HitLocation, HitNormal;
local Actor HitActor;
local vector DistanceToTarget, DistanceToTrader;
local KFTraderTrigger TestTrader;
local float ModuloDistanceToTrader, DotValue;
local bool bTraderFound;
local int IteratorTrader;
HitActor = Trace(HitLocation, HitNormal, ReferencePosition, MuzzleLoc,,,,TRACEFLAG_Bullet);
if (HitActor == none || KFPawn_Monster(HitActor) == none)
{
return false;
}
DistanceToTarget = Target.Location - MuzzleLoc;
bTraderFound = false;
for (IteratorTrader=0; IteratorTrader < KFGameInfo(WorldInfo.Game).TraderList.Length; ++ IteratorTrader)
{
TestTrader = KFGameInfo(WorldInfo.Game).TraderList[IteratorTrader];
DistanceToTrader = TestTrader.Location - MuzzleLoc;
ModuloDistanceToTrader = VSize(DistanceToTrader);
if (ModuloDistanceToTrader < VSize(DistanceToTarget))
{
DotValue = Normal(DistanceToTrader) Dot Normal(DistanceToTarget);
if (DotValue > 0.2f)
{
bTraderFound = true;
break;
}
}
}
if (bTraderFound)
{
return false;
}
return true;
}
simulated state Combat
{
simulated function BeginState(name PreviousStateName)
@ -543,10 +592,6 @@ simulated state Combat
local rotator MuzzleRot;
local rotator DesiredRotationRot;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
local Actor HitActor;
local float NewAmmoPercentage;
local bool bIsSpotted;
@ -580,17 +625,14 @@ simulated state Combat
{
if (EnemyTarget != none)
{
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, EnemyTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
// Visible by local player or team
bIsSpotted = (EnemyTarget.bIsCloakingSpottedByLP || EnemyTarget.bIsCloakingSpottedByTeam);
/** Search for new enemies if current is dead, cloaked or too far, or something between the drone that's world geometry */
if (!EnemyTarget.IsAliveAndWell()
if (EnemyTarget.IsAliveAndWell() == false
|| (EnemyTarget.bIsCloaking && bIsSpotted == false)
|| VSizeSq(EnemyTarget.Location - Location) > EffectiveRadius * EffectiveRadius
|| (HitActor != none && HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
|| TargetValidWithGeometry(EnemyTarget, MuzzleLoc, EnemyTarget.Mesh.GetBoneLocation('Spine1')))
{
EnemyTarget = none;
CheckForTargets();
@ -613,11 +655,9 @@ simulated state Combat
if (Role == ROLE_Authority && ReachedRotation())
{
HitActor = Trace(HitLocation, HitNormal, MuzzleLoc + vector(Rotation) * EffectiveRadius, MuzzleLoc, , , HitInfo, TRACEFLAG_Bullet);
if (TurretWeapon != none)
{
if (HitActor != none && HitActor.bWorldGeometry == false)
if (TargetValidWithGeometry(EnemyTarget, MuzzleLoc, EnemyTarget.Mesh.GetBoneLocation('Spine1')))
{
TurretWeapon.Fire();
@ -751,9 +791,6 @@ function CheckForTargets()
local vector MuzzleLoc;
local rotator MuzzleRot;
local vector HitLocation, HitNormal;
local Actor HitActor;
local bool bIsSpotted;
if (EnemyTarget != none)
@ -778,10 +815,7 @@ function CheckForTargets()
continue;
}
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, CurrentTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
if (HitActor == none || (HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
if (TargetValidWithGeometry(CurrentTarget, MuzzleLoc, CurrentTarget.Mesh.GetBoneLocation('Spine1')) == false)
{
continue;
}
@ -1045,6 +1079,11 @@ simulated function bool CanInteractWithZoneVelocity()
return false;
}
function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab)
{
return false;
}
simulated function UpdateTurretMeshMaterialColor(float Value)
{
if (TurretWeaponAttachment == none)

View File

@ -501,6 +501,55 @@ simulated state TargetSearch
}
}
simulated function bool TargetValidWithGeometry(Actor Target, vector MuzzleLoc, vector ReferencePosition)
{
local vector HitLocation, HitNormal;
local Actor HitActor;
local vector DistanceToTarget, DistanceToTrader;
local KFTraderTrigger TestTrader;
local float ModuloDistanceToTrader, DotValue;
local bool bTraderFound;
local int IteratorTrader;
HitActor = Trace(HitLocation, HitNormal, ReferencePosition, MuzzleLoc,,,,TRACEFLAG_Bullet);
if (HitActor == none || KFPawn_Monster(HitActor) == none)
{
return false;
}
DistanceToTarget = Target.Location - MuzzleLoc;
bTraderFound = false;
for (IteratorTrader=0; IteratorTrader < KFGameInfo(WorldInfo.Game).TraderList.Length; ++ IteratorTrader)
{
TestTrader = KFGameInfo(WorldInfo.Game).TraderList[IteratorTrader];
DistanceToTrader = TestTrader.Location - MuzzleLoc;
ModuloDistanceToTrader = VSize(DistanceToTrader);
if (ModuloDistanceToTrader < VSize(DistanceToTarget))
{
DotValue = Normal(DistanceToTrader) Dot Normal(DistanceToTarget);
if (DotValue > 0.2f)
{
bTraderFound = true;
break;
}
}
}
if (bTraderFound)
{
return false;
}
return true;
}
simulated state Combat
{
simulated function BeginState(name PreviousStateName)
@ -547,10 +596,6 @@ simulated state Combat
local rotator MuzzleRot;
local rotator DesiredRotationRot;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
local Actor HitActor;
local float NewAmmoPercentage;
local bool bIsSpotted;
@ -584,17 +629,14 @@ simulated state Combat
{
if (EnemyTarget != none)
{
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, EnemyTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
// Visible by local player or team
bIsSpotted = (EnemyTarget.bIsCloakingSpottedByLP || EnemyTarget.bIsCloakingSpottedByTeam);
/** Search for new enemies if current is dead, cloaked or too far, or something between the drone that's world geometry */
if (!EnemyTarget.IsAliveAndWell()
if (EnemyTarget.IsAliveAndWell() == false
|| (EnemyTarget.bIsCloaking && bIsSpotted == false)
|| VSizeSq(EnemyTarget.Location - Location) > EffectiveRadius * EffectiveRadius
|| (HitActor != none && HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
|| TargetValidWithGeometry(EnemyTarget, MuzzleLoc, EnemyTarget.Mesh.GetBoneLocation('Spine1')))
{
EnemyTarget = none;
CheckForTargets();
@ -617,11 +659,9 @@ simulated state Combat
if (Role == ROLE_Authority && ReachedRotation())
{
HitActor = Trace(HitLocation, HitNormal, MuzzleLoc + vector(Rotation) * EffectiveRadius, MuzzleLoc, , , HitInfo, TRACEFLAG_Bullet);
if (TurretWeapon != none)
{
if (HitActor != none && HitActor.bWorldGeometry == false)
if (TargetValidWithGeometry(EnemyTarget, MuzzleLoc, EnemyTarget.Mesh.GetBoneLocation('Spine1')))
{
TurretWeapon.CurrentTarget = EnemyTarget;
@ -632,7 +672,7 @@ simulated state Combat
SetTurretState(ETS_Empty);
}
}
}
}
}
}
@ -848,7 +888,7 @@ simulated function StopIdleSound()
function CheckForTargets()
{
local KFPawn_Monster CurrentTarget;
local TraceHitInfo HitInfo;
local TraceHitInfo HitInfo;
local float CurrentDistance;
local float Distance;
@ -856,9 +896,6 @@ function CheckForTargets()
local vector MuzzleLoc;
local rotator MuzzleRot;
local vector HitLocation, HitNormal;
local Actor HitActor;
local bool bIsSpotted;
if (EnemyTarget != none)
@ -883,10 +920,7 @@ function CheckForTargets()
continue;
}
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, CurrentTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
if (HitActor == none || (HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
if (TargetValidWithGeometry(CurrentTarget, MuzzleLoc, CurrentTarget.Mesh.GetBoneLocation('Spine1')) == false)
{
continue;
}
@ -1150,6 +1184,11 @@ simulated function bool CanInteractWithZoneVelocity()
return false;
}
function bool CanBeGrabbed(KFPawn GrabbingPawn, optional bool bIgnoreFalling, optional bool bAllowSameTeamGrab)
{
return false;
}
simulated function UpdateTurretMeshMaterialColor(float Value)
{
if (TurretWeaponAttachment == none)

View File

@ -407,4 +407,8 @@ DefaultProperties
MinSpawnSquadSizeType=EST_Large
bIsBloatClass=true
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -790,4 +790,8 @@ defaultproperties
bCanBePinned=false
bCanBeKilledByShrinking=false
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here (here defaults to this same class)
MapReplacePawnClass[0]= class'KFPawn_ZedBloatKing'
}

View File

@ -102,4 +102,8 @@ DefaultProperties
// AI / Navigation
//DebugRange_Melee_Material=Material'ENG_EditorResources_MAT.Debug_Radius_M'
RotationRate=(Pitch=50000,Yaw=30000,Roll=50000)
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -470,4 +470,8 @@ defaultproperties
MinSpawnSquadSizeType=EST_Crawler
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -436,4 +436,8 @@ defaultproperties
StopSprintingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_Stop'
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -315,10 +315,22 @@ function class<KFDamageType> GetBumpAttackDamageType()
*/
simulated function AdjustAffliction(out float AfflictionPower)
{
local KFGameInfo KFGI;
if ( bIsEnraged )
{
AfflictionPower *= 0.25f;
}
if (bIsBountyHuntObjective) // Only on Bounty Hunt Weekly
{
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none && KFGI.OutbreakEvent != none)
{
AfflictionPower -= AfflictionPower * KFGI.OutbreakEvent.ActiveEvent.BountyHuntSpecialZedBuffAfflictionResistance;
}
}
}
/** Track the fleshpound's speed and play the appropriate cues */
@ -610,4 +622,8 @@ End Object
OnDeathAchievementID=KFACHID_ItsOnlyAFleshWound
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -985,4 +985,8 @@ DefaultProperties
bCanBePinned=false
bCanBeKilledByShrinking=false
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here (here defaults to this same class)
MapReplacePawnClass[0] = class'KFPawn_ZedFleshpoundKing'
}

View File

@ -131,4 +131,8 @@ DefaultProperties
// ---------------------------------------------
// Spawning
MinSpawnSquadSizeType=EST_Medium
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -1671,4 +1671,8 @@ DefaultProperties
MinSpawnSquadSizeType=EST_Boss
OnDeathAchievementID=KFACHID_DieVolter
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here (here defaults to this same class)
MapReplacePawnClass.Add(class'KFPawn_ZedHans')
}

View File

@ -0,0 +1,96 @@
//=============================================================================
// KFPawn_ZedHansClot
//=============================================================================
// KF Pawn for Hans Clot
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//
//=============================================================================
class KFPawn_ZedHansClot extends KFPawn_ZedClot;
/** Returns (hardcoded) trader advice dialog ID */
static function int GetTraderAdviceID()
{
return 36;//TRAD_AdviceClotU
}
defaultproperties
{
LocalizationKey=KFPawn_ZedHansClot
// ---------------------------------------------
// Stats
XPValues(0)=8
XPValues(1)=11
XPValues(2)=11
XPValues(3)=11
Begin Object Name=KFPawnSkeletalMeshComponent
bPerBoneMotionBlur=false
End Object
// ---------------------------------------------
// Content
MonsterArchPath="ZED_ARCH.ZED_HansClot_Archetype"
PawnAnimInfo=KFPawnAnimInfo'ZED_Clot_Anim.UndevClot_AnimGroup'
DifficultySettings=class'KFDifficulty_ClotCyst'
// ---------------------------------------------
// Gameplay
GrabAttackFrequency=0.8f
KnockedDownBySonicWaveOdds=0.35f
// for reference: Vulnerability=(default, head, legs, arms, special)
IncapSettings(AF_Stun)= (Vulnerability=(2.0, 2.0, 1.0, 1.0, 1.0), Cooldown=3.0, Duration=3.0)
IncapSettings(AF_Knockdown)= (Vulnerability=(1.f), Cooldown=1.0)
IncapSettings(AF_Stumble)= (Vulnerability=(1.3f), Cooldown=0.2)
IncapSettings(AF_GunHit)= (Vulnerability=(2.f), Cooldown=0.2)
IncapSettings(AF_MeleeHit)= (Vulnerability=(2.0), Cooldown=0.0)
IncapSettings(AF_Poison)= (Vulnerability=(5), Cooldown=6.0, Duration=4.5)
IncapSettings(AF_Microwave)= (Vulnerability=(0.5), Cooldown=8.0, Duration=4.5)
IncapSettings(AF_FirePanic)= (Vulnerability=(1.5), Cooldown=7.0, Duration=5)
IncapSettings(AF_EMP)= (Vulnerability=(2.5), Cooldown=5.0, Duration=5.0)
IncapSettings(AF_Freeze)= (Vulnerability=(2.5), Cooldown=1.5, Duration=5.0)
IncapSettings(AF_Snare)= (Vulnerability=(10.0, 10.0, 10.0, 10.0), Cooldown=5.5, Duration=4.0)
IncapSettings(AF_Bleed)= (Vulnerability=(2.0))
IncapSettings(AF_Shrink)= (Vulnerability=(1.0))
ShrinkEffectModifier = 2.0f
ParryResistance=0
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(1.5))) //3.0
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_AssaultRifle', DamageScale=(1.5))) //2.5
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Shotgun', DamageScale=(1.0)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Handgun', DamageScale=(1.01)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Rifle', DamageScale=(1.0))) //0.76
DamageTypeModifiers.Add((DamageType=class'KFDT_Slashing', DamageScale=(0.85))) //0.5
DamageTypeModifiers.Add((DamageType=class'KFDT_Bludgeon', DamageScale=(0.9))) // 0.5
DamageTypeModifiers.Add((DamageType=class'KFDT_Fire', DamageScale=(1.0))) //0.8
DamageTypeModifiers.Add((DamageType=class'KFDT_Microwave', DamageScale=(0.25)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Explosive', DamageScale=(1.0))) //0.85
DamageTypeModifiers.Add((DamageType=class'KFDT_Piercing', DamageScale=(1.0)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Toxic', DamageScale=(1.0))) //0.9
// special case
DamageTypeModifiers.Add((DamageType=class'KFDT_Slashing_Knife', DamageScale=(1.0))
// ---------------------------------------------
// AI / Navigation
ControllerClass=class'KFAIController_ZedClot_Cyst'
PeripheralVision=-0.5f //180
DamageRecoveryTimeHeavy=0.85f
DamageRecoveryTimeMedium=1.0f
RotationRate=(Pitch=50000,Yaw=20000,Roll=50000)
KnockdownImpulseScale=1.0f
`if(`notdefined(ShippingPC))
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Underdeveloped';
`endif
}

View File

@ -662,4 +662,8 @@ DefaultProperties
MinSpawnSquadSizeType=EST_Medium
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -2033,4 +2033,8 @@ defaultproperties
ZEDCowboyHatAttachName=Hat_Attach
ShrinkEffectModifier = 0.15f
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here (here defaults to this same class)
MapReplacePawnClass.Add(class'KFPawn_ZedMatriarch')
}

View File

@ -2340,4 +2340,8 @@ defaultproperties
TickDialogInterval=0.5f
OnDeathAchievementID=KFACHID_QuickOnTheTrigger
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here (here defaults to this same class)
MapReplacePawnClass.Add(class'KFPawn_ZedPatriarch')
}

View File

@ -406,4 +406,8 @@ defaultproperties
OnDeathAchievementID=KFACHID_HackAndSlash
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -255,4 +255,8 @@ defaultproperties
OnDeathAchievementID=KFACHID_DeadSilence
ZEDCowboyHatAttachName=Hat_Attach
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -554,4 +554,8 @@ DefaultProperties
`if(`notdefined(ShippingPC))
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Stalker';
`endif
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
}

View File

@ -0,0 +1,23 @@
//=============================================================================
// KFProj_Bullet_MG3_Alt
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_MG3_Alt extends KFProj_Bullet
hidedropdown;
defaultproperties
{
MaxSpeed=22500.0
Speed=22500.0
DamageRadius=0
ProjFlightTemplate=ParticleSystem'WEP_MG3_EMIT.FX_MG3_Tracer_ZEDTime'
ImpactEffects=KFImpactEffectInfo'WEP_MG3_ARCH.MG3_ALT_impact'
}

View File

@ -256,7 +256,10 @@ static function bool IsValidPullClass(KFPawn PullPawn)
MonsterPawn = KFPawn_Monster(PullPawn);
if (PullPawn.class == class'KFPawn_ZedBloatKingSubspawn' || MonsterPawn != none && MonsterPawn.IsABoss())
if (PullPawn.class == class'KFPawn_ZedBloatKingSubspawn'
|| MonsterPawn != none && MonsterPawn.IsABoss()
|| PullPawn.class == class'KFPawn_HRG_Warthog'
|| PullPawn.class == class'KFPawn_AutoTurret')
{
return false;
}

View File

@ -0,0 +1,181 @@
//=============================================================================
// KFSeasonalEventStats_Fall2023
//=============================================================================
// Tracks event-specific challenges/accomplishments for Fall 2023
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Fall2023 extends KFSeasonalEventStats;
var transient private const int HansVolterKillsRequired, CollectiblesLimit, EndlessWaveRequired;
var transient string SavedMapName;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
SavedMapName = CapsMapName;
bObjectiveIsValidForMap[0] = 1; // Kill Hans Volter in 5 different maps
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Castle Volter
bObjectiveIsValidForMap[2] = 0; // Find ten Castle Volter's Collectibles
bObjectiveIsValidForMap[3] = 0; // Unlock the Castle Volter's trophy room
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Castle Volter
if (CapsMapName == "KF-CASTLEVOLTER")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(HansVolterKillsRequired, 0, CollectiblesLimit, 0, EndlessWaveRequired);
}
simulated event OnStatsInitialized()
{
super.OnStatsInitialized();
CheckRestartObjective(2, CollectiblesLimit);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
GrantEventItem(9754);
}
}
// Complete the Weekly on Castle Volter
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
local int ObjIdx;
ObjIdx = 1;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
CheckRestartObjective(2, CollectiblesLimit);
}
simulated event OnGameEnd(class<GameInfo> GameClass)
{
CheckRestartObjective(2, CollectiblesLimit);
}
// Complete wave 15 on Endless Hard or higher difficulty on Castle Volter
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
simulated function CheckRestartObjective(int ObjectiveIndex, int ObjectiveLimit)
{
local int StatValue;
StatValue = Outer.GetSeasonalEventStatValue(ObjectiveIndex);
if (StatValue != 0 && StatValue < ObjectiveLimit)
{
ResetSeasonalEventStat(ObjectiveIndex);
}
}
simulated function OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
{
local int ObjIdx;
ObjIdx=3;
if (bObjectiveIsValidForMap[ObjIdx] != 0 && EventIndex == SEI_Fall && ObjectiveIndex == ObjIdx)
{
FinishedObjective(EventIndex, ObjectiveIndex);
}
}
// Kill Hans Volter in 5 different maps
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
local KFProfileSettings Profile;
ObjIdx = 0;
if (Outer.IsEventObjectiveComplete(ObjIdx))
{
return;
}
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (MonsterClass == class'KFPawn_ZedHansBase'
|| MonsterClass == class'KFPawn_ZedHans')
{
if (Outer.GetSeasonalEventStatValue(ObjIdx) < HansVolterKillsRequired) // If we still didn't reach the limit..
{
Profile = KFProfileSettings(Outer.MyKFPC.OnlineSub.PlayerInterface.GetProfileSettings(Outer.MyKFPC.StoredLocalUserNum));
if(Profile != none)
{
if (Profile.AddHansVolterKilledInMap(SavedMapName))
{
//`Log("AddHansVolterKilledInMap : " $SavedMapName);
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= HansVolterKillsRequired)
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
}
}
}
}
// Find ten Castle Volter's Collectibles
simulated function OnCollectibleFound(int Limit)
{
local int ObjIdx;
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= CollectiblesLimit)
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
defaultproperties
{
HansVolterKillsRequired=5
CollectiblesLimit=10
EndlessWaveRequired=15
}

View File

@ -0,0 +1,109 @@
// KFWeapAttach_LMG_MG3
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2022 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_LMG_MG3 extends KFWeaponAttachment;
var transient byte CachedNumAltBullets;
var transient float CachedAltFireOffset;
event PreBeginPlay()
{
super.PreBeginPlay();
CachedNumAltBullets = class'KFWeap_LMG_MG3'.default.NumAltBullets;
CachedAltFireOffset = (class'KFWeap_LMG_MG3'.default.SpreadWidthDegrees * DegToRad) / (CachedNumAltBullets - 1);
}
/** Plays fire animation on weapon mesh */
simulated function PlayWeaponFireAnim()
{
local float Duration;
local float NewAnimRate;
// Increase Anim Rate so loop firing shows the ammo belt moving.
NewAnimRate = 2.0f;
if ( Instigator.bIsWalking )
{
Duration = WeapMesh.GetAnimLength( WeaponIronFireAnim );
WeapMesh.PlayAnim( WeaponIronFireAnim, Duration / NewAnimRate,, true );
}
else
{
Duration = WeapMesh.GetAnimLength( WeaponFireAnim );
WeapMesh.PlayAnim( WeaponFireAnim, Duration / NewAnimRate,, true );
}
}
/** Spawn tracer effects for this weapon */
simulated function SpawnTracer(vector EffectLocation, vector HitLocation)
{
local vector OriginalDir;
local vector UpVector, RightVector;
local KFTracerInfo TracerInfo;
local Quat R;
local byte i;
if ( Instigator == None || Instigator.FiringMode >= TracerInfos.Length )
{
return;
}
if (Instigator.FiringMode != 1 || Instigator.Controller != None)
{
Super.SpawnTracer(EffectLocation, HitLocation);
return;
}
TracerInfo = TracerInfos[Instigator.FiringMode];
if( ((`NotInZedTime(self) && TracerInfo.bDoTracerDuringNormalTime)
|| (`IsInZedTime(self) && TracerInfo.bDoTracerDuringZedTime))
&& TracerInfo.TracerTemplate != none )
{
// At least one matches the 1P
OriginalDir = HitLocation - EffectLocation;
SpawnTracerVFX(TracerInfo, OriginalDir, EffectLocation);
RightVector = vector(Rotation) cross vect(0,0,1);
UpVector = RightVector cross vector(Rotation);
for (i = 0; i < (CachedNumAltBullets - 1) / 2; ++i)
{
R = QuatFromAxisAndAngle(UpVector, CachedAltFireOffset * (i+1));
SpawnTracerVFX(TracerInfo, QuatRotateVector(R, OriginalDir), EffectLocation);
R = QuatFromAxisAndAngle(UpVector, -CachedAltFireOffset * (i+1));
SpawnTracerVFX(TracerInfo, QuatRotateVector(R, OriginalDir), EffectLocation);
}
}
}
simulated function SpawnTracerVFX(KFTracerInfo TracerInfo, vector Direction, vector EffectLocation)
{
local ParticleSystemComponent E;
local float DistSQ;
local float TracerDuration;
DistSQ = VSizeSq(Direction);
if ( DistSQ > TracerInfo.MinTracerEffectDistanceSquared )
{
// Lifetime scales based on the distance from the impact point. Subtract a frame so it doesn't clip.
TracerDuration = fMin( (Sqrt(DistSQ) - 100.f) / TracerInfo.TracerVelocity, 1.f );
if( TracerDuration > 0.f )
{
E = WorldInfo.MyEmitterPool.SpawnEmitter( TracerInfo.TracerTemplate, EffectLocation, rotator(Direction) );
E.SetVectorParameter( 'Tracer_Velocity', TracerInfo.VelocityVector );
E.SetFloatParameter( 'Tracer_Lifetime', TracerDuration );
}
}
}
defaultproperties
{
CachedNumAltBullets=0
CachedAltFireOffset=0
}

View File

@ -46,7 +46,7 @@ static simulated event EFilterTypeUI GetTraderFilter()
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Explosive;
return FT_Shotgun;
}
/** Instead of switch fire mode use as immediate alt fire */

View File

@ -9,6 +9,19 @@
class KFWeap_AssaultRifle_FNFal extends KFWeap_ScopedBase;
simulated state WeaponSingleFiring
{
simulated event EndState( Name NextStateName )
{
Super.EndState(NextStateName);
if (WorldInfo.NetMode == NM_Client && bAllowClientAmmoTracking && FireInterval[CurrentFireMode] <= MinFireIntervalToTriggerSync)
{
SyncCurrentAmmoCount(CurrentFireMode, AmmoCount[CurrentFireMode]);
}
}
}
defaultproperties
{
// Shooting Animations

View File

@ -44,6 +44,11 @@ simulated function AttachLaserSight()
}
}
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Assault;
}
defaultproperties
{
bHasFireLastAnims=true

View File

@ -10,7 +10,7 @@ class KFWeap_AssaultRifle_HRGIncendiaryRifle extends KFWeap_AssaultRifle_M16M203
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Rifle;
return FT_Assault;
}
static simulated event EFilterTypeUI GetAltTraderFilter()

View File

@ -971,8 +971,8 @@ defaultproperties
{
FlameSprayArchetype = SprayActor_Flame'WEP_Laser_Cutter_ARCH.WEP_Laser_Cutter_Flame'
ChargeTimePerLevel = 1.0f;
ChargeConsumeTime = 0.12f; //Consumes 25 on full charge
ChargeTimePerLevel = 0.7f;
ChargeConsumeTime = 0.082f; //Consumes 25 on full charge
OverchargeConsumeTime = 0; //Setting to 0 or below deactivates ammo consumption while holding a charge
// Shooting Animations
@ -1002,7 +1002,7 @@ defaultproperties
// Ammo
MagazineCapacity[0] = 50
SpareAmmoCapacity[0] = 300
SpareAmmoCapacity[0] = 450
InitialSpareMags[0] = 1
bCanBeReloaded = true
bReloadFromMagazine = true
@ -1039,7 +1039,7 @@ defaultproperties
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_LazerCutter'
FireInterval(DEFAULT_FIREMODE)=+0.0857 // 700 RPM
Spread(DEFAULT_FIREMODE)=0.015
InstantHitDamage(DEFAULT_FIREMODE)=50.0
InstantHitDamage(DEFAULT_FIREMODE)=55.0
FireOffset=(X=30,Y=4.5,Z=-5)
AmmoCost(DEFAULT_FIREMODE)=1
@ -1116,11 +1116,11 @@ defaultproperties
ChargingRotationSpeedLimit = 0.f;
ChargingMovementSpeedModifier = 1.f;
FiringRotationSpeedLimit(0)=420.f;
FiringRotationSpeedLimit(1)=240.f;
FiringRotationSpeedLimit(2)=180.f;
FiringRotationSpeedLimit(3)=120.f;
FiringMovementSpeedModifier=0.75f;
FiringRotationSpeedLimit(0)=900.f;
FiringRotationSpeedLimit(1)=800.f;
FiringRotationSpeedLimit(2)=700.f;
FiringRotationSpeedLimit(3)=600.f;
FiringMovementSpeedModifier=1f;
MaxRotationAdjustmentTime = 0.25f;
RotationAdjustmentCurve = { (Points = ((InVal = 0.000000,OutVal = 120.0f),

View File

@ -107,6 +107,7 @@ defaultproperties
AmmoCost(ALTFIRE_FIREMODE)=30
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
InstantHitDamage(ALTFIRE_FIREMODE)=5.0
// BASH_FIREMODE
InstantHitDamage(BASH_FIREMODE)=27

View File

@ -164,7 +164,7 @@ simulated function bool ShouldAutoReload(byte FireModeNum)
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Electric;
return FT_Flame;
}
defaultproperties

View File

@ -0,0 +1,119 @@
//=============================================================================
// KFWeap_HRG_93R
//=============================================================================
// An KFWeap_HRG_93R Pistol
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_93R extends KFWeap_PistolBase;
defaultproperties
{
// FOV
MeshFOV=96
MeshIronSightFOV=77
PlayerIronSightFOV=77
// Depth of field
DOF_FG_FocalRadius=40
DOF_FG_MaxNearBlurSize=3.5
// Zooming/Position
PlayerViewOffset=(X=12.0,Y=12,Z=-6)
// Content
PackageKey="HRG_93R_Pistol"
FirstPersonMeshName="wep_1p_hrg_93r_pistol_mesh.WEP_1P_HRG_93R_Pistol_Rig"
FirstPersonAnimSetNames(0)="wep_1p_hrg_93r_pistol_anim.Wep_1stP_9MM_Anim"
PickupMeshName="wep_3p_hrg_93r_pistol_mesh.Wep_3rdP_HRG_93R_Pistol_Pickup"
AttachmentArchetypeName="wep_hrg_93r_pistol_arch.Wep_HRG_93R_Pistol_3P"
MuzzleFlashTemplateName="wep_hrg_93r_pistol_arch.Wep_HRG_93R_Pistol_MuzzleFlash"
// Zooming/Position
IronSightPosition=(X=10,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=30
SpareAmmoCapacity[0]=240 //225
InitialSpareMags[0]=4
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=250
minRecoilPitch=200
maxRecoilYaw=100
minRecoilYaw=-100
RecoilRate=0.01
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=250
RecoilISMinPitchLimit=65485
// DEFAULT_FIREMODE
FiringStatesArray(DEFAULT_FIREMODE)=WeaponBurstFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Pistol9mm'
FireInterval(DEFAULT_FIREMODE)=+0.08 //0.175
InstantHitDamage(DEFAULT_FIREMODE)=12.f //15
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_93R'
Spread(DEFAULT_FIREMODE)=0.015
FireOffset=(X=20,Y=4.0,Z=-3)
BurstAmount=3
// ALT_FIREMODE
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_None
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_93R'
InstantHitDamage(BASH_FIREMODE)=20
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Handling_DryFire'
// Attachments
bHasIronSights=true
bHasFlashlight=true
AssociatedPerkClasses(0)=none
// Inventory
InventorySize=0
GroupPriority=13
bCanThrow=false
bDropOnDeath=false
WeaponSelectTexture=Texture2D'wep_ui_hrg_93r_pistol_tex.UI_WeaponSelect_HRG_93R'
bIsBackupWeapon=true
DualClass=class'KFWeap_HRG_93R_Dual'
// Custom animations
FireSightedAnims=(Shoot_Iron, Shoot_Iron2, Shoot_Iron3)
IdleFidgetAnims=(Guncheck_v1, Guncheck_v2, Guncheck_v3, Guncheck_v4)
bHasFireLastAnims=true
BonesToLockOnEmpty=(RW_Bolt, RW_Bullets1)
// Weapon Upgrade stat boosts. Setting weight to 0 because single 9MM cannot be sold.
//WeaponUpgrades[1]=(IncrementDamage=1.2f,IncrementWeight=0)
//WeaponUpgrades[2]=(IncrementDamage=1.4f,IncrementWeight=0) //1
//WeaponUpgrades[3]=(IncrementDamage=1.6f,IncrementWeight=0) //1
//WeaponUpgrades[4]=(IncrementDamage=1.8f,IncrementWeight=0) //2
//WeaponUpgrades[5]=(IncrementDamage=2.0f,IncrementWeight=0) //3
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.2f)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.4f)))
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.6f)))
WeaponUpgrades[4]=(Stats=((Stat=EWUS_Damage0, Scale=1.8f)))
WeaponUpgrades[5]=(Stats=((Stat=EWUS_Damage0, Scale=2.0f)))
}

View File

@ -0,0 +1,140 @@
//=============================================================================
// A set of KFWeap_HRG_93R Pistols
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_93R_Dual extends KFWeap_DualBase;
simulated state WeaponBurstFiring
{
simulated function BeginState(Name PrevStateName)
{
bFireFromRightWeapon = !bFireFromRightWeapon;
super.BeginState(PrevStateName);
}
}
defaultproperties
{
// Content
PackageKey="Dual_HRG_93R_Pistol"
FirstPersonMeshName="wep_1p_dual_hrg_93r_pistol_mesh.WEP_1P_HRG_93R_Dual_Pistol_Rig"
FirstPersonAnimSetNames(0)="wep_1p_dual_hrg_93r_pistol_anim.Wep_1stP_Dual_9MM_Anim"
PickupMeshName="wep_3p_dual_hrg_93r_pistol_mesh.Wep_Dual_HRG_93R_Pickup"
AttachmentArchetypeName="wep_dual_hrg_93r_pistol_arch.Wep_Dual_HRG_93R_Pistol_3P"
MuzzleFlashTemplateName="wep_dual_hrg_93r_pistol_arch.Wep_Dual_HRG_93R_Pistol_MuzzleFlash"
FireOffset=(X=17,Y=4.0,Z=-2.25)
LeftFireOffset=(X=17,Y=-4,Z=-2.25)
// Zooming/Position
IronSightPosition=(X=-3,Y=0,Z=0)
PlayerViewOffset=(X=5,Y=0,Z=-5)
QuickWeaponDownRotation=(Pitch=-8192,Yaw=0,Roll=0)
bCanThrow=true
bDropOnDeath=true
SingleClass=class'KFWeap_HRG_93R'
// FOV
MeshFOV=96
MeshIronSightFOV=77
PlayerIronSightFOV=77
// Depth of field
DOF_FG_FocalRadius=40
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=60 // twice as much as single
SpareAmmoCapacity[0]=240
InitialSpareMags[0]=3
AmmoPickupScale[0]=1.0
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=250
minRecoilPitch=200
maxRecoilYaw=100
minRecoilYaw=-100
RecoilRate=0.01
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=250
RecoilISMinPitchLimit=65485
// DEFAULT_FIREMODE
FiringStatesArray(DEFAULT_FIREMODE)=WeaponBurstFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Pistol9mm'
FireInterval(DEFAULT_FIREMODE)=+0.08
InstantHitDamage(DEFAULT_FIREMODE)=12.0 //15
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_93R'
Spread(DEFAULT_FIREMODE)=0.015
BurstAmount=3
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
// ALTFIRE_FIREMODE
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponBurstFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_Pistol9mm'
FireInterval(ALTFIRE_FIREMODE)=+0.08 // about twice as fast as single
InstantHitDamage(ALTFIRE_FIREMODE)=12.0 //15
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_93R'
Spread(ALTFIRE_FIREMODE)=0.015
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
// BASH_FIREMODE
InstantHitDamage(BASH_FIREMODE)=22
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_93R'
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Handling_DryFire'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Fire_1P')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_HRG_93R.Play_WEP_HRG_93R_Handling_DryFire'
// Attachments
bHasIronSights=true
bHasFlashlight=true
AssociatedPerkClasses(0)=none
// Inventory
InventoryGroup=IG_Secondary
InventorySize=2
GroupPriority=20
WeaponSelectTexture=Texture2D'wep_ui_dual_hrg_93r_pistol_tex.UI_WeaponSelect_Dual_HRG_93R'
bIsBackupWeapon=false
BonesToLockOnEmpty=(RW_Bolt, RW_Bullets1)
BonesToLockOnEmpty_L=(LW_Bolt, LW_Bullets1)
bHasFireLastAnims=true
// Weapon Upgrade stat boosts
//WeaponUpgrades[1]=(IncrementDamage=1.2f,IncrementWeight=0)
//WeaponUpgrades[2]=(IncrementDamage=1.4f,IncrementWeight=0) //1
//WeaponUpgrades[3]=(IncrementDamage=1.6f,IncrementWeight=0) //1
//WeaponUpgrades[4]=(IncrementDamage=1.8f,IncrementWeight=0) //2
//WeaponUpgrades[5]=(IncrementDamage=2.0f,IncrementWeight=0) //3
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.2f), (Stat=EWUS_Damage1, Scale=1.2f)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.4f), (Stat=EWUS_Damage1, Scale=1.4f)))
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.6f), (Stat=EWUS_Damage1, Scale=1.6f)))
WeaponUpgrades[4]=(Stats=((Stat=EWUS_Damage0, Scale=1.8f), (Stat=EWUS_Damage1, Scale=1.8f)))
WeaponUpgrades[5]=(Stats=((Stat=EWUS_Damage0, Scale=2.0f), (Stat=EWUS_Damage1, Scale=2.0f)))
}

View File

@ -414,7 +414,10 @@ function StartHealRecharge()
if (Role == ROLE_Authority)
{
InstigatorPerk = GetPerk();
UsedHealRechargeTime = HealFullRechargeSeconds * static.GetUpgradeHealRechargeMod(CurrentWeaponUpgradeIndex);
UsedHealRechargeTime = HealFullRechargeSeconds;
UsedHealRechargeTime *= static.GetUpgradeHealRechargeMod(CurrentWeaponUpgradeIndex);
UsedHealRechargeTime *= InstigatorPerk.GetHealRechargeMod();
InstigatorPerk.ModifyHealerRechargeTime(UsedHealRechargeTime);
// Set the healing recharge rate whenever we start charging
@ -1071,7 +1074,7 @@ defaultproperties
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
FireInterval(ALTFIRE_FIREMODE)=+0.175
InstantHitDamage(ALTFIRE_FIREMODE)=0 //Acidic compound skill can adjust that
InstantHitDamage(ALTFIRE_FIREMODE)=5
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
Spread(ALTFIRE_FIREMODE)=0.015
AmmoCost(ALTFIRE_FIREMODE)=40

View File

@ -299,7 +299,7 @@ simulated function IncrementChargeAndPlayAnimation()
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Explosive;
return FT_Projectile;
}
simulated function float GetForceReloadDelay()

View File

@ -316,7 +316,7 @@ simulated function bool ShouldAutoReload(byte FireModeNum)
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Electric;
return FT_Projectile;
}
@ -1372,4 +1372,6 @@ defaultproperties
BloodSplashClass=KFProj_BloodSplash
NumBloodStolenParticlesForPool = 15
bForceCrosshair=true
}

View File

@ -310,6 +310,12 @@ simulated function UpdateAmmoCounter()
WeaponMICs[3].SetScalarParameterValue('opacity', PercentageAmmo);
}
/** Returns trader filter index based on weapon type (copied from riflebase) */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Rifle;
}
defaultproperties
{
// FOV

View File

@ -148,7 +148,7 @@ simulated function SetPilotDynamicLightEnabled( bool bLightEnabled );
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Electric;
return FT_Flame;
}
defaultproperties

View File

@ -0,0 +1,491 @@
//=============================================================================
// KFWeap_LMG_MG3
//=============================================================================
// The MG3 rifle
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeap_LMG_MG3 extends KFWeap_RifleBase;
/** Alternate reload anims (when below the bullet belt threshold */
const ReloadLowAmmoAnim = 'Reload_Empty_Half';
const ReloadLowAmmoEliteAnim = 'Reload_Empty_Half_Elite';
const AltFireLoopAnim = 'ShootLoop_Secondary';
const AltFireLoopStartAnim = 'ShootLoop_Start_Secondary';
const AltFireLoopEndAnim = 'ShootLoop_End_Secondary';
/** Array of bone names corresponding to bullets in the ammo belt */
var protected const string AmmoBeltBulletBonePrefix;
/** Number of bullets in the ammo belt */
var protected const int NumAmmoBeltBullets;
/** How much ammo we had the last time we updated the ammo belt */
var transient protected int LastAmmoCount;
/** TRUE when set for the first time */
var transient protected bool bAmmoBeltInitialized;
/** Number of bullets fired (Alt firemode)) */
var byte NumAltBullets;
/** Degrees used in altfire */
var float SpreadWidthDegrees;
/** Max offset from shot in Y and X axes. */
var vector2d SpreadMaxOffset;
var transient float StartingAltBulletPosition;
/** Just in case we spawned in with an ammo count that's lower than the threshold */
simulated event ReplicatedEvent( name VarName )
{
super.ReplicatedEvent( VarName );
if( !bAmmoBeltInitialized )
{
UpdateAmmoBeltBullets();
}
}
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
Spread[ALTFIRE_FIREMODE] = SpreadWidthDegrees * DegToRad / (NumAltBullets - 1);
StartingAltBulletPosition = -SpreadWidthDegrees * DegToRad * 0.5f;
}
/** Just in case we spawned in with an ammo count that's lower than the threshold */
simulated event PostBeginPlay()
{
super.PostBeginPlay();
if( !bAmmoBeltInitialized && Role == ROLE_Authority )
{
UpdateAmmoBeltBullets();
}
}
/** Update ammo belt */
simulated function ConsumeAmmo( byte FireModeNum )
{
super.ConsumeAmmo( FireModeNum );
UpdateAmmoBeltBullets();
}
/** Update ammo belt */
simulated function PerformReload( optional byte FireModeNum )
{
super.PerformReload( FireModeNum );
UpdateAmmoBeltBullets();
}
/** Notify triggered by reload animations, when ammo belt is grabbed offscreen */
simulated function ANIMNOTIFY_RestoreAmmoBelt()
{
local int AmmoType, PendingAmmoCount;
AmmoType = GetAmmoType(0);
// This value will sync with the amount actually reloaded in PerformReload()
PendingAmmoCount = Min( AmmoCount[AmmoType] + SpareAmmoCount[AmmoType], MagazineCapacity[AmmoType] );
if( PendingAmmoCount < NumAmmoBeltBullets )
{
UpdateAmmoBeltBullets( PendingAmmoCount );
}
else
{
UpdateAmmoBeltBullets( , true );
}
}
/** Hides/shows bones on the weapon to simulate reaching the end of the ammo belt */
simulated function UpdateAmmoBeltBullets( optional int ForcedBulletCount=INDEX_NONE, optional bool bShowAll=false )
{
local Name BulletBoneName;
local int NumAmmo, i;
if( WorldInfo.NetMode == NM_DedicatedServer )
{
return;
}
// Don't do any bone alterations until the bone array has been filled out
if( MySkelMesh.LocalAtoms.Length == 0 )
{
// Check on the next frame to see if we can init our ammo belt
if( !IsTimerActive(nameOf(Timer_AttemptAmmoBeltUpdate)) )
{
SetTimer( 0.01f, false, nameOf(Timer_AttemptAmmoBeltUpdate) );
}
return;
}
// So we don't do this in PostInitAnimTree() or again in Timer_AttemptAmmoBeltUpdate() if we don't have to
bAmmoBeltInitialized = true;
// Don't do anything if ammo hasn't changed
NumAmmo = ForcedBulletCount != INDEX_NONE ? ForcedBulletCount : AmmoCount[GetAmmoType(0)];
if( !bShowAll && (LastAmmoCount == NumAmmo || (LastAmmoCount >= NumAmmoBeltBullets && NumAmmo >= NumAmmoBeltBullets)) )
{
return;
}
// Hide or unhide depending on place in array
for( i = 0; i < NumAmmoBeltBullets; ++i )
{
BulletBoneName = Name( AmmoBeltBulletBonePrefix $ (i+1) );
// Unhide all bullets if our ammo count is higher than the number of bullets
if( bShowAll || NumAmmo >= NumAmmoBeltBullets )
{
MySkelMesh.UnHideBoneByName( BulletBoneName );
continue;
}
if( i > NumAmmo-1 )
{
MySkelMesh.HideBoneByName( BulletBoneName, PBO_None );
}
else
{
MySkelMesh.UnHideBoneByName( BulletBoneName );
}
}
LastAmmoCount = NumAmmo;
}
simulated function Timer_AttemptAmmoBeltUpdate()
{
if( !bAmmoBeltInitialized )
{
UpdateAmmoBeltBullets();
}
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName( bool bTacticalReload )
{
if( AmmoCount[0] > 0 && AmmoCount[0] < NumAmmoBeltBullets )
{
// If we are below the threshold, play our low ammo reload
return bTacticalReload ? ReloadLowAmmoEliteAnim : ReloadLowAmmoAnim;
}
else
{
return super.GetReloadAnimName( bTacticalReload );
}
}
/**
* 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 event BeginState( Name PreviousStateName )
{
super.BeginState( PreviousStateName );
// Just in case a reload was interrupted after ANIMNOTIFY_RestoreAmmoBelt() was called,
// set the ammo belt to the current amount of bullets in the magazine on equip
UpdateAmmoBeltBullets();
}
}
simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
{
local int i;
local float InitialOffset;
if (CurrentFireMode != ALTFIRE_FIREMODE)
{
return Super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir);
}
InitialOffset = StartingAltBulletPosition;
for (i = 0; i < NumAltBullets; i++)
{
SpawnProjectile(KFProjClass, RealStartLoc, CalculateSpread(InitialOffset, Spread[ALTFIRE_FIREMODE], i));
}
return None;
}
simulated function vector CalculateSpread(float InitialOffset, float CurrentSpread, byte BulletNum)
{
local Vector X, Y, Z, POVLoc;
local Quat R;
local rotator POVRot;
local float RandValue;
if (Instigator != None && Instigator.Controller != none)
{
Instigator.Controller.GetPlayerViewPoint(POVLoc, POVRot);
}
GetAxes(POVRot, X, Y, Z);
// Calculate random offset on X axis
RandValue = FRand() * SpreadMaxOffset.X * DegToRad * (Rand(2) == 0 ? 1 : -1);
R = QuatFromAxisAndAngle(Z, InitialOffset + CurrentSpread * BulletNum + RandValue);
// Calculate random offset on Y axisº
RandValue = FRand() * SpreadMaxOffset.Y * DegToRad * (Rand(2) == 0 ? 1 : -1);
R = QuatProduct(R, QuatFromAxisAndAngle(Y, RandValue));
return QuatRotateVector(R, vector(POVRot));
}
simulated function StartFire(byte FireModeNum)
{
if (FireModeNum == DEFAULT_FIREMODE && bUseAltFireMode)
{
if (AmmoCount[FireModeNum] < AmmoCost[ALTFIRE_FIREMODE] && SpareAmmoCount[FireModeNum] > 0)
{
BeginFire(RELOAD_FIREMODE);
return;
}
}
super.StartFire(FireModeNum);
}
simulated function InstantFireClient()
{
local vector StartTrace, EndTrace;
local rotator AimRot;
local Array<ImpactInfo> ImpactList;
local int Idx;
local ImpactInfo RealImpact;
local float CurPenetrationValue;
// see Controller AimHelpDot() / AimingHelp()
bInstantHit = true;
// define range to use for CalcWeaponFire()
StartTrace = GetSafeStartTraceLocation();
AimRot = GetAdjustedAim(StartTrace);
EndTrace = StartTrace + vector(AimRot) * GetTraceRange();
bInstantHit = false;
// Initialize penetration power
PenetrationPowerRemaining = GetInitialPenetrationPower(CurrentFireMode);
CurPenetrationValue = PenetrationPowerRemaining;
if (bUseAltFireMode)
{
EndTrace = StartTrace + CalculateSpread(StartingAltBulletPosition, Spread[ALTFIRE_FIREMODE], 0) * GetTraceRange();
}
// Perform shot
RealImpact = CalcWeaponFire(StartTrace, EndTrace, ImpactList);
// Set flash location to trigger client side effects. Bypass Weapon.SetFlashLocation since
// that function is not marked as simulated and we want instant client feedback.
// ProjectileFire/IncrementFlashCount has the right idea:
// 1) Call IncrementFlashCount on Server & Local
// 2) Replicate FlashCount if ( !bNetOwner )
// 3) Call WeaponFired() once on local player
if( Instigator != None )
{
Instigator.SetFlashLocation( Self, CurrentFireMode, RealImpact.HitLocation );
}
// local player only for clientside hit detection
if ( Instigator != None && Instigator.IsLocallyControlled() )
{
// allow weapon to add extra bullet impacts (useful for shotguns)
InstantFireClient_AddImpacts(StartTrace, AimRot, ImpactList);
for (Idx = 0; Idx < ImpactList.Length; Idx++)
{
ProcessInstantHitEx(CurrentFireMode, ImpactList[Idx],, CurPenetrationValue, Idx);
}
if ( Instigator.Role < ROLE_Authority )
{
SendClientImpactList(CurrentFireMode, ImpactList);
}
}
}
simulated function InstantFireClient_AddImpacts(vector StartTrace, rotator Aim, out array<ImpactInfo> ImpactList)
{
local int i;
local ImpactInfo RealImpact;
if (!bUseAltFireMode)
{
return;
}
for (i = 1; i < NumAltBullets; ++i)
{
RealImpact = CalcWeaponFire(StartTrace, StartTrace + CalculateSpread(StartingAltBulletPosition, Spread[ALTFIRE_FIREMODE], i) * GetTraceRange(), ImpactList);
if( Instigator != None )
{
Instigator.SetFlashLocation( Self, CurrentFireMode, RealImpact.HitLocation );
}
}
}
/** Get name of the animation to play for PlayFireEffects */
simulated function name GetLoopingFireAnim(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE && !bUsingSights)
{
return AltFireLoopAnim;
}
return super.GetLoopingFireAnim(FireModeNum);
}
/** Get name of the animation to play for PlayFireEffects */
simulated function name GetLoopStartFireAnim(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE && !bUsingSights)
{
return AltFireLoopStartAnim;
}
return super.GetLoopStartFireAnim(FireModeNum);
}
/** Get name of the animation to play for PlayFireEffects */
simulated function name GetLoopEndFireAnim(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE && !bUsingSights)
{
return AltFireLoopEndAnim;
}
return super.GetLoopEndFireAnim(FireModeNum);
}
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="MG3"
FirstPersonMeshName="WEP_1P_MG3_MESH.Wep_1stP_MG3_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_MG3_ANIM.Wep_1stP_MG3_Anim"
PickupMeshName="WEP_3P_MG3_MESH.Wep_MG3_Pickup"
AttachmentArchetypeName="WEP_MG3_ARCH.Wep_MG3_3P"
MuzzleFlashTemplateName="WEP_MG3_ARCH.Wep_MG3_MuzzleFlash"
// Zooming/Position
PlayerViewOffset=(X=-5,Y=9,Z=-5) // (X=-8.5,Y=9,Z=-5)
IronSightPosition=(X=5,Y=0,Z=-5) // (X=8.5,Y=0,Z=-5)
// Ammo
MagazineCapacity[0]=75
SpareAmmoCapacity[0]=525
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=120
minRecoilPitch=70
maxRecoilYaw=130
minRecoilYaw=-130
RecoilRate=0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
RecoilViewRotationScale=0.25
IronSightMeshFOVCompensationScale=2.3
HippedRecoilModifier=1.5
// Inventory / Grouping
InventorySize=9
GroupPriority=100
WeaponSelectTexture=Texture2D'WEP_UI_MG3_TEX.UI_WeaponSelect_MG3'
AssociatedPerkClasses(0)=class'KFPerk_Commando'
// 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_MG3'
FireInterval(DEFAULT_FIREMODE)=+0.066 // 900 RPM
Spread(DEFAULT_FIREMODE)=0.0085
InstantHitDamage(DEFAULT_FIREMODE)=35.0
FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletBurst'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_MG3_Alt'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_MG3_Alt'
FireInterval(ALTFIRE_FIREMODE)=+0.132 // 900 RPM it was +0.066 originally
Spread(ALTFIRE_FIREMODE)=0.001
InstantHitDamage(ALTFIRE_FIREMODE)=15.0 // 30
AmmoCost(ALTFIRE_FIREMODE)=3
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_MG3'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_Fire_3P_Loop', FirstPersonCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_Fire_1P_Loop')
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_AltFire_3P_Single', FirstPersonCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_AltFire_1P_Single')
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_Fire_3P_EndLoop', FirstPersonCue=AkEvent'WW_WEP_MG3.Play_WEP_MG3_Fire_1P_EndLoop')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_L85A2.Play_WEP_SA_L85A2_Handling_DryFire'
WeaponDryFireSnd(ALTFIRE_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
bLoopingFireAnim(ALTFIRE_FIREMODE)=true
SingleFireSoundIndex=ALTFIRE_FIREMODE
// Attachments
bHasIronSights=true
bHasFlashlight=false
// Ammo belt
AmmoBeltBulletBonePrefix="RW_Bullets"
NumAmmoBeltBullets=14
LastAmmoCount=-1
NumAltBullets=5
SpreadWidthDegrees=30
StartingAltBulletPosition=0.0f
SpreadMaxOffset=(X=1.2f, Y=1.5f)
}

View File

@ -753,7 +753,7 @@ simulated function int GetChargeLevel()
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Flame;
return FT_Projectile;
}
static simulated function float CalculateTraderWeaponStatDamage()

View File

@ -9,11 +9,6 @@
class KFWeap_Pistol_DualHRGWinterbite extends KFWeap_DualBase;
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Flame;
}
defaultproperties
{
//Content

View File

@ -28,11 +28,16 @@ simulated function AltFireMode()
StartFire(ALTFIRE_FIREMODE);
}
static simulated event EFilterTypeUI GetAltTraderFilter()
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Pistol;
}
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Flame;
}
defaultproperties
{
ForceReloadTime=0.3f

View File

@ -9,11 +9,6 @@
class KFWeap_Pistol_HRGWinterbite extends KFWeap_PistolBase;
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Flame;
}
defaultproperties
{
// Content

View File

@ -112,6 +112,7 @@ defaultproperties
// ALTFIRE_FIREMODE
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
InstantHitDamage(ALTFIRE_FIREMODE)=5
// BASH_FIREMODE
InstantHitDamage(BASH_FIREMODE)=21

View File

@ -16,7 +16,12 @@ var int iNormalInstantHitDamage;
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Rifle;
return FT_Shotgun;
}
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Melee;
}
simulated event PreBeginPlay()

View File

@ -130,6 +130,7 @@ defaultproperties
AmmoCost(ALTFIRE_FIREMODE)=30
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
InstantHitDamage(ALTFIRE_FIREMODE)=5
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_Hemogoblin'

View File

@ -97,7 +97,7 @@ defaultproperties
AmmoCost(ALTFIRE_FIREMODE)=40
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
InstantHitDamage(ALTFIRE_FIREMODE)=5
// BASH_FIREMODE
InstantHitDamage(BASH_FIREMODE)=23.0

View File

@ -114,6 +114,7 @@ defaultproperties
AmmoCost(ALTFIRE_FIREMODE)=40
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HealingDart_MedicBase'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Dart_Toxic'
InstantHitDamage(ALTFIRE_FIREMODE)=5
// BASH_FIREMODE - Waiting on animations
InstantHitDamage(BASH_FIREMODE)=26.0

View File

@ -476,7 +476,7 @@ simulated function TriggerAltExplosion()
if (Role == ROLE_Authority)
{
MuzzleLocation = GetMuzzleLoc();
Trace( HitLocation, HitNormal, MuzzleLocation + vect(0, 0, -1) * 250000, MuzzleLocation);
Trace( HitLocation, HitNormal, MuzzleLocation + vect(0, 0, -1) * 250000, MuzzleLocation,,,,TRACEFLAG_BULLET);
// Move a bit from hit location
HitLocation = HitLocation + (vect(0,0,1) * 128.f);