1
0
This commit is contained in:
2021-03-02 14:56:51 +03:00
parent 1fd126afa1
commit 28f1e3c001
95 changed files with 3970 additions and 260 deletions

View File

@ -0,0 +1,24 @@
//=============================================================================
// KFDT_Ballistic_GravityImploderImpact
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_GravityImploderImpact extends KFDT_Ballistic_Shell
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=750
KDeathVel=1500
StumblePower=250
KnockdownPower=50
GunHitPower=150
WeaponDef=class'KFWeapDef_GravityImploder'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
}

View File

@ -0,0 +1,23 @@
//=============================================================================
// KFDT_Ballistic_GravityImploderImpactAlt
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_GravityImploderImpactAlt extends KFDT_Ballistic_Shell
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=750
KDeathVel=1500
StumblePower=250
GunHitPower=150
WeaponDef=class'KFWeapDef_GravityImploder'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
}

View File

@ -0,0 +1,46 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** 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)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Impact_AltFire'
OverrideImpactSound=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Hit_Surface'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=250
GunHitPower=120
MicrowavePower=25
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,46 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** 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)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_Microwave_Assault_EMIT.FX_Microwave_Assault_Impact'
OverrideImpactSound=AkEvent'WW_WEP_SA_DragonsBreath.Play_Bullet_DragonsBreath_Impact_Dirt'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=50
GunHitPower=60
MicrowavePower=50
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,47 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** 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)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Impact'
OverrideImpactSound=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Hit_Surface'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=0
GunHitPower=30
MicrowavePower=75
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
bCanObliterate=true
bCanGib=true
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

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

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Bludgeon_HRG_SonicGun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2017 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_HRG_SonicGun extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
ModifierPerkList(0)=class'KFPerk_Survivalist'
//defaults
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,33 @@
//=============================================================================
// KFDT_Explosive_GravityImploder
//=============================================================================
// Explosive damage type for the Gravity Imploder explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_GravityImploder extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood=true
// physics impact
//GibImpulseScale=0.9
//KDeathUpKick=1000
//KDeathVel=300
//RadialDamageImpulse=-1000
//KDamageImpulse=550
RadialDamageImpulse=-200
GibImpulseScale=0.85
KDeathUpKick=-200
KDeathVel=200
StumblePower=200
ModifierPerkList(0)=class'KFPerk_Demolitionist'
WeaponDef=class'KFWeapDef_GravityImploder'
}

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFDT_Explosive_GravityImploderWave
//=============================================================================
// Explosive damage type for the Gravity Imploder shockwave
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_GravityImploderWave extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood=true
// physics impact
RadialDamageImpulse=3000 //5000 //20000
GibImpulseScale=0.15
KDeathUpKick=1000
KDeathVel=300
KnockdownPower=400
//Perk
ModifierPerkList(0)=class'KFPerk_Demolitionist'
WeaponDef=class'KFWeapDef_GravityImploder'
}

View File

@ -6,11 +6,15 @@
// Killing Floor 2
// Copyright (C) 2016 Tripwire Interactive LLC
//=============================================================================
class KFDT_Freeze_FreezeThrower_IceShards extends KFDT_Freeze
class KFDT_Freeze_FreezeThrower_IceShards extends KFDT_Ballistic_Shotgun
abstract;
defaultproperties
{
KDamageImpulse=500
KDeathUpKick=-500
KDeathVel=350
WeaponDef=class'KFWeapDef_FreezeThrower'
FreezePower=0
StumblePower=25

View File

@ -11,16 +11,17 @@ class KFDT_Piercing_Crossbow extends KFDT_Piercing
abstract
hidedropdown;
var float HeadStunPower;
defaultproperties
{
KDamageImpulse=1500
KDeathUpKick=250
KDeathVel=150
KnockdownPower=20
StunPower=101 //90
HeadStunPower=1000 // Stun ensured when hit in the head
StunPower=30 // Stun used otherwise
StumblePower=250
GunHitPower=100
MeleeHitPower=40

View File

@ -0,0 +1,15 @@
//=============================================================================
// KFExplosion_GravityImplosion
//=============================================================================
// Implosive damage type for the Gravity Imploder "explosion"
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_GravityImplosion extends KFExplosionActor;
defaultproperties
{
}

View File

@ -41,6 +41,8 @@ var byte WaveMax; // The "end" wave
var int WaveNum; // The wave we are currently in
var bool bHumanDeathsLastWave; //Track this separate from player count in case someone dies and leaves
var int ObjectiveSpawnDelay; // How long should the first wave be delayed if there is an active objective.
// The boss waves spams the WaveEnd functions, adding this to prevent it (was affecting seasonal events).
var protected transient bool bWaveStarted;
/** Whether this game mode should play music from the get-go (lobby) */
static function bool ShouldPlayMusicAtStart()
@ -935,15 +937,17 @@ function ResetAllPickups()
/** Overridden to scale the number of active pickups by wave */
function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
{
NumPickups *= (float(WaveNum) / float(WaveMax));
// make sure to have at least 1 ammo pickup in the level, and if it's wave 2 or later make sure there's
// at least one weapon pickup
if( NumPickups == 0 && PickupList.Length > 0 && (WaveNum > 1 || KFPickupFactory_Ammo(PickupList[0]) != none) )
if(NumPickups != 0)
{
NumPickups = 1;
NumPickups *= (float(WaveNum) / float(WaveMax));
// make sure to have at least 1 ammo pickup in the level, and if it's wave 2 or later make sure there's
// at least one weapon pickup
if( NumPickups == 0 && PickupList.Length > 0 && (WaveNum > 1 || KFPickupFactory_Ammo(PickupList[0]) != none) )
{
NumPickups = 1;
}
}
super.ResetPickups( PickupList, NumPickups );
}
@ -1071,6 +1075,8 @@ function WaveStarted()
//So the server browser can have our new wave information
UpdateGameSettings();
bWaveStarted = true;
}
/** Do something when there are no AIs left */
@ -1111,6 +1117,9 @@ function WaveEnded(EWaveEndCondition WinCondition)
local int i;
local KFPlayerController KFPC;
if(!bWaveStarted)
return;
if (WorldInfo.NetMode == NM_DedicatedServer)
{
scripttrace();
@ -1182,6 +1191,7 @@ function WaveEnded(EWaveEndCondition WinCondition)
// To allow any statistics that are recorded on the very last zed killed at the end of the wave,
// wait a single frame to allow them to finalize.
SetTimer( WorldInfo.DeltaSeconds, false, nameOf(Timer_FinalizeEndOfWaveStats) );
bWaveStarted=false;
}
/** All stats should be finalized here */
@ -1822,7 +1832,8 @@ DefaultProperties
AARDisplayDelay=15
bCanPerkAlwaysChange=false
MaxGameDifficulty=3
bWaveStarted=false
ObjectiveSpawnDelay=5
SpawnManagerClasses(0)=class'KFGame.KFAISpawnManager_Short'
@ -1871,35 +1882,35 @@ DefaultProperties
// Short Wave
LateArrivalStarts(0)={(
StartingDosh[0]=550,
StartingDosh[1]=650,
StartingDosh[2]=1200,
StartingDosh[3]=1500
StartingDosh[0]=700, //550
StartingDosh[1]=850, //650
StartingDosh[2]=1650, //1200
StartingDosh[3]=2200 //1500
)}
// Normal Wave
LateArrivalStarts(1)={(
StartingDosh[0]=450,
StartingDosh[1]=600,
StartingDosh[2]=750,
StartingDosh[3]=800,
StartingDosh[4]=1100,
StartingDosh[5]=1400,
StartingDosh[6]=1500,
StartingDosh[7]=1600
StartingDosh[0]=600, //450
StartingDosh[1]=800, //600
StartingDosh[2]=1000, //750
StartingDosh[3]=1100, //800
StartingDosh[4]=1500, //1100
StartingDosh[5]=2000, //1400
StartingDosh[6]=2200, //1500
StartingDosh[7]=2400 //1600
)}
// Long Wave
LateArrivalStarts(2)={(
StartingDosh[0]=450,
StartingDosh[1]=550,
StartingDosh[2]=750,
StartingDosh[3]=1000,
StartingDosh[4]=1200,
StartingDosh[5]=1300,
StartingDosh[6]=1400,
StartingDosh[7]=1500,
StartingDosh[8]=1600,
StartingDosh[9]=1600
StartingDosh[0]=600, //450
StartingDosh[1]=700, //550
StartingDosh[2]=1000, //750
StartingDosh[3]=1300, //1000
StartingDosh[4]=1650, //1200
StartingDosh[5]=1800, //1300
StartingDosh[6]=2000, //1400
StartingDosh[7]=2200, //1500
StartingDosh[8]=2400, //1600
StartingDosh[9]=2400 //1600
)}
}

View File

