upload
This commit is contained in:
parent
23d1ca3a9a
commit
2c6c4ddc5c
36
KFGame/Classes/KFDT_Toxic_HRG_Locust.uc
Normal file
36
KFGame/Classes/KFDT_Toxic_HRG_Locust.uc
Normal file
@ -0,0 +1,36 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust bullet impact
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Toxic_HRG_Locust extends KFDT_Bleeding
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage dealt when zeds touch each other and spread the afflictions
|
||||
var int SpreadOnTouchDamage;
|
||||
|
||||
static function int GetSpreadOnTouchDamage()
|
||||
{
|
||||
return default.SpreadOnTouchDamage;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
DoT_Type=DOT_Bleeding
|
||||
DoT_Duration=3.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.5
|
||||
|
||||
BleedPower = 20
|
||||
PoisonPower = 25
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
|
||||
SpreadOnTouchDamage=30
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
class KFGFXSpecialEventObjectivesContainer_Fall2022 extends KFGFxSpecialEventObjectivesContainer;
|
||||
|
||||
function Initialize(KFGFxObject_Menu NewParentMenu)
|
||||
{
|
||||
super.Initialize(NewParentMenu);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
ObjectiveIconURLs[0] = "Halloween2022_UI.UI_Objectives_Halloween2022_CreaturesInDarkness" // Kill 15 Bosses on any map or mode
|
||||
ObjectiveIconURLs[1] = "Spring_UI.UI_Objectives_Spring_Weekly" // Complete the Weekly on BarmwichTown
|
||||
ObjectiveIconURLs[2] = "Halloween2022_UI.UI_Objetives_Halloween2022_ElementalMedallions" // Open the Weapon Room
|
||||
ObjectiveIconURLs[3] = "Halloween2022_UI.UI_Objectives_Halloween2022_ZedOnFire" // Make 50 Zeds to pass through the bonfires of Barmwitch Town
|
||||
ObjectiveIconURLs[4] = "Halloween2022_UI.UI_Objetives_Halloween2022_LongNightofWitches" // Complete wave 15 on Endless Hard or higher difficulty on Barmwitch Town
|
||||
|
||||
//defaults
|
||||
AllCompleteRewardIconURL="CHR_PlagueDoctorUniform_Item_TEX.potionbackpack.plaguedoctorbackpack_precious_large"
|
||||
ChanceDropIconURLs[0]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket"
|
||||
ChanceDropIconURLs[1]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket_golden"
|
||||
IconURL="halloween2022_ui.KF2_Halloween_BloodandBonfires_SmallLogo"
|
||||
|
||||
UsesProgressList[0] = true
|
||||
UsesProgressList[1] = false
|
||||
UsesProgressList[2] = false
|
||||
UsesProgressList[3] = true
|
||||
UsesProgressList[4] = false
|
||||
}
|
49
KFGame/Classes/KFGFxWidget_VIP.uc
Normal file
49
KFGame/Classes/KFGFxWidget_VIP.uc
Normal file
@ -0,0 +1,49 @@
|
||||
//=============================================================================
|
||||
// KFGFxWidget_VIP
|
||||
//=============================================================================
|
||||
// HUD Widget that displays VIP messages to the player
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFGFxWidget_VIP extends GFxObject;
|
||||
|
||||
function SetVIP()
|
||||
{
|
||||
SetString("VIPSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPString);
|
||||
SetString("VIPObjectiveSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveBString);
|
||||
SetString("VIPPlayerSet", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveCString);
|
||||
|
||||
SetBool("VIPPlayerNameSetVisibility", true);
|
||||
SetBool("VIPHideHealthBar", true);
|
||||
}
|
||||
|
||||
function SetNOVIP(string VIPPlayerName, int VIPCurrentHealth, int VIPMaxHealth)
|
||||
{
|
||||
SetString("VIPSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPString);
|
||||
SetString("VIPObjectiveSetLocalised", Class'KFCommon_LocalizedStrings'.default.VIPObjectiveAString);
|
||||
SetString("VIPPlayerSet", VIPPlayerName);
|
||||
|
||||
SetBool("VIPPlayerNameSetVisibility", true);
|
||||
|
||||
UpdateHealth(VIPCurrentHealth, VIPMaxHealth);
|
||||
}
|
||||
|
||||
function UpdateVIPVisibility(bool visible)
|
||||
{
|
||||
if (visible)
|
||||
{
|
||||
SetBool("VIPSetVisibility", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBool("VIPSetVisibility", false);
|
||||
}
|
||||
}
|
||||
|
||||
function UpdateHealth(int VIPCurrentHealth, int VIPMaxHealth)
|
||||
{
|
||||
SetFloat("VIPHealthBarPercentage", VIPMaxHealth != 0 ? (float(VIPCurrentHealth) / VIPMaxHealth) : 0.0f);
|
||||
}
|
29
KFGame/Classes/KFWeapDef_G36C.uc
Normal file
29
KFGame/Classes/KFWeapDef_G36C.uc
Normal file
@ -0,0 +1,29 @@
|
||||
//=============================================================================
|
||||
// KFWeaponDefintion
|
||||
//=============================================================================
|
||||
// A lightweight container for basic weapon properties that can be safely
|
||||
// accessed without a weapon actor (UI, remote clients).
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_G36C extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_G36C"
|
||||
|
||||
BuyPrice=1600
|
||||
AmmoPricePerMag=36
|
||||
ImagePath="wep_ui_g36c_tex.UI_WeaponSelect_G36C"
|
||||
|
||||
EffectiveRange=70
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
|
||||
SharedUnlockId=SCU_G36C
|
||||
|
||||
}
|
24
KFGame/Classes/KFWeapDef_HRG_Dragonbreath.uc
Normal file
24
KFGame/Classes/KFWeapDef_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,24 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_Dragonbreath
|
||||
// This is the Doomstick
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2017 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_Dragonbreath extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_Dragonbreath"
|
||||
|
||||
BuyPrice=1400
|
||||
AmmoPricePerMag=25
|
||||
ImagePath="WEP_UI_HRG_MegaDragonsbreath_TEX.UI_WeaponSelect_HRG_MegaDragonsbreath"
|
||||
|
||||
EffectiveRange=25
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
}
|
28
KFGame/Classes/KFWeapDef_HRG_Locust.uc
Normal file
28
KFGame/Classes/KFWeapDef_HRG_Locust.uc
Normal file
@ -0,0 +1,28 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_HRG_Locust
|
||||
//=============================================================================
|
||||
// A lightweight container for basic weapon properties that can be safely
|
||||
// accessed without a weapon actor (UI, remote clients).
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_Locust extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_Locust"
|
||||
|
||||
BuyPrice=900
|
||||
AmmoPricePerMag=40
|
||||
ImagePath="wep_ui_hrg_locust_tex.UI_WeaponSelect_HRG_Locust"
|
||||
|
||||
EffectiveRange=100
|
||||
|
||||
UpgradePrice[0]=700
|
||||
UpgradePrice[1]=1500
|
||||
|
||||
UpgradeSellPrice[0]=525
|
||||
UpgradeSellPrice[1]=1650
|
||||
}
|
26
KFGame/Classes/KFWeapDef_Scythe.uc
Normal file
26
KFGame/Classes/KFWeapDef_Scythe.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_Scythe
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_Scythe extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_Edged_Scythe"
|
||||
|
||||
BuyPrice=1500
|
||||
ImagePath="WEP_UI_Scythe_TEX.UI_WeaponSelect_Scythe"
|
||||
|
||||
EffectiveRange=5
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
|
||||
SharedUnlockId=SCU_Scythe
|
||||
|
||||
}
|
77
KFGameContent/Classes/KFBarmwichBonfireVolume.uc
Normal file
77
KFGameContent/Classes/KFBarmwichBonfireVolume.uc
Normal file
@ -0,0 +1,77 @@
|
||||
//=============================================================================
|
||||
// KFBarmwichBonfireVolume
|
||||
//=============================================================================
|
||||
// Barmwich volume used for bonfires. Triggers seasonal progression.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFBarmwichBonfireVolume extends KFPhysicsDamageByPawnVolume
|
||||
placeable;
|
||||
|
||||
/** Objective index for the event this is tied to */
|
||||
var() int ObjectiveIndex;
|
||||
|
||||
/** Index of the event this is tied to */
|
||||
var() int EventIndex;
|
||||
|
||||
var array<Actor> AffectedActors;
|
||||
|
||||
var transient bool bIsDataValid;
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
bIsDataValid = IsObjectiveDataValid();
|
||||
}
|
||||
|
||||
function CausePainTo(Actor Other)
|
||||
{
|
||||
Super.CausePainTo(Other);
|
||||
|
||||
if (bIsDataValid && KFPawn_Monster(Other) != none && KFPawn_Monster(Other).IsAliveAndWell())
|
||||
{
|
||||
if (AffectedActors.Find(Other) == INDEX_NONE)
|
||||
{
|
||||
AffectedActors.AddItem(Other);
|
||||
NotifyProgression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function NotifyProgression()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
if (!bIsDataValid)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
|
||||
{
|
||||
KFPC.ClientOnTryCompleteObjective(ObjectiveIndex, EventIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function ClearAllActors()
|
||||
{
|
||||
AffectedActors.Remove(0, AffectedActors.Length);
|
||||
}
|
||||
|
||||
function ClearActor(Actor Other)
|
||||
{
|
||||
AffectedActors.RemoveItem(Other);
|
||||
}
|
||||
|
||||
simulated function bool IsObjectiveDataValid()
|
||||
{
|
||||
return ObjectiveIndex >= 0 && ObjectiveIndex < 5 && EventIndex > SEI_None && EventIndex < SEI_MAX;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
bIsDataValid = false;
|
||||
}
|
87
KFGameContent/Classes/KFDT_Ballistic_G36C.uc
Normal file
87
KFGameContent/Classes/KFDT_Ballistic_G36C.uc
Normal file
@ -0,0 +1,87 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_G36C
|
||||
//=============================================================================
|
||||
// Class Description
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_G36C extends KFDT_Ballistic_AssaultRifle
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** G36C has still to play a metal effect if impacting metal. (and we demoted to impact on Flesh) */
|
||||
var ParticleSystem MetalImpactEffect;
|
||||
var AkEvent MetalImpactSound;
|
||||
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
local KFSkinTypeEffects SkinType, OriginalSkinType, FleshSkinType;
|
||||
local int i;
|
||||
|
||||
if ( P.CharacterArch != None && default.EffectGroup < FXG_Max )
|
||||
{
|
||||
// Search if affected target has Flesh skin type
|
||||
for (i = 0; i < P.CharacterArch.ImpactSkins.Length ; ++i)
|
||||
{
|
||||
if (P.CharacterArch.ImpactSkins[i].Name == 'Flesh'
|
||||
|| P.CharacterArch.ImpactSkins[i].Name == 'Tough_Flesh')
|
||||
{
|
||||
FleshSkinType = P.CharacterArch.ImpactSkins[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SkinType = P.GetHitZoneSkinTypeEffects( HitZoneIndex );
|
||||
OriginalSkinType = SkinType;
|
||||
|
||||
// If we don't hit flesh or shield, try to demote to Flesh
|
||||
if (SkinType != none && SkinType.Name != 'Flesh' && SkinType.Name != 'Tough_Flesh' && SkinType.Name != 'ShieldEffects')
|
||||
{
|
||||
// We default to none as we don't want bullet to ricochet if any
|
||||
SkinType = none;
|
||||
|
||||
// Demote to flesh skin hit
|
||||
if (FleshSkinType != none)
|
||||
{
|
||||
SkinType = FleshSkinType;
|
||||
}
|
||||
}
|
||||
|
||||
// If we hit metal we have to make sure we play it's Metal impact effect (this effect doesn't contain bullet ricochet) (don't play sound though!)
|
||||
if (OriginalSkinType != none && (OriginalSkinType.Name == 'Metal' || OriginalSkinType.Name == 'Machine'))
|
||||
{
|
||||
OriginalSkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup, default.MetalImpactEffect);
|
||||
OriginalSkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup, default.MetalImpactSound);
|
||||
}
|
||||
|
||||
if (SkinType != none)
|
||||
{
|
||||
SkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup);
|
||||
SkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-300
|
||||
KDeathVel=100
|
||||
|
||||
DamageModifierAP=0.8f
|
||||
ArmorDamageModifier=15.0f
|
||||
|
||||
StumblePower=15
|
||||
GunHitPower=15
|
||||
|
||||
WeaponDef=class'KFWeapDef_G36C'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Swat'
|
||||
|
||||
MetalImpactEffect=ParticleSystem'FX_Impacts_EMIT.FX_Wep_Impact_MetalArmor_E'
|
||||
MetalImpactSound=AkEvent'WW_Skin_Impacts.Play_Slashing_Metal_3P'
|
||||
}
|
82
KFGameContent/Classes/KFDT_Ballistic_HRG_Dragonbreath.uc
Normal file
82
KFGameContent/Classes/KFDT_Ballistic_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,82 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_HRG_Dragonbreath extends KFDT_Ballistic_Shotgun
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the burning damage over time
|
||||
var class<KFDamageType> BurnDamageType;
|
||||
|
||||
/** 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;
|
||||
}
|
||||
|
||||
/** Play damage type specific impact effects when taking damage */
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
// Play burn effect when dead
|
||||
if( P.bPlayedDeath && P.WorldInfo.TimeSeconds > P.TimeOfDeath )
|
||||
{
|
||||
default.BurnDamageType.static.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
|
||||
return;
|
||||
}
|
||||
|
||||
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
|
||||
}
|
||||
|
||||
/** 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
|
||||
{
|
||||
GoreDamageGroup=DGT_Shotgun
|
||||
BloodSpread=0.4
|
||||
BloodScale=0.6
|
||||
|
||||
KDamageImpulse=3500
|
||||
KDeathUpKick=800
|
||||
KDeathVel=650
|
||||
GibImpulseScale=1.0
|
||||
|
||||
BurnPower=40
|
||||
StumblePower=40
|
||||
GunHitPower=50
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
|
||||
BurnDamageType=class'KFDT_Fire_HRG_DragonsBreathDoT'
|
||||
|
||||
EffectGroup=FXG_IncendiaryRound
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Firebug'
|
||||
}
|
18
KFGameContent/Classes/KFDT_Ballistic_HRG_Locust.uc
Normal file
18
KFGameContent/Classes/KFDT_Ballistic_HRG_Locust.uc
Normal file
@ -0,0 +1,18 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust bullet impact
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Ballistic_HRG_Locust extends KFDamageType
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_G36C.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_G36C.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_G36C
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_G36C extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_G36C'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_Dragonbreath.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2017 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HRG_Dragonbreath extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_Dragonbreath'
|
||||
}
|
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_Locust.uc
Normal file
15
KFGameContent/Classes/KFDT_Bludgeon_HRG_Locust.uc
Normal file
@ -0,0 +1,15 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Bludgeon_HRG_Locust extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
}
|
40
KFGameContent/Classes/KFDT_Explosive_HRG_Locust.uc
Normal file
40
KFGameContent/Classes/KFDT_Explosive_HRG_Locust.uc
Normal file
@ -0,0 +1,40 @@
|
||||
//=============================================================================
|
||||
// KFDT_Explosive_HRG_Locust
|
||||
//=============================================================================
|
||||
// Explosive damage type for the HRG Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Explosive_HRG_Locust extends KFDT_Explosive
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
// Damage type to use for the damage over time effect
|
||||
var class<KFDamageType> DoTDamageType;
|
||||
|
||||
/** 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)
|
||||
{
|
||||
if (Victim.Controller == InstigatedBy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (default.DoTDamageType.default.DoT_Type != DOT_None)
|
||||
{
|
||||
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.DoTDamageType);
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Survivalist'
|
||||
WeaponDef=class'KFWeapDef_HRG_Locust'
|
||||
|
||||
DoTDamageType=class'KFDT_Toxic_HRG_Locust'
|
||||
|
||||
bCausesFracture=false
|
||||
bCanPlayDeadHitEffects=false
|
||||
}
|
39
KFGameContent/Classes/KFDT_Fire_Ground_HRG_DragonBreath.uc
Normal file
39
KFGameContent/Classes/KFDT_Fire_Ground_HRG_DragonBreath.uc
Normal file
@ -0,0 +1,39 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_Ground_HRG_DragonBreath
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by a HRG dragon breath ground fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_Ground_HRG_DragonBreath extends KFDT_Fire_Ground
|
||||
abstract;
|
||||
|
||||
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_HRG_Dragonbreath'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=2.7
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.7
|
||||
|
||||
BurnPower=10
|
||||
}
|
||||
|
41
KFGameContent/Classes/KFDT_Fire_HRG_DragonsBreathDoT.uc
Normal file
41
KFGameContent/Classes/KFDT_Fire_HRG_DragonsBreathDoT.uc
Normal file
@ -0,0 +1,41 @@
|
||||
//=============================================================================
|
||||
// KFDT_Fire_HRG_DragonsBreathDoT
|
||||
//=============================================================================
|
||||
// Damage caused by burning from being hit by an HRG dragon's breath round
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Fire_HRG_DragonsBreathDoT 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_HRG_Dragonbreath'
|
||||
|
||||
DoT_Type=DOT_Fire
|
||||
DoT_Duration=2.7 //5.0 //1.0
|
||||
DoT_Interval=0.5
|
||||
DoT_DamageScale=0.7 //1.0
|
||||
|
||||
BurnPower=10 //1.0 //18.5
|
||||
}
|
||||
|
23
KFGameContent/Classes/KFDT_Piercing_ScytheStab.uc
Normal file
23
KFGameContent/Classes/KFDT_Piercing_ScytheStab.uc
Normal file
@ -0,0 +1,23 @@
|
||||
//=============================================================================
|
||||
// KFDT_Piercing_ScytheStab
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Piercing_ScytheStab extends KFDT_Piercing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=200
|
||||
KDeathUpKick=250
|
||||
|
||||
StumblePower=50
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
23
KFGameContent/Classes/KFDT_Piercing_ScytheStabFolded.uc
Normal file
23
KFGameContent/Classes/KFDT_Piercing_ScytheStabFolded.uc
Normal file
@ -0,0 +1,23 @@
|
||||
//=============================================================================
|
||||
// KFDT_Piercing_ScytheStabFolded
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Piercing_ScytheStabFolded extends KFDT_Piercing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=200
|
||||
KDeathUpKick=250
|
||||
|
||||
StumblePower=50
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
140
KFGameContent/Classes/KFDT_Slashing_ScytheLong.uc
Normal file
140
KFGameContent/Classes/KFDT_Slashing_ScytheLong.uc
Normal file
@ -0,0 +1,140 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheLong
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheLong extends KFDT_Slashing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
|
||||
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
local KFCharacterInfo_Monster MonsterInfo;
|
||||
|
||||
MonsterInfo = InPawn.GetCharacterMonsterInfo();
|
||||
if ( MonsterInfo == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Randomly pick the left or right shoulder bone and split the guy in half vertically
|
||||
OutBoneName = Rand(2) == 0
|
||||
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
|
||||
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
|
||||
{
|
||||
// Split the guy in half horizontally
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
// ... and choose one of the shoulder constraints at random
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows the damage type to modify the impulse when a specified hit zone is dismembered */
|
||||
static simulated function ModifyDismembermentHitImpulse(KFPawn_Monster InPawn, name InHitZoneName, vector HitDirection,
|
||||
out vector OutImpulseDir, out vector OutParentImpulseDir,
|
||||
out float OutImpulseScale, out float OutParentImpulseScale)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
// Apply upward impulse on decapitation from a clean horizontal slash
|
||||
if( InHitZoneName == 'head' &&
|
||||
( SlashDir == DIR_Left || SlashDir == DIR_Right ) )
|
||||
{
|
||||
OutImpulseDir += 10*vect(0,0,1);
|
||||
OutImpulseDir = Normal(OutImpulseDir);
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
// Do not apply any impulse on split in half from a vertical slash
|
||||
else if( (InHitZoneName == 'head' || InHitZoneName == 'chest' ) &&
|
||||
( SlashDir == DIR_Forward || SlashDir == DIR_Backward) )
|
||||
{
|
||||
OutImpulseScale = 0.f;
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=10000 //1500
|
||||
KDeathUpKick=2000 //200
|
||||
KDeathVel=3750 //375
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=100
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
38
KFGameContent/Classes/KFDT_Slashing_ScytheLongAlt.uc
Normal file
38
KFGameContent/Classes/KFDT_Slashing_ScytheLongAlt.uc
Normal file
@ -0,0 +1,38 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheLongAlt
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheLongAlt extends KFDT_Slashing_ZweihanderHeavy
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3600 //1600
|
||||
KDeathUpKick=400 //200
|
||||
KDeathVel=750 //500
|
||||
|
||||
KnockdownPower=50
|
||||
StunPower=0
|
||||
StumblePower=200
|
||||
MeleeHitPower=100
|
||||
|
||||
// Obliteration
|
||||
GoreDamageGroup = DGT_Explosive
|
||||
RadialDamageImpulse = 8000.f // This controls how much impulse is applied to gibs when exploding
|
||||
bUseHitLocationForGibImpulses = true // This will make the impulse origin where the victim was hit for directional gibs
|
||||
bPointImpulseTowardsOrigin = true // This creates an impulse direction aligned along hitlocation and pawn location -- this will push all gibs in the same direction
|
||||
ImpulseOriginScale = 100.f // Higher means more directional gibbing, lower means more outward (and upward) gibbing
|
||||
ImpulseOriginLift = 150.f
|
||||
MaxObliterationGibs = 12 // Maximum number of gibs that can be spawned by obliteration, 0=MAX
|
||||
bCanGib = true
|
||||
bCanObliterate = true
|
||||
ObliterationHealthThreshold = 0
|
||||
ObliterationDamageThreshold = 100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
140
KFGameContent/Classes/KFDT_Slashing_ScytheShort.uc
Normal file
140
KFGameContent/Classes/KFDT_Slashing_ScytheShort.uc
Normal file
@ -0,0 +1,140 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheShort
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheShort extends KFDT_Slashing
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
/** Allows the damage type to customize exactly which hit zones it can dismember */
|
||||
static simulated function bool CanDismemberHitZone( name InHitZoneName )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
|
||||
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
local KFCharacterInfo_Monster MonsterInfo;
|
||||
|
||||
MonsterInfo = InPawn.GetCharacterMonsterInfo();
|
||||
if ( MonsterInfo == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Randomly pick the left or right shoulder bone and split the guy in half vertically
|
||||
OutBoneName = Rand(2) == 0
|
||||
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
|
||||
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
|
||||
{
|
||||
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
|
||||
{
|
||||
// Split the guy in half horizontally
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
// ... and choose one of the shoulder constraints at random
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
|
||||
{
|
||||
if( InHitZoneName == 'chest' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
else if( InHitZoneName == 'head' )
|
||||
{
|
||||
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
|
||||
{
|
||||
// Use a random chance to decide whether to dismember the head or the shoulder constraints
|
||||
if( Rand(2) == 0 )
|
||||
{
|
||||
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows the damage type to modify the impulse when a specified hit zone is dismembered */
|
||||
static simulated function ModifyDismembermentHitImpulse(KFPawn_Monster InPawn, name InHitZoneName, vector HitDirection,
|
||||
out vector OutImpulseDir, out vector OutParentImpulseDir,
|
||||
out float OutImpulseScale, out float OutParentImpulseScale)
|
||||
{
|
||||
local EPawnOctant SlashDir;
|
||||
|
||||
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
|
||||
|
||||
// Apply upward impulse on decapitation from a clean horizontal slash
|
||||
if( InHitZoneName == 'head' &&
|
||||
( SlashDir == DIR_Left || SlashDir == DIR_Right ) )
|
||||
{
|
||||
OutImpulseDir += 10*vect(0,0,1);
|
||||
OutImpulseDir = Normal(OutImpulseDir);
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
// Do not apply any impulse on split in half from a vertical slash
|
||||
else if( (InHitZoneName == 'head' || InHitZoneName == 'chest' ) &&
|
||||
( SlashDir == DIR_Forward || SlashDir == DIR_Backward) )
|
||||
{
|
||||
OutImpulseScale = 0.f;
|
||||
OutParentImpulseScale = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=10000 //1500
|
||||
KDeathUpKick=2000 //200
|
||||
KDeathVel=3750 //375
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=50
|
||||
MeleeHitPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
38
KFGameContent/Classes/KFDT_Slashing_ScytheShortAlt.uc
Normal file
38
KFGameContent/Classes/KFDT_Slashing_ScytheShortAlt.uc
Normal file
@ -0,0 +1,38 @@
|
||||
//=============================================================================
|
||||
// KFDT_Slashing_ScytheShortAlt
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Slashing_ScytheShortAlt extends KFDT_Slashing_ZweihanderHeavy
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3600 //1600
|
||||
KDeathUpKick=400 //200
|
||||
KDeathVel=750 //500
|
||||
|
||||
KnockdownPower=0
|
||||
StunPower=0
|
||||
StumblePower=150
|
||||
MeleeHitPower=100
|
||||
|
||||
// Obliteration
|
||||
GoreDamageGroup = DGT_Explosive
|
||||
RadialDamageImpulse = 8000.f // This controls how much impulse is applied to gibs when exploding
|
||||
bUseHitLocationForGibImpulses = true // This will make the impulse origin where the victim was hit for directional gibs
|
||||
bPointImpulseTowardsOrigin = true // This creates an impulse direction aligned along hitlocation and pawn location -- this will push all gibs in the same direction
|
||||
ImpulseOriginScale = 100.f // Higher means more directional gibbing, lower means more outward (and upward) gibbing
|
||||
ImpulseOriginLift = 150.f
|
||||
MaxObliterationGibs = 12 // Maximum number of gibs that can be spawned by obliteration, 0=MAX
|
||||
bCanGib = true
|
||||
bCanObliterate = true
|
||||
ObliterationHealthThreshold = 0
|
||||
ObliterationDamageThreshold = 100
|
||||
|
||||
WeaponDef=class'KFWeapDef_Scythe'
|
||||
ModifierPerkList(0)=class'KFPerk_Berserker'
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_Dragonbreath_GroundFire
|
||||
//=============================================================================
|
||||
// Explosion actor class for ground fire
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_Dragonbreath_GroundFire extends KFExplosionActorLingering;
|
||||
|
||||
|
||||
simulated function SpawnExplosionParticleSystem(ParticleSystem Template)
|
||||
{
|
||||
// If the template is none, grab the default
|
||||
if( !ExplosionTemplate.bAllowPerMaterialFX && Template == none )
|
||||
{
|
||||
Template = KFGameExplosion(ExplosionTemplate).ExplosionEffects.DefaultImpactEffect.ParticleTemplate;
|
||||
}
|
||||
|
||||
// Use custom pool
|
||||
WorldInfo.GroundFireEmitterPool.SpawnEmitter(Template, Location, rotator(ExplosionTemplate.HitNormal), None);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//Interval=0.25f INTERVAL IS OVERRIDDEN BY ITS PROJECTILE
|
||||
MaxTime=2.0
|
||||
|
||||
ExplosionLightPriority=LPP_Low
|
||||
LoopStartEvent=AkEvent'ww_wep_hrg_megadragonbreath.Play_WEP_HRG_MegaDragonbreath_Flame_LP'
|
||||
LoopStopEvent=AkEvent'ww_wep_hrg_megadragonbreath.Stop_WEP_HRG_MegaDragonbreath_End_Flame_LP'
|
||||
}
|
22
KFGameContent/Classes/KFExplosion_HRG_Locust.uc
Normal file
22
KFGameContent/Classes/KFExplosion_HRG_Locust.uc
Normal file
@ -0,0 +1,22 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_Locust
|
||||
//=============================================================================
|
||||
// Explosion actor class for HRG Locust
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_Locust extends KFExplosionActorLingering;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
Interval=0.5f
|
||||
MaxTime=3.0
|
||||
|
||||
bOnlyDamagePawns=true
|
||||
bDoFullDamage=false
|
||||
|
||||
LoopStartEvent=AkEvent'WW_WEP_HRG_Locust.Play_WEP_HRG_Locust_Insects'
|
||||
LoopStopEvent=AkEvent'WW_WEP_HRG_Locust.Stop_WEP_HRG_Locust_Insect'
|
||||
}
|
25
KFGameContent/Classes/KFProj_HRG_Dragonbreath_Splash.uc
Normal file
25
KFGameContent/Classes/KFProj_HRG_Dragonbreath_Splash.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// KFProj_HRG_DragonBreath_Splash
|
||||
//=============================================================================
|
||||
// Projectile class for hrg dragonbreath gun splash. Handles a few overrides.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_HRG_DragonBreath_Splash extends KFProj_FlareGunSplash;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
PostExplosionLifetime=2.5
|
||||
ExplosionActorClass=class'KFExplosion_HRG_Dragonbreath_GroundFire'
|
||||
|
||||
Begin Object Name=ExploTemplate0
|
||||
Damage=8
|
||||
DamageRadius=150.0
|
||||
MyDamageType=class'KFDT_Fire_Ground_HRG_DragonBreath'
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_Flamethrower_ARCH.GroundFire_Impacts'
|
||||
End Object
|
||||
|
||||
AssociatedPerkClass=none
|
||||
}
|
171
KFGameContent/Classes/KFProj_HRG_Locust.uc
Normal file
171
KFGameContent/Classes/KFProj_HRG_Locust.uc
Normal file
@ -0,0 +1,171 @@
|
||||
//=============================================================================
|
||||
// KFProj_HRG_Locust
|
||||
//=============================================================================
|
||||
// HRG Locust projectile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
class KFProj_HRG_Locust extends KFProj_BallisticExplosive
|
||||
hidedropdown;
|
||||
|
||||
/** Our intended target actor */
|
||||
var private KFPawn LockedTarget;
|
||||
|
||||
/** How much 'stickyness' when seeking toward our target. Determines how accurate rocket is */
|
||||
var const float SeekStrength;
|
||||
|
||||
replication
|
||||
{
|
||||
if( bNetInitial )
|
||||
LockedTarget;
|
||||
}
|
||||
|
||||
function SetLockedTarget( KFPawn NewTarget )
|
||||
{
|
||||
LockedTarget = NewTarget;
|
||||
}
|
||||
|
||||
simulated function bool AllowNuke()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistConcussive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistExplosionChangeRadius()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated event Tick( float DeltaTime )
|
||||
{
|
||||
local vector TargetImpactPos, DirToTarget;
|
||||
|
||||
super.Tick( DeltaTime );
|
||||
|
||||
// Skip the first frame, then start seeking
|
||||
if( !bHasExploded
|
||||
&& LockedTarget != none
|
||||
&& Physics == PHYS_Projectile
|
||||
&& Velocity != vect(0,0,0)
|
||||
&& LockedTarget.IsAliveAndWell()
|
||||
&& `TimeSince(CreationTime) > 0.03f )
|
||||
{
|
||||
// Grab our desired relative impact location from the weapon class
|
||||
TargetImpactPos = class'KFWeap_HRG_Locust'.static.GetLockedTargetLoc( LockedTarget );
|
||||
|
||||
// Seek towards target
|
||||
Speed = VSize( Velocity );
|
||||
DirToTarget = Normal( TargetImpactPos - Location );
|
||||
Velocity = Normal( Velocity + (DirToTarget * (SeekStrength * DeltaTime)) ) * Speed;
|
||||
|
||||
// Aim rotation towards velocity every frame
|
||||
SetRotation( rotator(Velocity) );
|
||||
}
|
||||
}
|
||||
|
||||
simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
local Weapon OwnerWeapon;
|
||||
local Pawn OwnerPawn;
|
||||
local KFPerk_Survivalist Perk;
|
||||
|
||||
super(KFProjectile).PrepareExplosionTemplate();
|
||||
|
||||
OwnerWeapon = Weapon(Owner);
|
||||
if (OwnerWeapon != none)
|
||||
{
|
||||
OwnerPawn = Pawn(OwnerWeapon.Owner);
|
||||
if (OwnerPawn != none)
|
||||
{
|
||||
Perk = KFPerk_Survivalist(KFPawn(OwnerPawn).GetPerk());
|
||||
if (Perk != none)
|
||||
{
|
||||
ExplosionTemplate.DamageRadius *= KFPawn(OwnerPawn).GetPerk().GetAoERadiusModifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
Physics=PHYS_Projectile
|
||||
Speed=4000 //6000
|
||||
MaxSpeed=4000 //6000
|
||||
TossZ=0
|
||||
GravityScale=1.0
|
||||
MomentumTransfer=0.0f
|
||||
|
||||
Damage=10
|
||||
DamageRadius=0
|
||||
|
||||
SeekStrength=928000.0f // 128000.0f
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
ProjFlightTemplate=ParticleSystem'WEP_HRG_Locust_EMIT.FX_HRG_Locust_Projectile'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Locust_EMIT.FX_HRG_Locust_Projectile_ZED_TIME'
|
||||
ProjDisintegrateTemplate=ParticleSystem'WEP_HRG_Locust_EMIT.FX_Flying_Bugs_dispersion'
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Projectile'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_Seeker_6.Stop_WEP_Seeker_6_Projectile'
|
||||
|
||||
ExplosionActorClass=class'KFExplosion_HRG_Locust'
|
||||
|
||||
AltExploEffects=KFImpactEffectInfo'WEP_HRG_Locust_ARCH.FX_HRG_Locust_Explosion_Concussive_force'
|
||||
|
||||
// Grenade 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
|
||||
Damage=60
|
||||
DamageRadius=200
|
||||
DamageFalloffExponent=0.5f
|
||||
DamageDelay=0.f
|
||||
|
||||
//Impulse applied to Zeds
|
||||
MomentumTransferScale=1
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Explosive_HRG_Locust'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=0.0
|
||||
FracturePartVel=0.0
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_Locust_ARCH.FX_HRG_Locust_Explosion_Concussive_force'
|
||||
ExplosionSound=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Explosion'
|
||||
|
||||
// Dynamic Light
|
||||
ExploLight=ExplosionPointLight
|
||||
ExploLightStartFadeOutTime=0.0
|
||||
ExploLightFadeOutTime=0.2
|
||||
|
||||
// Camera Shake
|
||||
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
|
||||
CamShakeInnerRadius=0
|
||||
CamShakeOuterRadius=500
|
||||
CamShakeFalloff=3.f
|
||||
bOrientCameraShakeTowardsEpicenter=true
|
||||
|
||||
bIgnoreInstigator=true
|
||||
End Object
|
||||
ExplosionTemplate=ExploTemplate0
|
||||
|
||||
bCanDisintegrate=false
|
||||
}
|
85
KFGameContent/Classes/KFProj_Pellet_HRG_Dragonbreath.uc
Normal file
85
KFGameContent/Classes/KFProj_Pellet_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,85 @@
|
||||
//=============================================================================
|
||||
// KFProj_Pellet_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Pellet_HRG_Dragonbreath extends KFProj_Bullet_Pellet
|
||||
hidedropdown;
|
||||
|
||||
|
||||
/** Last hit normal from Touch() or HitWall() */
|
||||
var vector LastHitNormal;
|
||||
|
||||
var float GroundFireChance;
|
||||
|
||||
|
||||
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
|
||||
{
|
||||
LastHitNormal = HitNormal;
|
||||
Super.ProcessTouch(Other, HitLocation, HitNormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explode this Projectile
|
||||
*/
|
||||
simulated function TriggerExplosion(Vector HitLocation, Vector HitNormal, Actor HitActor)
|
||||
{
|
||||
LastHitNormal = HitNormal;
|
||||
Super.TriggerExplosion(HitLocation, HitNormal, HitActor);
|
||||
}
|
||||
|
||||
|
||||
simulated protected function StopSimulating()
|
||||
{
|
||||
local vector FlameSpawnVel;
|
||||
|
||||
if (Role == ROLE_Authority && Physics == PHYS_Falling && FRand() < GroundFireChance)
|
||||
{
|
||||
//SpawnGroundFire();
|
||||
FlameSpawnVel = 0.25f * CalculateResidualFlameVelocity(LastHitNormal, Normal(Velocity), VSize(Velocity));
|
||||
SpawnResidualFlame(class'KFProj_HRG_DragonBreath_Splash', Location + (LastHitNormal * 10.f), FlameSpawnVel);
|
||||
}
|
||||
|
||||
super.StopSimulating();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
GroundFireChance=1.f
|
||||
Physics=PHYS_Falling
|
||||
|
||||
MaxSpeed=7000.0
|
||||
Speed=7000.0
|
||||
TerminalVelocity=7000.0
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
DamageRadius=0
|
||||
GravityScale=0.35
|
||||
TossZ=0
|
||||
|
||||
Begin Object Class=PointLightComponent Name=PointLight0
|
||||
LightColor=(R=252,G=218,B=171,A=255)
|
||||
Brightness=0.5f
|
||||
Radius=500.f
|
||||
FalloffExponent=10.f
|
||||
CastShadows=False
|
||||
CastStaticShadows=FALSE
|
||||
CastDynamicShadows=False
|
||||
bCastPerObjectShadows=false
|
||||
bEnabled=true
|
||||
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
||||
End Object
|
||||
ProjFlightLight=PointLight0
|
||||
|
||||
ImpactEffects=KFImpactEffectInfo'WEP_DragonsBreath_ARCH.DragonsBreath_bullet_impact'
|
||||
ProjFlightTemplate=ParticleSystem'WEP_DragonsBreath_EMIT.Tracer.FX_DragonsBreath_Tracer'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_DragonsBreath_EMIT.Tracer.FX_DragonsBreath_Tracer_ZEDTime'
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_SA_DragonsBreath.Play_SA_DragonsBreath_Projectile_Loop'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_SA_DragonsBreath.Stop_SA_DragonsBreath_Projectile_Loop'
|
||||
}
|
||||
|
128
KFGameContent/Classes/KFSeasonalEventStats_Fall2022.uc
Normal file
128
KFGameContent/Classes/KFSeasonalEventStats_Fall2022.uc
Normal file
@ -0,0 +1,128 @@
|
||||
//=============================================================================
|
||||
// KFSeasonalEventStats_Fall2022
|
||||
//=============================================================================
|
||||
// Tracks event-specific challenges/accomplishments for Fall 2022
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2021 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFSeasonalEventStats_Fall2022 extends KFSeasonalEventStats;
|
||||
|
||||
var transient private const int BossKillsRequired, ZedsInBonfiresRequired, EndlessWaveRequired;
|
||||
|
||||
private event Initialize(string MapName)
|
||||
{
|
||||
local string CapsMapName;
|
||||
CapsMapName = Caps(MapName);
|
||||
|
||||
bObjectiveIsValidForMap[0] = 1; // Kill 15 Bosses on any map or mode
|
||||
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on BarmwichTown
|
||||
bObjectiveIsValidForMap[2] = 0; // Open the Weapon Room
|
||||
bObjectiveIsValidForMap[3] = 0; // Make 50 Zeds to pass through the bonfires of Barmwitch Town
|
||||
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Barmwitch Town
|
||||
|
||||
if (CapsMapName == "KF-BARMWICHTOWN")
|
||||
{
|
||||
bObjectiveIsValidForMap[1] = 1;
|
||||
bObjectiveIsValidForMap[2] = 1;
|
||||
bObjectiveIsValidForMap[3] = 1;
|
||||
bObjectiveIsValidForMap[4] = 1;
|
||||
}
|
||||
|
||||
SetSeasonalEventStatsMax(BossKillsRequired, 0, 0, ZedsInBonfiresRequired, EndlessWaveRequired);
|
||||
}
|
||||
|
||||
private event GrantEventItems()
|
||||
{
|
||||
if (Outer.IsEventObjectiveComplete(0) &&
|
||||
Outer.IsEventObjectiveComplete(1) &&
|
||||
Outer.IsEventObjectiveComplete(2) &&
|
||||
Outer.IsEventObjectiveComplete(3) &&
|
||||
Outer.IsEventObjectiveComplete(4))
|
||||
{
|
||||
GrantEventItem(9424);
|
||||
}
|
||||
}
|
||||
|
||||
// Kill 15 Bosses on any map or mode
|
||||
simulated function OnBossDied()
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 0;
|
||||
|
||||
// Boss kills in any map
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= BossKillsRequired)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Complete the Weekly on Netherhold
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Complete wave 15 on Endless Hard or higher difficulty on Netherhold
|
||||
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 OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
|
||||
{
|
||||
local int WeaponRoomIdx, BonfireIdx;
|
||||
WeaponRoomIdx = 2;
|
||||
BonfireIdx = 3;
|
||||
|
||||
if(EventIndex == SEI_Fall)
|
||||
{
|
||||
if (ObjectiveIndex == WeaponRoomIdx)
|
||||
{
|
||||
if (bObjectiveIsValidForMap[ObjectiveIndex] != 0)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
else if (ObjectiveIndex == BonfireIdx)
|
||||
{
|
||||
if (bObjectiveIsValidForMap[ObjectiveIndex] != 0)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjectiveIndex, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjectiveIndex) >= ZedsInBonfiresRequired)
|
||||
{
|
||||
FinishedObjective(SEI_Fall, ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BossKillsRequired=15
|
||||
EndlessWaveRequired=15
|
||||
ZedsInBonfiresRequired=50
|
||||
}
|
83
KFGameContent/Classes/KFWeapAttach_HRG_Dragonbreath.uc
Normal file
83
KFGameContent/Classes/KFWeapAttach_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,83 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_HRG_Dragonbreath extends KFWeaponAttachment;
|
||||
|
||||
`define HRGDRAGONBREATH_MIC_BARREL_INDEX 0
|
||||
|
||||
var transient float BarrelHeatPerProjectile;
|
||||
var transient float MaxBarrelHeat;
|
||||
var transient float BarrelCooldownRate;
|
||||
var transient float CurrentBarrelHeat;
|
||||
var transient float LastBarrelHeat;
|
||||
var transient int NumPelletsDefault;
|
||||
var transient int NumPelletsAlt;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
BarrelHeatPerProjectile = class'KFWeap_HRG_Dragonbreath'.default.BarrelHeatPerProjectile;
|
||||
MaxBarrelHeat = class'KFWeap_HRG_Dragonbreath'.default.MaxBarrelHeat;
|
||||
BarrelCooldownRate = class'KFWeap_HRG_Dragonbreath'.default.BarrelCooldownRate;
|
||||
NumPelletsDefault = class'KFWeap_HRG_Dragonbreath'.default.NumPellets[0];
|
||||
NumPelletsAlt = class'KFWeap_HRG_Dragonbreath'.default.NumPellets[1];
|
||||
}
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
// Force start with "Glow_Intensity" of 0.0f
|
||||
LastBarrelHeat = MaxBarrelHeat;
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
simulated function ChangeBarrelMaterial()
|
||||
{
|
||||
if( CurrentBarrelHeat != LastBarrelHeat )
|
||||
{
|
||||
if ( WeaponMIC == None && WeapMesh != None )
|
||||
{
|
||||
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`HRGDRAGONBREATH_MIC_BARREL_INDEX);
|
||||
}
|
||||
|
||||
WeaponMIC.SetScalarParameterValue('Barrel_intensity', CurrentBarrelHeat);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function Tick(float Delta)
|
||||
{
|
||||
Super.Tick(Delta);
|
||||
|
||||
CurrentBarrelHeat = fmax(CurrentBarrelHeat - BarrelCooldownRate * Delta, 0.0f);
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
/** Override to update emissive in weapon's barrel after firing */
|
||||
simulated function PlayWeaponFireAnim()
|
||||
{
|
||||
local float BarrelHeatPerShot;
|
||||
local KFPawn OwnerPawn;
|
||||
|
||||
Super.PlayWeaponFireAnim();
|
||||
|
||||
OwnerPawn = KFPawn(Owner);
|
||||
|
||||
BarrelHeatPerShot = BarrelHeatPerProjectile * (OwnerPawn.FiringMode == 0 ? NumPelletsDefault : NumPelletsAlt);
|
||||
CurrentBarrelHeat = fmin(CurrentBarrelHeat + BarrelHeatPerShot, MaxBarrelHeat);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
CurrentBarrelHeat=0.0f
|
||||
LastBarrelHeat=0.0f
|
||||
NumPelletsDefault=0
|
||||
NumPelletsAlt=0
|
||||
}
|
144
KFGameContent/Classes/KFWeapAttach_Scythe.uc
Normal file
144
KFGameContent/Classes/KFWeapAttach_Scythe.uc
Normal file
@ -0,0 +1,144 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_Scythe
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_Scythe extends KFWeaponAttachment;
|
||||
|
||||
var const float UnfoldBlendingDuration;
|
||||
var const float UnfoldedAnimRateModifier;
|
||||
const FoldAnim = 'Clean_NoBlood';
|
||||
|
||||
var AnimTree CustomAnimTree;
|
||||
var AnimNodeBlendPerBone FoldBlendNode;
|
||||
|
||||
var transient bool bIsFolded;
|
||||
|
||||
event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
// Override the animtree. Doing this here (before AttachTo) instead of in defaultprops
|
||||
// avoids an undesired call to our owning Pawn's PostInitAnimTree
|
||||
if ( CustomAnimTree != None )
|
||||
{
|
||||
WeapMesh.SetAnimTreeTemplate(CustomAnimTree);
|
||||
|
||||
WeapAnimNode = AnimNodeSequence(WeapMesh.FindAnimNode('WeaponSeq'));
|
||||
FoldBlendNode = AnimNodeBlendPerBone(WeapMesh.FindAnimNode('FoldBlendNode'));
|
||||
|
||||
// The special event might have arrived before the attachment is created, but it's updated in the owner, so copy the state here...
|
||||
if (KFPawn(Owner) != none && FoldBlendNode != none)
|
||||
{
|
||||
bIsFolded = KFPawn(Owner).WeaponSpecialAction == 0;
|
||||
FoldBlendNode.SetBlendTarget(bIsFolded ? 1.0f : 0.0f, 0.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ChangeMode()
|
||||
{
|
||||
bIsFolded = !bIsFolded;
|
||||
|
||||
// FoldControl = SkelControlSingleBone( WeapMesh.FindSkelControl('FoldControl') );
|
||||
if( FoldBlendNode != none )
|
||||
{
|
||||
FoldBlendNode.SetBlendTarget( bIsFolded ? 1.0f : 0.0f, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
/** Called from the pawn when our first person weapon changes states */
|
||||
simulated function UpdateThirdPersonWeaponAction(EWeaponState NewWeaponState, KFPawn P, byte ThirdPersonAnimRateByte )
|
||||
{
|
||||
Super.UpdateThirdPersonWeaponAction(NewWeaponState, P, ThirdPersonAnimRate);
|
||||
|
||||
if (NewWeaponState == WEP_Cleaning)
|
||||
{
|
||||
if (WeapAnimNode != none)
|
||||
{
|
||||
if (WeapAnimNode.AnimSeq == none)
|
||||
{
|
||||
WeapAnimNode.SetAnim(FoldAnim);
|
||||
}
|
||||
|
||||
WeapAnimNode.PlayAnim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ANIMNOTIFY_ShellEject()
|
||||
{
|
||||
ChangeMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays a split (upper and lower body) animation on the owning pawn
|
||||
* Network: All but dedicated
|
||||
*
|
||||
* @param P Owning pawn to play animation on
|
||||
* @param AnimName Anim to play
|
||||
* @param bPlaySynchronizedWeaponAnim If true, try to play the same animation on the weapon mesh
|
||||
*/
|
||||
simulated function float PlayCharacterMeshAnim(KFPawn P, name AnimName, optional bool bPlaySynchedWeaponAnim, optional bool bLooping)
|
||||
{
|
||||
local float AnimRate;
|
||||
local float Duration;
|
||||
local EAnimSlotStance Stance;
|
||||
local string AnimStr;
|
||||
|
||||
// skip weapon anims while in a special move
|
||||
if( P.IsDoingSpecialMove() && !P.SpecialMoves[P.SpecialMove].bAllowThirdPersonWeaponAnims )
|
||||
{
|
||||
return 0.f;
|
||||
}
|
||||
|
||||
Stance = (!P.bIsCrouched) ? EAS_UpperBody : EAS_CH_UpperBody;
|
||||
|
||||
AnimRate = ThirdPersonAnimRate;
|
||||
AnimStr = Caps(string(AnimName));
|
||||
|
||||
if (!bIsFolded && (InStr(AnimStr, "ATK") != INDEX_NONE || InStr(AnimName, "COMB") != INDEX_NONE))
|
||||
{
|
||||
AnimRate *= UnfoldedAnimRateModifier;
|
||||
}
|
||||
|
||||
Duration = P.PlayBodyAnim(AnimName, Stance, AnimRate, DefaultBlendInTime, DefaultBlendOutTime, bLooping);
|
||||
|
||||
if ( Duration > 0 && bPlaySynchedWeaponAnim )
|
||||
{
|
||||
PlayWeaponMeshAnim(AnimName, P.BodyStanceNodes[Stance], bLooping);
|
||||
}
|
||||
|
||||
`log(GetFuncName()@"called on:"$P@"Anim:"$AnimName@"Duration:"$Duration, bDebug);
|
||||
|
||||
return Duration;
|
||||
}
|
||||
|
||||
/** Special event added for weap attachments. Free for use */
|
||||
function OnSpecialEvent(int Arg)
|
||||
{
|
||||
bIsFolded = Arg == 0;
|
||||
|
||||
// FoldControl = SkelControlSingleBone( WeapMesh.FindSkelControl('FoldControl') );
|
||||
if( FoldBlendNode != none )
|
||||
{
|
||||
FoldBlendNode.SetBlendTarget( bIsFolded ? 1.0f : 0.0f, 0.0f );
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
CustomAnimTree=AnimTree'WEP_Scythe_ARCH.3P_Scythe_Animtree'
|
||||
bIsFolded=true;
|
||||
UnfoldBlendingDuration=0.25f
|
||||
UnfoldedAnimRateModifier=0.7f;
|
||||
|
||||
// Weapon SkeletalMesh
|
||||
Begin Object Name=SkeletalMeshComponent0
|
||||
bForceRefPose=0
|
||||
End Object
|
||||
}
|
174
KFGameContent/Classes/KFWeap_AssaultRifle_G36C.uc
Normal file
174
KFGameContent/Classes/KFWeap_AssaultRifle_G36C.uc
Normal file
@ -0,0 +1,174 @@
|
||||
//=============================================================================
|
||||
// KFWeap_AssaultRifle_G36C
|
||||
//=============================================================================
|
||||
// Class Description
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_AssaultRifle_G36C extends KFWeap_SMGBase;
|
||||
|
||||
simulated function ZoomIn(bool bAnimateTransition, float ZoomTimeToGo)
|
||||
{
|
||||
super.ZoomIn(bAnimateTransition, ZoomTimeToGo);
|
||||
|
||||
if (LaserSight != none)
|
||||
{
|
||||
LaserSight.ChangeVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ZoomOut( bool bAnimateTransition, float ZoomTimeToGo )
|
||||
{
|
||||
super.ZoomOut( bAnimateTransition, ZoomTimeToGo );
|
||||
|
||||
if (LaserSight != none)
|
||||
{
|
||||
LaserSight.ChangeVisibility(true);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function AttachLaserSight()
|
||||
{
|
||||
if( WorldInfo.NetMode == NM_DedicatedServer )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
super.AttachLaserSight();
|
||||
|
||||
if (LaserSight != none)
|
||||
{
|
||||
LaserSight.bForceDotToMatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bHasFireLastAnims=true
|
||||
BonesToLockOnEmpty=(RW_Bolt, RW_Charging_Handle)
|
||||
|
||||
// Shooting Animations
|
||||
FireSightedAnims[0]=Shoot_Iron
|
||||
FireSightedAnims[1]=Shoot_Iron2
|
||||
FireSightedAnims[2]=Shoot_Iron3
|
||||
|
||||
// FOV
|
||||
MeshFOV=70
|
||||
MeshIronSightFOV=20
|
||||
PlayerIronSightFOV=70
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=150
|
||||
DOF_FG_MaxNearBlurSize=3
|
||||
|
||||
// Zooming/Position
|
||||
IronSightPosition=(X=40,Y=0.1,Z=-4.57)
|
||||
PlayerViewOffset=(X=14,Y=11,Z=-5)
|
||||
|
||||
// Content
|
||||
PackageKey="G36C"
|
||||
FirstPersonMeshName="WEP_1P_G36C_MESH.Wep_1stP_G36C_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_G36C_ANIM.Wep_1stP_G36C_Anim"
|
||||
PickupMeshName="WEP_3P_G36C_MESH.Wep_G36C_Pickup"
|
||||
AttachmentArchetypeName="WEP_G36C_ARCH.Wep_G36C_3P"
|
||||
MuzzleFlashTemplateName="WEP_G36C_ARCH.Wep_G36C_MuzzleFlash"
|
||||
|
||||
LaserSightTemplate=KFLaserSightAttachment'FX_LaserSight_ARCH.LaserSight_WithAttachment_1P'
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=30
|
||||
SpareAmmoCapacity[0]=450
|
||||
InitialSpareMags[0]=3
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=50
|
||||
minRecoilPitch=40
|
||||
maxRecoilYaw=70
|
||||
minRecoilYaw=-70
|
||||
RecoilRate=0.085
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=900
|
||||
RecoilMinPitchLimit=65035
|
||||
RecoilISMaxYawLimit=100
|
||||
RecoilISMinYawLimit=65460
|
||||
RecoilISMaxPitchLimit=350
|
||||
RecoilISMinPitchLimit=65460
|
||||
IronSightMeshFOVCompensationScale=6.0
|
||||
|
||||
// Old Recoil Data
|
||||
// maxRecoilPitch=80
|
||||
// minRecoilPitch=65
|
||||
// maxRecoilYaw=60
|
||||
// minRecoilYaw=-60
|
||||
// RecoilRate=0.063
|
||||
// RecoilMaxYawLimit=400
|
||||
// RecoilMinYawLimit=65135
|
||||
// RecoilMaxPitchLimit=800
|
||||
// RecoilMinPitchLimit=65035
|
||||
// RecoilISMaxYawLimit=150
|
||||
// RecoilISMinYawLimit=65385
|
||||
// RecoilISMaxPitchLimit=350
|
||||
// RecoilISMinPitchLimit=65435
|
||||
// IronSightMeshFOVCompensationScale=1.5
|
||||
|
||||
// Inventory
|
||||
InventorySize=7
|
||||
GroupPriority=100
|
||||
WeaponSelectTexture=Texture2D'wep_ui_g36c_tex.UI_WeaponSelect_G36C'
|
||||
|
||||
// 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_G36C'
|
||||
PenetrationPower(DEFAULT_FIREMODE)=4.0
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.08 // 750 RPM
|
||||
Spread(DEFAULT_FIREMODE)=0.005
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=45.0
|
||||
FireOffset=(X=30,Y=4.5,Z=-5)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_G36C'
|
||||
PenetrationPower(ALTFIRE_FIREMODE)=4.0
|
||||
FireInterval(ALTFIRE_FIREMODE)=+0.08 // 750 RPM
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=45.0
|
||||
Spread(ALTFIRE_FIREMODE)=0.005
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_G36C'
|
||||
InstantHitDamage(BASH_FIREMODE)=26
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_Shoot_LP', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_Shoot_LP')
|
||||
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_Shoot_Single', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_Shoot_Single')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_AK12.Play_WEP_SA_AK12_Handling_DryFire' //@TODO: Replace me
|
||||
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_AK12.Play_WEP_SA_AK12_Handling_DryFire' //@TODO: Replace me
|
||||
// WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_G36C.Play_WEP_G36C_Dry_Fire'
|
||||
// WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_G36C.Play_WEP_G36C_Dry_Fire'
|
||||
|
||||
// Advanced (High RPM) Fire Effects
|
||||
bLoopingFireAnim(DEFAULT_FIREMODE)=true
|
||||
bLoopingFireSnd(DEFAULT_FIREMODE)=true
|
||||
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_3P_End_LP', FirstPersonCue=AkEvent'WW_WEP_G36C.Play_WEP_G36C_1P_End_LP')
|
||||
SingleFireSoundIndex=ALTFIRE_FIREMODE
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
bHasLaserSight=true
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Swat'
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
}
|
437
KFGameContent/Classes/KFWeap_Edged_Scythe.uc
Normal file
437
KFGameContent/Classes/KFWeap_Edged_Scythe.uc
Normal file
@ -0,0 +1,437 @@
|
||||
//=============================================================================
|
||||
// KFWeap_Edged_AbominationAxe
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_Edged_Scythe extends KFWeap_MeleeBase;
|
||||
|
||||
var const array<MeleeHitBoxInfo> HitboxChainFolded;
|
||||
var const array<MeleeHitBoxInfo> HitboxChainUnfolded;
|
||||
|
||||
var const int MaxHitRangeFolded;
|
||||
var const int MaxHitRangeUnfolded;
|
||||
|
||||
var const int FoldedDamage;
|
||||
var const int FoldedDamageAlt;
|
||||
|
||||
var const int UnfoldedDamage;
|
||||
var const int UnfoldedDamageAlt;
|
||||
|
||||
var const class<DamageType> FoldedDT;
|
||||
var const class<DamageType> FoldedDTAlt;
|
||||
|
||||
var const class<DamageType> UnfoldedDT;
|
||||
var const class<DamageType> UnfoldedDTAlt;
|
||||
|
||||
var const float UnfoldBlendingDuration;
|
||||
|
||||
var const float FoldedAttackAnimRate;
|
||||
|
||||
var const vector PlayerViewOffsetUnfolded;
|
||||
|
||||
var transient vector OriginalPlayerViewOffset;
|
||||
var transient bool bIsFolded;
|
||||
|
||||
var AnimNodeBlendPerBone FoldBlendNode;
|
||||
|
||||
var const ParticleSystem BloodParticles;
|
||||
|
||||
const BloodParticlesSocket = 'BlockEffect';
|
||||
|
||||
var ParticleSystem FoldedTrailParticleSystem;
|
||||
var ParticleSystem UnfoldedTrailParticleSystem;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
OriginalPlayerViewOffset = PlayerViewOffset;
|
||||
}
|
||||
|
||||
event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
ChangeMode(true, false);
|
||||
|
||||
SetFoldedBladeBlendTarget(1.0f, 0.0f);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** The SkeletalMeshComponents Animations are being instanced from AnimTreeTemplate
|
||||
* before PostInitAnimTree. Be sure to never set the Mesh's animations directly through
|
||||
* the package */
|
||||
simulated event PostInitAnimTree(SkeletalMeshComponent SkelComp)
|
||||
{
|
||||
Super.PostInitAnimTree(SkelComp);
|
||||
|
||||
FoldBlendNode = AnimNodeBlendPerBone(SkelComp.FindAnimNode('FoldBlendNode'));
|
||||
|
||||
SetFoldedBladeBlendTarget(1.0f, 0.0f);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Returns true if weapon can potentially be reloaded */
|
||||
simulated function bool CanReload(optional byte FireModeNum)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated state WeaponUpkeep
|
||||
{
|
||||
simulated function BeginState(name PreviousStateName)
|
||||
{
|
||||
local name AnimName;
|
||||
local float Duration;
|
||||
|
||||
AnimName = CleanNonBloodyAnim;
|
||||
|
||||
Duration = MySkelMesh.GetAnimLength(AnimName);
|
||||
if ( Duration > 0.f )
|
||||
{
|
||||
if ( Instigator.IsFirstPerson() )
|
||||
{
|
||||
PlayAnimation(AnimName);
|
||||
SetTimer(Duration, FALSE, nameof(SwapComplete));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
`warn("Duration is zero!!!"@AnimName);
|
||||
SetTimer(0.001, FALSE, nameof(SwapComplete));
|
||||
}
|
||||
|
||||
NotifyBeginState();
|
||||
}
|
||||
|
||||
simulated function BeginFire(byte FireModeNum)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
simulated event EndState(Name NextStateName)
|
||||
{
|
||||
ClearTimer(nameof(SwapComplete));
|
||||
Super.EndState(NextStateName);
|
||||
NotifyEndState();
|
||||
}
|
||||
|
||||
simulated function SwapComplete()
|
||||
{
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
GotoState('Active');
|
||||
}
|
||||
else
|
||||
{
|
||||
GotoState('Active');
|
||||
ServerSwapComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server reliable function ServerSwapComplete()
|
||||
{
|
||||
GotoState('Active');
|
||||
}
|
||||
|
||||
simulated function ChangeMode(bool IsFolded, bool bApplyBlend = true)
|
||||
{
|
||||
if (MeleeAttackHelper == none)
|
||||
return;
|
||||
|
||||
if (IsFolded)
|
||||
{
|
||||
MeleeAttackHelper.SetMeleeRange(MaxHitRangeFolded);
|
||||
MeleeAttackHelper.SetHitBoxChain(HitboxChainFolded);
|
||||
|
||||
InstantHitDamage[DEFAULT_FIREMODE] = FoldedDamage;
|
||||
InstantHitDamage[HEAVY_ATK_FIREMODE] = FoldedDamageAlt;
|
||||
|
||||
InstantHitDamageTypes[DEFAULT_FIREMODE] = FoldedDT;
|
||||
InstantHitDamageTypes[HEAVY_ATK_FIREMODE] = FoldedDTAlt;
|
||||
|
||||
PlayerViewOffset = OriginalPlayerViewOffset;
|
||||
|
||||
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStabFolded';
|
||||
InstantHitMomentum[BASH_FIREMODE]=100000.f;
|
||||
InstantHitDamage[BASH_FIREMODE]=40;
|
||||
}
|
||||
else
|
||||
{
|
||||
MeleeAttackHelper.SetMeleeRange(MaxHitRangeUnfolded);
|
||||
MeleeAttackHelper.SetHitBoxChain(HitboxChainUnfolded);
|
||||
|
||||
InstantHitDamage[DEFAULT_FIREMODE] = UnfoldedDamage;
|
||||
InstantHitDamage[HEAVY_ATK_FIREMODE] = UnfoldedDamageAlt;
|
||||
|
||||
InstantHitDamageTypes[DEFAULT_FIREMODE] = UnfoldedDT;
|
||||
InstantHitDamageTypes[HEAVY_ATK_FIREMODE] = UnfoldedDTAlt;
|
||||
|
||||
PlayerViewOffset = PlayerViewOffsetUnfolded;
|
||||
|
||||
InstantHitDamageTypes[BASH_FIREMODE]=class'KFDT_Piercing_ScytheStab';
|
||||
InstantHitMomentum[BASH_FIREMODE]=100000.f;
|
||||
InstantHitDamage[BASH_FIREMODE]=60;
|
||||
}
|
||||
|
||||
NotifyServerMode(bIsFolded);
|
||||
|
||||
if (bApplyBlend)
|
||||
{
|
||||
SetFoldedBladeBlendTarget(bIsFolded ? 1.0f : 0.0f, UnfoldBlendingDuration);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function SetFoldedBladeBlendTarget(float Value, float BlendTime)
|
||||
{
|
||||
if ( FoldBlendNode != None )
|
||||
{
|
||||
FoldBlendNode.SetBlendTarget(Value, BlendTime);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function StartFire(byte FireModeNum)
|
||||
{
|
||||
if (StartFireDisabled && FireModeNum == BLOCK_FIREMODE)
|
||||
{
|
||||
StartFireDisabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (FireModeNum == DEFAULT_FIREMODE || FireModeNum == HEAVY_ATK_FIREMODE)
|
||||
{
|
||||
DistortTrailParticle = bIsFolded ? FoldedTrailParticleSystem : UnfoldedTrailParticleSystem;
|
||||
}
|
||||
else if (FireModeNum == BASH_FIREMODE)
|
||||
{
|
||||
DistortTrailParticle = none;
|
||||
}
|
||||
|
||||
super.StartFire(FireModeNum);
|
||||
}
|
||||
|
||||
static simulated function float CalculateTraderWeaponStatDamage()
|
||||
{
|
||||
// How is this calculated for this weapon?
|
||||
return default.UnfoldedDamage;
|
||||
}
|
||||
|
||||
simulated function PlayAnimation(name Sequence, optional float fDesiredDuration, optional bool bLoop, optional float BlendInTime=0.1, optional float BlendOutTime=0.0)
|
||||
{
|
||||
local string NewAnimName;
|
||||
|
||||
if (Sequence == 'Idle' ||
|
||||
Sequence == 'Guncheck_V1' ||
|
||||
Sequence == 'Guncheck_V2' ||
|
||||
Sequence == 'Guncheck_V3')
|
||||
{
|
||||
NewAnimName = string(Sequence);
|
||||
NewAnimName $= ((bIsFolded) ? "_Folded" : "_Unfolded");
|
||||
Super.PlayAnimation(name(NewAnimName), fDesiredDuration, bLoop, BlendInTime, BlendOutTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
Super.PlayAnimation(Sequence, fDesiredDuration, bLoop, BlendInTime, BlendOutTime);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ModifyMeleeAttackSpeed(out float InSpeed, optional int FireMode = DEFAULT_FIREMODE, optional int UpgradeIndex = INDEX_NONE, optional KFPerk CurrentPerk)
|
||||
{
|
||||
Super.ModifyMeleeAttackSpeed(InSpeed, FireMode, UpgradeIndex, CurrentPerk);
|
||||
|
||||
if (bIsFolded)
|
||||
{
|
||||
InSpeed *= FoldedAttackAnimRate;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriden to apply fold/unfold logic
|
||||
*/
|
||||
simulated function ANIMNOTIFY_LockBolt()
|
||||
{
|
||||
bIsFolded = !bIsFolded;
|
||||
ChangeMode(bIsFolded);
|
||||
}
|
||||
|
||||
/** Unused */
|
||||
simulated function ANIMNOTIFY_UnLockBolt()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Play blood VFX as we only use one anim. */
|
||||
simulated function ANIMNOTIFY_CleanBlood()
|
||||
{
|
||||
if (!bIsBloody)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer && BloodParticles != none)
|
||||
{
|
||||
WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(BloodParticles, MySkelMesh, BloodParticlesSocket, true);
|
||||
}
|
||||
|
||||
Super.ANIMNOTIFY_CleanBlood();
|
||||
}
|
||||
|
||||
simulated state WeaponEquipping
|
||||
{
|
||||
/** Initialize the weapon as being active and ready to go. */
|
||||
simulated event BeginState(Name PreviousStateName)
|
||||
{
|
||||
Super.BeginState(PreviousStateName);
|
||||
|
||||
if (WorldInfo.NetMode != NM_Client)
|
||||
{
|
||||
NotifyInitialState(bIsFolded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Should replicate to 3P to show the shield effects
|
||||
*/
|
||||
simulated function NotifyInitialState(bool bFolded)
|
||||
{
|
||||
local KFPawn KFP;
|
||||
|
||||
if (WorldInfo.NetMode != NM_Client)
|
||||
{
|
||||
`Log("NotifyInitialState: " $bFolded);
|
||||
|
||||
KFP = KFPawn(Instigator);
|
||||
KFP.OnWeaponSpecialAction(bFolded ? 0 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
reliable server function NotifyServerMode(bool bFolded)
|
||||
{
|
||||
bIsFolded = bFolded;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=10,Y=0,Z=-10) // (X=2,Y=0,Z=0)
|
||||
PlayerViewOffsetUnfolded=(X=12,Y=0,Z=-7)
|
||||
|
||||
// Content
|
||||
PackageKey="Scythe"
|
||||
FirstPersonMeshName="WEP_1P_Scythe_MESH.Wep_1stP_Scythe_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_Scythe_ANIM.Wep_1st_Scythe_Anim"
|
||||
FirstPersonAnimTree="WEP_1P_Scythe_ANIM.1P_Scythe_Animtree"
|
||||
PickupMeshName="wep_3p_scythe_mesh.Wep_3rdP_Scythe_Pickup"
|
||||
AttachmentArchetypeName="WEP_Scythe_ARCH.Wep_Scythe_3P"
|
||||
|
||||
// Short Range Mode Params
|
||||
MaxHitRangeFolded=220
|
||||
FoldedDamage = 70
|
||||
FoldedDamageAlt = 120
|
||||
FoldedDT=class'KFDT_Slashing_ScytheShort'
|
||||
FoldedDTAlt=class'KFDT_Slashing_ScytheShortAlt'
|
||||
HitboxChainFolded = {(
|
||||
(BoneOffset=(X=+3,Z=190)),
|
||||
(BoneOffset=(X=-3,Z=170)),
|
||||
(BoneOffset=(X=+3,Z=150)),
|
||||
(BoneOffset=(X=-3,Z=130)),
|
||||
(BoneOffset=(X=+3,Z=110)),
|
||||
(BoneOffset=(X=-3,Z=90)),
|
||||
(BoneOffset=(X=+3,Z=70)),
|
||||
(BoneOffset=(X=-3,Z=50)),
|
||||
(BoneOffset=(X=+3,Z=30)),
|
||||
(BoneOffset=(Z=10))
|
||||
)}
|
||||
|
||||
// Long Range Mode Params
|
||||
MaxHitRangeUnfolded=300
|
||||
UnfoldedDamage=140
|
||||
UnfoldedDamageAlt=190
|
||||
UnfoldedDT=class'KFDT_Slashing_ScytheLong'
|
||||
UnfoldedDTAlt=class'KFDT_Slashing_ScytheLongAlt'
|
||||
HitboxChainUnfolded = {(
|
||||
(BoneOffset=(X=-3,Z=290)),
|
||||
(BoneOffset=(X=-3,Z=270)),
|
||||
(BoneOffset=(X=-3,Z=250)),
|
||||
(BoneOffset=(X=+3,Z=230)),
|
||||
(BoneOffset=(X=-3,Z=210)),
|
||||
(BoneOffset=(X=+3,Z=190)),
|
||||
(BoneOffset=(X=-3,Z=170)),
|
||||
(BoneOffset=(X=+3,Z=150)),
|
||||
(BoneOffset=(X=-3,Z=130)),
|
||||
(BoneOffset=(X=+3,Z=110)),
|
||||
(BoneOffset=(X=-3,Z=90)),
|
||||
(BoneOffset=(X=+3,Z=70)),
|
||||
(BoneOffset=(X=-3,Z=50)),
|
||||
(BoneOffset=(X=+3,Z=30)),
|
||||
(BoneOffset=(Z=10))
|
||||
)}
|
||||
|
||||
Begin Object Name=MeleeHelper_0
|
||||
WorldImpactEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Bladed_melee_impact'
|
||||
MeleeImpactCamShakeScale=0.04f //0.5
|
||||
// modified combo sequences
|
||||
ChainSequence_F=(DIR_ForwardRight, DIR_ForwardLeft, DIR_ForwardRight, DIR_ForwardLeft)
|
||||
ChainSequence_B=(DIR_BackwardLeft, DIR_BackwardRight, DIR_BackwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right, DIR_Left)
|
||||
ChainSequence_L=(DIR_Right, DIR_Left)
|
||||
ChainSequence_R=(DIR_Left, DIR_Right, DIR_ForwardLeft, DIR_ForwardRight, DIR_Left, DIR_Right)
|
||||
End Object
|
||||
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Slashing_ScytheShort'
|
||||
InstantHitMomentum(DEFAULT_FIREMODE)=30000.f
|
||||
|
||||
InstantHitDamageTypes(HEAVY_ATK_FIREMODE)=class'KFDT_Slashing_ScytheShortAlt'
|
||||
FiringStatesArray(HEAVY_ATK_FIREMODE)=MeleeHeavyAttacking
|
||||
InstantHitMomentum(HEAVY_ATK_FIREMODE)=30000.f
|
||||
|
||||
// Defined in ChangeMode function
|
||||
//InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Piercing_ScytheStab'
|
||||
//InstantHitMomentum(BASH_FIREMODE)=100000.f
|
||||
//InstantHitDamage(BASH_FIREMODE)=50
|
||||
|
||||
// Inventory
|
||||
GroupPriority=50
|
||||
InventorySize=7
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_Scythe_TEX.UI_WeaponSelect_Scythe'
|
||||
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Berserker'
|
||||
|
||||
// Block Sounds
|
||||
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Katana'
|
||||
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
|
||||
|
||||
ParryDamageMitigationPercent=0.4
|
||||
BlockDamageMitigation=0.5
|
||||
ParryStrength=5
|
||||
|
||||
bIsFolded=true
|
||||
|
||||
BonesToLockOnEmpty.Empty()
|
||||
|
||||
UnfoldBlendingDuration=0.05f
|
||||
|
||||
FoldedAttackAnimRate=0.65f
|
||||
|
||||
// IdleFidgetAnims=(Guncheck_v1, Guncheck_v2, Guncheck_v3)
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
|
||||
DistortTrailParticle = none
|
||||
WhiteTrailParticle = none
|
||||
BlueTrailParticle = none
|
||||
RedTrailParticle = none
|
||||
|
||||
FoldedTrailParticleSystem=ParticleSystem'WEP_Scythe_EMIT.FX_Scythe_Custom_R_01'
|
||||
UnfoldedTrailParticleSystem=ParticleSystem'WEP_Scythe_EMIT.FX_Scythe_Custom_Unfold_01';
|
||||
|
||||
BloodParticles = ParticleSystem'WEP_1P_KATANA_EMIT.FX_katana_blood_flick_01'
|
||||
}
|
286
KFGameContent/Classes/KFWeap_HRG_Dragonbreath.uc
Normal file
286
KFGameContent/Classes/KFWeap_HRG_Dragonbreath.uc
Normal file
@ -0,0 +1,286 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_Dragonbreath
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeap_HRG_Dragonbreath extends KFWeap_ShotgunBase;
|
||||
|
||||
/** How much to scale recoil when firing in double barrel fire. */
|
||||
var(Recoil) float QuadFireRecoilModifier;
|
||||
|
||||
/** Shoot animation to play when shooting both barrels from the hip */
|
||||
var(Animations) const editconst name FireQuadAnim;
|
||||
|
||||
/** How much momentum to apply when fired in double barrel */
|
||||
var(Recoil) float DoubleBarrelKickMomentum;
|
||||
|
||||
/** How much to reduce shoot momentum when falling */
|
||||
var(Recoil) float FallingMomentumReduction;
|
||||
|
||||
var(Spread) const float SpreadWidthDegrees;
|
||||
var(Spread) const float SpreadWidthDegreesAlt;
|
||||
|
||||
var transient float StartingPelletPosition;
|
||||
var transient float StartingPelletPositionAlt;
|
||||
|
||||
var const float BarrelHeatPerProjectile;
|
||||
var const float MaxBarrelHeat;
|
||||
var const float BarrelCooldownRate;
|
||||
var transient float CurrentBarrelHeat;
|
||||
var transient float LastBarrelHeat;
|
||||
|
||||
simulated event PreBeginPlay()
|
||||
{
|
||||
Super.PreBeginPlay();
|
||||
|
||||
Spread[DEFAULT_FIREMODE] = SpreadWidthDegrees * DegToRad / NumPellets[DEFAULT_FIREMODE];
|
||||
Spread[ALTFIRE_FIREMODE] = SpreadWidthDegreesAlt * DegToRad / NumPellets[ALTFIRE_FIREMODE];
|
||||
|
||||
StartingPelletPosition = -SpreadWidthDegrees * DegToRad / 2.0f;
|
||||
StartingPelletPositionAlt = -SpreadWidthDegreesAlt * DegToRad / 2.0f;
|
||||
}
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
// Force start with "Glow_Intensity" of 0.0f
|
||||
LastBarrelHeat = MaxBarrelHeat;
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
simulated function AltFireMode()
|
||||
{
|
||||
if ( !Instigator.IsLocallyControlled() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartFire(ALTFIRE_FIREMODE);
|
||||
}
|
||||
|
||||
/** Returns number of projectiles to fire from SpawnProjectile */
|
||||
simulated function byte GetNumProjectilesToFire(byte FireModeNum)
|
||||
{
|
||||
return NumPellets[CurrentFireMode];
|
||||
}
|
||||
|
||||
/** Handle one-hand fire anims */
|
||||
simulated function name GetWeaponFireAnim(byte FireModeNum)
|
||||
{
|
||||
if (bUsingSights)
|
||||
{
|
||||
return FireSightedAnims[FireModeNum];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FireModeNum == ALTFIRE_FIREMODE)
|
||||
{
|
||||
return FireQuadAnim;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FireAnim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
|
||||
{
|
||||
local int ProjectilesToFire, i;
|
||||
local float InitialOffset;
|
||||
|
||||
ProjectilesToFire = GetNumProjectilesToFire(CurrentFireMode);
|
||||
if (CurrentFireMode == GRENADE_FIREMODE || ProjectilesToFire <= 1)
|
||||
{
|
||||
return SpawnProjectile(KFProjClass, RealStartLoc, AimDir);
|
||||
}
|
||||
|
||||
InitialOffset = CurrentFireMode == DEFAULT_FIREMODE ? StartingPelletPosition : StartingPelletPositionAlt;
|
||||
|
||||
for (i = 0; i < ProjectilesToFire; i++)
|
||||
{
|
||||
SpawnProjectile(KFProjClass, RealStartLoc, CalculateSpread(InitialOffset, Spread[CurrentFireMode], i, CurrentFireMode == ALTFIRE_FIREMODE));
|
||||
CurrentBarrelHeat = fmin(CurrentBarrelHeat + BarrelHeatPerProjectile, MaxBarrelHeat);
|
||||
}
|
||||
|
||||
ChangeBarrelMaterial();
|
||||
return None;
|
||||
}
|
||||
|
||||
simulated function vector CalculateSpread(float InitialOffset, float CurrentSpread, byte PelletNum, bool bHorizontal)
|
||||
{
|
||||
local Vector X, Y, Z, POVLoc;
|
||||
local Quat R;
|
||||
local rotator POVRot;
|
||||
|
||||
if (Instigator != None && Instigator.Controller != none)
|
||||
{
|
||||
Instigator.Controller.GetPlayerViewPoint(POVLoc, POVRot);
|
||||
}
|
||||
|
||||
GetAxes(POVRot, X, Y, Z);
|
||||
|
||||
R = QuatFromAxisAndAngle(bHorizontal ? Z : Y, InitialOffset + CurrentSpread * PelletNum);
|
||||
return QuatRotateVector(R, vector(POVRot));
|
||||
}
|
||||
|
||||
simulated function ChangeBarrelMaterial()
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( CurrentBarrelHeat != LastBarrelHeat )
|
||||
{
|
||||
for( i = 0; i < WeaponMICs.Length; ++i )
|
||||
{
|
||||
if( WeaponMICs[i] != none )
|
||||
{
|
||||
WeaponMICs[i].SetScalarParameterValue('Barrel_intensity', CurrentBarrelHeat);
|
||||
LastBarrelHeat = CurrentBarrelHeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function Tick(float Delta)
|
||||
{
|
||||
Super.Tick(Delta);
|
||||
|
||||
CurrentBarrelHeat = fmax(CurrentBarrelHeat - BarrelCooldownRate * Delta, 0.0f);
|
||||
ChangeBarrelMaterial();
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
// Inventory
|
||||
InventorySize=7
|
||||
GroupPriority=110
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_HRG_MegaDragonsbreath_TEX.UI_WeaponSelect_HRG_MegaDragonsbreath'
|
||||
|
||||
// FOV
|
||||
MeshFOV=60
|
||||
MeshIronSightFOV=52
|
||||
PlayerIronSightFOV=70
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=65
|
||||
DOF_FG_MaxNearBlurSize=3
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=15.0,Y=8.0,Z=-4.5)
|
||||
IronSightPosition=(X=3,Y=0,Z=0)
|
||||
|
||||
// Content
|
||||
PackageKey="HRG_MegaDragonsbreath"
|
||||
FirstPersonMeshName="wep_1p_hrg_megadragonsbreath_mesh.Wep_1stP_HRG_MegaDragonsbreath_Rig"
|
||||
FirstPersonAnimSetNames(0)="wep_1p_hrg_megadragonsbreath_anim.Wep_1stP_HRG_MegaDragonsbreath_Anim"
|
||||
PickupMeshName="wep_3p_hrg_megadragonsbreath_mesh.Wep_3rdP_HRG_MegaDragonsbreath_Pickup"
|
||||
AttachmentArchetypeName="wep_hrg_megadragonsbreath_arch.Wep_HRG_MegaDragonsbreath_3P"
|
||||
MuzzleFlashTemplateName="wep_hrg_megadragonsbreath_arch.Wep_HRG_MegaDragonsbreath_MuzzleFlash"
|
||||
|
||||
// Animations
|
||||
FireAnim=Shoot_Single
|
||||
FireQuadAnim=Shoot_Double
|
||||
FireSightedAnims[0]=Shoot_Iron_Single
|
||||
FireSightedAnims[1]=Shoot_Iron_Double
|
||||
bHasFireLastAnims=false
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Pellet_HRG_Dragonbreath'
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=28.0 //36
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_Dragonbreath'
|
||||
PenetrationPower(DEFAULT_FIREMODE)=4.0
|
||||
FireInterval(DEFAULT_FIREMODE)=0.25 // 240 RPM
|
||||
FireOffset=(X=25,Y=3.5,Z=-4)
|
||||
NumPellets(DEFAULT_FIREMODE)=8
|
||||
Spread(DEFAULT_FIREMODE)=0
|
||||
ForceReloadTimeOnEmpty=0.3
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunAuto'
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)= WeaponSingleFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Pellet_HRG_Dragonbreath'
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=28.0
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_Dragonbreath'
|
||||
PenetrationPower(ALTFIRE_FIREMODE)=4.0
|
||||
FireInterval(ALTFIRE_FIREMODE)=0.25 // 240 RPM
|
||||
NumPellets(ALTFIRE_FIREMODE)=8
|
||||
Spread(ALTFIRE_FIREMODE)=0
|
||||
AmmoCost(ALTFIRE_FIREMODE)=1
|
||||
DoubleBarrelKickMomentum=1000
|
||||
FallingMomentumReduction=0.5
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_Dragonbreath'
|
||||
InstantHitDamage(BASH_FIREMODE)=27
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_Fire_3P_Single', FirstPersonCue=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_Fire_1P_Single') //@TODO: Replace
|
||||
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_Fire_3P_AltFire', FirstPersonCue=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_Fire_1P_AltFire') //@TODO: Replace
|
||||
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_DryFire' //@TODO: Replace
|
||||
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_Quad_Shotgun.Play_Quad_Shotgun_DryFire' //@TODO: Replace
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=4
|
||||
SpareAmmoCapacity[0]=60 //48 //72
|
||||
InitialSpareMags[0]=3 //8
|
||||
AmmoPickupScale[0]=2.0 //3.0
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
bNoMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=1200 //900
|
||||
minRecoilPitch=775
|
||||
maxRecoilYaw=800 //500
|
||||
minRecoilYaw=-500
|
||||
RecoilRate=0.085
|
||||
RecoilBlendOutRatio=1.1
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=1500
|
||||
RecoilMinPitchLimit=64785
|
||||
RecoilISMaxYawLimit=50
|
||||
RecoilISMinYawLimit=65485
|
||||
RecoilISMaxPitchLimit=500
|
||||
RecoilISMinPitchLimit=65485
|
||||
RecoilViewRotationScale=0.8
|
||||
FallingRecoilModifier=1.5
|
||||
HippedRecoilModifier=1.1 //1.25
|
||||
QuadFireRecoilModifier=2.0
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Firebug'
|
||||
|
||||
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Heavy_Recoil_SingleShot'
|
||||
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
//WeaponUpgrades[1]=(IncrementDamage=1.15f,IncrementWeight=1)
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
|
||||
SpreadWidthDegrees=7.0f
|
||||
SpreadWidthDegreesAlt=15.0f
|
||||
|
||||
StartingPelletPosition=0.0f
|
||||
StartingPelletPositionAlt=0.0f
|
||||
|
||||
MaxBarrelHeat=5.0f
|
||||
BarrelHeatPerProjectile=0.089f
|
||||
BarrelCooldownRate=0.45f
|
||||
|
||||
CurrentBarrelHeat=0.0f
|
||||
LastBarrelHeat=0.0f
|
||||
|
||||
NumBloodMapMaterials=3
|
||||
}
|
684
KFGameContent/Classes/KFWeap_HRG_Locust.uc
Normal file
684
KFGameContent/Classes/KFWeap_HRG_Locust.uc
Normal file
@ -0,0 +1,684 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_Locust
|
||||
//=============================================================================
|
||||
// A mosquito rocket launcher
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//
|
||||
//=============================================================================
|
||||
class KFWeap_HRG_Locust extends KFWeap_GrenadeLauncher_Base;
|
||||
|
||||
const MAX_LOCKED_TARGETS = 6;
|
||||
|
||||
/** Constains all currently locked-on targets */
|
||||
var protected array<Pawn> LockedTargets;
|
||||
|
||||
/** How much to scale recoil when firing in multi-rocket mode */
|
||||
var float BurstFireRecoilModifier;
|
||||
|
||||
/** The last time a target was acquired */
|
||||
var protected float LastTargetLockTime;
|
||||
|
||||
/** The last time a target validation check was performed */
|
||||
var protected float LastTargetValidationCheckTime;
|
||||
|
||||
/** How much time after a lock on occurs before another is allowed */
|
||||
var const float TimeBetweenLockOns;
|
||||
|
||||
/** How much time should pass between target validation checks */
|
||||
var const float TargetValidationCheckInterval;
|
||||
|
||||
/** Minimum distance a target can be from the crosshair to be considered for lock on */
|
||||
var const float MinTargetDistFromCrosshairSQ;
|
||||
|
||||
/** Dot product FOV that targets need to stay within to maintain a target lock */
|
||||
var const float MaxLockMaintainFOVDotThreshold;
|
||||
|
||||
/** Sound Effects to play when Locking */
|
||||
var AkBaseSoundObject LockAcquiredSoundFirstPerson;
|
||||
var AkBaseSoundObject LockLostSoundFirstPerson;
|
||||
|
||||
/** Icon textures for lock on drawing */
|
||||
var const Texture2D LockedOnIcon;
|
||||
var LinearColor LockedIconColor;
|
||||
|
||||
/** Ironsights Audio */
|
||||
var AkComponent IronsightsComponent;
|
||||
var AkEvent IronsightsZoomInSound;
|
||||
var AkEvent IronsightsZoomOutSound;
|
||||
|
||||
/** Reduction for the amount of damage dealt to the weapon owner (including damage by the explosion) */
|
||||
var() float SelfDamageReductionValue;
|
||||
|
||||
/**
|
||||
* Toggle between DEFAULT and ALTFIRE
|
||||
*/
|
||||
simulated function AltFireMode()
|
||||
{
|
||||
super.AltFireMode();
|
||||
|
||||
LockedTargets.Length = 0;
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Target Locking And Validation
|
||||
**********************************************************************************************/
|
||||
|
||||
/** We need to update our locked targets every frame and make sure they're within view and not dead */
|
||||
simulated event Tick( float DeltaTime )
|
||||
{
|
||||
local Pawn RecentlyLocked, StaticLockedTargets[6];
|
||||
local bool bUpdateServerTargets;
|
||||
local int i;
|
||||
|
||||
super.Tick( DeltaTime );
|
||||
|
||||
if( bUsingSights && bUseAltFireMode
|
||||
&& Instigator != none
|
||||
&& Instigator.IsLocallyControlled() )
|
||||
{
|
||||
if( `TimeSince(LastTargetLockTime) > TimeBetweenLockOns
|
||||
&& LockedTargets.Length < AmmoCount[GetAmmoType(0)]
|
||||
&& LockedTargets.Length < MAX_LOCKED_TARGETS)
|
||||
{
|
||||
bUpdateServerTargets = FindTargets( RecentlyLocked );
|
||||
}
|
||||
|
||||
if( LockedTargets.Length > 0 )
|
||||
{
|
||||
bUpdateServerTargets = bUpdateServerTargets || ValidateTargets( RecentlyLocked );
|
||||
}
|
||||
|
||||
// If we are a client, synchronize our targets with the server
|
||||
if( bUpdateServerTargets && Role < ROLE_Authority )
|
||||
{
|
||||
for( i = 0; i < MAX_LOCKED_TARGETS; ++i )
|
||||
{
|
||||
if( i < LockedTargets.Length )
|
||||
{
|
||||
StaticLockedTargets[i] = LockedTargets[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
StaticLockedTargets[i] = none;
|
||||
}
|
||||
}
|
||||
|
||||
ServerSyncLockedTargets( StaticLockedTargets );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an potential target TA determine if we can lock on to it. By default only allow locking on
|
||||
* to pawns.
|
||||
*/
|
||||
simulated function bool CanLockOnTo(Actor TA)
|
||||
{
|
||||
Local KFPawn PawnTarget;
|
||||
|
||||
PawnTarget = KFPawn(TA);
|
||||
|
||||
// Make sure the pawn is legit, isn't dead, and isn't already at full health
|
||||
if ((TA == None) || !TA.bProjTarget || TA.bDeleteMe || (PawnTarget == None) ||
|
||||
(TA == Instigator) || (PawnTarget.Health <= 0) ||
|
||||
!HasAmmo(DEFAULT_FIREMODE))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Make sure and only lock onto players on the same team
|
||||
return !WorldInfo.GRI.OnSameTeam(Instigator, TA);
|
||||
}
|
||||
|
||||
/** Finds a new lock on target, adds it to the target array and returns TRUE if the array was updated */
|
||||
simulated function bool FindTargets( out Pawn RecentlyLocked )
|
||||
{
|
||||
local Pawn P, BestTargetLock;
|
||||
local byte TeamNum;
|
||||
local vector AimStart, AimDir, TargetLoc, Projection, DirToPawn, LinePoint;
|
||||
local Actor HitActor;
|
||||
local float PointDistSQ, Score, BestScore, TargetSizeSQ;
|
||||
|
||||
TeamNum = Instigator.GetTeamNum();
|
||||
AimStart = GetSafeStartTraceLocation();
|
||||
AimDir = vector( GetAdjustedAim(AimStart) );
|
||||
BestScore = 0.f;
|
||||
|
||||
//Don't add targets if we're already burst firing
|
||||
if (IsInState('WeaponBurstFiring'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach WorldInfo.AllPawns( class'Pawn', P )
|
||||
{
|
||||
if (!CanLockOnTo(P))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Want alive pawns and ones we already don't have locked
|
||||
if( P != none && P.IsAliveAndWell() && P.GetTeamNum() != TeamNum && LockedTargets.Find(P) == INDEX_NONE )
|
||||
{
|
||||
TargetLoc = GetLockedTargetLoc( P );
|
||||
Projection = TargetLoc - AimStart;
|
||||
DirToPawn = Normal( Projection );
|
||||
|
||||
// Filter out pawns too far from center
|
||||
if( AimDir dot DirToPawn < 0.5f )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check to make sure target isn't too far from center
|
||||
PointDistToLine( TargetLoc, AimDir, AimStart, LinePoint );
|
||||
PointDistSQ = VSizeSQ( LinePoint - P.Location );
|
||||
|
||||
TargetSizeSQ = P.GetCollisionRadius() * 2.f;
|
||||
TargetSizeSQ *= TargetSizeSQ;
|
||||
|
||||
if( PointDistSQ > (TargetSizeSQ + MinTargetDistFromCrosshairSQ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure it's not obstructed
|
||||
HitActor = class'KFAIController'.static.ActorBlockTest(self, TargetLoc, AimStart,, true, true);
|
||||
if( HitActor != none && HitActor != P )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Distance from target has much more impact on target selection score
|
||||
Score = VSizeSQ( Projection ) + PointDistSQ;
|
||||
if( BestScore == 0.f || Score < BestScore )
|
||||
{
|
||||
BestTargetLock = P;
|
||||
BestScore = Score;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( BestTargetLock != none )
|
||||
{
|
||||
LastTargetLockTime = WorldInfo.TimeSeconds;
|
||||
LockedTargets.AddItem( BestTargetLock );
|
||||
RecentlyLocked = BestTargetLock;
|
||||
|
||||
// Plays sound/FX when locking on to a new target
|
||||
PlayTargetLockOnEffects();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RecentlyLocked = none;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Checks to ensure all of our current locked targets are valid */
|
||||
simulated function bool ValidateTargets( optional Pawn RecentlyLocked )
|
||||
{
|
||||
local int i;
|
||||
local bool bShouldRemoveTarget, bAlteredTargets;
|
||||
local vector AimStart, AimDir, TargetLoc;
|
||||
local Actor HitActor;
|
||||
|
||||
if( `TimeSince(LastTargetValidationCheckTime) < TargetValidationCheckInterval )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LastTargetValidationCheckTime = WorldInfo.TimeSeconds;
|
||||
|
||||
AimStart = GetSafeStartTraceLocation();
|
||||
AimDir = vector( GetAdjustedAim(AimStart) );
|
||||
|
||||
bAlteredTargets = false;
|
||||
for( i = 0; i < LockedTargets.Length; ++i )
|
||||
{
|
||||
// For speed don't bother checking a target we just locked
|
||||
if( RecentlyLocked != none && RecentlyLocked == LockedTargets[i] )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bShouldRemoveTarget = false;
|
||||
|
||||
if( LockedTargets[i] == none
|
||||
|| !LockedTargets[i].IsAliveAndWell() )
|
||||
{
|
||||
bShouldRemoveTarget = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
TargetLoc = GetLockedTargetLoc( LockedTargets[i] );
|
||||
if( AimDir dot Normal(LockedTargets[i].Location - AimStart) >= MaxLockMaintainFOVDotThreshold )
|
||||
{
|
||||
HitActor = class'KFAIController'.static.ActorBlockTest( self, TargetLoc, AimStart,, true, true );
|
||||
if( HitActor != none && HitActor != LockedTargets[i] )
|
||||
{
|
||||
bShouldRemoveTarget = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bShouldRemoveTarget = true;
|
||||
}
|
||||
}
|
||||
|
||||
// A target was invalidated, remove it from the list
|
||||
if( bShouldRemoveTarget )
|
||||
{
|
||||
LockedTargets.Remove( i, 1 );
|
||||
--i;
|
||||
bAlteredTargets = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Plays sound/FX when losing a target lock, but only if we didn't play a lock on this frame
|
||||
if( bAlteredTargets && RecentlyLocked == none )
|
||||
{
|
||||
PlayTargetLostEffects();
|
||||
}
|
||||
|
||||
return bAlteredTargets;
|
||||
}
|
||||
|
||||
/** Synchronizes our locked targets with the server */
|
||||
reliable server function ServerSyncLockedTargets( Pawn TargetPawns[MAX_LOCKED_TARGETS] )
|
||||
{
|
||||
local int i;
|
||||
|
||||
LockedTargets.Length = 0;
|
||||
for( i = 0; i < MAX_LOCKED_TARGETS; ++i )
|
||||
{
|
||||
if (TargetPawns[i] != none)
|
||||
{
|
||||
LockedTargets.AddItem(TargetPawns[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Adjusts our destination target impact location */
|
||||
static simulated function vector GetLockedTargetLoc( Pawn P )
|
||||
{
|
||||
// Go for the chest, but just in case we don't have something with a chest bone we'll use collision and eyeheight settings
|
||||
if( P.Mesh.SkeletalMesh != none && P.Mesh.bAnimTreeInitialised )
|
||||
{
|
||||
if( P.Mesh.MatchRefBone('Spine2') != INDEX_NONE )
|
||||
{
|
||||
return P.Mesh.GetBoneLocation( 'Spine2' );
|
||||
}
|
||||
else if( P.Mesh.MatchRefBone('Spine1') != INDEX_NONE )
|
||||
{
|
||||
return P.Mesh.GetBoneLocation( 'Spine1' );
|
||||
}
|
||||
|
||||
return P.Mesh.GetPosition() + ((P.CylinderComponent.CollisionHeight + (P.BaseEyeHeight * 0.5f)) * vect(0,0,1)) ;
|
||||
}
|
||||
|
||||
// General chest area, fallback
|
||||
return P.Location + ( vect(0,0,1) * P.BaseEyeHeight * 0.75f );
|
||||
}
|
||||
|
||||
simulated function ZoomIn(bool bAnimateTransition, float ZoomTimeToGo)
|
||||
{
|
||||
super.ZoomIn(bAnimateTransition, ZoomTimeToGo);
|
||||
|
||||
if (IronsightsZoomInSound != none && Instigator != none && Instigator.IsLocallyControlled())
|
||||
{
|
||||
IronsightsComponent.PlayEvent(IronsightsZoomInSound, false);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clear all locked targets when zooming out, both server and client */
|
||||
simulated function ZoomOut( bool bAnimateTransition, float ZoomTimeToGo )
|
||||
{
|
||||
super.ZoomOut( bAnimateTransition, ZoomTimeToGo );
|
||||
|
||||
if (IronsightsZoomOutSound != none && Instigator != none && Instigator.IsLocallyControlled())
|
||||
{
|
||||
IronsightsComponent.PlayEvent(IronsightsZoomOutSound, false);
|
||||
}
|
||||
|
||||
// Play a target lost effect if we're clearing targets on the way out
|
||||
if( Instigator.IsLocallyControlled() && LockedTargets.Length > 0 )
|
||||
{
|
||||
PlayTargetLostEffects();
|
||||
}
|
||||
LockedTargets.Length = 0;
|
||||
}
|
||||
|
||||
/** Play FX or sounds when locking on to a new target */
|
||||
simulated function PlayTargetLockOnEffects()
|
||||
{
|
||||
if( Instigator != none && Instigator.IsHumanControlled() )
|
||||
{
|
||||
PlaySoundBase( LockAcquiredSoundFirstPerson, true );
|
||||
}
|
||||
}
|
||||
|
||||
/** Play FX or sounds when losing a target lock */
|
||||
simulated function PlayTargetLostEffects()
|
||||
{
|
||||
if( Instigator != none && Instigator.IsHumanControlled() )
|
||||
{
|
||||
PlaySoundBase( LockLostSoundFirstPerson, true );
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Projectile Spawning
|
||||
**********************************************************************************************/
|
||||
|
||||
/** Spawn projectile is called once for each rocket fired. In burst mode it will cycle through targets until it runs out */
|
||||
simulated function KFProjectile SpawnProjectile( class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir )
|
||||
{
|
||||
local KFProj_HRG_Locust LocustProj;
|
||||
|
||||
if( CurrentFireMode == GRENADE_FIREMODE )
|
||||
{
|
||||
return super.SpawnProjectile( KFProjClass, RealStartLoc, AimDir );
|
||||
}
|
||||
|
||||
// We need to set our target if we are firing from a locked on position
|
||||
if( bUsingSights
|
||||
&& CurrentFireMode == ALTFIRE_FIREMODE
|
||||
&& LockedTargets.Length > 0 )
|
||||
{
|
||||
// We'll aim our rocket at a target here otherwise we will spawn a dumbfire rocket at the end of the function
|
||||
if( LockedTargets.Length > 0 )
|
||||
{
|
||||
// Spawn our projectile and set its target
|
||||
LocustProj = KFProj_HRG_Locust( super.SpawnProjectile(KFProjClass, RealStartLoc, AimDir) );
|
||||
if( LocustProj != none )
|
||||
{
|
||||
//Seek to new target, then remove from list. Always use first target in the list for new fire.
|
||||
LocustProj.SetLockedTarget( KFPawn(LockedTargets[0]) );
|
||||
LockedTargets.Remove(0, 1);
|
||||
|
||||
return LocustProj;
|
||||
}
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
return super.SpawnProjectile( KFProjClass, RealStartLoc, AimDir );
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Targeting HUD -- Partially adapted from KFWeap_Rifle_RailGun
|
||||
**********************************************************************************************/
|
||||
|
||||
/** Handle drawing our custom lock on HUD */
|
||||
simulated function DrawHUD( HUD H, Canvas C )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( !bUsingSights || LockedTargets.Length == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw target locked icons
|
||||
C.EnableStencilTest( true );
|
||||
for( i = 0; i < LockedTargets.Length; ++i )
|
||||
{
|
||||
if( LockedTargets[i] != none )
|
||||
{
|
||||
DrawTargetingIcon( C, i );
|
||||
}
|
||||
}
|
||||
C.EnableStencilTest( false );
|
||||
}
|
||||
|
||||
/** Draws a targeting icon for each one of our locked targets */
|
||||
simulated function DrawTargetingIcon( Canvas Canvas, int Index )
|
||||
{
|
||||
local vector WorldPos, ScreenPos;
|
||||
local float IconSize, IconScale;
|
||||
|
||||
// Project world pos to canvas
|
||||
WorldPos = GetLockedTargetLoc( LockedTargets[Index] );
|
||||
ScreenPos = Canvas.Project( WorldPos );//WorldToCanvas(Canvas, WorldPos);
|
||||
|
||||
// calculate scale based on resolution and distance
|
||||
IconScale = fMin( float(Canvas.SizeX) / 1024.f, 1.f );
|
||||
// Scale down up to 40 meters away, with a clamp at 20% size
|
||||
IconScale *= fClamp( 1.f - VSize(WorldPos - Instigator.Location) / 4000.f, 0.2f, 1.f );
|
||||
|
||||
// Apply size scale
|
||||
IconSize = 200.f * IconScale;
|
||||
ScreenPos.X -= IconSize / 2.f;
|
||||
ScreenPos.Y -= IconSize / 2.f;
|
||||
|
||||
// Off-screen check
|
||||
if( ScreenPos.X < 0 || ScreenPos.X > Canvas.SizeX || ScreenPos.Y < 0 || ScreenPos.Y > Canvas.SizeY )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Canvas.SetPos( ScreenPos.X, ScreenPos.Y );
|
||||
|
||||
// Draw the icon
|
||||
Canvas.DrawTile( LockedOnIcon, IconSize, IconSize, 0, 0, LockedOnIcon.SizeX, LockedOnIcon.SizeY, LockedIconColor );
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State WeaponSingleFiring
|
||||
* Fire must be released between every shot.
|
||||
*********************************************************************************************/
|
||||
|
||||
simulated state WeaponSingleFiring
|
||||
{
|
||||
simulated function BeginState( Name PrevStateName )
|
||||
{
|
||||
LockedTargets.Length = 0;
|
||||
|
||||
super.BeginState( PrevStateName );
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* State WeaponBurstFiring
|
||||
* Fires a burst of bullets. Fire must be released between every shot.
|
||||
*********************************************************************************************/
|
||||
|
||||
simulated state WeaponBurstFiring
|
||||
{
|
||||
simulated function int GetBurstAmount()
|
||||
{
|
||||
// Clamp our bursts to either the number of targets or how much ammo we have remaining
|
||||
return Clamp( LockedTargets.Length, 1, AmmoCount[GetAmmoType(CurrentFireMode)] );
|
||||
}
|
||||
|
||||
/** Overridden to apply scaled recoil when in multi-rocket mode */
|
||||
simulated function ModifyRecoil( out float CurrentRecoilModifier )
|
||||
{
|
||||
super.ModifyRecoil( CurrentRecoilModifier );
|
||||
|
||||
CurrentRecoilModifier *= BurstFireRecoilModifier;
|
||||
}
|
||||
|
||||
simulated function bool ShouldRefire()
|
||||
{
|
||||
return LockedTargets.Length > 0;
|
||||
}
|
||||
|
||||
simulated function FireAmmunition()
|
||||
{
|
||||
super.FireAmmunition();
|
||||
if (Role < ROLE_Authority)
|
||||
{
|
||||
LockedTargets.Remove(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event EndState( Name NextStateName )
|
||||
{
|
||||
LockedTargets.Length = 0;
|
||||
|
||||
super.EndState( NextStateName );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Reduce the damage received and apply it to the shield
|
||||
*/
|
||||
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
|
||||
{
|
||||
super.AdjustDamage(InDamage, DamageType, DamageCauser);
|
||||
|
||||
if (Instigator != none && DamageCauser.Instigator == Instigator)
|
||||
{
|
||||
InDamage *= SelfDamageReductionValue;
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ForceReloadTime=0.4f
|
||||
|
||||
// Inventory
|
||||
InventoryGroup=IG_Primary
|
||||
GroupPriority=100
|
||||
InventorySize=6
|
||||
WeaponSelectTexture=Texture2D'wep_ui_hrg_locust_tex.UI_WeaponSelect_HRG_Locust'
|
||||
|
||||
// FOV
|
||||
MeshFOV=86
|
||||
MeshIronSightFOV=65
|
||||
PlayerIronSightFOV=70
|
||||
PlayerSprintFOV=95
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=50
|
||||
DOF_FG_MaxNearBlurSize=2.5
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=20.0,Y=5,Z=-5)
|
||||
FastZoomOutTime=0.2
|
||||
|
||||
// Content
|
||||
PackageKey="HRG_Locust"
|
||||
FirstPersonMeshName="wep_1p_hrg_locust_mesh.Wep_1stP_HRG_Locust_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_HRG_Locust_ANIM.Wep_1stP_HRG_Locust_Anim"
|
||||
PickupMeshName="wep_3p_hrg_locust_mesh.Wep_3rdP_HRG_Locust_Pickup"
|
||||
AttachmentArchetypeName="wep_hrg_locust_arch.Wep_HRG_Locust_3P"
|
||||
MuzzleFlashTemplateName="wep_hrg_locust_arch.Wep_HRG_Locust_MuzzleFlash"
|
||||
|
||||
// Target Locking
|
||||
MinTargetDistFromCrosshairSQ=2500.0f // 0.5 meters
|
||||
TimeBetweenLockOns=0.06f
|
||||
TargetValidationCheckInterval=0.1f
|
||||
MaxLockMaintainFOVDotThreshold=0.36f
|
||||
|
||||
// LockOn Visuals
|
||||
LockedOnIcon=Texture2D'Wep_Scope_TEX.Wep_1stP_Yellow_Red_Target'
|
||||
LockedIconColor=(R=1.f, G=0.f, B=0.f, A=0.5f)
|
||||
|
||||
// Lock On/Lost Sounds
|
||||
LockAcquiredSoundFirstPerson=AkEvent'WW_WEP_SA_Railgun.Play_Railgun_Scope_Locked'
|
||||
LockLostSoundFirstPerson=AkEvent'WW_WEP_SA_Railgun.Play_Railgun_Scope_Lost'
|
||||
|
||||
// Zooming/Position
|
||||
IronSightPosition=(X=0,Y=-0.065,Z=-0.31)
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=6
|
||||
SpareAmmoCapacity[0]=84
|
||||
InitialSpareMags[0]=3
|
||||
AmmoPickupScale[0]=2.0
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=400
|
||||
minRecoilPitch=275
|
||||
maxRecoilYaw=200
|
||||
minRecoilYaw=-200
|
||||
RecoilRate=0.085
|
||||
RecoilBlendOutRatio=0.35
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=1500
|
||||
RecoilMinPitchLimit=64785
|
||||
RecoilISMaxYawLimit=50
|
||||
RecoilISMinYawLimit=65485
|
||||
RecoilISMaxPitchLimit=500
|
||||
RecoilISMinPitchLimit=65485
|
||||
RecoilViewRotationScale=0.8
|
||||
FallingRecoilModifier=1.5
|
||||
HippedRecoilModifier=1.25
|
||||
BurstFireRecoilModifier=0.15f // Reduce recoil between rockets when in burst mode
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'UI_FireModes_TEX.UI_FireModeSelect_Rocket'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_HRG_Locust'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.35
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=1 //140 // 120.0 //100.00
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_Locust'
|
||||
Spread(DEFAULT_FIREMODE)=0.025
|
||||
FireOffset=(X=20,Y=4.0,Z=-3)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FireModeIconPaths(ALTFIRE_FIREMODE)= Texture2D'UI_SecondaryAmmo_TEX.UI_FireModeSelect_AutoTarget'
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponBurstFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_HRG_Locust'
|
||||
FireInterval(ALTFIRE_FIREMODE)=+0.3 //0.1
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=1 //140 // 120.0 //100.00
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_Locust'
|
||||
Spread(ALTFIRE_FIREMODE)=0.025
|
||||
AmmoCost(ALTFIRE_FIREMODE)=1
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_Locust'
|
||||
InstantHitDamage(BASH_FIREMODE)=29
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Fire_1P')
|
||||
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_Seeker_6.Play_WEP_Seeker_6_Fire_1P')
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_RPG7.Play_WEP_SA_RPG7_DryFire'
|
||||
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_RPG7.Play_WEP_SA_RPG7_DryFire'
|
||||
|
||||
// Animation
|
||||
bHasFireLastAnims=true
|
||||
IdleFidgetAnims=(Guncheck_v1, Guncheck_v2)
|
||||
|
||||
//BonesToLockOnEmpty=(RW_Grenade1)
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_Survivalist'
|
||||
|
||||
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Heavy_Recoil_SingleShot'
|
||||
|
||||
// Audio
|
||||
Begin Object Class=AkComponent name=IronsightsComponent0
|
||||
bForceOcclusionUpdateInterval=true
|
||||
OcclusionUpdateInterval=0.f // never update occlusion for footsteps
|
||||
bStopWhenOwnerDestroyed=true
|
||||
End Object
|
||||
IronsightsComponent=IronsightsComponent0
|
||||
Components.Add(IronsightsComponent0)
|
||||
IronsightsZoomInSound=AkEvent'WW_WEP_Seeker_6.Play_Seeker_6_Iron_In'
|
||||
IronsightsZoomOutSound=AkEvent'WW_WEP_Seeker_6.Play_Seeker_6_Iron_In_Out'
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
//WeaponUpgrades[1]=(IncrementDamage=1.125f,IncrementWeight=1)
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Damage1, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
|
||||
|
||||
SelfDamageReductionValue = 0f;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user