@ -129,6 +129,13 @@ function SetPickupItemList()
//So many loops
foreach AllActors(class'KFPickupFactory_Item', ItemFactory)
{
//we dont want item pickups, so kiss them goodbye
if(OutbreakEvent.ActiveEvent.OverrideItemPickupModifier == 0)
{
ItemFactory.ShutDown();
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
continue;
}
foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem)
{
for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx)
@ -211,15 +218,81 @@ function ResetPermanentZed()
}
}
function float GetAdjustedAIDoshValue( class<KFPawn_Monster> MonsterClass )
{
return super.GetAdjustedAIDoshValue(MonsterClass) * OutbreakEvent.ActiveEvent.DoshOnKillGlobalModifier;
}
protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPawn_Monster MonsterPawn )
{
super.ScoreMonsterKill(Killer, Monster, MonsterPawn);
if(OutbreakEvent.ActiveEvent.bHealAfterKill)
{
if( MonsterPawn != none && MonsterPawn.DamageHistory.Length > 0 )
{
HealAfterKilling( MonsterPawn, Killer );
}
}
}
/** Heal players after a Zed was killed, based in more heal to the player that was the killer and less heal to the players that damaged the Zed */
function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
{
local int i;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo DamagerKFPRI;
local array<DamageInfo> DamageHistory;
local array<KFPlayerController> Attackers;
local KFPawn_Human PawnHuman;
DamageHistory = MonsterPawn.DamageHistory;
for ( i = 0; i < DamageHistory.Length; i++ )
{
if( DamageHistory[i].DamagerController != none
&& DamageHistory[i].DamagerController.bIsPlayer
&& DamageHistory[i].DamagerPRI.GetTeamNum() == 0
&& DamageHistory[i].DamagerPRI != none )
{
DamagerKFPRI = KFPlayerReplicationInfo(DamageHistory[i].DamagerPRI);
if( DamagerKFPRI != none )
{
KFPC = KFPlayerController(DamagerKFPRI.Owner);
if( KFPC != none )
{
if(Attackers.Find(KFPC) < 0)
{
PawnHuman = KFPawn_Human(KFPC.Pawn);
Attackers.AddItem(KFPC);
if( KFPC == Killer )
{
`Log("Heal by Kill: "$MonsterPawn.HealByKill);
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
if( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none )
{
KFPC.ReceivePowerUp(class'KFPowerUp_HellishRage_NoCostHeal');
}
}
else
{
`Log("Heal by Assistance: "$MonsterPawn.HealByAssistance);
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
}
}
}
}
}
}
}
function StartMatch()
{
super.StartMatch();
//Set timer for global ticking damage
if (OutbreakEvent.ActiveEvent.GlobalDamageTickRate > 0.f && OutbreakEvent.ActiveEvent.GlobalDamageTickAmount > 0.f)
{
SetTimer(OutbreakEvent.ActiveEvent.GlobalDamageTickRate, true, 'ApplyGlobalDamage', OutbreakEvent);
}
}
function CreateDifficultyInfo(string Options)
@ -321,6 +394,8 @@ function TickZedTime( float DeltaTime )
function WaveEnded(EWaveEndCondition WinCondition)
{
local KFPawn_Human Pawn;
super.WaveEnded(WinCondition);
if (OutbreakEvent.ActiveEvent.bPermanentZedTime && ZedTimeRemaining > ZedTimeBlendOutTime)
@ -328,6 +403,16 @@ function WaveEnded(EWaveEndCondition WinCondition)
ClearZedTimePCTimers();
ZedTimeRemaining = ZedTimeBlendOutTime;
}
if (OutbreakEvent.ActiveEvent.bHealPlayerAfterWave)
{
foreach WorldInfo.AllPawns(class'KFPawn_Human', Pawn)
{
Pawn.Health = Pawn.HealthMax;
}
}
DisableGlobalDamage();
}
function ClearZedTimePCTimers()
@ -360,6 +445,24 @@ function EndOfMatch(bool bVictory)
function StartWave()
{
super.StartWave();
// Stop Global Damage for boss wave
if (!OutbreakEvent.ActiveEvent.bApplyGlobalDamageBossWave && WaveNum == WaveMax)
{
DisableGlobalDamage();
}
// In case there was a previous boss wave. Not sure if possible
else if (OutbreakEvent.ActiveEvent.GlobalDamageTickRate > 0.f && OutbreakEvent.ActiveEvent.GlobalDamageTickAmount > 0.f)
{
if(!IsTimerActive('EnableGlobalDamage', self))
{
SetTimer(OutbreakEvent.ActiveEvent.DamageDelayAfterWaveStarted, false, 'EnableGlobalDamage', self);
}
// Check if we are in the zed frustration time to stop applying damage
SetTimer(1.0f, true, 'CheckForZedFrustrationMode', self);
}
if (OutbreakEvent.ActiveEvent.bPermanentZedTime)
{
//If we're a boss wave, wait until the camera animation is going
@ -378,6 +481,40 @@ function StartWave()
{
SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave));
}
}
function EnableGlobalDamage()
{
MyKFGRI.SetGlobalDamage(true);
SetTimer(OutbreakEvent.ActiveEvent.GlobalDamageTickRate, true, 'ApplyGlobalDamage', OutbreakEvent);
}
function DisableGlobalDamage()
{
MyKFGRI.SetGlobalDamage(false);
if (IsTimerActive('ApplyGlobalDamage', OutbreakEvent))
{
ClearTimer('ApplyGlobalDamage', OutbreakEvent);
}
if (IsTimerActive('EnableGlobalDamage', self))
{
ClearTimer('EnableGlobalDamage', self);
}
}
function CheckForZedFrustrationMode()
{
if(IsTimerActive('ApplyGlobalDamage', OutbreakEvent))
{
if(class'KFAIController'.default.FrustrationThreshold > 0 && MyKFGRI.AIRemaining <= class'KFAIController'.default.FrustrationThreshold)
{
DisableGlobalDamage();
ClearTimer('CheckForZedFrustrationMode', self);
}
}
}
function BossCameraZedTimeRecheck()
@ -477,6 +614,8 @@ function InitAllPickups()
{
NumWeaponPickups = ItemPickups.Length * (OutbreakEvent.ActiveEvent.OverrideItemPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideItemPickupModifier : DifficultyInfo.GetItemPickupModifier());
NumAmmoPickups = AmmoPickups.Length * (OutbreakEvent.ActiveEvent.OverrideAmmoPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideAmmoPickupModifier : DifficultyInfo.GetAmmoPickupModifier());
`log("OutbreakEvent.ActiveEvent.OverrideItemPickupModifier"@OutbreakEvent.ActiveEvent.OverrideItemPickupModifier);
`log("NumWeaponPickups"@NumWeaponPickups);
`if(`__TW_SDK_)
if( BaseMutator != none )
@ -528,6 +667,7 @@ function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
else if (OutbreakEvent.ActiveEvent.WaveItemPickupModifiers.Length >= WaveMax && KFPickupFactory_Item(PickupList[0]) != none)
{
NumPickups *= OutbreakEvent.ActiveEvent.WaveItemPickupModifiers[WaveNum];
if(OutbreakEvent.ActiveEvent.OverrideItemPickupModifier == 0) NumPickups = 0;
super(KFGameInfo).ResetPickups(PickupList, NumPickups);
}
//Otherwise, use normal path
@ -560,7 +700,25 @@ function bool AllowPrimaryWeapon(string ClassPath)
{
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
{
if (Item.ClassName == name(ClassPath))
if ( name(Item.WeaponDef.default.WeaponClassPath) == name(ClassPath) )
{
return true;
}
}
return false;
}
return true;
}
/** Whether or not a specific secondary weapon is allowed. Called at player spawn time while setting inventory. */
function bool AllowSecondaryWeapon(string ClassPath)
{
local STraderItem Item;
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none && OutbreakEvent.ActiveEvent.bSpawnWeaponListAffectsSecondaryWeapons)
{
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
{
if ( name(Item.WeaponDef.default.WeaponClassPath) == name(ClassPath) )
{
return true;
}
@ -580,6 +738,27 @@ function int AdjustStartingGrenadeCount(int CurrentCount)
return CurrentCount;
}
/** Allows gametype to validate a perk for the current match */
function bool IsPerkAllowed(class<KFPerk> PerkClass)
{
Local int index;
if(OutbreakEvent.ActiveEvent.PerksAvailableList.length == 0)
{
return true;
}
for( index=0 ; index<OutbreakEvent.ActiveEvent.PerksAvailableList.length ; index++)
{
if(OutbreakEvent.ActiveEvent.PerksAvailableList[index] == PerkClass)
{
return true;
}
}
return false;
}
function RestartPlayer(Controller NewPlayer)
{
local KFPawn_Human KFPH;
@ -609,6 +788,7 @@ function DoDeathExplosion(Pawn DeadPawn, KFGameExplosion ExplosionTemplate, clas
}
}
defaultproperties
{
//Overrides

View File

@ -100,7 +100,7 @@ defaultproperties
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',bStartEnraged=true,bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.BigPawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster')
)},
)}
)}
//Zombies
@ -310,9 +310,104 @@ defaultproperties
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0)
)},
)}
)}
//Blood Thirst
SetEvents[8]={(
EventDifficulty = 1, //2
GameLength = GL_Normal,
GlobalDamageTickRate = 2.0,
GlobalDamageTickAmount = 6.0, //5.0,
bHealAfterKill = true,
bCannotBeHealed = true,
bGlobalDamageAffectsShield = false,
bHealPlayerAfterWave = true,
bApplyGlobalDamageBossWave = false,
DamageDelayAfterWaveStarted = 10.0f,
SpawnRateMultiplier=6.0, //8.0,
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=1.0,DamageDealtScale=0.75)
)},
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealByKill=12,HealByAssistance=8, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',HealByKill=7,HealByAssistance=5, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealByKill=7,HealByAssistance=5, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealByKill=16, HealByAssistance=11, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',HealByKill=12,HealByAssistance=8, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealByKill=50,HealByAssistance=35, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealByKill=60,HealByAssistance=42, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealByKill=36,HealByAssistance=25, InitialGroundSpeedModifierScale=1.20)
)}
)}
//Coliseum
SetEvents[9]={(
EventDifficulty=3,
GameLength=GL_Normal,
PerksAvailableList=(class'KFPerk_Berserker'),
SpawnWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.ColliseumWeeklySpawnList',
bSpawnWeaponListAffectsSecondaryWeapons=true,
TraderWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.ColliseumWeeklyTraderList',
bColliseumSkillConditionsActive=true,
bModifyZedTimeOnANearZedKill=true,
ZedTimeOnANearZedKill=0.6,
PickupResetTime=PRS_Wave,
OverrideItemPickupModifier=0,
DoshOnKillGlobalModifier=0.7,
SpawnRateMultiplier=2.0,
WaveAICountScale=(0.75, 0.7, 0.65, 0.6, 0.55, 0.5),
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealthScale=1.0,DamageDealtScale=0.75)
)},
SpawnReplacementList={(
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=0.1),
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=0.1),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=1.0),
(SpawnEntry=AT_Stalker,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=1.0),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedFleshpoundMini'),PercentChance=0.5),
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedFleshpoundMini'),PercentChance=0.5),
(SpawnEntry=AT_Husk,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=1.0),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.3),
(SpawnEntry=AT_Scrake,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.5)
)}
)}
//Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8

View File

@ -415,7 +415,9 @@ DefaultProperties
Begin Object Name=KFPawnSkeletalMeshComponent
// Enabling kinematic for physics interaction while alive. (see also MinDistFactorForKinematicUpdate)
bUpdateKinematicBonesFromAnimation=true
End Object
// Beam weapons (microwave gun, flamey things, etc.) won't hit his head without this
BlockNonZeroExtent=true
End Object
// ---------------------------------------------
// Stats

View File

@ -440,7 +440,7 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
}
}
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser)
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser)
{
if (ShieldHealthPctByte == 0)
{

View File

@ -26,18 +26,18 @@ defaultproperties
DoshValue=75 //200 //25 //50
// Stats
// Stats
XPValues(0)=17
XPValues(1)=22
XPValues(2)=30
XPValues(3)=34
Begin Object Name=MeleeHelper_0
Begin Object Name=MeleeHelper_0
BaseDamage=49.f
MaxHitRange=250.f
MomentumTransfer=55000.f
MyDamageType=class'KFDT_Bludgeon_Fleshpound'
End Object
End Object
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(0.62)))

View File

@ -692,6 +692,9 @@ function SetBattlePhase(int Phase)
ArmorInfo.ExplodeArmor(HEAD_ARMOR_IDX);
ArmorInfo.ExplodeArmor(CLAW_ARMOR_IDX);
ArmorInfo.UpdateArmorUI();
// Forcing armor to be updated.
OnArmorZoneStatusUpdated();
}
DoStumble();

View File

@ -163,6 +163,24 @@ simulated function SpawnFlightEffects()
}
}
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
Explode(HitLocation, HitNormal);
}
}
Super.SyncOriginalLocation();
}
defaultproperties
{
Physics=PHYS_Falling

View File

@ -280,26 +280,7 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) && ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{
//for (Index = 0; Index < vActorsTouched.Length; Index++)
//{
// if(vActorsTouched[Index] == Other)
// {
// return;
// }
//}
//if(Other == LastActorTouched)
//{
// return;
//}
//LastActorTouched = Other;
//bForceNetUpdate=true;
//vActorsTouched.AddItem(Other);
// Don't touch the same actor multiple time's immediately after just
// touching it if the TouchTimeThreshhold is set to greater than 0.
// This was causing projectiles just to "stop" sometimes when hitting
// dead/ragdolled pawns because it was counting as multiple penetrations
if( LastTouched.Actor == Other && TouchTimeThreshhold > 0
&& `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
if( LastTouched.Actor == Other && TouchTimeThreshhold > 0 && `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
{
return;
}
@ -311,13 +292,10 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
// Reflect off Wall w/damping but allow penetration if the pawn is dead
//if(KFPawn_Monster(Other) == None || KFPawn_Monster(Other).Health > 0)
//{
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
//}
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
}
else if (!bDud && !bIsTimedExplosive)
{
@ -350,7 +328,6 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
StopSimulating();
}
}
simulated protected function StopSimulating()
@ -370,6 +347,35 @@ simulated protected function StopSimulating()
}
}
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
ServerForceExplosion();
}
}
Super.SyncOriginalLocation();
}
reliable server function ServerForceExplosion()
{
local vector ExplosionNormal;
if (Instigator.Role == ROLE_Authority && !bHasExploded && !bHasDisintegrated)
{
ExplosionNormal = vect(0,0,1) >> Rotation;
CallExplode(Location, ExplosionNormal);
}
}
defaultproperties
{
TouchTimeThreshhold = 60.0f
@ -392,6 +398,10 @@ defaultproperties
DampenFactorParallel=0
WallHitDampenFactor=0.5
WallHitDampenFactorParallel=0.5
bNetTemporary=False
NetPriority=5
NetUpdateFrequency=200
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
bUseClientSideHitDetection=true

View File

@ -0,0 +1,188 @@
//=============================================================================
// KFProj_Grenade_GravityImploder
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_Grenade_GravityImploder extends KFProj_BallisticExplosive
hidedropdown;
/* Ensure it detonates */
var float DetonationTime;
var float VortexDuration;
var float VortexRadius;
var float VortexImpulseStrength;
var protected transient bool bVortexActive;
var protected RB_RadialImpulseComponent RadialImpulseComponent;
simulated state GrenadeState
{
simulated event BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
if (Role == ROLE_Authority)
{
SetTimer(DetonationTime, false, nameOf(Timer_Detonate));
}
}
}
simulated state VortexState
{
simulated event BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
ClearTimer(nameof(Timer_Detonate));
bVortexActive = true;
if (Role == ROLE_Authority)
{
SetTimer(VortexDuration, false, 'Timer_EndVortex');
}
}
simulated event Tick(float DeltaTime)
{
local float ImpulseModifier;
if(bVortexActive && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
{
// ImpulseModifier = (bReduceGibImpulseOnTick) ? (1.0f - AccumulatedTime / Lifetime) : 1.0f;
ImpulseModifier = 1.0f;
RadialImpulseComponent.ImpulseRadius = VortexRadius;
RadialImpulseComponent.ImpulseStrength = VortexImpulseStrength * ImpulseModifier;
RadialImpulseComponent.bVelChange = true;
RadialImpulseComponent.ImpulseFalloff = RIF_Constant;
RadialImpulseComponent.FireImpulse(Location);
}
}
}
/**
* Set the initial velocity and cook time
*/
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
AdjustCanDisintigrate();
GotoState('GrenadeState');
}
simulated function Timer_Detonate()
{
Detonate();
}
simulated function Detonate()
{
Explode(Location, vect(0,0,1) >> Rotation);
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
super.Explode(HitLocation, HitNormal);
GotoState('VortexState');
}
simulated function Timer_EndVortex()
{
bVortexActive = false;
DeferredDestroy(0.15);
}
/** Called when the owning instigator controller has left a game */
simulated function OnInstigatorControllerLeft()
{
if( WorldInfo.NetMode != NM_Client )
{
SetTimer( 1.f + Rand(5) + fRand(), false, nameOf(Timer_Detonate) );
}
}
defaultproperties
{
TouchTimeThreshhold = 60.0f
Physics=PHYS_Falling
Speed=3200
MaxSpeed=3200
TerminalVelocity=3200
GravityScale=1.0
LifeSpan=0.f
bWarnAIWhenFired=true
ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile'
ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile_ZEDTIME'
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=0,G=25,B=250,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=ImploTemplate0
Damage=350 //150
DamageRadius=375 //425
DamageFalloffExponent=0.2 //0.25
DamageDelay=0.f
MomentumTransferScale=-10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_GravityImploder'
KnockDownStrength=0
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion'
ExplosionSound=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Grenade_Yellow_Implosion'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.2
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=200
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ImploTemplate0
bIsTimedExplosive=false;
DetonationTime=5.0
VortexRadius=450
VortexImpulseStrength=-100
VortexDuration=0.5f
bVortexActive=false
Begin Object Class=RB_RadialImpulseComponent Name=ImpulseComponent0
End Object
RadialImpulseComponent=ImpulseComponent0
Components.Add(ImpulseComponent0)
}

View File

@ -0,0 +1,584 @@
//=============================================================================
// KFProj_Grenade_GravityImploderAlt
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_Grenade_GravityImploderAlt extends KFProj_BallisticExplosive
hidedropdown;
/** Factor added to the rolling speed of the ball when bouncing **/
var(Projectile) float RollingFactor;
/** Indicates that the ball hit the wall and is doing rolling animations **/
var transient bool bIsRolling;
/** Amount of roll stored for this cannonball **/
var transient float CurrentRoll;
var bool bHasAlreadyBounced;
/** Collider **/
var Object Collider;
/** Time before starting the implosion effect **/
var float PreparationTime;
/** Vortex params. */
var float VortexDuration;
var float VortexTime;
var float VortexRadius;
var float VortexAbsorptionStrength;
var float VortexElevationStrength;
var bool bVortexReduceImpulseOnDist;
var protected transient bool bFirstAbsorption;
var protected transient vector VortexLocation;
var protected vector VortexNormal;
var protected KFImpactEffectInfo VortexImpactEffects;
simulated state PreparingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
SetTimer( PreparationTime, false, nameOf(Timer_Ready) );
}
simulated event Tick(float DeltaTime)
{
local vector RollDelta;
local rotator NewRotation;
// Let's roll (only in the client)
if ( bIsRolling && WorldInfo.NetMode != NM_DedicatedServer && Physics != PHYS_None && (Velocity.X != 0 || Velocity.Y != 0) )
{
CurrentRoll -= (Abs(Velocity.X) + Abs(Velocity.Y)) * DeltaTime * RollingFactor;
RollDelta = ((vect(1, 0 , 0) * (Velocity.X)) + (vect(0, 1, 0) * (Velocity.Y) ));
NewRotation = Rotator(RollDelta);
NewRotation.pitch += CurrentRoll;
SetRotation(NewRotation);
}
Super.Tick(DeltaTime);
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
VortexNormal = HitNormal;
ProcessRebound(HitNormal, Wall, WallComp);
if( !bDud && !bIsTimedExplosive )
{
Super.HitWall(HitNormal, Wall, WallComp);
}
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
local bool bWantsClientSideDudHit;
local float TraveledDistance;
local Vector VNorm;
//local int Index;
// If we collided with a Siren shield, let the shield code handle touches
if( Other.IsA('KFTrigger_SirenProjectileShield') )
{
return;
}
if ( !bCollideWithTeammates && Pawn(Other) != None )
{
// Don't hit teammates
if( Other.GetTeamNum() == GetTeamNum() )
{
return;
}
}
// Need to do client side dud hits if this is a client
if( Instigator != none && Instigator.Role < ROLE_Authority )
{
bWantsClientSideDudHit = true;
}
TraveledDistance = (`TimeSince(CreationTime) * Speed);
TraveledDistance *= TraveledDistance;
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) && ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{
// Don't touch the same actor multiple time's immediately after just
// touching it if the TouchTimeThreshhold is set to greater than 0.
// This was causing projectiles just to "stop" sometimes when hitting
// dead/ragdolled pawns because it was counting as multiple penetrations
if( LastTouched.Actor == Other && TouchTimeThreshhold > 0
&& `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
{
return;
}
//TODO: Add an impact sound here
SetIsDud(bWantsClientSideDudHit, HitNormal);
if (Other != Instigator && !Other.bStatic && Other.GetTeamNum() != GetTeamNum() && !CheckRepeatingTouch(Other))
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
// Reflect off Wall w/damping but allow penetration if the pawn is dead
//if(KFPawn_Monster(Other) == None || KFPawn_Monster(Other).Health > 0)
//{
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
//}
}
else if (!bDud && !bIsTimedExplosive)
{
// Process impact hits
if (Other != Instigator && !Other.bStatic)
{
// check/ignore repeat touch events
if( !CheckRepeatingTouch(Other) && Other.GetTeamNum() != GetTeamNum())
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
}
if( WorldInfo.NetMode == NM_Standalone ||
(WorldInfo.NetMode == NM_ListenServer && Instigator != none && Instigator.IsLocallyControlled()) )
{
Super.ProcessTouch( Other, HitLocation, HitNormal );
return;
}
if( Owner != none && KFWeapon( Owner ) != none && Instigator != none )
{
if( Instigator.Role < ROLE_Authority && Instigator.IsLocallyControlled() )
{
KFWeapon(Owner).HandleClientProjectileExplosion(HitLocation, self);
Super.ProcessTouch( Other, HitLocation, HitNormal );
return;
}
}
}
}
}
simulated state WaitingToImplode
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
if (HitNormal Dot vect(0,0,1) > 0.5f)
{
GotoState('ImplodingState');
return;
}
ProcessRebound(HitNormal, Wall, WallComp);
if(!bDud && !bIsTimedExplosive)
{
Super.HitWall(HitNormal, Wall, WallComp);
}
}
simulated function Tick(float Delta)
{
if (vSize(Velocity) < 0.05f)
{
GotoState('ImplodingState');
return;
}
super.Tick(Delta);
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
// Prevent default funcionality;
super.ProcessTouch(Other, HitLocation, HitNormal);
}
}
simulated state ImplodingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
StopSimulating();
AdjustVortexForPerk();
if ( WorldInfo.NetMode != NM_Client )
{
Velocity=vect(0,0,0);
Acceleration=vect(0,0,0);
RotationRate=rot(0,0,0);
GravityScale=0.0;
bFirstAbsorption=true;
VortexTime=0.0f;
SetTimer(VortexDuration, false, nameOf(Detonation_Ready) );
}
VortexLocation = Location + vect(0,0,1) * 125;
// Start VGC
StartVortexVFX();
}
simulated function StartVortexVFX()
{
if(VortexImpactEffects != None)
{
if(VortexImpactEffects.DefaultImpactEffect.ParticleTemplate != None)
{
WorldInfo.MyEmitterPool.SpawnEmitter(VortexImpactEffects.DefaultImpactEffect.ParticleTemplate, VortexLocation, rotator(VortexNormal));
}
if(VortexImpactEffects.DefaultImpactEffect.Sound != None)
{
PlaySoundBase(VortexImpactEffects.DefaultImpactEffect.Sound, true,,, VortexLocation);
}
}
}
simulated function EndState(Name NextStateName)
{
super.EndState(NextStateName);
}
simulated event Tick(float DeltaTime)
{
Super.Tick(DeltaTime);
// Avoids to be moved in case there's any force applied.
SetLocation(VortexLocation);
`if(`notdefined(ShippingPC))
if( KFWeap_GravityImploder(Owner) != none && KFWeap_GravityImploder(Owner).bDebugDrawVortex)
{
DrawDebugSphere(Location, VortexRadius, 125, 0, 0, 255, false);
}
`endif
if (WorldInfo.NetMode < NM_Client)
{
VortexTime += DeltaTime;
AbsorbEnemies();
bFirstAbsorption=false;
}
}
function AdjustVortexForPerk()
{
local KFPlayerController KFPC;
local KFPerk Perk;
KFPC = KFPlayerController(InstigatorController);
if( KFPC != none )
{
Perk = KFPC.GetPerk();
if(Perk != none)
{
VortexRadius = default.VortexRadius * Perk.GetAoERadiusModifier();
}
}
}
simulated function AbsorbEnemies()
{
local Actor Victim;
local TraceHitInfo HitInfo;
local KFPawn KFP;
local KFPawn_Monster KFPM;
local float ColRadius, ColHeight;
local float Dist;
local vector Dir;
local vector Momentum;
local float MomentumModifier;
foreach CollidingActors(class'Actor', Victim, VortexRadius, VortexLocation, true,, HitInfo)
{
KFP = KFPawn(Victim);
KFPM = KFPawn_Monster(Victim);
if (Victim != Self
&& (!Victim.bWorldGeometry || Victim.bCanBeDamaged)
&& (NavigationPoint(Victim) == None)
&& Victim != Instigator
&& KFP != None
&& KFPawn_Human(Victim) == none // No player's character
&& (KFPM == none || VortexTime < VortexDuration*KFPM.GetVortexAttractionModifier()) )
{
KFP.GetBoundingCylinder(ColRadius, ColHeight);
if (bFirstAbsorption)
{
Dir = vect(0,0,1);
Momentum = Dir * VortexElevationStrength;
}
else
{
Dir = Normal(VortexLocation - KFP.Location);
Dist = FMax(vSize(Dir) - ColRadius, 0.f);
MomentumModifier = bVortexReduceImpulseOnDist ? (1.0f - Dist / VortexRadius) : 1.0f;
Momentum = Dir * VortexAbsorptionStrength * MomentumModifier + vect(0,0,1) * (Dist/VortexRadius) * VortexAbsorptionStrength;
}
if(KFPM != none)
{
Momentum *= KFPM.GetVortexAttractionModifier();
}
KFP.AddVelocity( Momentum, KFP.Location - 0.5 * (ColHeight + ColRadius) * Dir, class 'KFDT_Explosive_GravityImploder');
}
}
}
}
simulated state DetonatingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
Detonate();
}
}
simulated function PostBeginPlay()
{
Super.PostBeginPlay();
GotoState('PreparingState');
}
simulated function Timer_Ready()
{
// GotoState('ImplodingState');
GotoState('WaitingToImplode');
}
simulated function Detonation_Ready()
{
GotoState('DetonatingState');
}
simulated function Detonate()
{
local vector ExplosionNormal, vExplosionOffset;
// Check if the bomb should explode right now
if (!bHasExploded && !bHasDisintegrated)
{
ExplosionNormal = vect(0,0,1) >> Rotation;
vExplosionOffset.x = 0;
vExplosionOffset.y = 0;
vExplosionOffset.z = 10;
SetLocation(VortexLocation + vExplosionOffset);
CallExplode(VortexLocation, ExplosionNormal);
}
// If not, mark the bomb to explode as soon as it hits something
else
{
bIsTimedExplosive = false;
bNetDirty = true;
}
}
simulated function SetIsDud(bool bWantsClientSideDudHit, vector HitNormal)
{
// This projectile doesn't dud.
}
simulated protected function StopSimulating()
{
Velocity = vect(0,0,0);
Acceleration = vect(0,0,0);
RotationRate = rot(0,0,0);
SetCollision(FALSE, FALSE);
StopFlightEffects();
bRotationFollowsVelocity = FALSE;
}
simulated function ProcessRebound(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
local Vector VNorm;
local rotator NewRotation;
local Vector Offset;
local bool bWantsClientSideDudHit;
local TraceHitInfo HitInfo;
local float TraveledDistance;
bIsRolling = true;
// Need to do client side dud hits if this is a client
if( Instigator != none && Instigator.Role < ROLE_Authority )
{
bWantsClientSideDudHit = true;
}
TraveledDistance = (`TimeSince(CreationTime) * Speed);
TraveledDistance *= TraveledDistance;
// Bounce off the wall and cause the shell to dud if we hit too close
if( bDud || ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * WallHitDampenFactor + (Velocity - VNorm) * WallHitDampenFactorParallel;
Speed = VSize(Velocity);
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) )
{
SetIsDud(bWantsClientSideDudHit, HitNormal);
}
if ( WorldInfo.NetMode != NM_DedicatedServer && Pawn(Wall) == none && bHasAlreadyBounced == false )
{
// do the impact effects
bHasAlreadyBounced = true;
`ImpactEffectManager.PlayImpactEffects(Location, Instigator, HitNormal, GrenadeBounceEffectInfo, true );
}
// if we hit a pawn or we are moving too slowly stop moving and lay down flat
if ( Speed < MinSpeedBeforeStop )
{
ImpactedActor = Wall;
SetPhysics(PHYS_None);
if( ProjEffects != none )
{
ProjEffects.SetTranslation(LandedTranslationOffset);
}
// Position the shell on the ground
RotationRate.Yaw = 0;
RotationRate.Pitch = 0;
RotationRate.Roll = 0;
NewRotation = Rotation;
NewRotation.Pitch = 0;
if(ResetRotationOnStop)
{
SetRotation(NewRotation);
}
Offset.Z = LandedTranslationOffset.X;
SetLocation(Location + Offset);
}
if( !Wall.bStatic && Wall.bCanBeDamaged && (DamageRadius == 0 || bDamageDestructiblesOnTouch) && !CheckRepeatingTouch(Wall) )
{
HitInfo.HitComponent = WallComp;
HitInfo.Item = INDEX_None;
Wall.TakeDamage( Damage, InstigatorController, Location, MomentumTransfer * Normal(Velocity), MyDamageType, HitInfo, self);
}
}
}
defaultproperties
{
TouchTimeThreshhold = 60.0f
Physics=PHYS_Falling
Speed=3200
MaxSpeed=3200
TerminalVelocity=3200
GravityScale=1.0
MomentumTransfer=100000
LifeSpan=0.f
bWarnAIWhenFired=true
RollingFactor=1100
MinSpeedBeforeStop=5
ResetRotationOnStop=false
// Rolling and dampen values
DampenFactor=0.1
DampenFactorParallel=0
WallHitDampenFactor=0.4 //0.5
WallHitDampenFactorParallel=0.4 //0.5
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
bUseClientSideHitDetection=true
bNoReplicationToInstigator=false
bAlwaysReplicateExplosion=true;
bUpdateSimulatedPosition=true
Begin Object Name=CollisionCylinder
CollisionRadius=0.f
CollisionHeight=0.f
BlockNonZeroExtent=false
End Object
ExplosionActorClass=class'KFExplosionActor'
ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Blue_Projectile'
ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Blue_Projectile_ZEDTIME'
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Explosion_Concussive_Force'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=0,G=50,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=1
DamageRadius=450 //600
DamageFalloffExponent=0.f //2
DamageDelay=0.f
MomentumTransferScale=10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_GravityImploderWave'
KnockDownStrength=150
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Explosion'
ExplosionSound=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Grenade_Blue_Explosion'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.2
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=200
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
bIgnoreInstigator=false
End Object
ExplosionTemplate=ExploTemplate0
bIsTimedExplosive=true;
PreparationTime=0.8 //1.0
VortexDuration=0.5 //0.7
VortexRadius=500 //650
VortexAbsorptionStrength=120 //100
VortexElevationStrength=700
bVortexReduceImpulseOnDist=false
bFirstAbsorption=true
VortexImpactEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Attract'
}

View File

@ -8,7 +8,7 @@
// Roberto Moreno (Saber Interactive)
//=============================================================================
class KFProj_LightingFlare_HRGScorcher extends KFProj_RicochetBullet
class KFProj_LightingFlare_HRGScorcher extends KFProjectile
hidedropdown;
/** Time projectile is alive after being sticked to an actor or a pawn */
@ -120,6 +120,10 @@ simulated event HitWall( vector HitNormal, actor Wall, PrimitiveComponent WallCo
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
LastHitNormal = HitNormal;
if (Other != Instigator && !Other.bStatic && DamageRadius == 0.0 )
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
super.ProcessTouch(Other, HitLocation, HitNormal);
SetTimer(StickedTime, false, nameof(Timer_Explode));
StartStickedEffects();
@ -165,6 +169,23 @@ simulated event Tick( float DeltaTime )
}
}
// Last location needs to be correct, even on first tick.
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
StickHelper.TryStick(HitNormal, HitLocation, HitActor);
}
}
}
defaultproperties
{
Physics=PHYS_Falling
@ -186,7 +207,6 @@ defaultproperties
CurrentStickedTime=0.0
StickedLightFadeStartTime=4.0
StickedLightFadeTime=1.0
BouncesLeft=0
TouchTimeThreshhold=0.15
//Sticking to environment or pinning to enemies
@ -197,6 +217,10 @@ defaultproperties
bCollideActors=true
bCollideComplex=true
bPushedByEncroachers=false
bDamageDestructiblesOnTouch=true
bWaitForEffects=true
ProjEffectsFadeOutDuration=0.25
//Network due to sticking feature
bNetTemporary=false
NetPriority=5

View File

@ -228,7 +228,8 @@ simulated event HitWall( vector HitNormal, Actor Wall, PrimitiveComponent WallCo
return;
}
if( CanStick(Wall, HitNormal) && Wall.bStatic == true )
// Stick to static walls and destructible environment objects.
if( CanStick(Wall, HitNormal) && (Wall.bStatic == true || (Wall.bCanBeDamaged && KFPawn(Wall) == none)) )
{
Stick( Location, HitNormal );
}

View File

@ -0,0 +1,55 @@
//=============================================================================
// KFProj_SonicBlastFullyCharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastFullyCharged_HRG_SonicGun extends KFProj_Bullet;
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 1.0 );
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_AltFire_Impacts'
bWarnAIWhenFired=true
Lifespan=10.0
MaxSpeed=10000.0 //7200.0
Speed=10000.0 //7200.0
TerminalVelocity=7200
GravityScale=0.0//0.7
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,113 @@
//=============================================================================
// KFProj_SonicBlastHalfCharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastHalfCharged_HRG_SonicGun extends KFProj_Bullet;
var bool bDebugShowProjectile;
var bool bDebugPersistentLines;
`define SONICBLASTHALFCHARGED_COLLISION 30.0
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 2.0 );
}
simulated event Tick(float DeltaTime)
{
//cylinders debug
//local vector A, B;
//A = Location;
//B.X = `SONICBLASTHALFCHARGED_COLLISION;
//B.Y = `SONICBLASTHALFCHARGED_COLLISION;
//B.Z = `SONICBLASTHALFCHARGED_COLLISION;
//DrawDebugBox( A, B, 255, 255, 0, bDebugPersistentLines); // SLOW! Use for debugging only!
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
// bDebugShowProjectile=true
// bDebugPersistentLines=false
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_AltFire_Impacts'
bWarnAIWhenFired=true
Lifespan=1.8 //3.0
TouchTimeThreshhold=0.2
MaxSpeed=3600.0
Speed=3600.0
TerminalVelocity=3600
Physics=PHYS_Projectile
GravityScale=0.0//0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=false
bCollideActors=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=false
bCanDisintegrate=false
bIgnoreFoliageTouch=true
Begin Object Name=CollisionCylinder
CollisionRadius=0
CollisionHeight=0
BlockNonZeroExtent=false
BlockZeroExtent=true
// for siren scream
CollideActors=true
End Object
// Since we're still using an extent cylinder, we need a line at 0
ExtraLineCollisionOffsets.Add(())
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = -`SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = `SONICBLASTHALFCHARGED_COLLISION))
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,117 @@
//=============================================================================
// KFProj_SonicBlastUncharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastUncharged_HRG_SonicGun extends KFProj_Bullet;
`define SONICBLASTUNCHARGED_COLLISION 45.0
var bool bDebugShowProjectile;
var bool bDebugPersistentLines;
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 3.5 ); //5.0
}
simulated event Tick(float DeltaTime)
{
//cylinders debug
//local vector A, B;
//A = Location;
//B.X = `SONICBLASTUNCHARGED_COLLISION;
//B.Y = `SONICBLASTUNCHARGED_COLLISION;
//B.Z = `SONICBLASTUNCHARGED_COLLISION;
//DrawDebugBox( A, B, 255, 255, 0, bDebugPersistentLines); // SLOW! Use for debugging only!
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
bDebugShowProjectile=true
bDebugPersistentLines=false
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_Impacts'
bWarnAIWhenFired=true
Lifespan=1.5 //1.25
TouchTimeThreshhold=0.4
MaxSpeed=2000.0 //1400.0
Speed=2000.0 //1400.0
TerminalVelocity=1800
Physics=PHYS_Projectile
GravityScale=0.0//0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=false
bCollideActors=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=false
bCanDisintegrate=false
bIgnoreFoliageTouch=true
Begin Object Name=CollisionCylinder
CollisionRadius=0.f
CollisionHeight=0.f
BlockNonZeroExtent=false
BlockZeroExtent=true
// for siren scream
CollideActors=true
End Object
// Since we're still using an extent cylinder, we need a line at 0
ExtraLineCollisionOffsets.Add(())
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION, Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION, Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION, Z = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION, Z = -`SONICBLASTUNCHARGED_COLLISION))
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,140 @@
//=============================================================================
// KFSeasonalEventStats_Spring2021
//=============================================================================
// Tracks event-specific challenges/accomplishments for Spring 2021
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Spring2021 extends KFSeasonalEventStats;
var transient private const int BossKillsRequired, EDARKillsRequired, WavesWithoutDamageRequired, EndlessWaveRequired;
var transient bool bHitTakenThisWave;
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 Dystopia 2029
bObjectiveIsValidForMap[2] = 0; // Kill 100 E.D.A.R.s on Dystopia 2029
bObjectiveIsValidForMap[3] = 0; // Complete a wave without taking any damage 10 times on Dystopia 2029
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Dystopia 2029
if (CapsMapName == "KF-DYSTOPIA2029")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(BossKillsRequired, 0, EDARKillsRequired, WavesWithoutDamageRequired, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
// "Cyborg | Companion Backpack | Precious"
GrantEventItem(8716);
}
}
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
// Dystopia weekly
if (bObjectiveIsValidForMap[1] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Spring, 1);
}
}
}
simulated function OnBossDied()
{
local int ObjIdx;
// Boss kills in any map
ObjIdx = 0;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= BossKillsRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
// E.D.A.R kills
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (ClassIsChildOf(MonsterClass, class'KFPawn_ZedDAR'))
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= EDARKillsRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
}
simulated function OnHitTaken()
{
bHitTakenThisWave=true;
}
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
// No damage wave completed
ObjIdx = 3;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (!bHitTakenThisWave)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= WavesWithoutDamageRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
bHitTakenThisWave = false;
}
// Wavesin Endless hard
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
defaultproperties
{
BossKillsRequired=15
EDARKillsRequired=50
WavesWithoutDamageRequired=10
EndlessWaveRequired=15
bHitTakenThisWave=false
}

View File

@ -0,0 +1,54 @@
//=============================================================================
// KFWeapAttach_GravityImploder
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_GravityImploder extends KFWeaponAttachment;
`define GRAVITYIMPLODER_MIC_LED_INDEX 1
/** Weapons material colors for each fire mode. */
var LinearColor DefaultFireMaterialColor;
var LinearColor AltFireMaterialColor;
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
if ( WorldInfo.NetMode == NM_DedicatedServer )
{
return;
}
if ( WeaponMIC == None && WeapMesh != None )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`GRAVITYIMPLODER_MIC_LED_INDEX);
WeaponMIC.SetVectorParameterValue('Vector_Center_Color_A', DefaultFireMaterialColor);
}
}
simulated function bool ThirdPersonFireEffects(vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local LinearColor MatColor;
if(P.FiringMode == 0) // DEFAULT_FIREMODE
{
MatColor = DefaultFireMaterialColor;
}
else if (P.FiringMode == 1) // ALTFIRE_FIREMODE
{
MatColor = AltFireMaterialColor;
}
WeaponMIC.SetVectorParameterValue('Vector_Center_Color_A', MatColor);
return super.ThirdPersonFireEffects(HitLocation, P, ThirdPersonAnimRateByte);
}
defaultproperties
{
DefaultFireMaterialColor = (R = 0.965f,G = 0.2972f, B = 0.0f)
AltFireMaterialColor = (R = 0.0f, G = 0.9631f, B = 0.96581f)
}

View File

@ -39,7 +39,7 @@ defaultproperties
// Ammo
MagazineCapacity[0]=30
SpareAmmoCapacity[0]=270
InitialSpareMags[0]=4
InitialSpareMags[0]=3 //4
bCanBeReloaded=true
bReloadFromMagazine=true
@ -62,7 +62,7 @@ defaultproperties
HippedRecoilModifier=1.5
// Inventory / Grouping
InventorySize=6
InventorySize=5 //6
GroupPriority=50
WeaponSelectTexture=Texture2D'ui_weaponselect_tex.UI_WeaponSelect_Bullpup'
AssociatedPerkClasses(0)=class'KFPerk_Commando'
@ -75,7 +75,7 @@ defaultproperties
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Bullpup'
FireInterval(DEFAULT_FIREMODE)=+0.0909 // 660 RPM
Spread(DEFAULT_FIREMODE)=0.0085
InstantHitDamage(DEFAULT_FIREMODE)=30.0 //25
InstantHitDamage(DEFAULT_FIREMODE)=32.0 //30.0 //25
FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE
@ -85,7 +85,7 @@ defaultproperties
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_Bullpup'
FireInterval(ALTFIRE_FIREMODE)=+0.1
InstantHitDamage(ALTFIRE_FIREMODE)=30.0 //25
InstantHitDamage(ALTFIRE_FIREMODE)=32.0 //30.0 //25
Spread(ALTFIRE_FIREMODE)=0.0085
// BASH_FIREMODE

View File

@ -39,6 +39,24 @@ static simulated event EFilterTypeUI GetTraderFilter()
return FT_Projectile;
}
simulated function float GetUpgradedAfflictionPower(EAfflictionType AfflictionType, float InPower, optional int FireMode = INDEX_NONE, optional int UpgradeIndex = INDEX_NONE)
{
local class<KFDT_Piercing_Crossbow> DT;
local KFPerk Perk;
Perk = GetPerk();
if(AfflictionType == AF_Stun && Perk != none && Perk.bWasLastHitAHeadshot)
{
DT = class<KFDT_Piercing_Crossbow>(InstantHitDamageTypes[DEFAULT_FIREMODE]);
if (DT != none)
{
return super.GetUpgradedAfflictionPower(AfflictionType, DT.default.HeadStunPower, FireMode, UpgradeIndex);
}
}
return super.GetUpgradedAfflictionPower(AfflictionType, InPower, FireMode, UpgradeIndex);
}
defaultproperties
{
// Inventory

View File

@ -0,0 +1,187 @@
//=============================================================================
// KFWeap_GravityImploder
//=============================================================================
// The unique and amazing Gravity Imploder weapon
//=============================================================================
// Killing Floor 2
// Copyright (C) 2019 Tripwire Interactive LLC
//=============================================================================
class KFWeap_GravityImploder extends KFWeapon;
`define GRAVITYIMPLODER_MIC_LED_INDEX 1
/** Reduction for the amount of damage dealt to the weapon owner (including damage by the explosion) */
var float SelfDamageReductionValue;
/** Weapons material colors for each fire mode. */
var LinearColor DefaultFireMaterialColor;
var LinearColor AltFireMaterialColor;
var bool bLastFireWasAlt;
var const bool bDebugDrawVortex;
simulated function Activate()
{
super.Activate();
UpdateMaterial();
}
simulated function UpdateMaterial()
{
local LinearColor MatColor;
MatColor = bLastFireWasAlt ? AltFireMaterialColor : DefaultFireMaterialColor;
if( WeaponMICs.Length > `GRAVITYIMPLODER_MIC_LED_INDEX )
{
WeaponMICs[`GRAVITYIMPLODER_MIC_LED_INDEX].SetVectorParameterValue('Vector_Center_Color_A', MatColor);
}
}
simulated function Projectile ProjectileFire()
{
UpdateMaterial();
return super.ProjectileFire();
}
simulated function BeginFire( Byte FireModeNum )
{
super.BeginFire(FireModeNum);
if(FireModeNum == ALTFIRE_FIREMODE && !bLastFireWasAlt)
{
bLastFireWasAlt=true;
}
else if (FireModeNum == DEFAULT_FIREMODE && bLastFireWasAlt)
{
bLastFireWasAlt=false;
}
}
simulated function AltFireMode()
{
StartFire(ALTFIRE_FIREMODE);
}
// Reduce damage to self
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
{
super.AdjustDamage(InDamage, DamageType, DamageCauser);
if (Instigator != none && DamageCauser != none && DamageCauser.Instigator == Instigator)
{
InDamage *= SelfDamageReductionValue;
}
}
defaultproperties
{
// Content
PackageKey="Gravity_Imploder"
FirstPersonMeshName="WEP_1P_Gravity_Imploder_MESH.Wep_1stP_Gravity_Imploder_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_Gravity_Imploder_ANIM.Wep_1stP_Gravity_Imploder_Anim"
PickupMeshName="WEP_3P_Gravity_Imploder_MESH.WEP_3rdP_Gravity_Imploder_Pickup"
AttachmentArchetypeName="WEP_Gravity_Imploder_ARCH.Wep_Gravity_Imploder_3P"
MuzzleFlashTemplateName="WEP_Gravity_Imploder_ARCH.Wep_Gravity_Imploder_MuzzleFlash"
// Inventory / Grouping
InventorySize=7 //8
GroupPriority=125 //75
WeaponSelectTexture=Texture2D'WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder'
AssociatedPerkClasses(0)=class'KFPerk_Demolitionist'
// FOV
MeshFOV=75
MeshIronSightFOV=40
PlayerIronSightFOV=65
// Depth of field
DOF_FG_FocalRadius=50
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=6 //5
SpareAmmoCapacity[0]=42 //35
InitialSpareMags[0]=2 //4
AmmoPickupScale[0]=1 //1
bCanBeReloaded=true
bReloadFromMagazine=true
// Zooming/Position
PlayerViewOffset=(X=5.5,Y=8,Z=-2) //(X=11.0,Y=8,Z=-2)
IronSightPosition=(X=10,Y=0,Z=-1.9) //(X=10,Y=0,Z=0)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=750 //500
minRecoilPitch=675//400
maxRecoilYaw=250 //150
minRecoilYaw=-250 //-150
RecoilRate=0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=1250
RecoilMinPitchLimit=64785
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=500
RecoilISMinPitchLimit=65485
RecoilViewRotationScale=0.6
IronSightMeshFOVCompensationScale=1.5
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Grenade'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Grenade_GravityImploder'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpact'
InstantHitDamage(DEFAULT_FIREMODE)=150
FireInterval(DEFAULT_FIREMODE)=1.33 //45 RPM
Spread(DEFAULT_FIREMODE)=0.02 //0
PenetrationPower(DEFAULT_FIREMODE)=0
FireOffset=(X=25,Y=3.0,Z=-2.5)
// ALTFIRE_FIREMODE (swap fire mode)
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Grenade_GravityImploderAlt'
FireInterval(ALTFIRE_FIREMODE)=1.33 //45 RPM
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpactAlt'
InstantHitDamage(ALTFIRE_FIREMODE)=200
Spread(ALTFIRE_FIREMODE)=0.02 //0.0085
AmmoCost(ALTFIRE_FIREMODE)=1
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_GravityImploder'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Dry_Fire'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_1P')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Dry_Fire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
SelfDamageReductionValue=0.f //0.25f
bLastFireWasAlt=false
DefaultFireMaterialColor = (R = 0.965f,G = 0.2972f, B = 0.0f)
AltFireMaterialColor = (R = 0.0f, G = 0.9631f, B = 0.96581f)
bHasFireLastAnims=true
NumBloodMapMaterials=2
}

View File

@ -0,0 +1,613 @@
//=============================================================================
// KFWeap_HRG_SonicGun
//=============================================================================
// The HRG Sonic Gun weapon
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_SonicGun extends KFWeapon;
`define SONICGUN_MIC_SIGHT_INDEX 1
var(Animations) const editconst name ChargeAnim;
var(Animations) const editconst name ChargeAnimLast;
var(Animations) const editconst name ChargeAnimIron;
var(Animations) const editconst name ChargeAnimIronLast;
/** How long to wait after firing to force reload */
var() float ForceReloadTime;
var transient int CurrentChargeLevel;
/** Maximum times weapon can be charged */
var int MaxChargeLevel;
/** How much multiply damage does default fire projectile do by charge level*/
var Array<float> SonicBlastDamageByChargeLevel;
/** how much multiply momentum for default fire projectile by charge level */
var Array<float> SonicBlastMomentumByChargeLevel;
/** how much multiply penetration power for default fire projectile by charge level */
var Array<float> SonicBlastPenetrationPowerByChargeLevel;
/** DamageTypes for default fire projectile by charge level*/
var Array< class<DamageType> > SonicBlastDamageTypeByChargeLevel;
/** Projectile classes for default fire projectile by charge level*/
var Array< class<KFProjectile> > SonicBlastProjectileClassByChargeLevel;
/** Sounds for default fire by charge level*/
var Array<WeaponFireSndInfo> SonicBlastFireSoundByChargeLevel;
/** Sounds for charge */
var Array<WeaponFireSndInfo> SonicBlastFireSoundCharge;
/** Sounds for charge sound by charge level*/
var Array<AkEvent> ChargeSoundByChargeLevel;
/** How much momentum to apply when fired in double barrel */
var(Recoil) float FullyChargedKickMomentum;
/** How much to reduce shoot momentum when falling */
var(Recoil) float FallingMomentumReduction;
/** VFX to play from the muzzle when firing the charged shot */
var ParticleSystem MuzzleEffectDefaultFire;
/** VFX to play from the muzzle when firing the charged shot */
var ParticleSystem MuzzleEffectChargedFire;
struct MomentumMultiplierByZed
{
var Name ZedClassName;
var float MomentumMultiplier;
};
var array<MomentumMultiplierByZed> MomentumMultiplierByZedArray;
/** Colors for holographic sight by charge level */
var const Array<LinearColor> HolographicSightByChargeLevel;
var const Array<LinearColor> HolographicSightScanlineByChargeLevel;
var Array<bool> HolographicSightUseDefaultByChargeLevel;
simulated function PostBeginPlay()
{
CurrentChargeLevel=0;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[0])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[0]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[0]);
}
else {
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
/**
* Toggle between DEFAULT and ALTFIRE
*/
simulated function AltFireMode()
{
// skip super
if (!Instigator.IsLocallyControlled())
{
return;
}
StartFire(ALTFIRE_FIREMODE);
}
/** Overridded to add spawned charge to list of spawned charges */
simulated function Projectile ProjectileFire()
{
local Projectile P;
P = super.ProjectileFire();
return P;
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName(bool bTacticalReload)
{
// magazine relaod
if (AmmoCount[0] > 0)
{
return (bTacticalReload) ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim;
}
else
{
return (bTacticalReload) ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim;
}
}
simulated function StartFire(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE)
{
if (!IsCanIncrementCharge())
{
return;
}
}
super.StartFire(FireModeNum);
}
/*********************************************************************************************
* State WeaponSonicGunCharging
* The weapon is in this state while detonating a charge
*********************************************************************************************/
simulated function GotoActiveState();
simulated state WeaponSonicGunCharging
{
ignores AllowSprinting;
simulated event BeginState( name PreviousStateName )
{
local KFPerk InstigatorPerk;
if (!IsCanIncrementCharge())
{
ClearPendingFire(CurrentFireMode);
GotoActiveState();
return;
}
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
}
IncrementChargeAndPlayAnimation();
}
simulated function GotoActiveState()
{
GotoState('Active');
}
}
simulated state WeaponSonicGunSingleFiring extends WeaponSingleFiring
{
simulated function BeginState(name PreviousStateName)
{
local vector UsedKickMomentum;
// Push the player back when they fire a fully charged sonic blast
if (Instigator != none && CurrentChargeLevel == 1 ) //2
{
UsedKickMomentum.X = -FullyChargedKickMomentum;
if( Instigator.Physics == PHYS_Falling )
{
UsedKickMomentum = UsedKickMomentum >> Instigator.GetViewRotation();
UsedKickMomentum *= FallingMomentumReduction;
}
else
{
UsedKickMomentum = UsedKickMomentum >> Instigator.Rotation;
UsedKickMomentum.Z = 0;
}
Instigator.AddVelocity(UsedKickMomentum,Instigator.Location,none);
}
//We want to do it at the end because the kickmomentum needs to use CurrentChargeLevel and this is reset in FireAmmunition
Super.BeginState(PreviousStateName);
}
simulated function FireAmmunition()
{
super.FireAmmunition();
CurrentChargeLevel=0;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[0])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[0]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[0]);
}
else
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
}
// GrenadeLaunchers determine ShouldPlayFireLast based on the spare ammo
// overriding to use the base KFWeapon version since that uses the current ammo in the mag
simulated function bool ShouldPlayFireLast(byte FireModeNum)
{
return Super(KFWeapon).ShouldPlayFireLast(FireModeNum);
}
simulated function bool IsCanIncrementCharge()
{
return CurrentChargeLevel < MaxChargeLevel && AmmoCount[DEFAULT_FIREMODE] > 0;
}
simulated function IncrementChargeAndPlayAnimation()
{
local name SelectedAnim;
local float AnimDuration;
local bool bInSprintState;
// choose the detonate animation based on whether it is in ironsights and whether it is the last harpoon
if (bUsingSights)
{
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? ChargeAnimIronLast : ChargeAnimIron;
}
else
{
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? ChargeAnimLast : ChargeAnim;
}
AnimDuration = MySkelMesh.GetAnimLength(SelectedAnim);
bInSprintState = IsInState('WeaponSprinting');
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if ( KFPawn(Owner).IsLocallyControlled() )
{
PlaySoundBase(SonicBlastFireSoundCharge[CurrentChargeLevel].FirstPersonCue);
}
if (bInSprintState)
{
AnimDuration *= 0.25f;
PlayAnimation(SelectedAnim, AnimDuration);
}
else
{
PlayAnimation(SelectedAnim);
}
}
// Don't want to play muzzle effects or shoot animation on detonate in 3p
//IncrementFlashCount();
//AnimDuration value here representes the ALTFIRE FireInterval
AnimDuration = 0.75f; //1.f;
if (bInSprintState)
{
SetTimer(AnimDuration * 0.8f, false, nameof(PlaySprintStart));
}
else
{
SetTimer(AnimDuration * 0.5f, false, nameof(GotoActiveState));
}
CurrentChargeLevel++;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[CurrentChargeLevel])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[CurrentChargeLevel]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[CurrentChargeLevel]);
}
else {
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Explosive;
}
simulated function float GetForceReloadDelay()
{
return fMax( ForceReloadTime - FireInterval[CurrentFireMode], 0.f );
}
//Overriding to be able to change projectile stats depending on the charge level
simulated function KFProjectile SpawnProjectile( class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir )
{
local KFProjectile SpawnedProjectile;
local int ProjDamage;
// Spawn projectile
SpawnedProjectile = Spawn( KFProjClass, Self,, RealStartLoc,,,true);
if( SpawnedProjectile != none && !SpawnedProjectile.bDeleteMe )
{
// Mirror damage and damage type from weapon. This is set on the server only and
// these properties are replicated via TakeHitInfo
if ( InstantHitDamage.Length > CurrentFireMode && InstantHitDamageTypes.Length > CurrentFireMode )
{
InstantHitDamage[DEFAULT_FIREMODE] = SonicBlastDamageByChargeLevel[CurrentChargeLevel];
InstantHitMomentum[DEFAULT_FIREMODE]=SonicBlastMomentumByChargeLevel[CurrentChargeLevel];
InstantHitDamageTypes[DEFAULT_FIREMODE]=SonicBlastDamageTypeByChargeLevel[CurrentChargeLevel];
ProjDamage = GetModifiedDamage(CurrentFireMode);
SpawnedProjectile.Damage = ProjDamage;
SpawnedProjectile.MyDamageType = InstantHitDamageTypes[DEFAULT_FIREMODE];
}
// Set the penetration power for this projectile
// because of clientside hit detection, we need two variables --
// one that replicates on init and one that updates but doesn't replicate
PenetrationPower[DEFAULT_FIREMODE]=SonicBlastPenetrationPowerByChargeLevel[CurrentChargeLevel];
SpawnedProjectile.InitialPenetrationPower = GetInitialPenetrationPower(CurrentFireMode);
SpawnedProjectile.PenetrationPower = SpawnedProjectile.InitialPenetrationPower;
SpawnedProjectile.UpgradeDamageMod = GetUpgradeDamageMod();
SpawnedProjectile.Init( AimDir );
}
// return it up the line
return SpawnedProjectile;
}
//Overriding to make KFProjectile Class for default fire mode to be dependant on charge level
simulated function class<KFProjectile> GetKFProjectileClass()
{
if (CurrentFireMode == DEFAULT_FIREMODE)
{
return SonicBlastProjectileClassByChargeLevel[CurrentChargeLevel];
}
return super.GetKFProjectileClass();
}
//Overriding to get current PenetrationPower, not default.PenetrationPower
simulated function float GetUpgradedPenetration(optional int FireMode = DEFAULT_FIREMODE, optional int UpgradeIndex = INDEX_NONE)
{
if (UpgradeIndex == INDEX_NONE)
{
UpgradeIndex = CurrentWeaponUpgradeIndex;
}
return int(GetUpgradedStatValue(PenetrationPower[FireMode], EWeaponUpgradeStat(EWUS_Penetration0 + UpgradeFireModes[FireMode]), UpgradeIndex));
}
//Overriding to change shot sounds for default fire mode to be dependant on charge level
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
WeaponFireSnd[DEFAULT_FIREMODE]=SonicBlastFireSoundByChargeLevel[CurrentChargeLevel];
super.PlayFireEffects(FireModeNum, HitLocation);
}
simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum )
{
local KFPerk InstigatorPerk;
local int IndexMomentumMultiplierByZed;
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
InstigatorPerk.UpdatePerkHeadShots( Impact, InstantHitDamageTypes[FiringMode], ImpactNum );
}
//Modifying momentum by zed impacted
if (Impact.HitActor != None && KFPawn_Monster(Impact.HitActor) != None)
{
IndexMomentumMultiplierByZed = MomentumMultiplierByZedArray.Find('ZedClassName', Impact.HitActor.Class.Name);
if (IndexMomentumMultiplierByZed != INDEX_NONE)
{
InstantHitMomentum[DEFAULT_FIREMODE] *= MomentumMultiplierByZedArray[IndexMomentumMultiplierByZed].MomentumMultiplier;
}
}
super.ProcessInstantHitEx( FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum );
}
simulated function CauseMuzzleFlash(byte FireModeNum)
{
if (MuzzleFlash == None)
{
AttachMuzzleFlash();
}
if (CurrentChargeLevel > 0)
{
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleEffectChargedFire;
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleEffectChargedFire);
}
else
{
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleEffectDefaultFire;
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleEffectDefaultFire);
}
super.CauseMuzzleFlash(FireModeNum);
}
defaultproperties
{
// Content
PackageKey="HRG_SonicGun"
FirstPersonMeshName="wep_1p_hrg_sonicgun_mesh.WEP_1stP_HRG_SonicGun_Rig"
FirstPersonAnimSetNames(0)="wep_1p_hrg_sonicgun_anim.Wep_1stP_HRG_SonicGun_Anim"
PickupMeshName="wep_3p_hrg_sonicgun_mesh.WEP_3rdP_HRG_SonicGun_Pickup"
AttachmentArchetypeName="wep_hrg_sonicgun_arch.Wep_HRG_SonicGun_3P"
MuzzleFlashTemplateName="WEP_HRG_SonicGun_ARCH.Wep_HRG_SonicGun_MuzzleFlash"
// Inventory / Grouping
InventorySize=7
GroupPriority=75
WeaponSelectTexture=Texture2D'WEP_UI_HRG_SonicGun_TEX.UI_WeaponSelect_HRG_SonicGun'
AssociatedPerkClasses(0)=class'KFPerk_Sharpshooter'
// FOV
MeshFOV=75
MeshIronSightFOV=40
PlayerIronSightFOV=65
// Depth of field
DOF_FG_FocalRadius=50
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=12 //8
SpareAmmoCapacity[0]=96 //72
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
// Zooming/Position
PlayerViewOffset=(X=11.0,Y=8,Z=-2)
IronSightPosition=(X=10,Y=-0.1,Z=-0.2)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=200 //500
minRecoilPitch=150 //400
maxRecoilYaw=50 //150
minRecoilYaw=-50 //-150
RecoilRate=0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=1250
RecoilMinPitchLimit=64785
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=500
RecoilISMinPitchLimit=65485
RecoilViewRotationScale=0.6
IronSightMeshFOVCompensationScale=1.5
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSonicGunSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_SonicBlastUncharged_HRG_SonicGun'
InstantHitDamage(DEFAULT_FIREMODE)=125
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged'
InstantHitMomentum(DEFAULT_FIREMODE)=200000
FireInterval(DEFAULT_FIREMODE)=0.5 //0.75
Spread(DEFAULT_FIREMODE)=0.005
PenetrationPower(DEFAULT_FIREMODE)=2.0
FireOffset=(X=25,Y=3.0,Z=-2.5)
FullyChargedKickMomentum=0 //1000
FallingMomentumReduction=0.5
// ALTFIRE_FIREMODE (remote detonate)
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSonicGunCharging
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
AmmoCost(ALTFIRE_FIREMODE)=0
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_SonicGun'
InstantHitDamage(BASH_FIREMODE)=26
// Custom animations
FireSightedAnims=(Shoot_Iron, Shoot_Iron2, Shoot_Iron3)
BonesToLockOnEmpty=(RW_BoltAssembly1, RW_BoltAssembly2, RW_BoltAssembly3)
bHasFireLastAnims=true
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Bass', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Bass')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_DryFire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
ChargeAnim=Alt_Fire
ChargeAnimLast=Alt_Fire_Last
ChargeAnimIron=Alt_Fire_Iron
ChargeAnimIronLast=Alt_Fire_Iron_Last
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
ForceReloadTime=0.3
bAllowClientAmmoTracking=true
AimCorrectionSize=0.f
MuzzleEffectDefaultFire=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Muzzle'
MuzzleEffectChargedFire=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Muzzle_AltFire'
SonicBlastDamageByChargeLevel(0)=110 //100
//SonicBlastDamageByChargeLevel(1)=170 //160
SonicBlastDamageByChargeLevel(1)=280 //310 //280
SonicBlastPenetrationPowerByChargeLevel(0)=4.0
//SonicBlastPenetrationPowerByChargeLevel(1)=3.0 //1.0
SonicBlastPenetrationPowerByChargeLevel(1)=2.0 //0.0
SonicBlastMomentumByChargeLevel(0)=100000 //80000 //60000
//SonicBlastMomentumByChargeLevel(1)=50000 //40000
SonicBlastMomentumByChargeLevel(1)=40000 //20000
SonicBlastDamageTypeByChargeLevel(0)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged'
//SonicBlastDamageTypeByChargeLevel(1)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged'
SonicBlastDamageTypeByChargeLevel(1)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged'
SonicBlastProjectileClassByChargeLevel(0)=class'KFProj_SonicBlastUncharged_HRG_SonicGun'
//SonicBlastProjectileClassByChargeLevel(1)=class'KFProj_SonicBlastHalfCharged_HRG_SonicGun'
SonicBlastProjectileClassByChargeLevel(1)=class'KFProj_SonicBlastFullyCharged_HRG_SonicGun'
SonicBlastFireSoundByChargeLevel(0)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Bass', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Bass')
//SonicBlastFireSoundByChargeLevel(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Mid', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Mid')
SonicBlastFireSoundByChargeLevel(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_High', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_High')
SonicBlastFireSoundCharge(0)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Once', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Once')
SonicBlastFireSoundCharge(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Twice', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Twice')
ChargeSoundByChargeLevel(0)=AkEvent'WW_WEP_Seeker_6.Play_Seeker_6_Reload_1'
ChargeSoundByChargeLevel(1)=AkEvent'WW_WEP_Lazer_Cutter.Play_WEP_LaserCutter_Handling_Equip'
//AkEvent'WW_WEP_Helios.Play_WEP_Helios_Handling_Equip'
MaxChargeLevel=1 //2
MomentumMultiplierByZedArray(0)=(ZedClassName="KFPawn_ZedClot_Cyst", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(1)=(ZedClassName="KFPawn_ZedClot_Alpha", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(2)=(ZedClassName="KFPawn_ZedClot_Slasher", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(3)=(ZedClassName="KFPawn_ZedCrawler", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(4)=(ZedClassName="KFPawn_ZedGorefast", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(5)=(ZedClassName="KFPawn_ZedStalker", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(6)=(ZedClassName="KFPawn_ZedScrake", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(7)=(ZedClassName="KFPawn_ZedFleshpound", MomentumMultiplier=1.3)
MomentumMultiplierByZedArray(8)=(ZedClassName="KFPawn_ZedFleshpoundMini", MomentumMultiplier=1.3)
MomentumMultiplierByZedArray(9)=(ZedClassName="KFPawn_ZedBloat", MomentumMultiplier=1.7)
MomentumMultiplierByZedArray(10)=(ZedClassName="KFPawn_ZedSiren", MomentumMultiplier=0.8)
MomentumMultiplierByZedArray(11)=(ZedClassName="KFPawn_ZedHusk", MomentumMultiplier=0.8)
MomentumMultiplierByZedArray(12)=(ZedClassName="KFPawn_ZedClot_AlphaKing", MomentumMultiplier=1.0) //elite clot
MomentumMultiplierByZedArray(13)=(ZedClassName="KFPawn_ZedCrawlerKing", MomentumMultiplier=1.0) //elite crawler
MomentumMultiplierByZedArray(14)=(ZedClassName="KFPawn_ZedGorefastDualBlade", MomentumMultiplier=1.3) //elite gorefast
MomentumMultiplierByZedArray(15)=(ZedClassName="KFPawn_ZedDAR_EMP", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(16)=(ZedClassName="KFPawn_ZedDAR_Laser", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(17)=(ZedClassName="KFPawn_ZedDAR_Rocket", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(18)=(ZedClassName="KFPawn_ZedBloatKingSubspawn", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(19)=(ZedClassName="KFPawn_ZedHans", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(20)=(ZedClassName="KFPawn_ZedPatriarch", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(21)=(ZedClassName="KFPawn_ZedFleshpoundKing", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(22)=(ZedClassName="KFPawn_ZedBloatKing", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(23)=(ZedClassName="KFPawn_ZedMatriarch", MomentumMultiplier=1.2)
//If no set any of the following colors, the default color from the material will be used
HolographicSightByChargeLevel(0)=(R=0.88f,G=0.36f,B=0.11f, A=0.92f)
HolographicSightByChargeLevel(1)=(R=0.27f,G=0.5f,B=2.35f, A=0.92f)
HolographicSightScanlineByChargeLevel(0)=(R=0.5f,G=0.96f,B=0.96f, A=0.92f)
HolographicSightScanlineByChargeLevel(1)=(R=0.88f,G=0.36f,B=0.11f, A=0.92f)
HolographicSightUseDefaultByChargeLevel(0)=false
HolographicSightUseDefaultByChargeLevel(1)=false
NumBloodMapMaterials=2
}

View File

@ -209,8 +209,8 @@ defaultproperties
// Recoil
maxRecoilPitch=150
minRecoilPitch=115
maxRecoilYaw=115
minRecoilYaw=-115
maxRecoilYaw=80 //115
minRecoilYaw=-80 //-115
RecoilRate=0.085
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
@ -223,7 +223,7 @@ defaultproperties
RecoilViewRotationScale=0.25
IronSightMeshFOVCompensationScale=1.5
HippedRecoilModifier=1.5
AltFireRecoilScale=4.0f
AltFireRecoilScale=6.0f //4.0f
// Inventory
InventorySize=7
@ -234,23 +234,23 @@ defaultproperties
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_Cryogun'
FiringStatesArray(DEFAULT_FIREMODE)=SprayingFire
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Custom
FireInterval(DEFAULT_FIREMODE)=+0.07 // 850 RPM
FireInterval(DEFAULT_FIREMODE)=+0.1 //+0.07 // 850 RPM
FireOffset=(X=30,Y=4.5,Z=-5)
//MinFireDuration=0.25
MinAmmoConsumed=4
MinAmmoConsumed=3 //4
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_2nd_Cryogun'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_FreezeThrower_IceShards'
InstantHitDamage(ALTFIRE_FIREMODE)=20.0
InstantHitDamage(ALTFIRE_FIREMODE)=35.0 //20.0
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Freeze_FreezeThrower_IceShards'
FireInterval(ALTFIRE_FIREMODE)=0.6f
PenetrationPower(ALTFIRE_FIREMODE)=4.0
AmmoCost(ALTFIRE_FIREMODE)=10
NumPellets(ALTFIRE_FIREMODE)=12
Spread(ALTFIRE_FIREMODE)=0.15f
NumPellets(ALTFIRE_FIREMODE)=8 //12
Spread(ALTFIRE_FIREMODE)=0.12f //0.15f
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_Freezethrower'

View File

@ -75,8 +75,15 @@ simulated state WeaponDoubleBarrelFiring extends WeaponSingleFiring
simulated function BeginState(name PreviousStateName)
{
local vector UsedKickMomentum;
local KFMapInfo KFMI;
Super.BeginState(PreviousStateName);
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if(KFMI != none && !KFMI.bAllowShootgunJump)
{
return;
}
// Push the player back when they fire both barrels
if (Instigator != none )
{

View File

@ -26,13 +26,8 @@ simulated function AltFireMode()
{
return;
}
if (ReloadStatus == RS_Reloading)
{
return;
}
if (AmmoCount[0] <= 1)
if (AmmoCount[0] == 1)
{
StartFire(DEFAULT_FIREMODE);
}
@ -93,8 +88,15 @@ simulated state WeaponQuadBarrelFiring extends WeaponSingleFiring
simulated function BeginState(name PreviousStateName)
{
local vector UsedKickMomentum;
local KFMapInfo KFMI;
Super.BeginState(PreviousStateName);
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if(KFMI != none && !KFMI.bAllowShootgunJump)
{
return;
}
// Push the player back when they fire both barrels
if (Instigator != none)
{