1
0
This commit is contained in:
GenZmeY 2021-06-02 23:06:18 +03:00
parent 9553ac0b31
commit 90e235396c
96 changed files with 5520 additions and 161 deletions

View File

@ -11,13 +11,21 @@ class GravityVolume extends PhysicsVolume
/** Gravity along Z axis applied to objects inside this volume. */ /** Gravity along Z axis applied to objects inside this volume. */
var() float GravityZ; var() float GravityZ;
/** Scaling GravityZ and being used different function (GetGravityZHuman) to retrieve GravityZ */
var() float ScaleGravityHuman;
/** Scaling GravityZ and being used different function (GetGravityZMonster) to retrieve GravityZ */
var() float ScaleGravityMonster;
cpptext cpptext
{ {
virtual FLOAT GetGravityZ() { return GravityZ; } virtual FLOAT GetGravityZ() { return GravityZ; }
virtual FLOAT GetGravityZHuman() { return GravityZ * ScaleGravityHuman; }
virtual FLOAT GetGravityZMonster() { return GravityZ * ScaleGravityMonster; }
} }
defaultproperties defaultproperties
{ {
GravityZ = -520.0 GravityZ = -520.0
ScaleGravityHuman = 1.0
ScaleGravityMonster = 1.0
} }

View File

@ -2596,10 +2596,17 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
Killer = SetKillInstigator(InstigatedBy, DamageType); Killer = SetKillInstigator(InstigatedBy, DamageType);
TearOffMomentum = momentum; TearOffMomentum = momentum;
Died(Killer, damageType, HitLocation); Died(Killer, damageType, HitLocation);
// using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done
HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), DamageType, DamageCauser);
} }
else else
{ {
HandleMomentum( momentum, HitLocation, DamageType, HitInfo ); HandleMomentum( momentum, HitLocation, DamageType, HitInfo );
// using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done
HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), DamageType, DamageCauser);
NotifyTakeHit(InstigatedBy, HitLocation, ActualDamage, DamageType, Momentum, DamageCauser); NotifyTakeHit(InstigatedBy, HitLocation, ActualDamage, DamageType, Momentum, DamageCauser);
if (DrivenVehicle != None) if (DrivenVehicle != None)
{ {
@ -2619,6 +2626,8 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
`endif `endif
} }
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser);
/* /*
* Queries the PRI and returns our current team index. * Queries the PRI and returns our current team index.
*/ */

View File

@ -79,6 +79,8 @@ cpptext
} }
native function float GetGravityZ(); native function float GetGravityZ();
native function float GetGravityZHuman();
native function float GetGravityZMonster();
native function vector GetZoneVelocityForActor(Actor TheActor); native function vector GetZoneVelocityForActor(Actor TheActor);
simulated event PostBeginPlay() simulated event PostBeginPlay()

View File

@ -43,6 +43,7 @@ var array<AARAward> TeamAwardList;
enum ETeamAwards enum ETeamAwards
{ {
ETA_ZedStomper,
ETA_MedicineMaster, ETA_MedicineMaster,
ETA_ZedSlayer, ETA_ZedSlayer,
ETA_Enforcer, ETA_Enforcer,
@ -70,7 +71,8 @@ enum EPersonalBests
EPB_Assists, EPB_Assists,
EPB_LargeZedKill, EPB_LargeZedKill,
EPB_Dosh, EPB_Dosh,
EPB_DoorWelding EPB_DoorWelding,
EPB_ZedStomps
}; };
var array<AARAward> PersonalBestList; var array<AARAward> PersonalBestList;
@ -99,6 +101,7 @@ var int TotalAmountHealGiven; //dialog
var int TotalAmountHealReceived; //dialog var int TotalAmountHealReceived; //dialog
var int TotalLargeZedKills; var int TotalLargeZedKills;
var int TotalStomps;
var bool bKilledBoss; var bool bKilledBoss;
@ -158,6 +161,9 @@ function RecordIntStat(int StatID, int Value)
case MATCH_EVENT_HEAL_RECEIVED: case MATCH_EVENT_HEAL_RECEIVED:
IncrementHealReceivedInWave(Value); IncrementHealReceivedInWave(Value);
break; break;
case MATCH_EVENT_STOMP_GIVEN:
IncrementStompsGivenInWave(Value);
break;
} }
} }
@ -224,6 +230,16 @@ function int GetHealGivenInWave()
return PWRI.VectData2.Z; return PWRI.VectData2.Z;
} }
function IncrementStompsGivenInWave(int Delta)
{
PWRI.NumStomps += Delta;
}
function int GetStompsGivenInWave()
{
return PWRI.NumStomps;
}
//Called at the end of the wave. @Note - End of wave is also called with the loss condition is met. This includes at trader time. //Called at the end of the wave. @Note - End of wave is also called with the loss condition is met. This includes at trader time.
function RecordWaveInfo() function RecordWaveInfo()
{ {
@ -239,6 +255,7 @@ function RecordWaveInfo()
TotalAmountHealReceived += GetHealReceivedInWave(); TotalAmountHealReceived += GetHealReceivedInWave();
TotalDamageTaken += GetDamageTakenInWave(); TotalDamageTaken += GetDamageTakenInWave();
TotalDamageDealt += GetDamageDealtInWave(); TotalDamageDealt += GetDamageDealtInWave();
TotalStomps += GetStompsGivenInWave();
if ( PWRI.bDiedDuringWave ) if ( PWRI.bDiedDuringWave )
{ {
@ -273,6 +290,7 @@ function ResetLastWaveInfo()
PWRI.bSomeSurvivedLastWave = false; PWRI.bSomeSurvivedLastWave = false;
PWRI.bOneSurvivedLastWave = false; PWRI.bOneSurvivedLastWave = false;
PWRI.bDiedDuringWave = false; PWRI.bDiedDuringWave = false;
PWRI.NumStomps = 0;
ZedsKilledLastWave = 0; ZedsKilledLastWave = 0;
} }
@ -736,6 +754,9 @@ function GetPersonalBests(out Array<AARAward> PersonalBests)
PersonalBests.AddItem( GivePersonalBestDoshEarned() ); PersonalBests.AddItem( GivePersonalBestDoshEarned() );
//Headshots //Headshots
PersonalBests.AddItem( GivePersonalBestHeadShots() ); PersonalBests.AddItem( GivePersonalBestHeadShots() );
// Stomps
PersonalBests.AddItem( GivePersonalBestZedStomp() );
} }
function int GetPistolKills() function int GetPistolKills()
@ -1002,6 +1023,29 @@ function AARAward GivePersonalBestDoorWelding()
return PersonalBestList[EPB_DoorWelding]; return PersonalBestList[EPB_DoorWelding];
} }
function AARAward GivePersonalBestZedStomp()
{
local int Value;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo(PlayerReplicationInfo);
Value = GetPersonalBest(EPB_ZedStomps);
if(Value < KFPRI.ZedStomps)
{
PersonalBestList[EPB_ZedStomps].DisplayValue = KFPRI.ZedStomps;
PersonalBestList[EPB_ZedStomps].bHighLight = true;
SavePersonalBest(EPB_ZedStomps, KFPRI.ZedStomps);
}
else
{
PersonalBestList[EPB_ZedStomps].DisplayValue = Value;
}
return PersonalBestList[EPB_ZedStomps];
}
static function GetTeamAward(ETeamAwards AwardIndex, out AARAward TempAwardObject, const out Array<KFPlayerController> KFPCArray) static function GetTeamAward(ETeamAwards AwardIndex, out AARAward TempAwardObject, const out Array<KFPlayerController> KFPCArray)
{ {
switch (AwardIndex) switch (AwardIndex)
@ -1056,6 +1100,9 @@ static function GetTeamAward(ETeamAwards AwardIndex, out AARAward TempAwardObjec
case ETA_Zednnihilation: case ETA_Zednnihilation:
Give_Zednnihilation(TempAwardObject, KFPCArray); Give_Zednnihilation(TempAwardObject, KFPCArray);
break; break;
case ETA_ZedStomper:
Give_ZedStomper(TempAwardObject, KFPCArray);
break;
} }
} }
@ -1352,6 +1399,23 @@ static function Give_Dominator(out AARAward outAward, const out Array<KFPlayerCo
} }
} }
static function Give_ZedStomper(out AARAward outAward, const out Array<KFPlayerController> KFPCArray)
{
local int i;
for(i = 0; i < KFPCArray.Length; i++)
{
if(KFPCArray[i].MatchStats != none)
{
if(KFPCArray[i].MatchStats.TotalStomps > outAward.DisplayValue)
{
outAward.PRI = KFPCArray[i].PlayerReplicationInfo;
outAward.DisplayValue = KFPCArray[i].MatchStats.TotalStomps;
`log(KFPCArray[i].PlayerReplicationInfo.PlayerName @KFPCArray[i].MatchStats.TotalStomps, class'EphemeralMatchStats'.default.bShowMatchStatsLogging);
}
}
}
}
function ReceiveAwardInfo(byte AwardID, PlayerReplicationInfo PRI, int Value) function ReceiveAwardInfo(byte AwardID, PlayerReplicationInfo PRI, int Value)
{ {
TeamAwardList[AwardID].PRI = PRI; TeamAwardList[AwardID].PRI = PRI;
@ -1370,6 +1434,7 @@ DefaultProperties
TeamAwardList(ETA_MoneyBags)=(TitleIdentifier="MoneyBags",ValueIdentifier="MoneyBagsValue",IconPath="UI_Award_Team.UI_Award_Team-Dosh") TeamAwardList(ETA_MoneyBags)=(TitleIdentifier="MoneyBags",ValueIdentifier="MoneyBagsValue",IconPath="UI_Award_Team.UI_Award_Team-Dosh")
TeamAwardList(ETA_HeadPopper)=(TitleIdentifier="HeadPopper",ValueIdentifier="HeadPopperValue",IconPath="UI_Award_Team.UI_Award_Team-Headshots") TeamAwardList(ETA_HeadPopper)=(TitleIdentifier="HeadPopper",ValueIdentifier="HeadPopperValue",IconPath="UI_Award_Team.UI_Award_Team-Headshots")
TeamAwardList(ETA_Dominator)=(TitleIdentifier="Dominator",ValueIdentifier="DominatorValue",IconPath="UI_Award_Team.UI_Award_Team-BossKO") TeamAwardList(ETA_Dominator)=(TitleIdentifier="Dominator",ValueIdentifier="DominatorValue",IconPath="UI_Award_Team.UI_Award_Team-BossKO")
TeamAwardList(ETA_ZedStomper)=(TitleIdentifier="ZedStomper",ValueIdentifier="ZedStomperValue",IconPath="UI_Award_Team.UI_Award_Team-ZedStomper")
//zed awards //zed awards
TeamAwardList(ETA_Carnage)=(TitleIdentifier="Carnage",ValueIdentifier="CarnageValue",IconPath="ui_award_zeds.UI_Award_ZED_RawDmg") TeamAwardList(ETA_Carnage)=(TitleIdentifier="Carnage",ValueIdentifier="CarnageValue",IconPath="ui_award_zeds.UI_Award_ZED_RawDmg")
TeamAwardList(ETA_Closer)=(TitleIdentifier="Closer",ValueIdentifier="CloserValue",IconPath="ui_award_zeds.UI_Award_ZED_Kills") TeamAwardList(ETA_Closer)=(TitleIdentifier="Closer",ValueIdentifier="CloserValue",IconPath="ui_award_zeds.UI_Award_ZED_Kills")
@ -1378,7 +1443,6 @@ DefaultProperties
TeamAwardList(ETA_ZedSupport)=(TitleIdentifier="ZedSupport",ValueIdentifier="ZedSupportValue",IconPath="ui_award_zeds.UI_Award_ZED_SupportAoE") TeamAwardList(ETA_ZedSupport)=(TitleIdentifier="ZedSupport",ValueIdentifier="ZedSupportValue",IconPath="ui_award_zeds.UI_Award_ZED_SupportAoE")
TeamAwardList(ETA_Zednnihilation)=(TitleIdentifier="Zednnihilation",ValueIdentifier="ZednnihilationValue",IconPath="ui_award_zeds.UI_Award_ZED_MostKills") TeamAwardList(ETA_Zednnihilation)=(TitleIdentifier="Zednnihilation",ValueIdentifier="ZednnihilationValue",IconPath="ui_award_zeds.UI_Award_ZED_MostKills")
PersonalBestList(EPB_Healing)=(TitleIdentifier="EPB_Healing",ValueIdentifier="EPB_HealingValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Healing") PersonalBestList(EPB_Healing)=(TitleIdentifier="EPB_Healing",ValueIdentifier="EPB_HealingValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Healing")
PersonalBestList(EPB_Kills)=(TitleIdentifier="EPB_Kills",ValueIdentifier="EPB_KillsValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Kills") PersonalBestList(EPB_Kills)=(TitleIdentifier="EPB_Kills",ValueIdentifier="EPB_KillsValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Kills")
PersonalBestList(EPB_Assists)=(TitleIdentifier="EPB_Assists",ValueIdentifier="EPB_AssistsValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Assists") PersonalBestList(EPB_Assists)=(TitleIdentifier="EPB_Assists",ValueIdentifier="EPB_AssistsValue",IconPath="UI_Award_PersonalMulti.UI_Award_PersonalMulti-Assists")
@ -1388,4 +1452,5 @@ DefaultProperties
PersonalBestList(EPB_KnifeKills)=(TitleIdentifier="EPB_KnifeKills",ValueIdentifier="EPB_KnifeKillsValue",IconPath="UI_Award_PersonalSolo.UI_Award_PersonalSolo-Knife") PersonalBestList(EPB_KnifeKills)=(TitleIdentifier="EPB_KnifeKills",ValueIdentifier="EPB_KnifeKillsValue",IconPath="UI_Award_PersonalSolo.UI_Award_PersonalSolo-Knife")
PersonalBestList(EPB_PistolKills)=(TitleIdentifier="EPB_PistolKills",ValueIdentifier="EPB_PistolKillsValue",IconPath="UI_Award_PersonalSolo.UI_Award_PersonalSolo-Pistol") PersonalBestList(EPB_PistolKills)=(TitleIdentifier="EPB_PistolKills",ValueIdentifier="EPB_PistolKillsValue",IconPath="UI_Award_PersonalSolo.UI_Award_PersonalSolo-Pistol")
PersonalBestList(EPB_DoorWelding)=(TitleIdentifier="EPB_DoorWelding",ValueIdentifier="EPB_DoorWeldingValue",IconPath="ui_weaponselect_tex.UI_WeaponSelect_Welder") PersonalBestList(EPB_DoorWelding)=(TitleIdentifier="EPB_DoorWelding",ValueIdentifier="EPB_DoorWeldingValue",IconPath="ui_weaponselect_tex.UI_WeaponSelect_Welder")
PersonalBestList(EPB_ZedStomps)=(TitleIdentifier="EPB_ZedStomps",ValueIdentifier="EPB_ZedStompsValue",IconPath="UI_Award_PersonalSolo.UI_Award_PersonalSolo-ZedStomper")
} }

View File

@ -192,7 +192,8 @@ protected function ProcessSpecialMoveAfflictions(KFPerk InstigatorPerk, vector H
return; return;
} }
HitZoneIdx = HitFxInfo.HitBoneIndex; // HitZoneIdx = HitFxInfo.HitBoneIndex;
HitZoneIdx = LastHitZoneIndex;
BodyPart = (HitZoneIdx != 255 && HitZoneIdx < HitZones.Length) ? HitZones[HitZoneIdx].Limb : BP_Torso; BodyPart = (HitZoneIdx != 255 && HitZoneIdx < HitZones.Length) ? HitZones[HitZoneIdx].Limb : BP_Torso;

View File

@ -0,0 +1,24 @@
//=============================================================================
// KFDT_GoompaStomp
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_GoompaStomp extends KFDamageType;
defaultproperties
{
RadialDamageImpulse = 1000.f // This controls how much impulse is applied to gibs when exploding
bUseHitLocationForGibImpulses = false // This will make the impulse origin where the victim was hit for directional gibs
bPointImpulseTowardsOrigin = true // This creates an impulse direction aligned along hitlocation and pawn location -- this will push all gibs in the same direction
ImpulseOriginScale = 100.f // Higher means more directional gibbing, lower means more outward (and upward) gibbing
ImpulseOriginLift = 150.f
MaxObliterationGibs = 12 // Maximum number of gibs that can be spawned by obliteration, 0=MAX
bCanGib = true
bCanObliterate = true
ObliterationHealthThreshold = 0
ObliterationDamageThreshold = 1
bIgnoreAggroOnDamage=true
}

View File

@ -83,6 +83,7 @@ simulated function SetPickupMesh(PrimitiveComponent NewPickupMesh)
local ActorComponent Comp; local ActorComponent Comp;
local SkeletalMeshComponent SkelMC; local SkeletalMeshComponent SkelMC;
local StaticMeshComponent StaticMC; local StaticMeshComponent StaticMC;
local KFGameInfo KFGI;
if (Role == ROLE_Authority ) if (Role == ROLE_Authority )
{ {
@ -93,6 +94,13 @@ simulated function SetPickupMesh(PrimitiveComponent NewPickupMesh)
bUpgradedPickup = KFWeapon(Inventory).CurrentWeaponUpgradeIndex > 0; bUpgradedPickup = KFWeapon(Inventory).CurrentWeaponUpgradeIndex > 0;
} }
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.DroppedItemLifespan >= 0.0f)
{
LifeSpan = KFGI.OutbreakEvent.ActiveEvent.DroppedItemLifespan;
}
SetTimer(LifeSpan, false, nameof(TryFadeOut)); SetTimer(LifeSpan, false, nameof(TryFadeOut));
} }

View File

@ -30,9 +30,11 @@ var int LastMaxWeight;
var int LastWeight; var int LastWeight;
// Amount of secondary ammo // Amount of secondary ammo
var byte LastSecondaryAmmo; var byte LastSecondaryAmmo;
var int LastSecondarySpareAmmo;
var bool bWasUsingAltFireMode; var bool bWasUsingAltFireMode;
var bool bUsesSecondaryAmmo; var bool bUsesSecondaryAmmo;
var bool bUsesGrenadesAsSecondaryAmmo; var bool bUsesGrenadesAsSecondaryAmmo;
var bool bUsesSecondaryAmmoAltHUD;
var class<KFPerk> LastPerkClass; var class<KFPerk> LastPerkClass;
var KFWeapon LastWeapon; var KFWeapon LastWeapon;
@ -138,6 +140,7 @@ function UpdateWeapon()
local int CurrentSpareAmmo; local int CurrentSpareAmmo;
local int CurrentMagazineAmmo; local int CurrentMagazineAmmo;
local byte CurrentSecondaryAmmo; local byte CurrentSecondaryAmmo;
local int CurrentSecondarySpareAmmo;
local string CurrentSpecialAmmo; local string CurrentSpecialAmmo;
local KFWeapon CurrentWeapon; local KFWeapon CurrentWeapon;
local ASColorTransform ColorChange; local ASColorTransform ColorChange;
@ -198,10 +201,28 @@ function UpdateWeapon()
CurrentSecondaryAmmo = CurrentWeapon.GetSecondaryAmmoForHUD(); CurrentSecondaryAmmo = CurrentWeapon.GetSecondaryAmmoForHUD();
// Update the amount of ammo // Update the amount of ammo
if (CurrentSecondaryAmmo != LastSecondaryAmmo) if (!bUsesSecondaryAmmoAltHUD)
{ {
SetInt("secondaryAmmo" , CurrentSecondaryAmmo); if (CurrentSecondaryAmmo != LastSecondaryAmmo)
LastSecondaryAmmo = CurrentSecondaryAmmo; {
SetInt("secondaryAmmo" , CurrentSecondaryAmmo);
LastSecondaryAmmo = CurrentSecondaryAmmo;
}
}
else
{
if (CurrentSecondaryAmmo != LastSecondaryAmmo)
{
SetInt("secondaryAltAmmo" , CurrentSecondaryAmmo);
LastSecondaryAmmo = CurrentSecondaryAmmo;
}
CurrentSecondarySpareAmmo = CurrentWeapon.GetSecondarySpareAmmoForHUD();
if (CurrentSecondarySpareAmmo != LastSecondarySpareAmmo)
{
SetInt("secondaryAltSpareAmmo", CurrentSecondarySpareAmmo);
LastSecondarySpareAmmo = CurrentSecondarySpareAmmo;
}
} }
// Force the color of the background if we detect a weapon change and the weapon doesn't use secondary ammo // Force the color of the background if we detect a weapon change and the weapon doesn't use secondary ammo
@ -251,8 +272,18 @@ function RefreshWeapon(KFWeapon CurrentWeapon)
SetBool("bUsesAmmo", bUsesAmmo); SetBool("bUsesAmmo", bUsesAmmo);
bUsesSecondaryAmmo = CurrentWeapon.UsesSecondaryAmmo(); bUsesSecondaryAmmo = CurrentWeapon.UsesSecondaryAmmo();
bUsesSecondaryAmmoAltHUD = bUsesSecondaryAmmo && CurrentWeapon.bUsesSecondaryAmmoAltHUD;
bUsesGrenadesAsSecondaryAmmo = CurrentWeapon.UsesGrenadesAsSecondaryAmmo(); bUsesGrenadesAsSecondaryAmmo = CurrentWeapon.UsesGrenadesAsSecondaryAmmo();
SetBool("bUsesSecondaryAmmo", bUsesSecondaryAmmo);
if (bUsesSecondaryAmmoAltHUD)
{
SetBool("bUsesSecondaryAmmoAlt", bUsesSecondaryAmmoAltHUD);
}
else
{
SetBool("bUsesSecondaryAmmo", bUsesSecondaryAmmo);
}
if( bUsesSecondaryAmmo ) if( bUsesSecondaryAmmo )
{ {
SetString("secondaryIcon", "img://"$CurrentWeapon.SecondaryAmmoTexture.GetPackageName()$"."$CurrentWeapon.SecondaryAmmoTexture); SetString("secondaryIcon", "img://"$CurrentWeapon.SecondaryAmmoTexture.GetPackageName()$"."$CurrentWeapon.SecondaryAmmoTexture);

View File

@ -45,20 +45,23 @@ function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI); KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
//@SABER_EGS IsEosBuild() case added if (class'GameEngine'.Static.IsGameFullyInstalled())
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{ {
class'GameEngine'.static.GetPlayfabInterface().AddOnCloudScriptExecutionCompleteDelegate(OnProcessEndGameRewardsComplete); //@SABER_EGS IsEosBuild() case added
KFGRI.SendPlayfabGameTimeUpdate(true); if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
class'GameEngine'.static.GetPlayfabInterface().AddInventoryReadCompleteDelegate( SearchPlayfabInventoryForNewItem );
}
else
{
if (KFGRI != none)
{ {
KFGRI.ProcessChanceDrop(); class'GameEngine'.static.GetPlayfabInterface().AddOnCloudScriptExecutionCompleteDelegate(OnProcessEndGameRewardsComplete);
KFGRI.SendPlayfabGameTimeUpdate(true);
class'GameEngine'.static.GetPlayfabInterface().AddInventoryReadCompleteDelegate( SearchPlayfabInventoryForNewItem );
} }
OnlineSub.AddOnInventoryReadCompleteDelegate(SearchInventoryForNewItem); else
{
if (KFGRI != none)
{
KFGRI.ProcessChanceDrop();
}
OnlineSub.AddOnInventoryReadCompleteDelegate(SearchInventoryForNewItem);
}
} }
LocalizeText(); LocalizeText();

View File

@ -62,6 +62,8 @@ var KFGFxWidget_NonCriticalGameMessage NonCriticalGameMessageWidget;
var KFGFxWidget_NonCriticalGameMessage InviteGameMessageWidget; var KFGFxWidget_NonCriticalGameMessage InviteGameMessageWidget;
// Widget that shows headshots for gunslinger // Widget that shows headshots for gunslinger
var KFGFxWidget_RhythmCounter RhythmCounterWidget; var KFGFxWidget_RhythmCounter RhythmCounterWidget;
// Widget that shows goompa jumps.
var KFGFxWidget_GoompaCounter GoompaCounterWidget;
// Widget that displays health bar // Widget that displays health bar
var KFGFxWidget_BossHealthBar bossHealthBar; var KFGFxWidget_BossHealthBar bossHealthBar;
// Widget that displays map texts // Widget that displays map texts
@ -335,12 +337,18 @@ event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
break; break;
case 'RhythmCounter': case 'RhythmCounter':
if(RhythmCounterWidget == none) if(RhythmCounterWidget == none)
{ {
RhythmCounterWidget=KFGFxWidget_RhythmCounter(Widget); RhythmCounterWidget=KFGFxWidget_RhythmCounter(Widget);
} }
break;
case 'GoompaCounter':
if (GoompaCounterWidget == none)
{
GoompaCounterWidget=KFGFxWidget_GoompaCounter(Widget);
}
break; break;
} }
return true; return true;
} }
@ -1074,6 +1082,14 @@ function UpdateRhythmCounterWidget(int value, int max)
} }
} }
function UpdateGoompaCounterWidget(int value, int max)
{
if(GoompaCounterWidget != none)
{
GoompaCounterWidget.SetCount(value, max);
}
}
//============================================================== //==============================================================
// Input // Input
//============================================================== //==============================================================
@ -1393,6 +1409,7 @@ DefaultProperties
WidgetBindings.Add((WidgetName="NonCriticalMessageWidget", WidgetClass=class'KFGFxWidget_NonCriticalGameMessage')) WidgetBindings.Add((WidgetName="NonCriticalMessageWidget", WidgetClass=class'KFGFxWidget_NonCriticalGameMessage'))
WidgetBindings.Add((WidgetName="InviteMessageWidget", WidgetClass=class'KFGFxWidget_NonCriticalGameMessage')) WidgetBindings.Add((WidgetName="InviteMessageWidget", WidgetClass=class'KFGFxWidget_NonCriticalGameMessage'))
WidgetBindings.Add((WidgetName="RhythmCounter", WidgetClass=class'KFGFxWidget_RhythmCounter')) WidgetBindings.Add((WidgetName="RhythmCounter", WidgetClass=class'KFGFxWidget_RhythmCounter'))
WidgetBindings.ADD((WidgetName="GoompaCounter", WidgetClass=class'KFGFxWidget_GoompaCounter'));
WidgetBindings.Add((WidgetName="bossHealthBar", WidgetClass=class'KFGFxWidget_BossHealthBar')) WidgetBindings.Add((WidgetName="bossHealthBar", WidgetClass=class'KFGFxWidget_BossHealthBar'))
WidgetBindings.Add((WidgetName="mapTextWidget", WidgetClass=class'KFGFxWidget_MapText')) WidgetBindings.Add((WidgetName="mapTextWidget", WidgetClass=class'KFGFxWidget_MapText'))
WidgetBindings.Add((WidgetName="counterMapTextWidget", WidgetClass=class'KFGFxWidget_MapCounterText')) WidgetBindings.Add((WidgetName="counterMapTextWidget", WidgetClass=class'KFGFxWidget_MapCounterText'))

View File

@ -41,25 +41,40 @@ function SetMapOptions()
{ {
local GFxObject MapList; local GFxObject MapList;
local GFxObject MapObject; local GFxObject MapObject;
local int i; local int i, Counter;
local array<string> ServerMapList; local array<string> ServerMapList;
local KFGameReplicationInfo KFGRI; local KFGameReplicationInfo KFGRI;
local bool IsBrokenTrader;
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI); KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
Counter = 0;
if(KFGRI != none && KFGRI.VoteCollector != none) if(KFGRI != none && KFGRI.VoteCollector != none)
{ {
ServerMapList = KFGRI.VoteCollector.MapList; ServerMapList = KFGRI.VoteCollector.MapList;
IsBrokenTrader = class'KFGameEngine'.static.GetWeeklyEventIndex() == 11;
//gfx //gfx
MapList = CreateArray(); MapList = CreateArray();
for (i = 0; i < ServerMapList.length; i++) for (i = 0; i < ServerMapList.length; i++)
{ {
if (IsBrokenTrader && ( ServerMapList[i] == "KF-Biolapse" ||
ServerMapList[i] == "KF-Nightmare" ||
ServerMapList[i] == "KF-PowerCore_Holdout" ||
ServerMapList[i] == "KF-TheDescent" ||
ServerMapList[i] == "KF-KrampusLair"))
{
continue;
}
MapObject = CreateObject("Object"); MapObject = CreateObject("Object");
MapObject.SetString("label", class'KFCommon_LocalizedStrings'.static.GetFriendlyMapName(ServerMapList[i]) ); MapObject.SetString("label", class'KFCommon_LocalizedStrings'.static.GetFriendlyMapName(ServerMapList[i]) );
MapObject.SetString("mapSource", GetMapSource(ServerMapList[i]) ); MapObject.SetString("mapSource", GetMapSource(ServerMapList[i]) );
MapList.SetElementObject(i, MapObject); MapObject.SetInt("mapindex", i);
MapList.SetElementObject(Counter, MapObject);
Counter++;
} }
} }

View File

@ -12,7 +12,7 @@ class KFGFxPostGameContainer_PlayerStats extends KFGFxObject_Container
dependson(EphemeralMatchStats); dependson(EphemeralMatchStats);
var localized string AchievementsString, ZedKillsString, TopWeaponsString; var localized string AchievementsString, ZedKillsString, TopWeaponsString;
var localized string TotalDamageDealtString, HeadShotsString, LargeZedKillsString, TotalDoshEarnedString, TotalKillsString, AssistsString, DamageDealtString; var localized string TotalDamageDealtString, HeadShotsString, LargeZedKillsString, TotalDoshEarnedString, TotalKillsString, AssistsString, DamageDealtString, TotalStompsString;
var localized string KnifeString; var localized string KnifeString;
var string PlayerStatsString; var string PlayerStatsString;
var int ItemCount; var int ItemCount;
@ -74,7 +74,7 @@ function SetPlayerStats()
ObjectArray.SetElementObject(ItemCount, MakeTextObject(HeadShotsString, String(StatCollector.TotalHeadShots) )); ObjectArray.SetElementObject(ItemCount, MakeTextObject(HeadShotsString, String(StatCollector.TotalHeadShots) ));
ObjectArray.SetElementObject(ItemCount, MakeTextObject(TotalDamageDealtString, String(StatCollector.TotalDamageDealt) )); ObjectArray.SetElementObject(ItemCount, MakeTextObject(TotalDamageDealtString, String(StatCollector.TotalDamageDealt) ));
//ObjectArray.SetElementObject(ItemCount, MakeTextObject("Total Damage Received:", String(StatCollector.TotalDamageTaken) )); //ObjectArray.SetElementObject(ItemCount, MakeTextObject("Total Damage Received:", String(StatCollector.TotalDamageTaken) ));
//weapons //weapons
StatCollector.GetTopWeapons(3, TopWeaponList); StatCollector.GetTopWeapons(3, TopWeaponList);
@ -141,7 +141,7 @@ function GFxObject MakeZedKillObject(Class<KFPawn_Monster> MonsterClass, String
function GFxObject MakeWeaponObject( string WeaponName, string WeaponIcon, int WeaponDamage, int HeadShotsWithWeapon, int LargeZedKillsWithWeapon ) function GFxObject MakeWeaponObject( string WeaponName, string WeaponIcon, int WeaponDamage, int HeadShotsWithWeapon, int LargeZedKillsWithWeapon )
{ {
local GFxObject TempObject; local GFxObject TempObject;
TempObject = CreateObject("Object"); TempObject = CreateObject("Object");
TempObject.SetString("typeString", "TopWeapon"); TempObject.SetString("typeString", "TopWeapon");
TempObject.SetString("weaponName", WeaponName); TempObject.SetString("weaponName", WeaponName);

View File

@ -0,0 +1,27 @@
class KFGFxSpecialEventObjectivesContainer_Summer2021 extends KFGFxSpecialEventObjectivesContainer;
function Initialize(KFGFxObject_Menu NewParentMenu)
{
super.Initialize(NewParentMenu);
}
DefaultProperties
{
ObjectiveIconURLs[0] = "Summer2021_UI.UI_Objective_Summer2021_Kicked" // Stomp on 50 Zeds
ObjectiveIconURLs[1] = "Spring2021_UI.UI_Objectives_Spring2021_Weekly_Hack" // Complete the Weekly on Moonbase
ObjectiveIconURLs[2] = "Summer2021_UI.UI_Objective_Summer2021_ShckingMoonlight" // Use the laser trap to kill 20 Zeds on Moonbase
ObjectiveIconURLs[3] = "Summer2021_UI.UI_Objective_Summer2021_WeightlessSklls" // Kill 300 Zeds while jumping in the air on Moonbase
ObjectiveIconURLs[4] = "Summer2021_UI.UI_Objective_Summer2021_InfiniteVoid" // Complete wave 15 on Endless Hard or higher difficulty on Moonbase
//defaults
AllCompleteRewardIconURL="CHR_CosmeticSet_SS_02_ItemTex.astronaut_companionbackpack.astronautcompanionbackpack_precious"
ChanceDropIconURLs[0]="CHR_CosmeticSet_SS_01_ItemTex.SideshowPremiumTicket_Small"
ChanceDropIconURLs[1]="CHR_CosmeticSet_SS_01_ItemTex.SideshowGoldenTicket_Small"
IconURL="Summer2021_UI.KF2_Summer_InterstellarInsanity_SmallLogo"
UsesProgressList[0] = true
UsesProgressList[1] = false
UsesProgressList[2] = true
UsesProgressList[3] = true
UsesProgressList[4] = false
}

View File

@ -182,28 +182,31 @@ function FillWhatsNew()
local SWhatsNew item; local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length); WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update // Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_DystopianDevastation_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_InterstellarInsanity_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// KF2 Armory Season Pass 2021 // KF2 Armory Season Pass 2021
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Time Limited Item // Featured Time Limited Item
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5803"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_SS_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/4928");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Astronaut", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8953");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Foundry","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/8956");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle // Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Neon_MKVII", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8774"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_BeyondHorizon", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8955");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Paratrooper","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/8775");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_DystopianDevastation", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8773");
WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Chemical", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8776");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Bundle // Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_GravityImploder", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8777"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_FamasMasterkey", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8957");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_ThermiteBore", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8958");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Weaponsbundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8959");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Misc Community Links // Misc Community Links
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");

View File

@ -201,6 +201,8 @@ function InitializeGameOptions()
bIsSoloGame = GetBool("bIsSoloGame"); bIsSoloGame = GetBool("bIsSoloGame");
StartMenu.GetMapList(StartMenu.MapStringList, ParentMenu.Manager.GetModeIndex(false), StartMenu.GetStartMenuState() == EMatchmaking); StartMenu.GetMapList(StartMenu.MapStringList, ParentMenu.Manager.GetModeIndex(false), StartMenu.GetStartMenuState() == EMatchmaking);
FilterWeeklyMaps(StartMenu.MapStringList);
InitialMapIndex = GetInitialMapIndex(); InitialMapIndex = GetInitialMapIndex();
UpdateButtonsEnabled(); UpdateButtonsEnabled();
@ -260,6 +262,24 @@ function InitializeGameOptions()
SetObject("localizedText", TextObject); SetObject("localizedText", TextObject);
} }
function FilterWeeklyMaps(out array<string> List)
{
if (ParentMenu.Manager.GetModeIndex(false) != EGameMode_Weekly)
{
return;
}
// Scavenger index = 11
if (class'KFGameEngine'.static.GetWeeklyEventIndex() == 11)
{
List.RemoveItem("KF-Biolapse");
List.RemoveItem("KF-Nightmare");
List.RemoveItem("KF-PowerCore_Holdout");
List.RemoveItem("KF-TheDescent");
List.RemoveItem("KF-KrampusLair");
}
}
function GFxObject CreateList( array<string> TextArray, byte SelectedIndex, bool bAddNoPrefString, optional bool bIsMapList, optional byte MaxLength) function GFxObject CreateList( array<string> TextArray, byte SelectedIndex, bool bAddNoPrefString, optional bool bIsMapList, optional byte MaxLength)
{ {
local int i; local int i;

View File

@ -446,19 +446,21 @@ DefaultProperties
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
FeaturedItemIDs[0]=8115 FeaturedItemIDs[0]=8178
FeaturedItemIDs[1]=8773 FeaturedItemIDs[1]=8953
FeaturedItemIDs[2]=8774 FeaturedItemIDs[2]=8959
FeaturedItemIDs[3]=8775 FeaturedItemIDs[3]=8956
FeaturedItemIDs[4]=8776 FeaturedItemIDs[4]=8955
FeaturedItemIDs[5]=8777 FeaturedItemIDs[5]=8957
FeaturedItemIDs[6]=8958
ConsoleFeaturedItemIDs[0]=8116 ConsoleFeaturedItemIDs[0]=8181
ConsoleFeaturedItemIDs[1]=8773 ConsoleFeaturedItemIDs[1]=8953
ConsoleFeaturedItemIDs[2]=8774 ConsoleFeaturedItemIDs[2]=8959
ConsoleFeaturedItemIDs[3]=8775 ConsoleFeaturedItemIDs[3]=8956
ConsoleFeaturedItemIDs[4]=8776 ConsoleFeaturedItemIDs[4]=8955
ConsoleFeaturedItemIDs[5]=8777 ConsoleFeaturedItemIDs[5]=8957
ConsoleFeaturedItemIDs[6]=8958
MaxFeaturedItems=5 MaxFeaturedItems=5
} }

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFGFxWidget_GoompaCounter
//=============================================================================
// HUD Widget that displays messages to the player
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// - Zane Gholson 01/14/2015
//=============================================================================
class KFGFxWidget_GoompaCounter extends GFxObject;
function SetCount( int Count, int Max )
{
SetInt("count", Count);
SetBonusPercentage(float(Min(Max,Count)) / float(Max));
if (Count > 0)
{
SetBool("hidden", false);
}
}
function SetBonusPercentage( float NewValue )
{
SetFloat("bonusPercentage", NewValue);
}

View File

@ -68,7 +68,7 @@ function UpdateReadyButtonVisibility()
KFGRI = KFGameReplicationInfo( GetPC().WorldInfo.GRI ); KFGRI = KFGameReplicationInfo( GetPC().WorldInfo.GRI );
if ( KFGRI != none ) if ( KFGRI != none )
{ {
if (KFGRI.bMatchHasBegun && (MyKFPRI != none && MyKFPRI.bHasSpawnedIn && KFGRI.bTraderIsOpen) && !KFGRI.bMatchIsOver && !KFGRI.bVersusGame) if (KFGRI.bMatchHasBegun && (MyKFPRI != none && MyKFPRI.bHasSpawnedIn && KFGRI.bTraderIsOpen) && !KFGRI.bMatchIsOver && MyKFPRI.GetTeamNum() != 255 )
{ {
bShowingSkipTrader = !MyKFPRI.bVotedToSkipTraderTime; bShowingSkipTrader = !MyKFPRI.bVotedToSkipTraderTime;
if (bShowingSkipTrader && !ReadyButton.GetBool("visible")) if (bShowingSkipTrader && !ReadyButton.GetBool("visible"))

View File

@ -1165,24 +1165,34 @@ function ResetAllPickups()
AllPickupFactories.AddItem( AmmoPickups[i] ); AllPickupFactories.AddItem( AmmoPickups[i] );
} }
if(NumWeaponPickups > 0 ) ResetPickups( ItemPickups, NumWeaponPickups );
{
ResetPickups( ItemPickups, NumWeaponPickups ); ResetPickups( AmmoPickups, NumAmmoPickups );
}
if(NumAmmoPickups > 0)
{
ResetPickups( AmmoPickups, NumAmmoPickups );
}
} }
/** Pick random pickup items to enable and put all others to sleep */
/** Pick random pickup items to enable and put all others to sleep */ /** Pick random pickup items to enable and put all others to sleep */
function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups ) function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
{ {
local byte i, ChosenIndex; local byte i, ChosenIndex;
local array<KFPickupFactory> PossiblePickups; local array<KFPickupFactory> PossiblePickups;
local int NumIterations;
if (PickupList.Length == 0)
return;
PossiblePickups = PickupList; PossiblePickups = PickupList;
for ( i = 0; i < NumPickups; i++ )
if (OutbreakEvent != none && OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups && KFPickupFactory_Item(PickupList[0]) != none)
{
NumIterations = Min(NumPickups, PickupList.Length - 1);
}
else
{
NumIterations = Min(NumPickups, PickupList.Length);
}
for ( i = 0; i < NumIterations; i++ )
{ {
ChosenIndex = Rand( PossiblePickups.Length ); ChosenIndex = Rand( PossiblePickups.Length );
PossiblePickups[ChosenIndex].Reset(); PossiblePickups[ChosenIndex].Reset();
@ -3774,6 +3784,19 @@ static function bool HasCustomTraderVoiceGroup()
return false; return false;
} }
/***********************************************
* @name Initial loadout modifier
**********************************************/
simulated function AddWeaponsFromSpawnList(KFPawn P);
simulated function OverrideHumanDefaults(KFPawn_Human P);
/***********************************************
* @name Damage Modifier for Event
**********************************************/
simulated function ModifyDamageGiven(out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx );
defaultproperties defaultproperties
{ {
/** Scoring */ /** Scoring */

View File

@ -343,6 +343,11 @@ var repnotify KFMusicTrackInfo ReplicatedMusicTrackInfo;
* debug * debug
************************************/ ************************************/
/************************************
* Broken Trader Utils
************************************/
var transient bool bIsBrokenTrader;
/************************************ /************************************
* Steam heartbeat * Steam heartbeat
************************************/ ************************************/
@ -353,6 +358,7 @@ native function SendSteamRequestItemDrop();
function native private EndOfWave(); function native private EndOfWave();
cpptext cpptext
{ {
INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel ); INT* GetOptimizedRepList( BYTE* InDefault, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel );
@ -375,7 +381,7 @@ replication
if ( bNetDirty ) if ( bNetDirty )
TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage, TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage,
CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount, CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount,
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective; //@HSL - JRO - 3/21/2016 - PS4 Sessions bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader; //@HSL - JRO - 3/21/2016 - PS4 Sessions
if ( bNetInitial ) if ( bNetInitial )
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled; GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled;
if ( bNetInitial || bNetDirty ) if ( bNetInitial || bNetDirty )
@ -796,7 +802,7 @@ exec reliable client function ShowPreGameServerWelcomeScreen()
} }
simulated function GetKFPRIArray(out array<KFPlayerReplicationInfo> KFPRIArray, optional bool bGetSpectators) simulated function GetKFPRIArray(out array<KFPlayerReplicationInfo> KFPRIArray, optional bool bGetSpectators, optional bool bGetZedPlayers)
{ {
local int i; local int i;
local int Num; local int Num;
@ -805,7 +811,8 @@ simulated function GetKFPRIArray(out array<KFPlayerReplicationInfo> KFPRIArray,
for ( i = 0; i < PRIArray.Length; i++) for ( i = 0; i < PRIArray.Length; i++)
{ {
if ( PRIArray[i] != None && KFPlayerReplicationInfo(PRIArray[i]) != none && if ( PRIArray[i] != None && KFPlayerReplicationInfo(PRIArray[i]) != none &&
(bGetSpectators || !PRIArray[i].bOnlySpectator)) (bGetSpectators || !PRIArray[i].bOnlySpectator) &&
(bGetZedPlayers || PRIArray[i].GetTeamNum() != 255))
{ {
KFPRIArray[num++] = KFPlayerReplicationInfo(PRIArray[i]); KFPRIArray[num++] = KFPlayerReplicationInfo(PRIArray[i]);
} }
@ -2170,6 +2177,12 @@ simulated function UpdatePerksAvailable()
KFPlayerController(GetALocalPlayerController()).UpdatePerkOnInit(); KFPlayerController(GetALocalPlayerController()).UpdatePerkOnInit();
} }
simulated function NotifyBrokenTrader()
{
bIsBrokenTrader = true;
bNetDirty = true;
}
defaultproperties defaultproperties
{ {
TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems" TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems"
@ -2188,4 +2201,5 @@ defaultproperties
PreviousObjectiveResult=-1 PreviousObjectiveResult=-1
PreviousObjectiveVoshResult=-1 PreviousObjectiveVoshResult=-1
PreviousObjectiveXPResult=-1 PreviousObjectiveXPResult=-1
bIsBrokenTrader=false
} }

View File

@ -204,7 +204,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
case SEI_Spring: case SEI_Spring:
return class'KFGFxSpecialEventObjectivesContainer_Spring2021'; return class'KFGFxSpecialEventObjectivesContainer_Spring2021';
case SEI_Summer: case SEI_Summer:
return class'KFGFxSpecialEventObjectivesContainer_Summer2020'; return class'KFGFxSpecialEventObjectivesContainer_Summer2021';
case SEI_Fall: case SEI_Fall:
return class'KFGFxSpecialEventObjectivesContainer_Fall2020'; return class'KFGFxSpecialEventObjectivesContainer_Fall2020';
case SEI_Winter: case SEI_Winter:

View File

@ -209,7 +209,7 @@ function Callback_ReadyClicked( bool bReady )
//player has spawned, skip trader time //player has spawned, skip trader time
if (KFGRI.bTraderIsOpen && KFPRI.bHasSpawnedIn) if (KFGRI.bTraderIsOpen && KFPRI.bHasSpawnedIn)
{ {
if (KFPC.MyGFxManager.bMenusOpen && KFPC.MyGFxManager.CurrentMenu != KFPC.MyGFxManager.TraderMenu && !KFGRI.bVersusGame) if (KFPC.MyGFxManager.bMenusOpen && KFPC.MyGFxManager.CurrentMenu != KFPC.MyGFxManager.TraderMenu)
{ {
//skip trader request //skip trader request
KFPRI.RequestSkiptTrader(KFPRI); KFPRI.RequestSkiptTrader(KFPRI);

View File

@ -26,8 +26,8 @@ enum EMeleeAttackType
}; };
/** Attack settings that should be initialized before calling BeginMeleeAttack */ /** Attack settings that should be initialized before calling BeginMeleeAttack */
var private EPawnOctant NextAttackDir; var protected EPawnOctant NextAttackDir;
var private EMeleeAttackType NextAttackType; var protected EMeleeAttackType NextAttackType;
/** Direction of the last played attack */ /** Direction of the last played attack */
var EPawnOctant CurrentAttackDir; var EPawnOctant CurrentAttackDir;

View File

@ -67,6 +67,7 @@ defaultproperties
ColumnIds.Add(STATID_ACHIEVE_HellmarkStationCollectibles) ColumnIds.Add(STATID_ACHIEVE_HellmarkStationCollectibles)
ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen) ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen)
ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles) ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles)
ColumnIds.Add(STATID_ACHIEVE_MoonbaseCollectibles)
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
@ -122,4 +123,5 @@ defaultproperties
ColumnMappings.Add((Id=STATID_ACHIEVE_HellmarkStationCollectibles,Name="AchievementCollectHellmarkStation")) ColumnMappings.Add((Id=STATID_ACHIEVE_HellmarkStationCollectibles,Name="AchievementCollectHellmarkStation"))
ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium")) ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium"))
ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029")) ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MoonbaseCollectibles,NAme="AchievementCollectMoonbase"))
} }

View File

@ -429,6 +429,10 @@ const KFACHID_Dystopia2029Hard = 280;
const KFACHID_Dystopia2029HellOnEarth = 281; const KFACHID_Dystopia2029HellOnEarth = 281;
const KFACHID_Dystopia2029Collectibles = 282; const KFACHID_Dystopia2029Collectibles = 282;
const KFACHID_MoonbaseHard = 283;
const KFACHID_MoonbaseHellOnEarth = 284;
const KFACHID_MoonbaseCollectibles = 285;
/* __TW_ANALYTICS_ */ /* __TW_ANALYTICS_ */
var int PerRoundWeldXP; var int PerRoundWeldXP;
var int PerRoundHealXP; var int PerRoundHealXP;
@ -1083,6 +1087,11 @@ private event AddToHitsTaken()
SeasonalEventStats_OnHitTaken(); SeasonalEventStats_OnHitTaken();
} }
private event AddToHitsGiven(class<DamageType> DT)
{
SeasonalEventStats_OnHitGiven(DT);
}
/** /**
* @brief Add a kill and give some EXP tp the player * @brief Add a kill and give some EXP tp the player
* @param MonsterClass The killed monster's class * @param MonsterClass The killed monster's class
@ -1810,6 +1819,14 @@ final simulated function SeasonalEventStats_OnHitTaken()
} }
} }
final simulated function SeasonalEventStats_OnHitGiven(class<DamageType> DT)
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnHitGiven(DT);
}
}
final simulated function SeasonalEventStats_OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT) final simulated function SeasonalEventStats_OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{ {
if (SeasonalEventIsValid()) if (SeasonalEventIsValid())
@ -2003,6 +2020,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_P90, KFDT_Ballistic_P90,KFDT_Bludgeon_P90),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_P90, KFDT_Ballistic_P90,KFDT_Bludgeon_P90),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Kriss, KFDT_Ballistic_Kriss,KFDT_Bludgeon_Kriss),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_Kriss, KFDT_Ballistic_Kriss,KFDT_Bludgeon_Kriss),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_HK_UMP, KFDT_Ballistic_HK_UMP,KFDT_Bludgeon_HK_UMP),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_SMG_HK_UMP, KFDT_Ballistic_HK_UMP,KFDT_Bludgeon_HK_UMP),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BarrierRifle, KFDT_Ballistic_HRG_BarrierRifle,KFDT_Bludgeon_HRG_BarrierRifle),CompletionAmount=10000))
//Commando Weapons //Commando Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_AR15, KFDT_Ballistic_AR15,KFDT_Bludgeon_AR15),CompletionAmount=5000)) //3000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_AR15, KFDT_Ballistic_AR15,KFDT_Bludgeon_AR15),CompletionAmount=5000)) //3000
@ -2020,6 +2038,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_M4, KFDT_Ballistic_M4Shotgun,KFDT_Bludgeon_M4Shotgun),CompletionAmount=10000)) //7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_M4, KFDT_Ballistic_M4Shotgun,KFDT_Bludgeon_M4Shotgun),CompletionAmount=10000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_AA12, KFDT_Ballistic_AA12Shotgun,KFDT_Bludgeon_AA12Shotgun),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_AA12, KFDT_Ballistic_AA12Shotgun,KFDT_Bludgeon_AA12Shotgun),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_ElephantGun, KFDT_Ballistic_ElephantGun,KFDT_Bludgeon_ElephantGun),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_ElephantGun, KFDT_Ballistic_ElephantGun,KFDT_Bludgeon_ElephantGun),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BlastBrawlers, KFDT_Ballistic_BlastBrawlersShotgun,KFDT_Bludgeon_BlastBrawlers,KFDT_Bludgeon_BlastBrawlersHeavy,KFDT_Bludgeon_BlastBrawlersBash),CompletionAmount=10000))
//Medic Weapons //Medic Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Medic, KFDT_Ballistic_Pistol_Medic,KFDT_Bludgeon_Pistol_Medic),CompletionAmount=5000)) //3000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Medic, KFDT_Ballistic_Pistol_Medic,KFDT_Bludgeon_Pistol_Medic),CompletionAmount=5000)) //3000
@ -2225,7 +2244,10 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=1)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=2)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=3)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-DYSTOPIA2029),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=3))
//Versus Damage //Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount // Per design doc that I have right now, these are x class damage y players, not damage y amount
/*DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedClot_Alpha, KFPawn_ZedClot_Alpha_Versus),CompletionAmount=1)) /*DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedClot_Alpha, KFPawn_ZedClot_Alpha_Versus),CompletionAmount=1))

View File

@ -69,4 +69,5 @@ defaultproperties
Properties.Add((PropertyId = STATID_ACHIEVE_HellmarkStationCollectibles,Data = (Type = SDT_Int32,Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_HellmarkStationCollectibles,Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Data = (Type = SDT_Int32,Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_Dystopia2029Collectibles, Data = (Type = SDT_Int32,Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_Dystopia2029Collectibles, Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_MoonbaseCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
} }

View File

@ -93,7 +93,6 @@ struct StatAdjustments
/** Speed modifier */ /** Speed modifier */
var() float InitialGroundSpeedModifierScale; var() float InitialGroundSpeedModifierScale;
structdefaultproperties structdefaultproperties
{ {
HealthScale = 1.f; HealthScale = 1.f;
@ -146,6 +145,9 @@ struct WeeklyOverrides
* array prior to calling in to P.AddDefaultInventory * array prior to calling in to P.AddDefaultInventory
*/ */
var() KFGFxObject_TraderItems SpawnWeaponList; var() KFGFxObject_TraderItems SpawnWeaponList;
/** Adds weapon spawn list to the player's loadout */
var() bool bAddSpawnListToLoadout;
/** If this flag is set to true, the secondary weapon will be checked for availability in the current game mode */ /** If this flag is set to true, the secondary weapon will be checked for availability in the current game mode */
var() bool bSpawnWeaponListAffectsSecondaryWeapons; var() bool bSpawnWeaponListAffectsSecondaryWeapons;
@ -333,12 +335,39 @@ struct WeeklyOverrides
/** Replenish player's health once a wave ends. */ /** Replenish player's health once a wave ends. */
var() bool bHealPlayerAfterWave; var() bool bHealPlayerAfterWave;
/** Can kill enemies by jumping on them */
var() bool bGoompaJumpEnabled;
/** Damage done when jumping over an enemy */
var() int GoompaJumpDamage;
/** Damage added per goompa streak */
var() float GoompaStreakDamage;
/** Max number of goompa jumps that counts for damage increase */
var() int GoompaStreakMax;
/** Impulse applied to the player when jumping over an enemy */
var() float GoompaJumpImpulse;
/** Duration of the goompa streak bonus */
var() float GoompaBonusDuration;
/** Z velocity for jumping */
var() float JumpZ;
/** Drop items lifespan */
var() float DroppedItemLifespan;
/** Global modifier of dosh received by players when a zed is killed. Default value is 1.0 */ /** Global modifier of dosh received by players when a zed is killed. Default value is 1.0 */
var() float DoshOnKillGlobalModifier; var() float DoshOnKillGlobalModifier;
/** Delay After a wave starts for applying global damage. */ /** Delay After a wave starts for applying global damage. */
var() float DamageDelayAfterWaveStarted; var() float DamageDelayAfterWaveStarted;
/** If weapon pickups should spawn unfinitely */
var() bool bUnlimitedWeaponPickups;
/** If another outbreak mode shares the same events, this will link the two to quicker UI lookup */ /** If another outbreak mode shares the same events, this will link the two to quicker UI lookup */
var() int WeeklyOutbreakId; var() int WeeklyOutbreakId;
@ -378,13 +407,23 @@ struct WeeklyOverrides
bGlobalDamageAffectsShield = true bGlobalDamageAffectsShield = true
bApplyGlobalDamageBossWave = true bApplyGlobalDamageBossWave = true
bHealPlayerAfterWave = false bHealPlayerAfterWave = false
bGoompaJumpEnabled = false
bUnlimitedWeaponPickups = false
GoompaJumpDamage = 0;
GoompaStreakDamage = 0;
GoompaJumpImpulse = 0;
GoompaStreakMax = 0;
GoompaBonusDuration = 0.0f;
DamageDelayAfterWaveStarted = 10.0f DamageDelayAfterWaveStarted = 10.0f
WeeklyOutbreakId=INDEX_NONE WeeklyOutbreakId=INDEX_NONE
bAddSpawnListToLoadout = false
bSpawnWeaponListAffectsSecondaryWeapons = false bSpawnWeaponListAffectsSecondaryWeapons = false
bColliseumSkillConditionsActive = false bColliseumSkillConditionsActive = false
bModifyZedTimeOnANearZedKill = false bModifyZedTimeOnANearZedKill = false
ZedTimeOnANearZedKill = 0.05 ZedTimeOnANearZedKill = 0.05
DoshOnKillGlobalModifier = 1.0f DoshOnKillGlobalModifier = 1.0f
JumpZ = -1.f
DroppedItemLifespan=-1.0f
} }
}; };
@ -756,7 +795,6 @@ function AdjustMonsterDefaults(out KFPawn_Monster P)
P.HealByKill = ToAdjust.HealByKill; P.HealByKill = ToAdjust.HealByKill;
P.HealByAssistance = ToAdjust.HealByAssistance; P.HealByAssistance = ToAdjust.HealByAssistance;
P.InitialGroundSpeedModifier *= ToAdjust.InitialGroundSpeedModifierScale; P.InitialGroundSpeedModifier *= ToAdjust.InitialGroundSpeedModifierScale;
if (ToAdjust.bStartEnraged) if (ToAdjust.bStartEnraged)

View File

@ -871,6 +871,14 @@ var bool bLogCustomAnim;
var Texture2D DebugRadarTexture; var Texture2D DebugRadarTexture;
var repnotify bool bHasStartedFire; var repnotify bool bHasStartedFire;
var repnotify byte WeaponSpecialAction;
/*********************************************************************************************
* @name Cached last hit index.
* Afflictions are failing to get the proper zone index of the hit as it is read before
written. This is a temp fix for it.
********************************************************************************************* */
var transient byte LastHitZoneIndex;
replication replication
{ {
@ -897,7 +905,7 @@ replication
// Replicated to all but the owning client // Replicated to all but the owning client
if ( bNetDirty && (!bNetOwner || bDemoRecording) ) if ( bNetDirty && (!bNetOwner || bDemoRecording) )
WeaponAmbientSound, SecondaryWeaponAmbientSound; WeaponAmbientSound, SecondaryWeaponAmbientSound, WeaponSpecialAction;
if ( bEnableAimOffset && (!bNetOwner || bDemoRecording) ) if ( bEnableAimOffset && (!bNetOwner || bDemoRecording) )
ReplicatedAimOffsetPct; ReplicatedAimOffsetPct;
if ( bNetDirty && bCanCloak ) if ( bNetDirty && bCanCloak )
@ -1155,6 +1163,8 @@ simulated event ReplicatedEvent(name VarName)
OnStartFire(); OnStartFire();
} }
break; break;
case nameof(WeaponSpecialAction):
OnWeaponSpecialAction(WeaponSpecialAction);
} }
Super.ReplicatedEvent(VarName); Super.ReplicatedEvent(VarName);
@ -1886,6 +1896,20 @@ simulated function OnStartFire()
} }
} }
simulated function OnWeaponSpecialAction(int Arg)
{
if (Role == ROLE_Authority)
{
WeaponSpecialAction = Arg;
bNetDirty = true;
}
if(WeaponAttachment != none)
{
WeaponAttachment.OnSpecialEvent(Arg);
}
}
/** /**
* Called when a pawn's weapon has fired and is responsibile for * Called when a pawn's weapon has fired and is responsibile for
* delegating the creation off all of the different effects. * delegating the creation off all of the different effects.
@ -2673,7 +2697,7 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
Super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); Super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
// using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done // using the passed in damage type instead of the hitfxinfo since that doesn't get updated when zero damage is done
HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), class<KFDamageType>(DamageType), DamageCauser); // HandleAfflictionsOnHit(InstigatedBy, Normal(Momentum), class<KFDamageType>(DamageType), DamageCauser);
ActualDamage = OldHealth - Health; ActualDamage = OldHealth - Health;
if( ActualDamage > 0 ) if( ActualDamage > 0 )
@ -2776,6 +2800,8 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
InDamage = Health - 1; InDamage = Health - 1;
} }
LastHitZoneIndex = HitZoneIdx;
`log(self @ GetFuncName() @ " After KFPawn adjustment Damage=" $ InDamage @ "Momentum=" $ Momentum @ "Zone=" $ HitInfo.BoneName @ "DamageType=" $ DamageType, bLogTakeDamage); `log(self @ GetFuncName() @ " After KFPawn adjustment Damage=" $ InDamage @ "Momentum=" $ Momentum @ "Zone=" $ HitInfo.BoneName @ "DamageType=" $ DamageType, bLogTakeDamage);
} }
@ -3999,12 +4025,12 @@ simulated function KFSkinTypeEffects GetHitZoneSkinTypeEffects( int HitZoneIdx )
*/ */
simulated function AdjustAffliction(out float AfflictionPower); simulated function AdjustAffliction(out float AfflictionPower);
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser) function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser)
{ {
//Handle afflictions //Handle afflictions
if (AfflictionHandler != None) if (AfflictionHandler != None)
{ {
AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, DamageType, DamageCauser); AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, class<KFDamageType>(DamageType), DamageCauser);
} }
} }
@ -5623,4 +5649,5 @@ defaultproperties
bAllowDeathSM=true bAllowDeathSM=true
bCanBePinned=false bCanBePinned=false
LastHitZoneIndex=0
} }

View File

@ -230,6 +230,8 @@ cpptext
virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive,AActor *SourceActor, DWORD TraceFlags); virtual UBOOL ShouldTrace(UPrimitiveComponent* Primitive,AActor *SourceActor, DWORD TraceFlags);
} }
native function float GetGravityZ();
/********************************************************************************************* /*********************************************************************************************
* @name General * @name General
********************************************************************************************* */ ********************************************************************************************* */
@ -309,6 +311,9 @@ function PossessedBy(Controller C, bool bVehicleTransition)
{ {
SetTimer( 1.f, true, nameOf(Timer_CheckSurrounded) ); SetTimer( 1.f, true, nameOf(Timer_CheckSurrounded) );
} }
KFGameInfo(WorldInfo.Game).OverrideHumanDefaults( self );
} }
simulated function NotifyTeamChanged() simulated function NotifyTeamChanged()
@ -2093,6 +2098,22 @@ function UpdateActiveSkillsPath(string IconPath, bool Active)
KFPC.MyGFxHUD.PlayerStatusContainer.ShowActiveIndicators(ActiveSkillIconPaths); KFPC.MyGFxHUD.PlayerStatusContainer.ShowActiveIndicators(ActiveSkillIconPaths);
} }
event Landed(vector HitNormal, actor FloorActor)
{
local KFPlayerController_WeeklySurvival KFPC;
super.Landed(HitNormal, FloorActor);
if (KFPawn_Monster(FloorActor) == none)
{
KFPC = KFPlayerController_WeeklySurvival(Controller);
if (KFPC != none)
{
KFPC.ResetGoompaStreak();
}
}
}
defaultproperties defaultproperties
{ {
Begin Object Class=KFFlashlightAttachment name=Flashlight_0 Begin Object Class=KFFlashlightAttachment name=Flashlight_0

View File

@ -592,6 +592,8 @@ native function SetChokePointCollision( bool bUseChokeCollision );
/** Checks if we are our current location encroaches any world geometry */ /** Checks if we are our current location encroaches any world geometry */
native function bool CheckEncroachingWorldGeometry(); native function bool CheckEncroachingWorldGeometry();
native function float GetGravityZ();
/** /**
* Check on various replicated data and act accordingly. * Check on various replicated data and act accordingly.
*/ */
@ -1392,6 +1394,58 @@ function SetMovementPhysics()
/** Implements bKnockdownWhenJumpedOn */ /** Implements bKnockdownWhenJumpedOn */
function CrushedBy(Pawn OtherPawn) function CrushedBy(Pawn OtherPawn)
{ {
local KFGameInfo KFGI;
local KFPlayerController_WeeklySurvival KFPC_WS;
local KFPawn_Human KFPH;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
KFPH = KFPawn_Human(OtherPawn);
if (KFPH != none)
{
/*
* For summer season event, we wanto to know if we stomp a zed.
* Adding the notify here will prevent more network data.
* DmgType_Crushed is enough for it, no need to add the goompa.
*/
KFPC = KFPlayerController(KFPH.Controller);
if (KFPC != none)
{
KFPC.NotifyHitGiven(class'DmgType_Crushed');
}
///
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none) // Only for players
{
if (KFGI.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled)
{
OtherPawn.Velocity = OtherPawn.Velocity * vect(1,1,0);
OtherPawn.AddVelocity( vect(0,0,1) * KFGI.OutbreakEvent.ActiveEvent.GoompaJumpImpulse, Instigator.Location, none);
TakeDamage( KFGI.OutbreakEvent.ActiveEvent.GoompaJumpDamage, OtherPawn.Controller,Location, vect(0,0,0) , class'KFDT_GoompaStomp');
KFPC_WS = KFPlayerController_WeeklySurvival(OtherPawn.Controller);
if(KFPC_WS != none)
{
KFPC_WS.UpdateGoompaStreak();
}
// Registering awards information.
`RecordAARIntStat(KFPC, STOMP_GIVEN, 1);
KFPRI = KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo);
if (KFPRI != none)
{
KFPRI.ZedStomps++;
}
return;
}
}
}
Super.CrushedBy(OtherPawn); Super.CrushedBy(OtherPawn);
if ( bKnockdownWhenJumpedOn if ( bKnockdownWhenJumpedOn
@ -2087,6 +2141,7 @@ function AdjustDamageForInstigator(out int InDamage, Controller InstigatedBy, cl
local KFPawn_Human KFPH; local KFPawn_Human KFPH;
local KFPerk InstigatorPerk; local KFPerk InstigatorPerk;
local KFPowerUp InstigatorPowerUp; local KFPowerUp InstigatorPowerUp;
local KFGameInfo KFGI;
local float TempDamage; local float TempDamage;
// Let the instigator's perk adjust the damage // Let the instigator's perk adjust the damage
@ -2105,6 +2160,12 @@ function AdjustDamageForInstigator(out int InDamage, Controller InstigatedBy, cl
InstigatorPowerUp.ModifyDamageGiven(InDamage, DamageCauser, self, KFPC, class<KFDamageType>(DamageType), HitZoneIdx); InstigatorPowerUp.ModifyDamageGiven(InDamage, DamageCauser, self, KFPC, class<KFDamageType>(DamageType), HitZoneIdx);
} }
KFGI = KFGameInfo(WorldInfo.Game);
if(KFGI != none && KFGI.OutbreakEvent != none)
{
KFGI.ModifyDamageGiven(InDamage, DamageCauser, self, KFPC, class<KFDamageType>(DamageType), HitZoneIdx);
}
if( KFPC.Pawn != none ) if( KFPC.Pawn != none )
{ {
KFPH = KFPawn_Human(KFPC.Pawn); KFPH = KFPawn_Human(KFPC.Pawn);

View File

@ -472,6 +472,28 @@ static function bool IsDual9mm( KFWeapon KFW )
return KFW != none && KFW.Class.Name == 'KFWeap_Pistol_Dual9mm'; return KFW != none && KFW.Class.Name == 'KFWeap_Pistol_Dual9mm';
} }
/**
* @brief Return if a weapon is FAMAS (special case for high capacity perk)
*
* @param KFW Weapon to check
* @return true if backup weapon
*/
static function bool IsFAMAS( KFWeapon KFW )
{
return KFW != none && KFW.Class.Name == 'KFWeap_AssaultRifle_FAMAS';
}
/**
* @brief Return if a weapon is the Blast Brawlers (special case needed for ZedTime perks)
*
* @param KFW Weapon to check
* @return true if backup weapon
*/
static function bool IsBlastBrawlers( KFWeapon KFW )
{
return KFW != none && KFW.Class.Name == 'KFWeap_HRG_BlastBrawlers';
}
/********************************************************************************************* /*********************************************************************************************
* @name Build / Level Management - Apply and save the updated build and level * @name Build / Level Management - Apply and save the updated build and level
********************************************************************************************* */ ********************************************************************************************* */
@ -941,15 +963,17 @@ function AddDefaultInventory( KFPawn P )
if (KFGameInfo(WorldInfo.Game) != none) if (KFGameInfo(WorldInfo.Game) != none)
{ {
if (KFGameInfo(WorldInfo.Game).AllowPrimaryWeapon(GetPrimaryWeaponClassPath())) if (KFGameInfo(WorldInfo.Game).AllowPrimaryWeapon(GetPrimaryWeaponClassPath()))
{ {
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class'))); P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class')));
} }
if(KFGameInfo(WorldInfo.Game).AllowSecondaryWeapon(GetSecondaryWeaponClassPath())) if(KFGameInfo(WorldInfo.Game).AllowSecondaryWeapon(GetSecondaryWeaponClassPath()))
{ {
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetSecondaryWeaponClassPath(), class'Class'))); P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetSecondaryWeaponClassPath(), class'Class')));
} }
KFGameInfo(WorldInfo.Game).AddWeaponsFromSpawnList(P);
} }
else else
{ {

View File

@ -195,7 +195,7 @@ simulated function ModifyMeleeAttackSpeed( out float InDuration, KFWeapon KFW )
{ {
local float TempDuration; local float TempDuration;
if( KFW == none || !KFW.IsMeleeWeapon() ) if( KFW == none || !KFW.IsMeleeWeapon() || IsBlastBrawlers(KFW) )
{ {
return; return;
} }
@ -265,7 +265,7 @@ simulated function ModifySpeed( out float Speed )
} }
if (MyKFWeapon != none && if (MyKFWeapon != none &&
(MyKFWeapon.IsMeleeWeapon() || IsWeaponOnPerk(MyKFWeapon,, self.class))) ((MyKFWeapon.IsMeleeWeapon() && !IsBlastBrawlers(MyKFWeapon)) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{ {
Speed += Speed * GetSkillValue( PerkSkills[EBerserkerNinja] ); Speed += Speed * GetSkillValue( PerkSkills[EBerserkerNinja] );
} }
@ -297,7 +297,7 @@ simulated function ModifySprintSpeed( out float Speed )
} }
if (MyKFWeapon != none && if (MyKFWeapon != none &&
(MyKFWeapon.IsMeleeWeapon() || IsWeaponOnPerk(MyKFWeapon,, self.class))) ((MyKFWeapon.IsMeleeWeapon() && !IsBlastBrawlers(MyKFWeapon)) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{ {
Speed += Speed * static.GetNinjaSprintModifier(); Speed += Speed * static.GetNinjaSprintModifier();
} }
@ -973,7 +973,7 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl
DefaultProperties DefaultProperties
{ {
ParryDuration=10.f ParryDuration=6.f //10.f
ParrySpeed=0.05 ParrySpeed=0.05
FurySpeed=0.05 FurySpeed=0.05
NinjaSprintModifer=0.25 NinjaSprintModifer=0.25
@ -982,14 +982,14 @@ DefaultProperties
SpeedDamageModifier=0.2 SpeedDamageModifier=0.2
SmashHeadDamageModifier=0.25 SmashHeadDamageModifier=0.25
VampireAttackSpeedModifier=0.2f VampireAttackSpeedModifier=0.2f
ParryDamageReduction=0.4f //0.75 ParryDamageReduction=0.25f //0.4f //0.75
RageRadius=1000 //300 RageRadius=1000 //300
RageFleeDuration=5.f //3 RageFleeDuration=5.f //3
RageFleeDistance=2500 //5000 RageFleeDistance=2500 //5000
RageDialogEvent=229 RageDialogEvent=229
RegenerationInterval=1 RegenerationInterval=1
RegenerationAmount=2 RegenerationAmount=1 //2
ZedTimeModifyingStates(0)="MeleeChainAttacking" ZedTimeModifyingStates(0)="MeleeChainAttacking"
ZedTimeModifyingStates(1)="MeleeAttackBasic" ZedTimeModifyingStates(1)="MeleeAttackBasic"
@ -1013,14 +1013,14 @@ DefaultProperties
GrenadeWeaponDef=class'KFWeapDef_Grenade_Berserker' GrenadeWeaponDef=class'KFWeapDef_Grenade_Berserker'
BerserkerDamage=(Name="Berserker Damage",Increment=0.01,Rank=0,StartingValue=0.f,MaxValue=0.25) BerserkerDamage=(Name="Berserker Damage",Increment=0.01,Rank=0,StartingValue=0.f,MaxValue=0.25)
DamageResistance=(Name="Damage Resistance",Increment=0.03f,Rank=0,StartingValue=0.f,MaxValue=0.15f) DamageResistance=(Name="Damage Resistance",Increment=0.02f,Rank=0,StartingValue=0.f,MaxValue=0.1f) //0.03f, 0, 0.f, 0.15f
NightVision=(Name="Night Vision",Increment=0.f,Rank=0,StartingValue=0.f,MaxValue=0.f) NightVision=(Name="Night Vision",Increment=0.f,Rank=0,StartingValue=0.f,MaxValue=0.f)
PerkSkills(EBerserkerFortitude)=(Name="Fortitude",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Fortitude",Increment=0.f,Rank=0,StartingValue=1.0,MaxValue=1.0) //0.75 PerkSkills(EBerserkerFortitude)=(Name="Fortitude",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Fortitude",Increment=0.f,Rank=0,StartingValue=1.0,MaxValue=1.0) //0.75
PerkSkills(EBerserkerNinja)=(Name="Ninja",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Ninja",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f) PerkSkills(EBerserkerNinja)=(Name="Ninja",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Ninja",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f)
PerkSkills(EBerserkerVampire)=(Name="Vampire",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Vampire",Increment=0.f,Rank=0,StartingValue=4.f,MaxValue=4.f) PerkSkills(EBerserkerVampire)=(Name="Vampire",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Vampire",Increment=0.f,Rank=0,StartingValue=3.f,MaxValue=3.f) //4.f
PerkSkills(EBerserkerSpeed)=(Name="Speed",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Speed",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f) PerkSkills(EBerserkerSpeed)=(Name="Speed",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Speed",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f)
PerkSkills(EBerserkerResistance)=(Name="Resistance",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_PoisonResistance",Increment=0.f,Rank=0,StartingValue=0.25f,MaxValue=0.25f) //0.2 PerkSkills(EBerserkerResistance)=(Name="Resistance",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_PoisonResistance",Increment=0.f,Rank=0,StartingValue=0.15f,MaxValue=0.15f) //0.15 //0.2
PerkSkills(EBerserkerParry)=(Name="Parry",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Parry",Increment=0.f,Rank=0,StartingValue=0.35,MaxValue=0.35) PerkSkills(EBerserkerParry)=(Name="Parry",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Parry",Increment=0.f,Rank=0,StartingValue=0.35,MaxValue=0.35)
PerkSkills(EBerserkerSmash)=(Name="Smash",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Smash",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f) PerkSkills(EBerserkerSmash)=(Name="Smash",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Smash",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f)
PerkSkills(EBerserkerFury)=(Name="Fury",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Intimidate",Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f) PerkSkills(EBerserkerFury)=(Name="Fury",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Intimidate",Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f)

View File

@ -250,7 +250,8 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
TempCapacity = MagazineCapacity; TempCapacity = MagazineCapacity;
if( !bSecondary && IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) ) // FAMAS needs its secondary ammo affected
if( (!bSecondary || IsFAMAS(KFW)) && IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) )
{ {
if( IsLargeMagActive() ) if( IsLargeMagActive() )
{ {

View File

@ -1037,7 +1037,7 @@ DefaultProperties
PerkSkills(EDemoDamage)=(Name="Damage",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_GrenadeSupplier",Increment=0.f,Rank=0,StartingValue=0.25f,MaxValue=0.25f) PerkSkills(EDemoDamage)=(Name="Damage",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_GrenadeSupplier",Increment=0.f,Rank=0,StartingValue=0.25f,MaxValue=0.25f)
PerkSkills(EDemoTacticalReload)=(Name="Speed",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Speed",Increment=0.f,Rank=0,StartingValue=0.10f,MaxValue=0.10f) PerkSkills(EDemoTacticalReload)=(Name="Speed",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Speed",Increment=0.f,Rank=0,StartingValue=0.10f,MaxValue=0.10f)
PerkSkills(EDemoDirectHit)=(Name="DirectHit",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_ExplosiveResistance",Increment=0.f,Rank=0,StartingValue=0.25,MaxValue=0.25) PerkSkills(EDemoDirectHit)=(Name="DirectHit",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_ExplosiveResistance",Increment=0.f,Rank=0,StartingValue=0.25,MaxValue=0.25)
PerkSkills(EDemoAmmo)=(Name="Ammo",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Ammo",Increment=0.f,Rank=0,StartingValue=5.f,MaxValue=5.f,) PerkSkills(EDemoAmmo)=(Name="Ammo",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Ammo",Increment=0.f,Rank=0,StartingValue=10.f,MaxValue=10.f) //5.f
PerkSkills(EDemoSirenResistance)=(Name="SirenResistance",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_SirenResistance",Increment=0.f,Rank=0,StartingValue=0.5,MaxValue=0.5) PerkSkills(EDemoSirenResistance)=(Name="SirenResistance",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_SirenResistance",Increment=0.f,Rank=0,StartingValue=0.5,MaxValue=0.5)
PerkSkills(EDemoAoE)=(Name="AreaOfEffect",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_AoE",Increment=0.f,Rank=0,StartingValue=1.50,MaxValue=1.50) PerkSkills(EDemoAoE)=(Name="AreaOfEffect",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_AoE",Increment=0.f,Rank=0,StartingValue=1.50,MaxValue=1.50)
PerkSkills(EDemoCriticalHit)=(Name="CriticalHit",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Crit",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f) PerkSkills(EDemoCriticalHit)=(Name="CriticalHit",IconPath="UI_PerkTalent_TEX.demolition.UI_Talents_Demolition_Crit",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f)

View File

@ -645,7 +645,7 @@ DefaultProperties
ProgressStatID=STATID_Medic_Progress ProgressStatID=STATID_Medic_Progress
PerkBuildStatID=STATID_Medic_Build PerkBuildStatID=STATID_Medic_Build
SelfHealingSurgePct=0.1f SelfHealingSurgePct=0.06f //0.1f
MaxSurvivalistResistance=0.60f //0.70f //0.5f //0.8 MaxSurvivalistResistance=0.60f //0.70f //0.5f //0.8
CombatantSpeedModifier=0.1f CombatantSpeedModifier=0.1f
@ -726,7 +726,7 @@ DefaultProperties
HealPotency=(Name="Healer Potency",Increment=0.02f,Rank=0,StartingValue=1.0f,MaxValue=1.5f) HealPotency=(Name="Healer Potency",Increment=0.02f,Rank=0,StartingValue=1.0f,MaxValue=1.5f)
BloatBileResistance=(Name="Bloat Bile Resistance",Increment=0.02,Rank=0,StartingValue=0.f,MaxValue=0.5f) BloatBileResistance=(Name="Bloat Bile Resistance",Increment=0.02,Rank=0,StartingValue=0.f,MaxValue=0.5f)
MovementSpeed=(Name="Movement Speed",Increment=0.004f,Rank=0,StartingValue=0.f,MaxValue=0.1f) MovementSpeed=(Name="Movement Speed",Increment=0.004f,Rank=0,StartingValue=0.f,MaxValue=0.1f)
Armor=(Name="Armor",Increment=0.03f,Rank=0,StartingValue=1.f,MaxValue=1.75f) Armor=(Name="Armor",Increment=0.02f,Rank=0,StartingValue=1.f,MaxValue=1.5f) //0.03f, 0f, 1f, 1.75f
PerkSkills(EMedicHealingSurge)=(Name="HealingSurge",IconPath="UI_PerkTalent_TEX.Medic.UI_Talents_Medic_HealingSurge", Increment=0.f,Rank=0,StartingValue=0.25,MaxValue=0.25) PerkSkills(EMedicHealingSurge)=(Name="HealingSurge",IconPath="UI_PerkTalent_TEX.Medic.UI_Talents_Medic_HealingSurge", Increment=0.f,Rank=0,StartingValue=0.25,MaxValue=0.25)
PerkSkills(EMedicSurvivalist)=(Name="Survivalist",IconPath="ui_perktalent_tex.Medic.UI_Talents_Medic_Resilience", Increment=0.f,Rank=0,StartingValue=0.01f,MaxValue=0.01f) PerkSkills(EMedicSurvivalist)=(Name="Survivalist",IconPath="ui_perktalent_tex.Medic.UI_Talents_Medic_Resilience", Increment=0.f,Rank=0,StartingValue=0.01f,MaxValue=0.01f)

View File

@ -246,7 +246,8 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
TempCapacity = MagazineCapacity; TempCapacity = MagazineCapacity;
if( !bSecondary && IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && // FAMAS needs its secondary ammo affected
if( (!bSecondary || IsFAMAS(KFW)) && IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) &&
HighCapMagExemptList.Find(WeaponClassName) == INDEX_NONE ) HighCapMagExemptList.Find(WeaponClassName) == INDEX_NONE )
{ {
if( IsHighCapMagsMagActive() ) if( IsHighCapMagsMagActive() )
@ -559,8 +560,9 @@ simulated function float GetZedTimeModifier( KFWeapon W )
local name StateName; local name StateName;
StateName = W.GetStateName(); StateName = W.GetStateName();
// Blast Brawlers use a different state for shooting (combining melee + firing). Needs a special case for this
if( IsWeaponOnPerk( W,, self.class ) && CouldBarrageActive() && if( IsWeaponOnPerk( W,, self.class ) && CouldBarrageActive() &&
ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE ) (ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE || (StateName == 'MeleeChainAttacking' && IsBlastBrawlers(W))))
{ {
return BarrageFiringRate; return BarrageFiringRate;
} }
@ -821,7 +823,7 @@ DefaultProperties
ShotgunPenetration=(Name="Shotgun Penetration",Increment=0.20,Rank=0,StartingValue=0.0f,MaxValue=5.0f) //6.25 ShotgunPenetration=(Name="Shotgun Penetration",Increment=0.20,Rank=0,StartingValue=0.0f,MaxValue=5.0f) //6.25
Strength=(Name="Strength",Increment=1.f,Rank=0,StartingValue=0.f,MaxValue=5.f) Strength=(Name="Strength",Increment=1.f,Rank=0,StartingValue=0.f,MaxValue=5.f)
PerkSkills(ESupportHighCapMags)=(Name="HighCapMags",IconPath="UI_PerkTalent_TEX.support.UI_Talents_Support_HighCapacityMags",Increment=0.f,Rank=0,StartingValue=0.5,MaxValue=0.5) //0.25 PerkSkills(ESupportHighCapMags)=(Name="HighCapMags",IconPath="UI_PerkTalent_TEX.support.UI_Talents_Support_HighCapacityMags",Increment=0.f,Rank=0,StartingValue=0.75,MaxValue=0.75) //0.5
PerkSkills(ESupportTacticalReload)=(Name="TacticalReload",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_TacticalReload",Increment=0.f,Rank=0,StartingValue=0.8f,MaxValue=0.f) PerkSkills(ESupportTacticalReload)=(Name="TacticalReload",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_TacticalReload",Increment=0.f,Rank=0,StartingValue=0.8f,MaxValue=0.f)
PerkSkills(ESupportFortitude)=(Name="Fortitude",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_Fortitude",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f) PerkSkills(ESupportFortitude)=(Name="Fortitude",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_Fortitude",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f)
PerkSkills(ESupportSalvo)=(Name="Salvo",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_Salvo",Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f) PerkSkills(ESupportSalvo)=(Name="Salvo",IconPath="UI_PerkTalent_TEX.Support.UI_Talents_Support_Salvo",Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f)

View File

@ -462,11 +462,13 @@ simulated function float GetAoERadiusModifier()
simulated function float GetZedTimeModifier( KFWeapon W ) simulated function float GetZedTimeModifier( KFWeapon W )
{ {
local name StateName; local name StateName;
if( GetMadManActive() && (!W.IsMeleeWeapon() || KFWeap_MeleeBase(W).default.bHasToBeConsideredAsRangedWeaponForPerks )) if( GetMadManActive() && (!W.IsMeleeWeapon() || KFWeap_MeleeBase(W).default.bHasToBeConsideredAsRangedWeaponForPerks || IsBlastBrawlers(W) ))
{ {
StateName = W.GetStateName(); StateName = W.GetStateName();
`Warn(StateName); `Warn(StateName);
if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
// Blast Brawlers use a different state for shooting (combining melee + firing). Needs a special case for this
if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE || (StateName == 'MeleeChainAttacking' && IsBlastBrawlers(W)) )
{ {
return GetSkillValue( PerkSkills[ESurvivalist_MadMan] ); return GetSkillValue( PerkSkills[ESurvivalist_MadMan] );
} }

View File

@ -20,7 +20,7 @@ struct native ItemPickup
var() class<Inventory> ItemClass; var() class<Inventory> ItemClass;
/** Chance relative to other valid attacks (Works like AnimNodeRandom) */ /** Chance relative to other valid attacks (Works like AnimNodeRandom) */
var() const float Priority<ClampMin=0.0>; var() float Priority<ClampMin=0.0>;
structdefaultproperties structdefaultproperties
{ {
@ -49,6 +49,24 @@ replication
PickupIndex; PickupIndex;
} }
simulated event PreBeginPlay()
{
local KFGameInfo KFGI;
// For Scavenger weekly, we need to treat the factory items as non kismet items.
KFGI = KFGameInfo( WorldInfo.Game );
if (KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
{
if (bKismetDriven && bEnabledAtStart)
{
bKismetDriven=false;
}
}
////////////////////////////////////////
super.PreBeginPlay();
}
simulated event ReplicatedEvent(name VarName) simulated event ReplicatedEvent(name VarName)
{ {
super.ReplicatedEvent( VarName ); super.ReplicatedEvent( VarName );
@ -98,14 +116,32 @@ function Reset()
SetPickupMesh(); SetPickupMesh();
} }
simulated event OverridePickup()
{
PickupIndex = ChooseWeaponPickup();
bNetDirty=true;
SetPickupMesh();
}
function SetRespawn() function SetRespawn()
{ {
local KFGameInfo KFGI;
//For ones that spawn in the world on timer, reset info here. //For ones that spawn in the world on timer, reset info here.
if (bKismetDriven && bEnabledAtStart) if (bKismetDriven && bEnabledAtStart)
{ {
PickupIndex = ChooseWeaponPickup(); PickupIndex = ChooseWeaponPickup();
SetPickupMesh(); SetPickupMesh();
} }
else
{
KFGI = KFGameInfo( WorldInfo.Game );
if (KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
{
StartSleeping();
return;
}
}
super.SetRespawn(); super.SetRespawn();
} }
@ -158,6 +194,11 @@ simulated native function GetPickupMesh(class<KFWeapon> ItemClass);
/** Use the pickups static mesh for this factory */ /** Use the pickups static mesh for this factory */
simulated function SetPickupMesh() simulated function SetPickupMesh()
{ {
if (PickupIndex >= ItemPickups.Length)
{
return;
}
if (ItemPickups[PickupIndex].ItemClass.Name == ArmorClassName) if (ItemPickups[PickupIndex].ItemClass.Name == ArmorClassName)
{ {
FinalizePickupMesh(StaticMeshComponent(ItemPickups[PickupIndex].ItemClass.default.PickupFactoryMesh).StaticMesh); FinalizePickupMesh(StaticMeshComponent(ItemPickups[PickupIndex].ItemClass.default.PickupFactoryMesh).StaticMesh);
@ -181,6 +222,11 @@ simulated event FinalizePickupMesh(StaticMesh NewMesh)
/** Give the pickup or its ammo to the player */ /** Give the pickup or its ammo to the player */
function GiveTo( Pawn P ) function GiveTo( Pawn P )
{ {
if (PickupIndex >= ItemPickups.Length)
{
return;
}
if ( ItemPickups[ PickupIndex ].ItemClass.Name == ArmorClassName ) if ( ItemPickups[ PickupIndex ].ItemClass.Name == ArmorClassName )
{ {
GiveArmor( P ); GiveArmor( P );
@ -276,7 +322,7 @@ function ActivateNewPickup(Pawn P)
/** Determine what kind of pickup is visible. Used for dialog. */ /** Determine what kind of pickup is visible. Used for dialog. */
function bool CurrentPickupIsWeapon() function bool CurrentPickupIsWeapon()
{ {
if( ItemPickups.Length == 0 ) if( ItemPickups.Length == 0 || ItemPickups.Length <= PickupIndex)
{ {
return false; return false;
} }
@ -286,7 +332,7 @@ function bool CurrentPickupIsWeapon()
function bool CurrentPickupIsArmor() function bool CurrentPickupIsArmor()
{ {
if( ItemPickups.Length == 0 ) if( ItemPickups.Length == 0 || ItemPickups.Length <= PickupIndex)
{ {
return false; return false;
} }

View File

@ -543,6 +543,7 @@ struct native PostWaveReplicationInfo
var Vector VectData1; //used for compressing data //X:HeadShots Y:Dosh Earned Z:Damage Dealt var Vector VectData1; //used for compressing data //X:HeadShots Y:Dosh Earned Z:Damage Dealt
var Vector VectData2; //used for compressing data //Damage Taken, Heals Received, Heals Given var Vector VectData2; //used for compressing data //Damage Taken, Heals Received, Heals Given
var byte NumStomps;
var byte LargeZedKills; var byte LargeZedKills;
//Dialog //Dialog
var bool bDiedDuringWave; var bool bDiedDuringWave;
@ -6475,6 +6476,14 @@ function UpdateRhythmCounterWidget( int Count, int Max )
} }
} }
function UpdateGoompaCounterWidget(int Count, int Max)
{
if( MyGFxHUD != none )
{
MyGFxHUD.UpdateGoompaCounterWidget(Count, Max);
}
}
/********************************************************************************************* /*********************************************************************************************
* Objective * Objective
* Tell the objective that a player has accepted/denied the objective * Tell the objective that a player has accepted/denied the objective
@ -7266,7 +7275,7 @@ reliable client event ClientUnlockAchievement( int AchievementIndex, optional bo
{ {
if( WorldInfo.IsConsoleBuild( CONSOLE_Durango ) ) if( WorldInfo.IsConsoleBuild( CONSOLE_Durango ) )
{ {
`log("PS4: Client unlock achievement: " @AchievementIndex); `log("Client unlock achievement: " @AchievementIndex);
// Just toggle the stat relevent to this to on now, so the next stats write will trigger the achievement unlock. // Just toggle the stat relevent to this to on now, so the next stats write will trigger the achievement unlock.
StatsWrite.UnlockDingoAchievement(AchievementIndex); StatsWrite.UnlockDingoAchievement(AchievementIndex);
OnlineSub.StatsInterface.WriteOnlineStats('Game', PlayerReplicationInfo.UniqueId, StatsWrite); OnlineSub.StatsInterface.WriteOnlineStats('Game', PlayerReplicationInfo.UniqueId, StatsWrite);
@ -7357,6 +7366,12 @@ function NotifyHitTaken()
} }
native reliable client private function ClientNotifyHitTaken(); native reliable client private function ClientNotifyHitTaken();
function NotifyHitGiven(class<DamageType> DT)
{
ClientNotifyHitGiven(DT);
}
native reliable client private function ClientNotifyHitGiven(class<DamageType> DT);
/** Kill stat */ /** Kill stat */
function AddZedKill( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller ) function AddZedKill( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller )
{ {

View File

@ -24,6 +24,23 @@ var float ZedTimeHeight;
/** How often to check for coming out of partial zed time if bUsingPermanentZedTime is on */ /** How often to check for coming out of partial zed time if bUsingPermanentZedTime is on */
var float ZedRecheckTime; var float ZedRecheckTime;
/** Number of consecutive goompa stomps */
var int GoompaStreak;
/** Bonus to apply */
var int GoompaStreakBonus;
/** Max number of goompa stomps for damage bonus */
var transient int MaxGoompaStreak;
var protected const name RhytmMethodRTPCName;
var protected const AkEvent RhythmMethodSoundReset;
var protected const AkEvent RhythmMethodSoundHit;
var protected const AkEvent RhythmMethodSoundTop;
var protected const AkEvent AracnoStompSoundEvent;
cpptext cpptext
{ {
virtual UBOOL TestZedTimeVisibility(APawn* P, UNetConnection* Connection, UBOOL bLocalPlayerTest) override; virtual UBOOL TestZedTimeVisibility(APawn* P, UNetConnection* Connection, UBOOL bLocalPlayerTest) override;
@ -32,9 +49,23 @@ cpptext
replication replication
{ {
if (bNetDirty) if (bNetDirty)
bUsingPermanentZedTime, ZedTimeRadius, ZedTimeBossRadius, ZedTimeHeight; bUsingPermanentZedTime, ZedTimeRadius, ZedTimeBossRadius, ZedTimeHeight, GoompaStreak;
} }
simulated event PostBeginPlay()
{
local KFGameInfo KFGI;
super.PostBeginPlay();
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none && KFGI.OutbreakEvent != none && KFGI.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled)
{
MaxGoompaStreak = KFGI.OutbreakEvent.ActiveEvent.GoompaStreakMax;
}
}
function EnterZedTime() function EnterZedTime()
{ {
local bool bNewResult; local bool bNewResult;
@ -81,4 +112,99 @@ function EnterZedTime()
function RecheckZedTime() function RecheckZedTime()
{ {
EnterZedTime(); EnterZedTime();
}
/**
Arachnophobia Goompa Stomp Streak functions
*/
function UpdateGoompaStreak()
{
++GoompaStreak;
GoompaStreakBonus = GoompaStreak;
UpdateGoompaCounterWidget(GoompaStreak, MaxGoompaStreak);
GoompaStompMessage(GoompaStreak);
if (IsTimerActive(nameof(ResetStreakInfo)))
{
ClearTimer(nameof(ResetStreakInfo));
}
}
function ResetGoompaStreak()
{
local KFGameInfo KFGI;
if (GoompaStreak > 0)
{
KFGI = KFGameInfo(WorldInfo.Game);
GoompaStreak = 0;
if(KFGI != none)
{
SetTimer(KFGI.OutbreakEvent.ActiveEvent.GoompaBonusDuration, false, nameof(ResetStreakInfo));
}
}
}
function ResetStreakInfo()
{
UpdateGoompaCounterWidget(GoompaStreak, MaxGoompaStreak);
GoompaStompMessage(GoompaStreak);
GoompaStreakBonus = 0;
}
function bool IsGoompaBonusActive()
{
return GoompaStreakBonus > 0;
}
reliable client function GoompaStompMessage( byte StompNum)
{
local int i;
local AkEvent TempAkEvent;
if( MyGFxHUD == none )
{
return;
}
i = StompNum;
UpdateGoompaCounterWidget( StompNum, MaxGoompaStreak );
if (StompNum == 0)
{
TempAkEvent = RhythmMethodSoundReset;
}
else if (StompNum == MaxGoompaStreak - 1)
{
TempAkEvent = RhythmMethodSoundHit;
}
else if (StompNum == MaxGoompaStreak)
{
TempAkEvent = RhythmMethodSoundTop;
++i;
}
if( TempAkEvent != none )
{
PlayRMEffect( TempAkEvent, RhytmMethodRTPCName, i );
}
if (StompNum > 0 && AracnoStompSoundEvent != none)
{
PlaySoundBase(AracnoStompSoundEvent);
}
}
//
defaultProperties
{
GoompaStreak = 0
MaxGoompaStreak = -1
GoompaStreakBonus = 0
RhytmMethodRTPCName ="R_Method"
RhythmMethodSoundReset =AkEvent'WW_UI_PlayerCharacter.Play_R_Method_Reset'
RhythmMethodSoundHit =AkEvent'WW_UI_PlayerCharacter.Play_R_Method_Hit'
RhythmMethodSoundTop =AkEvent'WW_UI_PlayerCharacter.Play_R_Method_Top'
AracnoStompSoundEvent =AkEvent'WW_GLO_Runtime.WeeklyArcno'
} }

View File

@ -125,6 +125,8 @@ var bool bNukeActive;
var bool bConcussiveActive; var bool bConcussiveActive;
/** Certain perks can supply ammo etc. We need to replicate that for the HUD */ /** Certain perks can supply ammo etc. We need to replicate that for the HUD */
var byte PerkSupplyLevel; var byte PerkSupplyLevel;
/** Number of stomps during Arachnophobia */
var int ZedStomps;
/************************************ /************************************
* Not replicated Perk Data, * Not replicated Perk Data,
@ -203,7 +205,7 @@ replication
RepCustomizationInfo, NetPerkIndex, ActivePerkLevel, ActivePerkPrestigeLevel, bHasSpawnedIn, RepCustomizationInfo, NetPerkIndex, ActivePerkLevel, ActivePerkPrestigeLevel, bHasSpawnedIn,
CurrentPerkClass, bObjectivePlayer, Assists, PlayerHealth, PlayerHealthPercent, CurrentPerkClass, bObjectivePlayer, Assists, PlayerHealth, PlayerHealthPercent,
bExtraFireRange, bSplashActive, bNukeActive, bConcussiveActive, PerkSupplyLevel, bExtraFireRange, bSplashActive, bNukeActive, bConcussiveActive, PerkSupplyLevel,
CharPortrait, DamageDealtOnTeam, bVOIPRegisteredWithOSS, CurrentVoiceCommsRequest,CurrentHeadShotEffectID, bCarryingCollectible; CharPortrait, DamageDealtOnTeam, bVOIPRegisteredWithOSS, CurrentVoiceCommsRequest,CurrentHeadShotEffectID, bCarryingCollectible, ZedStomps;
// sent to non owning clients // sent to non owning clients
if ( bNetDirty && (!bNetOwner || bDemoRecording) ) if ( bNetDirty && (!bNetOwner || bDemoRecording) )

View File

@ -72,4 +72,5 @@ simulated function OnBossDied();
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum); simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum);
simulated event OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass); simulated event OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass);
simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex); simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex);
simulated function OnHitTaken(); simulated function OnHitTaken();
simulated function OnHitGiven(class<DamageType> DT);

View File

@ -28,6 +28,8 @@ enum ESharedContentUnlock
SCU_MineReconstructor, SCU_MineReconstructor,
SCU_FrostFang, SCU_FrostFang,
SCU_GravityImploder, SCU_GravityImploder,
SCU_FAMAS,
SCU_Thermite
}; };
@ -330,4 +332,12 @@ defaultproperties
Name=KFWeap_GravityImploder, Name=KFWeap_GravityImploder,
IconPath="WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder", IconPath="WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder",
ID=8778)} ID=8778)}
SharedContentList(SCU_FAMAS)={(
Name=KFWeap_AssaultRifle_FAMAS,
IconPath="WEP_UI_Famas_TEX.UI_WeaponSelect_Famas",
ID=8934)}
SharedContentList(SCU_Thermite)={(
Name=KFWeap_RocketLauncher_ThermiteBore,
IconPath="WEP_UI_Thermite_TEX.UI_WeaponSelect_Thermite",
ID=8940)}
} }

View File

@ -468,7 +468,7 @@ function ServerStartVoteSkipTrader(PlayerReplicationInfo PRI)
GetKFPRIArray(PRIs); GetKFPRIArray(PRIs);
for (i = 0; i < PRIs.Length; i++) for (i = 0; i < PRIs.Length; i++)
{ {
PRIs[i].ShowSkipTraderVote(PRI, CurrentVoteTime, !(PRIs[i] == PRI)); PRIs[i].ShowSkipTraderVote(PRI, CurrentVoteTime, !(PRIs[i] == PRI) && PRI.GetTeamNum() != 255);
} }
KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', LMT_SkipTraderVoteStarted, CurrentSkipTraderVote.PlayerPRI); KFGI.BroadcastLocalized(KFGI, class'KFLocalMessage', LMT_SkipTraderVoteStarted, CurrentSkipTraderVote.PlayerPRI);
SetTimer( CurrentVoteTime, false, nameof(ConcludeVoteSkipTrader), self ); SetTimer( CurrentVoteTime, false, nameof(ConcludeVoteSkipTrader), self );

View File

@ -0,0 +1,35 @@
//=============================================================================
// KFWeapDef_FAMAS
//=============================================================================
// A lightweight container for basic weapon properties that can be safely
// accessed without a weapon actor (UI, remote clients).
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_FAMAS extends KFWeaponDefinition
abstract;
defaultproperties
{
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_FAMAS"
BuyPrice=1200
AmmoPricePerMag=25
SecondaryAmmoMagPrice=15 //13
SecondaryAmmoMagSize=6 // Num of bullets given (not magazines)
ImagePath="WEP_UI_Famas_TEX.UI_WeaponSelect_Famas"
EffectiveRange=67 // @TODO: ¿?¿?¿?
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradeSellPrice[0]=525
UpgradeSellPrice[1]=1650
SharedUnlockId=SCU_FAMAS
}

View File

@ -0,0 +1,24 @@
//=============================================================================
// KFWeapDef_HRG_BarrierRifle
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_BarrierRifle extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_BarrierRifle"
BuyPrice=2000
AmmoPricePerMag=55
ImagePath="wep_ui_hrg_barrierrifle_tex.UI_WeaponSelect_HRG_BarrierRifle"
EffectiveRange=68
//UpgradePrice[0]=1500
//UpgradeSellPrice[0]=1125
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFWeapDef_HRG_BlastBrawlers
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_BlastBrawlers extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_BlastBrawlers"
BuyPrice=1600
AmmoPricePerMag=30
ImagePath="WEP_UI_HRG_BlastBrawlers_TEX.UI_WeaponSelect_HRG_BlastBrawlers"
EffectiveRange=15
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFWeapDef_ThermiteBore
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_ThermiteBore extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_RocketLauncher_ThermiteBore"
BuyPrice=1500
AmmoPricePerMag=78
ImagePath="WEP_UI_Thermite_TEX.UI_WeaponSelect_Thermite"
EffectiveRange=78
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
SharedUnlockId=SCU_Thermite
}

View File

@ -43,6 +43,8 @@ var int CurrentScopeTextureSize;
var(Scope) float ScopedSensitivityMod; var(Scope) float ScopedSensitivityMod;
/** MIC Index for the scope material */
var byte ScopeMICIndex;
simulated exec function ScopeFOV( float NewFOV ) simulated exec function ScopeFOV( float NewFOV )
{ {
@ -128,7 +130,7 @@ reliable client function ClientWeaponSet(bool bOptionalSet, optional bool bDoNot
ScopeLenseMIC.SetParent(ScopeLenseMICTemplate); ScopeLenseMIC.SetParent(ScopeLenseMICTemplate);
ScopeLenseMIC.SetTextureParameterValue('ScopeTextureTarget', SniperScopeTextureTarget); ScopeLenseMIC.SetTextureParameterValue('ScopeTextureTarget', SniperScopeTextureTarget);
ScopeLenseMIC.SetScalarParameterValue(InterpParamName, 0.0); ScopeLenseMIC.SetScalarParameterValue(InterpParamName, 0.0);
mesh.SetMaterial(2, ScopeLenseMIC); mesh.SetMaterial(ScopeMICIndex, ScopeLenseMIC);
} }
} }
@ -351,4 +353,6 @@ DefaultProperties
// Aim Assist // Aim Assist
AimCorrectionSize=40.f AimCorrectionSize=40.f
ScopeMICIndex=2
} }

View File

@ -367,6 +367,9 @@ var int InitialSpareMags[2];
/** What percentage of a full single magazine capacity to give when resupplying this weapon from an ammo pickup */ /** What percentage of a full single magazine capacity to give when resupplying this weapon from an ammo pickup */
var(Inventory) float AmmoPickupScale[2]; var(Inventory) float AmmoPickupScale[2];
/** */
var(Inventory) bool bUsesSecondaryAmmoAltHUD;
enum EReloadStatus enum EReloadStatus
{ {
RS_None, RS_None,
@ -4396,6 +4399,11 @@ static simulated event bool UsesSecondaryAmmo()
return default.MagazineCapacity[1] > 0; return default.MagazineCapacity[1] > 0;
} }
static simulated event bool UsesAltSecondaryAmmo()
{
return default.bUsesSecondaryAmmoAltHUD;
}
/** /**
* Returns true if this weapon uses greandes as secondary ammo * Returns true if this weapon uses greandes as secondary ammo
*/ */
@ -4754,6 +4762,12 @@ simulated function int GetSecondaryAmmoForHUD()
return AmmoCount[1] + SpareAmmoCount[1]; return AmmoCount[1] + SpareAmmoCount[1];
} }
/** Determines the secondary spare ammo */
simulated function int GetSecondarySpareAmmoForHUD()
{
return -1;
}
/** Determines if we have to reload the secondary ammo of the weapon (EX: m16 grenades) */ /** Determines if we have to reload the secondary ammo of the weapon (EX: m16 grenades) */
simulated function bool HasToReloadSecondaryAmmoForHUD() simulated function bool HasToReloadSecondaryAmmoForHUD()
{ {
@ -7985,5 +7999,7 @@ defaultproperties
NumPellets(CUSTOM_FIREMODE)=1 NumPellets(CUSTOM_FIREMODE)=1
bKeepIronSightsOnJump=false bKeepIronSightsOnJump=false
bUsesSecondaryAmmoAltHUD = false
} }

View File

@ -1223,6 +1223,9 @@ simulated State LoopingWeaponAction
} }
} }
/** Special event added for weap attachments. Free for use */
function OnSpecialEvent(int Arg);
defaultproperties defaultproperties
{ {
Begin Object class=AnimNodeSequence Name=MeshSequenceA Begin Object class=AnimNodeSequence Name=MeshSequenceA

View File

@ -3522,4 +3522,103 @@ defaultproperties
//Coliseum Zweihander //Coliseum Zweihander
Skins.Add((Id=8791, Weapondef=class'KFWeapDef_Zweihander', MIC_1P=("WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_1P_Mint_MIC"), MIC_3P="WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_3P_Pickup_MIC")); Skins.Add((Id=8791, Weapondef=class'KFWeapDef_Zweihander', MIC_1P=("WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_1P_Mint_MIC"), MIC_3P="WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet42_MAT.coliseum_zweihander.Coliseum_Zweihander_3P_Pickup_MIC"));
//Famas Standard
Skins.Add((Id=8934, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_1P_Famas_MAT.Wep_1stP_Famas_MIC"), MIC_3P="WEP_3P_Famas_MAT.Wep_3rdP_Famas_MIC", MIC_Pickup="WEP_3P_Famas_MAT.Wep_3rdP_Famas_Pickup_MIC"));
//Famas Flourished
Skins.Add((Id=8935, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_SkinSet45_MAT.Wep_1stP_Famas_Flourished_MIC"), MIC_3P="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Flourished_MIC", MIC_Pickup="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Pickup_Flourished_MIC"));
//Famas Jagged Wars
Skins.Add((Id=8936, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_SkinSet45_MAT.Wep_1stP_Famas_JaggedWars_MIC"), MIC_3P="WEP_SkinSet45_MAT.Wep_3rdP_Famas_JaggedWars_MIC", MIC_Pickup="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Pickup_JaggedWars_MIC"));
//Famas Japped
Skins.Add((Id=8937, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_SkinSet45_MAT.Wep_1stP_Famas_Japped_MIC"), MIC_3P="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Japped_MIC", MIC_Pickup="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Pickup_Japped_MIC"));
//Famas Skull Candy
Skins.Add((Id=8938, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_SkinSet45_MAT.Wep_1stP_Famas_SkullCandy_MIC"), MIC_3P="WEP_SkinSet45_MAT.Wep_3rdP_Famas_SkullCandy_MIC", MIC_Pickup="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Pickup_SkullCandy_MIC"));
//Famas Turfed
Skins.Add((Id=8939, Weapondef=class'KFWeapDef_FAMAS', MIC_1P=("WEP_SkinSet45_MAT.Wep_1stP_Famas_Turfed_MIC"), MIC_3P="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Turfed_MIC", MIC_Pickup="WEP_SkinSet45_MAT.Wep_3rdP_Famas_Pickup_Turfed_MIC"));
//Thermite Standard
Skins.Add((Id=8940, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_1P_Thermite_MAT.Wep_1P_Thermite_MIC"), MIC_3P="WEP_3P_Thermite_MAT.WEP_3P_Thermite_MIC", MIC_Pickup="WEP_3p_Gravity_Imploder_MAT.Wep_3rdP_Gravity_Imploder_Pickup_MIC"))
//Thermite Japped
Skins.Add((Id=8941, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_Japped_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Japped_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_Japped_MIC"));
//Thermite Much Danger
Skins.Add((Id=8942, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_MuchDanger_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_MuchDanger_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_MuchDanger_MIC"));
//Thermite Not Liandri
Skins.Add((Id=8943, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_NotLiandri_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_NotLiandri_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_NotLiandri_MIC"));
//Thermite Rusted
Skins.Add((Id=8944, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_Rusted_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Rusted_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_Rusted_MIC"));
//Thermite Thunder Jaws
Skins.Add((Id=8945, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_ThunderJaws_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_ThunderJaws_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_ThunderJaws_MIC"));
//BeyondHorizon AA12
Skins.Add((Id=8845, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.space_aa12.Space_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Pickup_MIC"))
//BeyondHorizon AK12
Skins.Add((Id=8846, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.space_ak12.Space_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_ak12.Space_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Pickup_MIC"))
//BeyondHorizon Desert Eagle
Skins.Add((Id=8847, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.space_deagle.Space_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Pickup_MIC"))
//BeyondHorizon Doomstick
Skins.Add((Id=8848, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Pickup_MIC"))
//BeyondHorizon Hemoclobber
Skins.Add((Id=8849, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Pickup_MIC"))
//BeyondHorizon HMTech-501 Grenade Rifle
Skins.Add((Id=8850, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Pickup_MIC"))
//BeyondHorizon M32
Skins.Add((Id=8851, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.space_m32.Space_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_m32.Space_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Pickup_MIC"))
//BeyondHorizon MAC 10
Skins.Add((Id=8852, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.space_mac10.Space_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Pickup_MIC"))
//BeyondHorizon Microwave Gun
Skins.Add((Id=8853, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Pickup_MIC"))
//BeyondHorizon P90
Skins.Add((Id=8854, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.space_p90.Space_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_p90.Space_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Pickup_MIC"))
//BeyondHorizon AA12
Skins.Add((Id=8855, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Pickup_MIC"))
//BeyondHorizon AK12
Skins.Add((Id=8856, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Pickup_MIC"))
//BeyondHorizon Desert Eagle
Skins.Add((Id=8857, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Pickup_MIC"))
//BeyondHorizon Doomstick
Skins.Add((Id=8858, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Pickup_MIC"))
//BeyondHorizon Hemoclobber
Skins.Add((Id=8859, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Pickup_MIC"))
//BeyondHorizon HMTech-501 Grenade Rifle
Skins.Add((Id=8860, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Pickup_MIC"))
//BeyondHorizon M32
Skins.Add((Id=8861, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Pickup_MIC"))
//BeyondHorizon MAC 10
Skins.Add((Id=8862, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Pickup_MIC"))
//BeyondHorizon Microwave Gun
Skins.Add((Id=8863, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Pickup_MIC"))
//BeyondHorizon P90
Skins.Add((Id=8864, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Pickup_MIC"))
//Scavenger AK12
Skins.Add((Id=8921, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_1P_Mint_MIC", "wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_Scope_1P_Mint_MIC"), MIC_3P="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Mint_MIC", MIC_Pickup="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Pickup_MIC"))
} }

View File

@ -27,6 +27,7 @@
const MATCH_EVENT_HEAL_RECEIVED = 5; const MATCH_EVENT_HEAL_RECEIVED = 5;
const MATCH_EVENT_STOMP_GIVEN = 6;
/** Match has ended */ /** Match has ended */
const MATCH_EVENT_MAX_EVENTID = 0x0000FFFF; const MATCH_EVENT_MAX_EVENTID = 0x0000FFFF;

View File

@ -153,4 +153,5 @@ const STATID_ACHIEVE_DesolationCollectibles = 4055;
const STATID_ACHIEVE_HellmarkStationCollectibles = 4056; const STATID_ACHIEVE_HellmarkStationCollectibles = 4056;
const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057; const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057;
const STATID_ACHIEVE_Dystopia2029Collectibles = 4058; const STATID_ACHIEVE_Dystopia2029Collectibles = 4058;
const STATID_ACHIEVE_MoonbaseCollectibles = 4059;
/** `endif */ /** `endif */

View File

@ -0,0 +1,52 @@
//=============================================================================
// KFDT_Ballistic_BlastBrawlersShotgun
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_BlastBrawlersShotgun extends KFDT_Ballistic_Shotgun
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
if( super.CanDismemberHitZone( InHitZoneName ) )
{
return true;
}
switch ( InHitZoneName )
{
case 'lupperarm':
case 'rupperarm':
case 'chest':
case 'heart':
return true;
}
return false;
}
defaultproperties
{
BloodSpread=0.4
BloodScale=0.6
KDamageImpulse=900
KDeathUpKick=-500
KDeathVel=350
//KDamageImpulse=350
//KDeathUpKick=120
//KDeathVel=10
StumblePower=12
GunHitPower=12
OverrideImpactEffect=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Impact'
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
}

View File

@ -0,0 +1,27 @@
//=============================================================================
// KFDT_Ballistic_FAMAS_Rifle
//=============================================================================
// Damage type class for the FAMAS rifle
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_FAMAS_Rifle extends KFDT_Ballistic_AssaultRifle
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=12
GunHitPower=0
WeaponDef=class'KFWeapDef_FAMAS'
ModifierPerkList(0)=class'KFPerk_Commando'
ModifierPerkList(1)=class'KFPerk_Support'
}

View File

@ -0,0 +1,47 @@
//=============================================================================
// KFDT_Ballistic_FAMAS_Shotgun
//=============================================================================
// Damage type class for the FAMAS shotgun alt fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_FAMAS_Shotgun extends KFDT_Ballistic_Shotgun
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
if( super.CanDismemberHitZone( InHitZoneName ) )
{
return true;
}
switch ( InHitZoneName )
{
case 'lupperarm':
case 'rupperarm':
case 'chest':
case 'heart':
return true;
}
return false;
}
defaultproperties
{
BloodSpread=0.4
BloodScale=0.6
KDamageImpulse=900
KDeathUpKick=500
KDeathVel=350
StumblePower=10
GunHitPower=15
WeaponDef=class'KFWeapDef_FAMAS'
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFDT_Ballistic_HRG_BarrierRifle
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_BarrierRifle extends KFDT_Ballistic_AssaultRifle
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=20
GunHitPower=20
WeaponDef=class'KFWeapDef_HRG_BarrierRifle'
//Perk
ModifierPerkList(0)=class'KFPerk_SWAT'
}

View File

@ -0,0 +1,55 @@
//=============================================================================
// KFDT_Ballistic_ThermiteBoreImpact
//=============================================================================
// Rocket impact damage type for the Thermite rocket launcher
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_ThermiteBoreImpact extends KFDT_Ballistic_Shell
abstract
hidedropdown;
// Damage type to use for the burning damage over time
var class<KFDamageType> BurnDamageType;
static simulated function bool CanDismemberHitZone(name InHitZoneName)
{
return false;
}
static simulated function bool CanDismemberHitZoneWhileAlive(name InHitZoneName)
{
return false;
}
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
{
// Overriden to specific a different damage type to do the burn damage over
// time. We do this so we don't get shotgun pellet impact sounds/fx during
// the DOT burning.
if ( default.BurnDamageType.default.DoT_Type != DOT_None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BurnDamageType);
}
}
defaultproperties
{
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
BurnPower=50
KnockdownPower=50
StumblePower=350
GunHitPower=300
BurnDamageType=class'KFDT_Fire_ThermiteImpactDoT'
ModifierPerkList(0)=class'KFPerk_FireBug'
WeaponDef=class'KFWeapDef_ThermiteBore'
}

View File

@ -0,0 +1,24 @@
//=============================================================================
// KFDT_Bludgeon_BlastBrawlers
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_BlastBrawlers extends KFDT_Bludgeon
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2500
KDeathUpKick=500
KDeathVel=400
MeleeHitPower=100
StunPower=0
StumblePower=0
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
ModifierPerkList(0)=class'KFPerk_Support'
}

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFDT_Bludgeon_BlastBrawlersBash
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_BlastBrawlersBash extends KFDT_Bludgeon
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=3500
KDeathUpKick=800
KDeathVel=575
KnockdownPower=0
StunPower=0
StumblePower=200
MeleeHitPower=100
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
ModifierPerkList(0)=class'KFPerk_Support'
}

View File

@ -0,0 +1,28 @@
//=============================================================================
// KFDT_Bludgeon_BlastBrawlersHeavy
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_BlastBrawlersHeavy extends KFDT_Bludgeon
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=3500
KDeathUpKick=800
KDeathVel=575
KnockdownPower=75
StunPower=0
StumblePower=150
MeleeHitPower=150
EMPPower=0
WeaponDef=class'KFWeapDef_HRG_BlastBrawlers'
ModifierPerkList(0)=class'KFPerk_Support'
//OverrideImpactEffect=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_Static_Strikers_Impact'
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,49 @@
//=============================================================================
// KFDT_Explosive_Thermite
//=============================================================================
// Explosive damage type for the Seal Squeal
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_Thermite extends KFDT_Fire
abstract
hidedropdown;
// Damage type to use for the burning damage over time
var class<KFDamageType> BurnDamageType;
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
{
// Overriden to specific a different damage type to do the burn damage over
// time. We do this so we don't get shotgun pellet impact sounds/fx during
// the DOT burning.
if ( default.BurnDamageType.default.DoT_Type != DOT_None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, default.BurnDamageType);
}
}
defaultproperties
{
bShouldSpawnPersistentBlood = true
// physics impact
RadialDamageImpulse = 2000
GibImpulseScale = 0.15
KDeathUpKick = 1000
KDeathVel = 300
KnockdownPower = 0
BurnPower = 50
StumblePower = 200
BurnDamageType=class'KFDT_Fire_ThermiteExplosionDoT'
//Perk
ModifierPerkList(0) = class'KFPerk_Firebug'
WeaponDef = class'KFWeapDef_ThermiteBore'
}

View File

@ -0,0 +1,33 @@
//=============================================================================
// KFDT_Fire_Ground_ThermiteBore
//=============================================================================
// Damage type class for the thermite bore ground fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Fire_Ground_ThermiteBore extends KFDT_Fire_Ground
abstract;
defaultproperties
{
bShouldSpawnPersistentBlood=false
// physics impact
RadialDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
KnockdownPower=0
StumblePower=100
BurnPower=10
// DOT
DoT_Duration=3.0 //5.0
DoT_Interval=0.5
DoT_DamageScale=0.5 //0.2
bIgnoreSelfInflictedScale=false
WeaponDef=class'KFWeapDef_ThermiteBore'
}

View File

@ -0,0 +1,42 @@
//=============================================================================
// KFDT_Fire_ThermiteExplosionDoT
//=============================================================================
// Damage caused by burning from being hit by a thermite bore explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Fire_ThermiteExplosionDoT extends KFDT_Fire
abstract
hidedropdown;
static function int GetKillerDialogID()
{
return 86;//KILL_Fire
}
static function int GetDamagerDialogID()
{
return 102;//DAMZ_Fire
}
static function int GetDamageeDialogID()
{
return 116;//DAMP_Fire
}
defaultproperties
{
WeaponDef=class'KFWeapDef_ThermiteBore'
DoT_Type=DOT_Fire
DoT_Duration=3.0
DoT_Interval=0.5
DoT_DamageScale=0.2
BurnPower=10
// Explosion DOT does not damage the instigator
bNoInstigatorDamage=true
}

View File

@ -0,0 +1,40 @@
//=============================================================================
// KFDT_Fire_ThermiteImpactDoT
//=============================================================================
// Damage caused by burning from being hit by a thermite bore projectile
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Fire_ThermiteImpactDoT extends KFDT_Fire
abstract
hidedropdown;
static function int GetKillerDialogID()
{
return 86;//KILL_Fire
}
static function int GetDamagerDialogID()
{
return 102;//DAMZ_Fire
}
static function int GetDamageeDialogID()
{
return 116;//DAMP_Fire
}
defaultproperties
{
WeaponDef=class'KFWeapDef_ThermiteBore'
DoT_Type=DOT_Fire
DoT_Duration=3.0
DoT_Interval=0.5
DoT_DamageScale=0.2
BurnPower=10
}

View File

@ -0,0 +1,30 @@
//=============================================================================
// KFExplosion_Thermite
//=============================================================================
// Used by projectiles and kismet to spawn an explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_Thermite extends KFExplosionActorLingering;
/** Replacement particles to play when hitting surfaces at different angles */
var() ParticleSystem LoopingParticleEffectCeiling;
var() ParticleSystem LoopingParticleEffectWall;
DefaultProperties
{
Interval=0.5
MaxTime=10
bDoFullDamage=true
LoopingParticleEffect=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_ground_fire_01'
LoopingParticleEffectCeiling=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_Ceiling_01'
LoopingParticleEffectWall=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_Wall_01'
LoopStartEvent=AkEvent'WW_WEP_SA_Flamethrower.Play_WEP_SA_Flamethrower_Residual_Fire_Loop'
LoopStopEvent=AkEvent'WW_WEP_SA_Flamethrower.Stop_WEP_SA_Flamethrower_Residual_Fire_Loop'
}

View File

@ -170,7 +170,7 @@ function bool TrySetNextWaveSpecial()
function WaveEnded(EWaveEndCondition WinCondition) function WaveEnded(EWaveEndCondition WinCondition)
{ {
if(!bWaveStarted) if(!bWaveStarted && !MyKFGRI.bTraderIsOpen && WinCondition != WEC_TeamWipedOut)
{ {
return; return;
} }

View File

@ -937,16 +937,19 @@ function ResetAllPickups()
/** Overridden to scale the number of active pickups by wave */ /** Overridden to scale the number of active pickups by wave */
function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups ) function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
{ {
if(NumPickups != 0) NumPickups *= (float(WaveNum) / float(WaveMax));
// make sure to have at least 1 ammo pickup in the level, and if it's wave 2 or later make sure there's
// at least one weapon pickup. Also, we need to ensure if OverrideItemPickupModifier is set to 0 we really
// don't want any item pickups.
if( NumPickups == 0 && PickupList.Length > 0
&& (WaveNum > 1
|| KFPickupFactory_Ammo(PickupList[0]) != none
|| (KFPickupFactory_Item(PickupList[0]) != none && (OutbreakEvent == none || OutbreakEvent.ActiveEvent.OverrideItemPickupModifier != 0))
)
)
{ {
NumPickups *= (float(WaveNum) / float(WaveMax)); NumPickups = 1;
// 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 ); super.ResetPickups( PickupList, NumPickups );
} }
@ -1117,8 +1120,10 @@ function WaveEnded(EWaveEndCondition WinCondition)
local int i; local int i;
local KFPlayerController KFPC; local KFPlayerController KFPC;
if(!bWaveStarted && !MyKFGRI.bTraderIsOpen) if(!bWaveStarted && !MyKFGRI.bTraderIsOpen && WinCondition != WEC_TeamWipedOut)
{
return; return;
}
if (WorldInfo.NetMode == NM_DedicatedServer) if (WorldInfo.NetMode == NM_DedicatedServer)
{ {

View File

@ -65,6 +65,11 @@ event PreBeginPlay()
super.PreBeginPlay(); super.PreBeginPlay();
OutbreakEvent.UpdateGRI(); OutbreakEvent.UpdateGRI();
if (Role == Role_Authority && MyKFGRI != none && OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
{
MyKFGRI.NotifyBrokenTrader();
}
} }
function CreateOutbreakEvent() function CreateOutbreakEvent()
@ -136,6 +141,7 @@ function SetPickupItemList()
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length); ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
continue; continue;
} }
foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem) foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem)
{ {
for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx) for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx)
@ -241,14 +247,18 @@ protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPa
function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer) function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
{ {
local int i; local int i;
local int j;
local KFPlayerController KFPC; local KFPlayerController KFPC;
local KFPlayerReplicationInfo DamagerKFPRI; local KFPlayerReplicationInfo DamagerKFPRI;
local array<DamageInfo> DamageHistory; local array<DamageInfo> DamageHistory;
local array<KFPlayerController> Attackers; local array<KFPlayerController> Attackers;
local KFPawn_Human PawnHuman; local KFPawn_Human PawnHuman;
local KFGameInfo KFGI;
DamageHistory = MonsterPawn.DamageHistory; DamageHistory = MonsterPawn.DamageHistory;
KFGI = KFGameInfo(WorldInfo.Game);
for ( i = 0; i < DamageHistory.Length; i++ ) for ( i = 0; i < DamageHistory.Length; i++ )
{ {
if( DamageHistory[i].DamagerController != none if( DamageHistory[i].DamagerController != none
@ -266,9 +276,30 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
{ {
PawnHuman = KFPawn_Human(KFPC.Pawn); PawnHuman = KFPawn_Human(KFPC.Pawn);
Attackers.AddItem(KFPC); Attackers.AddItem(KFPC);
/*
Weekly event Aracnophobia (10):
2 kind of heales: one for killing and another for killing by jumping on enemies.
HealByAssistance is used for the latest, no need to add extra variables.
*/
if( KFPC == Killer && KFGI != none && KFGI.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled )
{
for (j = 0; j < DamageHistory[i].DamageTypes.Length; j++)
{
if (DamageHistory[i].DamageTypes[j] == class 'KFDT_GoompaStomp')
{
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
return;
}
}
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
return;
}
//
if( KFPC == Killer ) if( KFPC == Killer )
{ {
`Log("Heal by Kill: "$MonsterPawn.HealByKill);
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false ); PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
if( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none ) if( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none )
@ -278,7 +309,6 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
} }
else else
{ {
`Log("Heal by Assistance: "$MonsterPawn.HealByAssistance);
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false ); PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
} }
} }
@ -286,7 +316,6 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
} }
} }
} }
} }
@ -482,6 +511,34 @@ function StartWave()
SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave)); SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave));
} }
if (OutbreakEvent.ActiveEvent.bUnlimitedWeaponPickups)
{
OverridePickupList();
}
}
function bool OverridePickupList()
{
local KFPickupFactory PickupFactory;
local KFPickupFactory_Item ItemFactory;
local KFGameReplicationInfo_WeeklySurvival KFGRI_WS;
KFGRI_WS=KFGameReplicationInfo_WeeklySurvival(MyKFGRI);
if (KFGRI_WS == none)
return false;
foreach ItemPickups(PickupFactory)
{
ItemFactory = KFPickupFactory_Item(PickupFactory);
if (ItemFactory == none)
continue;
KFGRI_WS.OverrideWeaponPickups(ItemFactory);
ItemFactory.OverridePickup();
}
return true;
} }
function EnableGlobalDamage() function EnableGlobalDamage()
@ -614,8 +671,6 @@ function InitAllPickups()
{ {
NumWeaponPickups = ItemPickups.Length * (OutbreakEvent.ActiveEvent.OverrideItemPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideItemPickupModifier : DifficultyInfo.GetItemPickupModifier()); 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()); 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(`__TW_SDK_)
if( BaseMutator != none ) if( BaseMutator != none )
@ -696,6 +751,7 @@ function class<KFPawn_Monster> GetAISpawnType(EAIType AIType)
function bool AllowPrimaryWeapon(string ClassPath) function bool AllowPrimaryWeapon(string ClassPath)
{ {
local STraderItem Item; local STraderItem Item;
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none) if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none)
{ {
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item) foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
@ -704,8 +760,8 @@ function bool AllowPrimaryWeapon(string ClassPath)
{ {
return true; return true;
} }
} }
return false; return true;
} }
return true; return true;
} }
@ -788,6 +844,42 @@ function DoDeathExplosion(Pawn DeadPawn, KFGameExplosion ExplosionTemplate, clas
} }
} }
simulated function AddWeaponsFromSpawnList(KFPawn P)
{
local STraderItem Item;
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none || OutbreakEvent.ActiveEvent.bAddSpawnListToLoadout)
{
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
{
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(Item.WeaponDef.default.WeaponClassPath, class'Class')));
}
}
}
simulated function OverrideHumanDefaults(KFPawn_Human P)
{
if (OutbreakEvent.ActiveEvent.JumpZ >= 0.0f)
{
P.JumpZ = OutbreakEvent.ActiveEvent.JumpZ;
}
}
simulated function ModifyDamageGiven(out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
local KFPlayerController_WeeklySurvival KFPC;
local int Streak;
if (OutbreakEvent.ActiveEvent.bGoompaJumpEnabled)
{
KFPC = KFPlayerController_WeeklySurvival(DamageInstigator);
if (KFPC != none)
{
Streak = KFPC.GoompaStreakBonus < KFPC.MaxGoompaStreak ? KFPC.GoompaStreakBonus : KFPC.MaxGoompaStreak;
InDamage *= (1 + OutbreakEvent.ActiveEvent.GoompaStreakDamage * Streak);
}
}
}
defaultproperties defaultproperties
{ {

View File

@ -9,6 +9,14 @@
class KFGameReplicationInfo_WeeklySurvival extends KFGameReplicationInfo; class KFGameReplicationInfo_WeeklySurvival extends KFGameReplicationInfo;
struct SBrokeTraderPickupItem
{
/** Weapons available for spawning */
var() array<class<KFWeaponDefinition> > WeaponClasses;
};
var() array<SBrokeTraderPickupItem> BrokenTraderItemPickups;
simulated function array<int> GetKFSeqEventLevelLoadedIndices() simulated function array<int> GetKFSeqEventLevelLoadedIndices()
{ {
local array<int> ActivateIndices; local array<int> ActivateIndices;
@ -16,4 +24,262 @@ simulated function array<int> GetKFSeqEventLevelLoadedIndices()
ActivateIndices[0] = 7; ActivateIndices[0] = 7;
return ActivateIndices; return ActivateIndices;
} }
simulated function OverrideWeaponPickups(out KFPickupFactory_Item ItemFactory)
{
local int Idx;
local ItemPickup Pickup;
if (ItemFactory == none)
return;
if ( BrokenTraderItemPickups.Length == 0 || WaveNum > BrokenTraderItemPickups.Length )
return;
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
for(Idx = 0; Idx < BrokenTraderItemPickups[WaveNum-1].WeaponClasses.Length; Idx++)
{
Pickup.ItemClass = class<KFWeapon> (DynamicLoadObject(BrokenTraderItemPickups[WaveNum-1].WeaponClasses[Idx].default.WeaponClassPath, class'Class'));
ItemFactory.ItemPickups.AddItem(Pickup);
}
}
simulated function NotifyWaveStart()
{
local KFPickupFactory_Item ItemFactory;
if (WorldInfo.NetMode == NM_Client && bIsBrokenTrader)
{
foreach AllActors(class'KFPickupFactory_Item', ItemFactory)
{
OverrideWeaponPickups(ItemFactory);
ItemFactory.SetPickupMesh();
}
}
super.NotifyWaveStart();
}
DefaultProperties
{
BrokenTraderItemPickups={(
(WeaponClasses={(
class'KFGame.KFWeapDef_9mmDual',
class'KFGame.KFWeapDef_Crovel',
class'KFGame.KFWeapDef_MB500',
class'KFGame.KFWeapDef_MedicPistol',
class'KFGame.KFWeapDef_HX25',
class'KFGame.KFWeapDef_CaulkBurn',
class'KFGame.KFWeapDef_Remington1858Dual',
class'KFGame.KFWeapDef_Winchester1894',
class'KFGame.KFWeapDef_MP7',
class'KFGame.KFWeapDef_AR15'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_Nailgun',
class'KFGame.KFWeapDef_Katana',
class'KFGame.KFWeapDef_ChainBat',
class'KFGame.KFWeapDef_FireAxe',
class'KFGame.KFWeapDef_Bullpup',
class'KFGame.KFWeapDef_Thompson',
class'KFGame.KFWeapDef_DoubleBarrel',
class'KFGame.KFWeapDef_HZ12',
class'KFGame.KFWeapDef_DragonsBreath',
class'KFGame.KFWeapDef_MedicSMG',
class'KFGame.KFWeapDef_Healthrower_HRG',
class'KFGame.KFWeapDef_M79',
class'KFGame.KFWeapDef_FlareGunDual',
class'KFGame.KFWeapDef_Mac10',
class'KFGame.KFWeapDef_HRGScorcher',
class'KFGame.KFWeapDef_Colt1911Dual',
class'KFGame.KFWeapDef_HRGWinterbite',
class'KFGame.KFWeapDef_CenterfireMB464',
class'KFGame.KFWeapDef_Crossbow',
class'KFGame.KFWeapDef_MP5RAS'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_Nailgun',
class'KFGame.KFWeapDef_Katana',
class'KFGame.KFWeapDef_ChainBat',
class'KFGame.KFWeapDef_FireAxe',
class'KFGame.KFWeapDef_Bullpup',
class'KFGame.KFWeapDef_Thompson',
class'KFGame.KFWeapDef_DoubleBarrel',
class'KFGame.KFWeapDef_HZ12',
class'KFGame.KFWeapDef_DragonsBreath',
class'KFGame.KFWeapDef_MedicSMG',
class'KFGame.KFWeapDef_Healthrower_HRG',
class'KFGame.KFWeapDef_M79',
class'KFGame.KFWeapDef_FlareGunDual',
class'KFGame.KFWeapDef_Mac10',
class'KFGame.KFWeapDef_HRGScorcher',
class'KFGame.KFWeapDef_Colt1911Dual',
class'KFGame.KFWeapDef_HRGWinterbite',
class'KFGame.KFWeapDef_CenterfireMB464',
class'KFGame.KFWeapDef_Crossbow',
class'KFGame.KFWeapDef_MP5RAS'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_MedicBat',
class'KFGame.KFWeapDef_Pulverizer',
class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe',
class'KFGame.KFWeapDef_AK12',
class'KFGame.KFWeapDef_MKB42',
class'KFGame.KFWeapDef_M16M203',
class'KFGame.KFWeapDef_M4',
class'KFGame.KFWeapDef_SW500Dual_HRG',
class'KFGame.KFWeapDef_MedicShotgun',
class'KFGame.KFWeapDef_Hemogoblin',
class'KFGame.KFWeapDef_Mine_Reconstructor',
class'KFGame.KFWeapDef_SealSqueal',
class'KFGame.KFWeapDef_FlameThrower',
class'KFGame.KFWeapDef_HRGIncendiaryRifle',
class'KFGame.KFWeapDef_ChiappaRhinoDual',
class'KFGame.KFWeapDef_DeagleDual',
class'KFGame.KFWeapDef_M14EBR',
class'KFGame.KFWeapDef_HRG_SonicGun',
class'KFGame.KFWeapDef_MosinNagant',
class'KFGame.KFWeapDef_P90',
class'KFGame.KFWeapDef_Nailgun_HRG',
class'KFGame.KFWeapDef_HK_UMP',
class'KFGame.KFWeapDef_FreezeThrower',
class'KFGame.KFWeapDef_HRG_Kaboomstick',
class'KFGame.KFWeapDef_FAMAS'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_MedicBat',
class'KFGame.KFWeapDef_Rifle_FrostShotgunAxe',
class'KFGame.KFWeapDef_M16M203',
class'KFGame.KFWeapDef_M4',
class'KFGame.KFWeapDef_MedicShotgun',
class'KFGame.KFWeapDef_FlameThrower',
class'KFGame.KFWeapDef_HRGIncendiaryRifle',
class'KFGame.KFWeapDef_DeagleDual',
class'KFGame.KFWeapDef_HRG_SonicGun',
class'KFGame.KFWeapDef_MosinNagant',
class'KFGame.KFWeapDef_HK_UMP',
class'KFGame.KFWeapDef_FreezeThrower',
class'KFGame.KFWeapDef_HRG_Kaboomstick',
class'KFGame.KFWeapDef_FAMAS',
class'KFGame.KFWeapDef_Eviscerator',
class'KFGame.KFWeapDef_FNFal',
class'KFGame.KFWeapDef_MedicRifle',
class'KFGame.KFWeapDef_ElephantGun',
class'KFGame.KFWeapDef_Seeker6',
class'KFGame.KFWeapDef_HuskCannon',
class'KFGame.KFWeapDef_SW500Dual',
class'KFGame.KFWeapDef_Kriss',
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_HRGTeslauncher',
class'KFGame.KFWeapDef_Eviscerator',
class'KFGame.KFWeapDef_MaceAndShield',
class'KFGame.KFWeapDef_PowerGloves',
class'KFGame.KFWeapDef_SCAR',
class'KFGame.KFWeapDef_Stoner63A',
class'KFGame.KFWeapDef_MedicRifle',
class'KFGame.KFWeapDef_FNFal',
class'KFGame.KFWeapDef_AA12',
class'KFGame.KFWeapDef_ElephantGun',
class'KFGame.KFWeapDef_Blunderbuss',
class'KFGame.KFWeapDef_HRGIncision',
class'KFGame.KFWeapDef_HRG_Vampire',
class'KFGame.KFWeapDef_RPG7',
class'KFGame.KFWeapDef_Seeker6',
class'KFGame.KFWeapDef_HuskCannon',
class'KFGame.KFWeapDef_MicrowaveGun',
class'KFGame.KFWeapDef_SW500Dual',
class'KFGame.KFWeapDef_AF2011Dual',
class'KFGame.KFWeapDef_Pistol_DualG18',
class'KFGame.KFWeapDef_RailGun',
class'KFGame.KFWeapDef_G18',
class'KFGame.KFWeapDef_Kriss',
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
class'KFGame.KFWeapDef_AbominationAxe',
class'KFGame.KFWeapDef_Minigun',
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
class'KFGame.KFWeapDef_MicrowaveRifle',
class'KFGame.KFWeapDef_CompoundBow',
class'KFGame.KFWeapDef_M99',
class'KFGame.KFWeapDef_LazerCutter',
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
class'KFGame.KFWeapDef_ThermiteBore',
class'KFGame.KFWeapDef_HRG_BarrierRifle'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_HRGTeslauncher',
class'KFGame.KFWeapDef_Eviscerator',
class'KFGame.KFWeapDef_MaceAndShield',
class'KFGame.KFWeapDef_PowerGloves',
class'KFGame.KFWeapDef_SCAR',
class'KFGame.KFWeapDef_Stoner63A',
class'KFGame.KFWeapDef_MedicRifle',
class'KFGame.KFWeapDef_FNFal',
class'KFGame.KFWeapDef_AA12',
class'KFGame.KFWeapDef_ElephantGun',
class'KFGame.KFWeapDef_Blunderbuss',
class'KFGame.KFWeapDef_HRGIncision',
class'KFGame.KFWeapDef_HRG_Vampire',
class'KFGame.KFWeapDef_RPG7',
class'KFGame.KFWeapDef_Seeker6',
class'KFGame.KFWeapDef_HuskCannon',
class'KFGame.KFWeapDef_MicrowaveGun',
class'KFGame.KFWeapDef_SW500Dual',
class'KFGame.KFWeapDef_AF2011Dual',
class'KFGame.KFWeapDef_Pistol_DualG18',
class'KFGame.KFWeapDef_RailGun',
class'KFGame.KFWeapDef_G18',
class'KFGame.KFWeapDef_Kriss',
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
class'KFGame.KFWeapDef_AbominationAxe',
class'KFGame.KFWeapDef_Minigun',
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
class'KFGame.KFWeapDef_MicrowaveRifle',
class'KFGame.KFWeapDef_CompoundBow',
class'KFGame.KFWeapDef_M99',
class'KFGame.KFWeapDef_LazerCutter',
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
class'KFGame.KFWeapDef_ThermiteBore',
class'KFGame.KFWeapDef_HRG_BarrierRifle'
)}),
(WeaponClasses={(
class'KFGame.KFWeapDef_HRGTeslauncher',
class'KFGame.KFWeapDef_Eviscerator',
class'KFGame.KFWeapDef_MaceAndShield',
class'KFGame.KFWeapDef_PowerGloves',
class'KFGame.KFWeapDef_SCAR',
class'KFGame.KFWeapDef_Stoner63A',
class'KFGame.KFWeapDef_MedicRifle',
class'KFGame.KFWeapDef_FNFal',
class'KFGame.KFWeapDef_AA12',
class'KFGame.KFWeapDef_ElephantGun',
class'KFGame.KFWeapDef_Blunderbuss',
class'KFGame.KFWeapDef_HRGIncision',
class'KFGame.KFWeapDef_HRG_Vampire',
class'KFGame.KFWeapDef_RPG7',
class'KFGame.KFWeapDef_Seeker6',
class'KFGame.KFWeapDef_HuskCannon',
class'KFGame.KFWeapDef_MicrowaveGun',
class'KFGame.KFWeapDef_SW500Dual',
class'KFGame.KFWeapDef_AF2011Dual',
class'KFGame.KFWeapDef_Pistol_DualG18',
class'KFGame.KFWeapDef_RailGun',
class'KFGame.KFWeapDef_G18',
class'KFGame.KFWeapDef_Kriss',
class'KFGame.KFWeapDef_HRG_EMP_ArcGenerator',
class'KFGame.KFWeapDef_AbominationAxe',
class'KFGame.KFWeapDef_Minigun',
class'KFGame.KFWeapDef_MedicRifleGrenadeLauncher',
class'KFGame.KFWeapDef_MicrowaveRifle',
class'KFGame.KFWeapDef_CompoundBow',
class'KFGame.KFWeapDef_M99',
class'KFGame.KFWeapDef_LazerCutter',
class'KFGame.KFWeapDef_HRG_BlastBrawlers',
class'KFGame.KFWeapDef_ThermiteBore',
class'KFGame.KFWeapDef_HRG_BarrierRifle'
)})
)}
}

View File

@ -0,0 +1,34 @@
//=============================================================================
// KFMeleeHelperWeaponBlastBrawlers
//=============================================================================
// Manages melee attack related functionality for 1st person weapons
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFMeleeHelperWeaponBlastBrawlers extends KFMeleeHelperWeapon
config(Game);
event InitWorldTraceForHitboxCollision()
{
local KFWeap_HRG_BlastBrawlers BlastBrawlers;
BlastBrawlers = KFWeap_HRG_BlastBrawlers(Instigator.Weapon);
if (BlastBrawlers != none)
{
BlastBrawlers.Shoot();
}
super.InitWorldTraceForHitboxCollision();
}
simulated function InitAttackSequence(EPawnOctant NewAtkDir, EMeleeAttackType NewAtkType)
{
super.InitAttackSequence(NewAtkDir, NewAtkType);
NextAttackType = NewAtkType;
}
defaultproperties
{
}

View File

@ -407,6 +407,115 @@ defaultproperties
)} )}
// Aracnophobia
SetEvents[10]={(
EventDifficulty=2, //1,
GameLength=GL_Normal,
SpawnRateMultiplier=0.75, //5.0,
bHealAfterKill = true,
bGoompaJumpEnabled = true,
GoompaJumpDamage = 550, //300,
GoompaStreakDamage = 0.1, //0.2,
GoompaJumpImpulse = 600, //1000,
GoompaStreakMax = 5,
GoompaBonusDuration=8.0f, //10.0f,
DoshOnKillGlobalModifier=1.0,
SpawnWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.AracnophobiaWeeklySpawnList',
bAddSpawnListToLoadout=true,
WaveAICountScale=(0.6, 0.6, 0.6, 0.6, 0.6, 0.6),
JumpZ=700.f, // 650.0 by default; -1 used for not overriding.
/** HealByKill = Normal kill. HealByAssistance = Goomba stomping */
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler',HealthScale=10.0, HeadHealthScale=20.0, DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.7, HealByAssistance=10),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing',HealthScale=10.0,HeadHealthScale=20.0, DamageDealtScale=0.7, InitialGroundSpeedModifierScale=0.7, HealByAssistance=20)
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket',HealByAssistance=5),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealByAssistance=15),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealByAssistance=15),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealByAssistance=15),
//(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',HealByAssistance=5)
)},
SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_Stalker,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_Husk,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
//(SpawnEntry=AT_Scrake,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
//(SpawnEntry=AT_FleshPound,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
//(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.7),
(SpawnEntry=AT_EliteClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_EliteGoreFast,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_EDAR_EMP,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_EDAR_Laser,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_EDAR_Rocket,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.6),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=1.0)
)}
)}
// Broken Trader
SetEvents[11]={(
EventDifficulty=1,
GameLength=GL_Normal,
bSpawnWeaponListAffectsSecondaryWeapons=true,
TraderWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.BrokenTraderWeeklyTraderList',
PickupResetTime=PRS_Wave,
bDisableTraders=false,
DroppedItemLifespan=10.0f, // 300 default
DoshOnKillGlobalModifier=0.2,
//Pickup Notes for when you're modifying:
// NumPickups = Actors * OverridePickupModifer * WavePickupModifier
// Ex: 16 item pickups in the world
// * 0.9 Pickup Modifier = 14
// * 0.5 Current wave modifier = 7 expected to spawn
//
// Ex: 16 ammo pickups in the world
// * 0.1 pickup modifier = 2
// * 0.5 current wave modifier = 1 expected to spawn
bUnlimitedWeaponPickups=true,
OverrideItemPickupModifier=2.0,
OverrideAmmoPickupModifier=0.8, //0.5,
WaveItemPickupModifiers={(
1.0, 1.0, 1.0, 1.0, 1.0
)},
WaveAmmoPickupModifiers={(
0.5, 0.6, 0.7, 0.8, 0.9
)},
bUseOverrideAmmoRespawnTime=true,
OverrideAmmoRespawnTime={(
PlayersMod[0]=20.000000,
PlayersMod[1]=20.000000,
PlayersMod[2]=10.000000,
PlayersMod[3]=10.000000,
PlayersMod[4]=5.000000,
PlayersMod[5]=5.000000,
ModCap=1.000000
)},
bUseOverrideItemRespawnTime=true,
OverrideItemRespawnTime={(
PlayersMod[0]=10.000000,
PlayersMod[1]=10.000000,
PlayersMod[2]=5.000000,
PlayersMod[3]=5.000000,
PlayersMod[4]=2.000000,
PlayersMod[5]=2.000000,
ModCap=1.000000
)}
)}
//Test events from here down. These don't end up in the regular rotation. //Test events from here down. These don't end up in the regular rotation.

View File

@ -36,7 +36,13 @@ simulated function PlayHeadAsplode()
/** Set our gib flag on the server, replicate it with bTearOff */ /** Set our gib flag on the server, replicate it with bTearOff */
function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLocation) function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLocation)
{ {
if( !bPlayedDeath && DamageType != class'KFSM_PlayerCrawler_Suicide'.default.SuicideDamageType ) local KFGameInfo_WeeklySurvival KFGI_WS;
// Not exploding if we are in arachnophobia weekly.
KFGI_WS = KFGameInfo_WeeklySurvival(WorldInfo.Game);
if( !bPlayedDeath && DamageType != class'KFSM_PlayerCrawler_Suicide'.default.SuicideDamageType &&
(KFGI_WS == none|| !KFGI_WS.OutbreakEvent.ActiveEvent.bGoompaJumpEnabled))
{ {
bShouldExplode = true; bShouldExplode = true;
} }

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) if (ShieldHealthPctByte == 0)
{ {

View File

@ -0,0 +1,51 @@
//=============================================================================
// KFPhysicsDamageByPawnVolume
//=============================================================================
// PhysicsVolume are, by default, used for traps on all maps. This KFPhysicsDamageByPawnVolume
// gives the ability to make different damage values for Humans and Monsters.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
// Roberto Moreno
//=============================================================================
class KFPhysicsDamageByPawnVolume extends PhysicsVolume
placeable;
var() float DamagePerSecMultiplierForHuman;
var() float DamagePerSecMultiplierForMonster;
function CausePainTo(Actor Other)
{
local float DamagePerSecModified;
DamagePerSecModified = DamagePerSec;
if (KFPawn_Human(Other) != None)
{
DamagePerSecModified *= DamagePerSecMultiplierForHuman;
}
else if (KFPawn_Monster(Other) != None)
{
DamagePerSecModified *= DamagePerSecMultiplierForMonster;
}
if (DamagePerSecModified > 0)
{
if ( WorldInfo.bSoftKillZ && (Other.Physics != PHYS_Walking) )
return;
if ( (DamageType == None) || (DamageType == class'DamageType') )
`log("No valid damagetype ("$DamageType$") specified for "$PathName(self));
Other.TakeDamage(DamagePerSecModified*PainInterval, DamageInstigator, Location, vect(0,0,1), DamageType,, self);
}
else
{
Other.HealDamage(-DamagePerSecModified * PainInterval, DamageInstigator, DamageType);
}
}
DefaultProperties
{
DamagePerSecMultiplierForHuman=1.0
DamagePerSecMultiplierForMonster=1.0
}

View File

@ -234,9 +234,9 @@ defaultproperties
// Ice explosion // Ice explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0 Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=25 Damage=75 //25
DamageRadius=200 DamageRadius=250 //200
DamageFalloffExponent=1.f DamageFalloffExponent=0.5f //1.f
DamageDelay=0.f DamageDelay=0.f
bIgnoreInstigator=false bIgnoreInstigator=false

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFProj_Bullet_BlastBrawlers
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_BlastBrawlers extends KFProj_Bullet_Pellet
hidedropdown;
defaultproperties
{
MaxSpeed=7000.0
Speed=7000.0
bWarnAIWhenFired=true
DamageRadius=0
ImpactEffects = KFImpactEffectInfo'WEP_HRG_BlastBrawlers_ARCH.HRG_BlastBrawler_Projectile_Impacts'
ProjFlightTemplate=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Tracer_Instant'
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Tracer_Instant'
//ProjFlightTemplate=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Projectile'
//ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_BlastBrawlers_EMIT.FX_BlastBrawlers_Projectile'
AmbientSoundPlayEvent=none
AmbientSoundStopEvent=none
}

View File

@ -11,13 +11,10 @@ class KFProj_Grenade_GravityImploder extends KFProj_BallisticExplosive
/* Ensure it detonates */ /* Ensure it detonates */
var float DetonationTime; var float DetonationTime;
var float VortexDuration; var float VortexDuration;
var float VortexRadius; var float VortexRadius;
var float VortexImpulseStrength; var float VortexImpulseStrength;
var protected transient bool bVortexActive; var protected transient bool bVortexActive;
var protected RB_RadialImpulseComponent RadialImpulseComponent;
simulated state GrenadeState simulated state GrenadeState
{ {
simulated event BeginState(Name PrevStateName) simulated event BeginState(Name PrevStateName)
@ -49,18 +46,25 @@ simulated state VortexState
simulated event Tick(float DeltaTime) simulated event Tick(float DeltaTime)
{ {
local float ImpulseModifier; local Actor Victim;
local TraceHitInfo HitInfo;
local FracturedStaticMeshActor FracActor;
if(bVortexActive && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone)) if(bVortexActive && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
{ {
// ImpulseModifier = (bReduceGibImpulseOnTick) ? (1.0f - AccumulatedTime / Lifetime) : 1.0f; foreach CollidingActors(class'Actor', Victim, VortexRadius, Location, true,, HitInfo)
ImpulseModifier = 1.0f; {
if (KFPawn_Human(Victim) == none && Victim.CollisionComponent != none && !Victim.bWorldGeometry)
RadialImpulseComponent.ImpulseRadius = VortexRadius; {
RadialImpulseComponent.ImpulseStrength = VortexImpulseStrength * ImpulseModifier; Victim.CollisionComponent.AddRadialImpulse(Location, VortexRadius, VortexImpulseStrength, RIF_Constant, true);
RadialImpulseComponent.bVelChange = true; }
RadialImpulseComponent.ImpulseFalloff = RIF_Constant;
RadialImpulseComponent.FireImpulse(Location); FracActor = FracturedStaticMeshActor(Victim);
if (FracActor != none)
{
FracActor.BreakOffPartsInRadius(Location, VortexRadius, VortexImpulseStrength, true);
}
}
} }
} }
} }
@ -123,9 +127,9 @@ defaultproperties
ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile' ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile'
ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile_ZEDTIME' ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Yellow_Projectile_ZEDTIME'
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts' //GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01' ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force' //AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force'
// Grenade explosion light // Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight Begin Object Class=PointLightComponent Name=ExplosionPointLight
@ -179,10 +183,4 @@ defaultproperties
VortexImpulseStrength=-100 VortexImpulseStrength=-100
VortexDuration=0.5f VortexDuration=0.5f
bVortexActive=false bVortexActive=false
Begin Object Class=RB_RadialImpulseComponent Name=ImpulseComponent0
End Object
RadialImpulseComponent=ImpulseComponent0
Components.Add(ImpulseComponent0)
} }

View File

@ -0,0 +1,368 @@
//=============================================================================
// KFProj_Rocket_ThermiteBore
//=============================================================================
// Thermite Bore Rifle rocket launcher harpoon
//=============================================================================
// Killing Floor 2
// Copyright (C) 2012 Tripwire Interactive LLC
//=============================================================================
class KFProj_Rocket_ThermiteBore extends KFProjectile;
var float FuseTime;
/** This is the effect indicator that is played for the current user **/
var(Projectile) ParticleSystem ProjIndicatorTemplate;
var ParticleSystemComponent ProjIndicatorEffects;
var bool IndicatorActive;
/**
Fire effects
*/
var class<KFProjectile> ResidualFlameProjClass;
var int NumResidualFlames;
/** Cone Angle to determine residual flame directions */
var float ResidualFlameHalfConeAngle;
/** Impulse modiffier apply to residual forces*/
var float ResidualFlameForceMultiplier;
simulated function TryActivateIndicator()
{
if(!IndicatorActive && Instigator != None)
{
IndicatorActive = true;
if(WorldInfo.NetMode == NM_Standalone || Instigator.Role == Role_AutonomousProxy ||
(Instigator.Role == ROLE_Authority && WorldInfo.NetMode == NM_ListenServer && Instigator.IsLocallyControlled() ))
{
if( ProjIndicatorTemplate != None )
{
ProjIndicatorEffects = WorldInfo.MyEmitterPool.SpawnEmitterCustomLifetime(ProjIndicatorTemplate);
}
if(ProjIndicatorEffects != None)
{
ProjIndicatorEffects.SetAbsolute(false, false, false);
ProjIndicatorEffects.SetLODLevel(WorldInfo.bDropDetail ? 1 : 0);
ProjIndicatorEffects.bUpdateComponentInTick = true;
AttachComponent(ProjIndicatorEffects);
}
}
}
}
/**
* Set the initial velocity and cook time
*/
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
if (Role == ROLE_Authority)
{
SetTimer(FuseTime, false, 'Timer_Detonate');
}
AdjustCanDisintigrate();
}
/**
* Explode after a certain amount of time
*/
function Timer_Detonate()
{
Detonate();
}
/** Called when the owning instigator controller has left a game */
simulated function OnInstigatorControllerLeft()
{
if( WorldInfo.NetMode != NM_Client )
{
SetTimer( 1.f + Rand(5) + fRand(), false, nameOf(Timer_Detonate) );
}
}
/**
* Trace down and get the location to spawn the explosion effects and decal
*/
simulated function GetExplodeEffectLocation(out vector HitLocation, out vector HitRotation, out Actor HitActor)
{
local vector EffectStartTrace, EffectEndTrace;
local TraceHitInfo HitInfo;
EffectStartTrace = Location + vect(0,0,1) * 4.f;
EffectEndTrace = EffectStartTrace - vect(0,0,1) * 32.f;
// Find where to put the decal
HitActor = Trace(HitLocation, HitRotation, EffectEndTrace, EffectStartTrace, false,, HitInfo, TRACEFLAG_Bullet);
// If the locations are zero (probably because this exploded in the air) set defaults
if (IsZero(HitLocation))
{
HitLocation = Location;
}
if (IsZero(HitRotation))
{
HitRotation = vect(0,0,1);
}
}
/** Used to check current status of StuckTo actor (to figure out if we should fall) */
simulated event Tick(float DeltaTime)
{
super.Tick(DeltaTime);
StickHelper.Tick(DeltaTime);
if (!IsZero(Velocity))
{
SetRelativeRotation(rotator(Velocity));
}
TryActivateIndicator();
}
/** Causes charge to explode */
function Detonate()
{
local KFWeap_RocketLauncher_ThermiteBore WeaponOwner;
local vector ExplosionNormal;
if (Role == ROLE_Authority)
{
WeaponOwner = KFWeap_RocketLauncher_ThermiteBore(Owner);
if (WeaponOwner != none)
{
WeaponOwner.RemoveDeployedHarpoon(, self);
}
}
ExplosionNormal = vect(0,0,1) >> Rotation;
Explode(Location, ExplosionNormal);
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
local vector HitVelocity;
HitVelocity = Velocity;
StickHelper.UnPin();
super.Explode(HitLocation, HitNormal);
// Spawn fire projectiles
if(Role < Role_Authority)
{
return;
}
SpawnResidualFlames(HitLocation, HitNormal, HitVelocity);
SpawnResidualFlame(ResidualFlameProjClass, Location, HitVelocity);
}
simulated function Disintegrate( rotator InDisintegrateEffectRotation )
{
local KFWeap_RocketLauncher_ThermiteBore WeaponOwner;
if (Role == ROLE_Authority)
{
WeaponOwner = KFWeap_RocketLauncher_ThermiteBore(Owner);
if (WeaponOwner != none)
{
WeaponOwner.RemoveDeployedHarpoon(, self);
}
}
super.Disintegrate(InDisintegrateEffectRotation);
}
// for nukes && concussive force
simulated protected function PrepareExplosionTemplate()
{
class'KFPerk_Demolitionist'.static.PrepareExplosive(Instigator, self);
super.PrepareExplosionTemplate();
}
simulated function SyncOriginalLocation()
{
// IMPORTANT NOTE: We aren't actually syncing to the original location (or calling the super).
// We just want to receive the original location so we can do a trace between that location and
// our current location to determine if we hit any zeds between those two locations.
// KFII-45464
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
StickHelper.TryStick(HitNormal, HitLocation, HitActor);
}
}
}
simulated protected function StopSimulating()
{
super.StopSimulating();
if (ProjIndicatorEffects!=None)
{
ProjIndicatorEffects.DeactivateSystem();
}
}
/** Spawn several projectiles that explode and linger on impact */
function SpawnResidualFlames( vector HitLocation, vector HitNormal, vector HitVelocity )
{
local int i;
local vector HitVelDir;
local float HitVelMag;
local vector SpawnLoc, SpawnVel;
HitVelMag = VSize( HitVelocity );
HitVelDir = Normal( HitVelocity );
SpawnLoc = HitLocation + (HitNormal * 10.f);
// spawn random lingering fires (rather, projectiles that cause little fires)
for( i = 0; i < NumResidualFlames; ++i )
{
SpawnVel = CalculateResidualFlameVelocity( HitNormal, HitVelDir, HitVelMag );
SpawnResidualFlame( ResidualFlameProjClass, SpawnLoc, SpawnVel );
}
}
function vector CalculateResidualFlameVelocity( vector HitNormal, vector HitVelDir, float HitVelMag )
{
local vector SpawnDir;
// apply some spread
SpawnDir = VRandCone( HitNormal, ResidualFlameHalfConeAngle * DegToRad );
/*
// make HitVelDir parallel to contact surface by subtracting component parallel to HitNormal
SpawnDir = SpawnDir + (-(SpawnDir dot HitNormal) * HitNormal);
// apply some more spread to get some of the flames to stick to the wall and others the ground beneath the wall
// (makes it looks kind of smeared down the wall, like a real molotov)
SpawnDir = VRandCone( SpawnDir, PI/4 );
*/
return SpawnDir * ResidualFlameForceMultiplier;
}
defaultproperties
{
ProjFlightTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Harpoon_Projectile'
ProjIndicatorTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Harpoon_Projectile_Indicator'
bWarnAIWhenFired=true
MaxSpeed=5000.0 //4000.0
Speed=5000.0 //4000.0
TerminalVelocity=5000 //4000
Physics=PHYS_Falling
TossZ=0 //150
GravityScale=0.36 //0.5//0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=true
bIgnoreFoliageTouch=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
FuseTime=4.0
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=true
bCanDisintegrate=true
Begin Object Name=CollisionCylinder
BlockNonZeroExtent=false
// for siren scream
CollideActors=true
End Object
// explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=252,G=218,B=171,A=255)
Brightness=4.f
Radius=2000.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0 // @todo: change me
Damage=150 //250
DamageRadius=500 //600
DamageFalloffExponent=1.f
DamageDelay=0.f
// Damage Effects
MyDamageType=class'KFDT_Explosive_Thermite'
KnockDownStrength=0
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_Thermite_ARCH.ThermiteHarpoon_Explosion'
ExplosionSound=AkEvent'WW_WEP_SealSqueal.Play_WEP_SealSqueal_Shoot_Explode'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.2
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=200
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ExploTemplate0
ExplosionActorClass=class'KFExplosionActor'
bCanStick=true
bCanPin=true
Begin Object Class=KFProjectileStickHelper Name=StickHelper0
End Object
StickHelper=StickHelper0
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
ResidualFlameProjClass=class'KFProj_ThermiteSplash'
NumResidualFlames=4 //it always spawn 1 more than this parameter, so 5
ResidualFlameHalfConeAngle=72
ResidualFlameForceMultiplier=700f; //1000f;
}

View File

@ -0,0 +1,110 @@
//=============================================================================
// KFProj_ThermiteSplash
//=============================================================================
// Projectile class for the thermite rocket launchers
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_ThermiteSplash extends KFProj_MolotovSplash;
/*
simulated function Tick(float Delta)
{
super.Tick(Delta);
if (WorldInfo.NetMode != NM_Client && WorldInfo.NetMode != NM_Standalone)
{
return;
}
// Rotate towards velocity:
if (VSizeSq(Velocity) > 0)
{
SetRotation(rotator(Normal(Velocity)));
}
}
*/
defaultproperties
{
Physics=PHYS_Falling
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
// network
bNetTemporary=False
bAlwaysReplicateExplosion=true
AlwaysRelevantDistanceSquared=6250000 // 25m
// gameplay
bBlockedByInstigator=false
GlassShatterType=FMGS_ShatterNone
// audio
bStopAmbientSoundOnExplode=false
bAutoStartAmbientSound=true
bAmbientSoundZedTimeOnly=false
AmbientSoundPlayEvent=AkEvent'WW_WEP_SA_Flamethrower.Play_WEP_SA_Flamethrower_Residual_Fire_Loop'
AmbientSoundStopEvent=AkEvent'WW_WEP_SA_Flamethrower.Stop_WEP_SA_Flamethrower_Residual_Fire_Loop'
Begin Object name=AmbientAkSoundComponent
bStopWhenOwnerDestroyed=true
bForceOcclusionUpdateInterval=true
OcclusionUpdateInterval=0.25;
End Object
AmbientComponent=AmbientAkSoundComponent
Components.Add(AmbientAkSoundComponent)
// light
Begin Object Name=FlamePointLight
LightColor=(R=245,G=190,B=140,A=255)
Brightness=2.f
Radius=300.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=FALSE
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Name=ExploTemplate0
Damage=10
DamageRadius=150
DamageFalloffExponent=1.f
DamageDelay=0.f
// Don't burn the guy that tossed it, it's just too much damage with multiple fires, its almost guaranteed to kill the guy that tossed it
bIgnoreInstigator=true
MomentumTransferScale=1
// Damage Effects
MyDamageType=class'KFDT_Fire_Ground_ThermiteBore'
KnockDownStrength=0
FractureMeshRadius=0
ExplosionEffects=KFImpactEffectInfo'wep_thermite_arch.Thermite_GroundFire'
bDirectionalExplosion=true
// Camera Shake
CamShake=none
// Dynamic Light
ExploLight=FlamePointLight
ExploLightStartFadeOutTime=4.2
ExploLightFadeOutTime=0.3
End Object
ExplosionTemplate=ExploTemplate0
ProjFlightTemplate=ParticleSystem'WEP_Thermite_EMIT.FX_Thermite_Spread_01'
ExplosionActorClass=class'KFExplosion_Thermite'
AssociatedPerkClass=class'KFPerk_Firebug'
// Ground Fire Perk Skill Alternative FX
AltExploEffects=KFImpactEffectInfo'WEP_Thermite_ARCH.GroundFire_Splash_Impacts'
}

View File

@ -0,0 +1,137 @@
//=============================================================================
// KFSeasonalEventStats_Summer2021
//=============================================================================
// Tracks event-specific challenges/accomplishments for Summer 2021
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Summer2021 extends KFSeasonalEventStats;
var transient private const int ZedsStompRequired, LaserKillsRequired, JumpKillsRequired, EndlessWaveRequired;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
bObjectiveIsValidForMap[0] = 1; // Stomp on 50 Zeds
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Moonbase
bObjectiveIsValidForMap[2] = 0; // Use the laser trap to kill 20 Zeds on Moonbase
bObjectiveIsValidForMap[3] = 0; // Kill 300 Zeds while jumping in the air on Moonbase
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Moonbase
if (CapsMapName == "KF-MOONBASE")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(ZedsStompRequired, 0, LaserKillsRequired, JumpKillsRequired, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
// @TODO: Set Proper Reward ID
//
GrantEventItem(8844);
}
}
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
// Moonbase weekly
if (bObjectiveIsValidForMap[1] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Summer, 1);
}
}
}
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
local KFPlayerController KFPC;
local KFPawn_Human KFP;
// Laser Kills
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (ClassIsChildOf(DT, class'KFDT_EMPTrap'))
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= LaserKillsRequired)
{
FinishedObjective(SEI_SUMMER, ObjIdx);
}
}
}
ObjIdx = 3;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
KFPC = Outer.MyKFPC;
if (KFPC != none)
{
KFP = KFPawn_Human(KFPC.Pawn);
if (KFP != none && KFP.Physics == PHYS_Falling)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= JumpKillsRequired)
{
FinishedObjective(SEI_SUMMER, ObjIdx);
}
}
}
}
}
simulated function OnHitGiven(class<DamageType> DT)
{
local int ObjIdx;
ObjIdx = 0;
// Stomps
if (ClassIsChildOf(DT, class'DmgType_Crushed'))
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= ZedsStompRequired)
{
FinishedObjective(SEI_SUMMER, ObjIdx);
}
}
}
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
// Waves in Endless hard
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Summer, ObjIdx);
}
}
}
defaultproperties
{
ZedsStompRequired=50
LaserKillsRequired=20
JumpKillsRequired=300
EndlessWaveRequired=15
}

View File

@ -0,0 +1,231 @@
//=============================================================================
// KFWeapAttach_FAMAS
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_FAMAS extends KFWeaponAttachment;
const SecondaryFireAnim = 'Shoot_Secondary';
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
const SecondaryFireAnimLast = 'Shoot_Secondary_Last';
const SecondaryFireIronAnimLast = 'Shoot_Secondary_Iron_Last';
const SecondaryFireBodyAnim = 'ADD_Shoot_Secondary';
const SecondaryFireBodyAnimCH = 'ADD_Shoot_Secondary_CH';
const SecondaryFireBodyAnimIron = 'ADD_Shoot_Secondary_Iron';
const SecondaryReloadAnimEmpty = 'Reload_Secondary_Empty';
const SecondaryReloadAnimHalf = 'Reload_Secondary_Half';
const SecondaryReloadAnimEliteEmpty = 'Reload_Secondary_Elite_Empty';
const SecondaryReloadAnimEliteHalf = 'Reload_Secondary_Elite_Half';
const ShotgunMuzzleSocket = 'ShotgunMuzzleFlash';
var protected transient KFMuzzleFlash ShotgunMuzzleFlash;
/** Play a 3rd person reload animation */
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
{
local name AnimName;
if(NewWeaponState == WEP_ReloadSecondary || NewWeaponState == WEP_ReloadSecondary_Elite)
{
switch (NewWeaponState)
{
case WEP_ReloadSecondary:
AnimName = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryReloadAnimEmpty : SecondaryReloadAnimHalf;
break;
case WEP_ReloadSecondary_Elite:
AnimName = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryReloadAnimEliteEmpty : SecondaryReloadAnimEliteHalf;
break;
}
PlayCharacterMeshAnim(P, AnimName, true);
}
else
{
Super.PlayReloadMagazineAnim(NewWeaponState, P);
}
}
simulated function CauseMuzzleFlash(byte FiringMode)
{
if ( FiringMode == 1 ) // AltFire
{
if (ShotgunMuzzleFlash == None)
{
AttachMuzzleFlash();
}
if (ShotgunMuzzleFlash != None )
{
ShotgunMuzzleFlash.CauseMuzzleFlash(FiringMode);
if ( ShotgunMuzzleFlash.bAutoActivateShellEject )
{
ShotgunMuzzleFlash.CauseShellEject();
}
}
}
else
{
Super.CauseMuzzleFlash(FiringMode);
}
}
/** Added second weapon */
simulated function AttachMuzzleFlash()
{
Super.AttachMuzzleFlash();
if ( WeapMesh != none && ShotgunMuzzleFlash == None )
{
ShotgunMuzzleFlash = new(self) Class'KFMuzzleFlash'(class'KFWeap_AssaultRifle_FAMAS'.default.ShotgunMuzzleFlashTemplate);
ShotgunMuzzleFlash.AttachMuzzleFlash(WeapMesh, ShotgunMuzzleSocket,);
}
}
/** Plays fire animation on weapon mesh */
simulated function PlayFireAnim(KFPawn P)
{
local float Duration;
local name Anim;
local KFPawn OwnerPawn;
OwnerPawn = KFPawn(Owner);
if ( Instigator.bIsWalking ) // IronSight anims
{
if (OwnerPawn.FiringMode == 0) // DEFAULT FIRE MODE (Rifle)
{
Anim = WeaponIronFireAnim;
}
else if (OwnerPawn.FiringMode == 1) // ALT FIRE MODE (Shotgun)
{
// Anim = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryFireIronAnimLast : SecondaryFireIronAnim;
Anim = SecondaryFireIronAnim;
}
}
else // Normal anims
{
if (Pawn(Owner).FiringMode == 0) // DEFAULT FIRE MODE (Rifle)
{
Anim = WeaponFireAnim;
}
else if (Pawn(Owner).FiringMode == 1) // ALT FIRE MODE (Shotgun)
{
// Anim = (P.MyKFWeapon.AmmoCount[1] == 0) ? SecondaryFireAnimLast : SecondaryFireAnim;
Anim = SecondaryFireAnim;
}
}
Duration = WeapMesh.GetAnimLength( Anim );
WeapMesh.PlayAnim( Anim, Duration / ThirdPersonAnimRate,, true );
}
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local EAnimSlotStance AnimType;
if (P.FiringMode == 1) // AltFire
{
SpawnTracer(GetAltMuzzleLocation(), HitLocation);
}
else
{
SpawnTracer(GetMuzzleLocation(), HitLocation);
}
// Effects below this point are culled based on visibility and distance
if ( !ActorEffectIsRelevant(P, false, MaxFireEffectDistance) )
{
return false;
}
DecodeThirdPersonAnimRate( ThirdPersonAnimRateByte );
// Weapon shoot anims
if( !bWeapMeshIsPawnMesh )
{
PlayFireAnim(P);
}
if( P.IsDoingSpecialMove() && P.SpecialMoves[P.SpecialMove].bAllowFireAnims )
{
AnimType = EAS_Additive;
}
else
{
AnimType = EAS_FullBody;
}
// Character shoot anims
if ( !P.IsDoingSpecialMove() || AnimType == EAS_Additive )
{
PlayPawnFireAnim( P, AnimType );
// interrupt other weapon action anims (e.g. Reload)
if( !P.IsDoingSpecialMove() )
{
P.StopBodyAnim(P.bIsCrouched ? EAS_CH_UpperBody : EAS_UpperBody, 0.1f);
}
if ( OnWeaponStateChanged != None )
{
OnWeaponStateChanged(true);
}
}
CauseMuzzleFlash(P.FiringMode);
return true;
}
/** Plays fire animation on pawn */
simulated function PlayPawnFireAnim( KFPawn P, EAnimSlotStance AnimType )
{
if (P.FiringMode == 0)
{
super.PlayPawnFireAnim(P, AnimType);
}
else if (P.FiringMode == 1)
{
if ( P.bIsCrouched )
{
P.PlayBodyAnim(SecondaryFireBodyAnimCH, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else if ( P.bIsWalking )
{
P.PlayBodyAnim(SecondaryFireBodyAnimIron, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else
{
P.PlayBodyAnim(SecondaryFireBodyAnim, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
}
}
simulated function vector GetAltMuzzleLocation(optional byte MuzzleID)
{
local vector SocketLocation;
if (ShotgunMuzzleFlash == None && MuzzleFlashTemplate != None)
{
AttachMuzzleFlash();
}
if( ShotgunMuzzleFlash != none )
{
WeapMesh.GetSocketWorldLocationAndRotation(ShotgunMuzzleFlash.GetSocketName(), SocketLocation);
return SocketLocation;
}
return Super.GetMuzzleLocation(MuzzleID);
}
defaultproperties
{
}

View File

@ -0,0 +1,102 @@
//=============================================================================
// KFWeapAttach_HRG_BarrierRifle
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_BarrierRifle extends KFWeaponAttachment;
`define BARRIERRIFLE_MIC_SHIELD_INDEX 0
/** Indicates wheter we are activating/deactivating the shield fx */
var protected transient bool bActivatingShield;
var protected transient float FXDelta;
var protected transient float ShieldFXDuration;
var protected transient float OverlayDelta;
var protected transient float OverlayMax;
var protected transient float OverlayMin;
var protected transient float ShieldBlockVFXDuration;
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
if ( WorldInfo.NetMode == NM_DedicatedServer )
{
return;
}
ShieldFXDuration = class'KFWeap_HRG_BarrierRifle'.default.ShieldFXDuration;
OverlayMax = class'KFWeap_HRG_BarrierRifle'.default.RedOverlayMax;
OverlayMin = class'KFWeap_HRG_BarrierRifle'.default.RedOverlayMin;
ShieldBlockVFXDuration = class'KFWeap_HRG_BarrierRifle'.default.ShieldBlockVFXDuration;
UpdateShieldFXValue(0.0f);
}
simulated function UpdateShieldFXValue(float Value)
{
if ( WeaponMIC == None && WeapMesh != None )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`BARRIERRIFLE_MIC_SHIELD_INDEX);
}
WeaponMIC.SetScalarParameterValue('Opacity', Value);
}
unreliable client function SetShieldActive(bool bActive)
{
bActivatingShield = bActive;
}
/** Special event added for weap attachments. Free for use */
function OnSpecialEvent(int Arg)
{
if (Arg < 2)
{
SetShieldActive(Arg == 1 ? True : False);
}
else if (Arg == 3)
{
UpdateShieldBlockVFX(OverlayMax);
OverlayDelta = OverlayMax;
}
}
simulated function UpdateShieldBlockVFX(float Value)
{
if ( WeaponMIC == None && WeapMesh != None )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`BARRIERRIFLE_MIC_SHIELD_INDEX);
}
WeaponMIC.SetScalarParameterValue('RedOverlay', Value);
}
simulated event Tick(float DeltaTime)
{
// Update Shield visuals
if (bActivatingShield && FXDelta < class'KFWeap_HRG_BarrierRifle'.default.ShieldFXDuration)
{
FXDelta = FMin(FXDelta + DeltaTime, ShieldFXDuration);
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
}
else if (!bActivatingShield && FXDelta > 0.0f)
{
FXDelta = FMax(FXDelta - DeltaTime, 0.0f);
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
}
if (OverlayDelta > 0.0f)
{
OverlayDelta = FMax(OverlayDelta - DeltaTime, OverlayMin);
UpdateShieldBlockVFX(OverlayMax * (OverlayDelta / ShieldBlockVFXDuration));
}
}
defaultproperties
{
OverlayDelta=0.0f
}

View File

@ -0,0 +1,142 @@
//=============================================================================
// KFWeapAttach_HRG_BlastBrawlers
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_BlastBrawlers extends KFWeapAttach_DualBase;
var protected transient bool bUsingLeftWeapon;
var protected transient name ReloadAnimName;
var protected transient float ReloadAnimRateMod;
/** Overrides to prevent weapon animation */
simulated function PlayWeaponFireAnim();
/** Caching reload anim name */
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
ReloadAnimName = class'KFWeap_HRG_BlastBrawlers'.default.ReloadAnimation;
ReloadAnimRateMod = class'KFWeap_HRG_BlastBrawlers'.default.ReloadAnimRateModifier;
}
/** Overriding to avoid interrupting meleen anims with fire anims */
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
SpawnTracer(GetMuzzleLocation(), HitLocation);
// Effects below this point are culled based on visibility and distance
if ( !ActorEffectIsRelevant(P, false, MaxFireEffectDistance) )
{
return false;
}
CauseMuzzleFlash(P.FiringMode);
P.LastWeaponFireTime = -1.f;
return true;
}
simulated function vector GetMuzzleLocation(optional byte MuzzleID)
{
local vector SocketLocation;
if ( bUsingLeftWeapon)
{
if (LeftMuzzleFlash == None && MuzzleFlashTemplate != None)
{
AttachMuzzleFlash();
}
if( LeftMuzzleFlash != none )
{
LeftWeapMesh.GetSocketWorldLocationAndRotation(LeftMuzzleFlash.GetSocketName(), SocketLocation);
return SocketLocation;
}
}
return Super.GetMuzzleLocation(MuzzleID);
}
/** Added second weapon */
simulated function CauseMuzzleFlash(byte FiringMode)
{
if ( bUsingLeftWeapon )
{
if (LeftMuzzleFlash == None && MuzzleFlashTemplate != None)
{
AttachMuzzleFlash();
}
if (LeftMuzzleFlash != None )
{
LeftMuzzleFlash.CauseMuzzleFlash(FiringMode);
if ( LeftMuzzleFlash.bAutoActivateShellEject )
{
LeftMuzzleFlash.CauseShellEject();
}
}
}
else
{
Super.CauseMuzzleFlash(FiringMode);
bUsingLeftWeapon = true;
}
}
simulated function UpdateThirdPersonWeaponAction(EWeaponState NewWeaponState, KFPawn P, byte ThirdPersonAnimRateByte )
{
// Reset
bUsingLeftWeapon=false;
super.UpdateThirdPersonWeaponAction(NewWeaponState, P, ThirdPersonAnimRateByte);
}
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
{
PlayCharacterMeshAnim(P, ReloadAnimNAme, true);
}
simulated function PlayWeaponMeshAnim(name AnimName, AnimNodeSlot SyncNode, bool bLoop)
{
local float Duration;
/** Only reload animation could be played */
if ( !IsAnimationValid(AnimName) )
return;
// Weapon shoot anims
if( !bWeapMeshIsPawnMesh )
{
Duration = WeapMesh.GetAnimLength(AnimName);
if (AnimName == ReloadAnimName)
{
Duration *= ReloadAnimRateMod;
}
WeapMesh.PlayAnim(AnimName, Duration / ThirdPersonAnimRate, bLoop);
// syncronize this with the character anim
if ( SyncNode != None )
{
bSynchronizeWeaponAnim = true;
SyncPawnNode = SyncNode;
SyncAnimName = AnimName;
bSyncAnimCheckRelevance = false;
}
}
}
simulated function bool IsAnimationValid(name AnimName)
{
return AnimName == ReloadAnimName;
}
defaultproperties
{
bUsingLeftWeapon=false
}

View File

@ -0,0 +1,682 @@
//=============================================================================
// KFWeap_AssaultRifle_FAMAS
//=============================================================================
// FAMAS assault rifle with an extra of shotgun. Better than in MGS!
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_AssaultRifle_FAMAS extends KFWeap_ScopedBase;
var (Positioning) vector SecondaryFireOffset;
const SecondaryFireAnim = 'Shoot_Secondary';
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
const SecondaryFireAnimLast = 'Shoot_Secondary_Last';
const SecondaryFireIronAnimLast = 'Shoot_Secondary_Iron_Last';
const SecondaryReloadAnimEmpty = 'Reload_Secondary_Empty';
const SecondaryReloadAnimHalf = 'Reload_Secondary_Half';
const SecondaryReloadAnimEliteEmpty = 'Reload_Secondary_Elite_Empty';
const SecondaryReloadAnimEliteHalf = 'Reload_Secondary_Elite_Half';
const ShotgunMuzzleSocket = 'ShotgunMuzzleFlash';
/** Animation to play when the weapon is fired in burst mode with 2 rounds left */
var(Animations) const editconst name BurstFire2RdAnim;
var(Animations) const editconst name BurstFire2RdSightedAnim;
/** Animation to play when the weapon is fired in burst fire mode for 3 rounds*/
var(Animations) const editconst name BurstFire3RdAnim;
var(Animations) const editconst name BurstFire3RdSightedAnim;
var transient KFMuzzleFlash ShotgunMuzzleFlash;
var() KFMuzzleFlash ShotgunMuzzleFlashTemplate;
// Used on the server to keep track of grenades
var int ServerTotalAltAmmo;
var transient bool bCanceledAltAutoReload;
var transient int BurstAmountBegin;
var protected const float AltFireRecoilScale;
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Assault;
}
static simulated event EFilterTypeUI GetAltTraderFilter()
{
return FT_Explosive;
}
/** Instead of switch fire mode use as immediate alt fire */
simulated function AltFireMode()
{
if ( !Instigator.IsLocallyControlled() )
{
return;
}
if (bCanceledAltAutoReload)
{
bCanceledAltAutoReload = false;
TryToAltReload(true);
return;
}
// StartFire - StopFire called from KFPlayerInput
StartFire(ALTFIRE_FIREMODE);
}
simulated function BeginFire( Byte FireModeNum )
{
local bool bStoredAutoReload;
// We are trying to reload the weapon but the primary ammo in already at full capacity
if ( FireModeNum == RELOAD_FIREMODE && !CanReload() )
{
// Store the current state of bCanceledAltAutoReload in case its not possible to do the reload
bStoredAutoReload = bCanceledAltAutoReload;
bCanceledAltAutoReload = false;
if(CanAltAutoReload(false))
{
TryToAltReload(false);
return;
}
bCanceledAltAutoReload = bStoredAutoReload;
}
super.BeginFire( FireModeNum );
}
/**
* Initializes ammo counts, when weapon is spawned.
*/
function InitializeAmmo()
{
Super.InitializeAmmo();
// Add Secondary ammo to our secondary spare ammo count both of these are important, in order to allow dropping the weapon to function properly.
SpareAmmoCount[1] = Min(SpareAmmoCount[1] + InitialSpareMags[1] * default.MagazineCapacity[1], GetMaxAmmoAmount(1) - AmmoCount[1]);
ServerTotalAltAmmo += SpareAmmoCount[1];
// Make sure the server doesn't get extra shots on listen servers.
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
{
ServerTotalAltAmmo += AmmoCount[1];
}
}
/**
* @see Weapon::ConsumeAmmo
*/
simulated function ConsumeAmmo( byte FireModeNum )
{
local byte AmmoType;
local bool bNoInfiniteAmmo;
local int OldAmmoCount;
if(UsesSecondaryAmmo() && FireModeNum == ALTFIRE_FIREMODE && Role == ROLE_Authority && !Instigator.IsLocallyControlled())
{
AmmoType = GetAmmoType(FireModeNum);
OldAmmoCount = AmmoCount[AmmoType];
Super.ConsumeAmmo(FireModeNum);
bNoInfiniteAmmo = (OldAmmoCount - AmmoCount[AmmoType]) > 0 || AmmoCount[AmmoType] == 0;
if ( bNoInfiniteAmmo )
{
ServerTotalAltAmmo--;
}
}
else
{
Super.ConsumeAmmo(FireModeNum);
}
}
/** Make sure user can't fire infinitely if they cheat to get infinite ammo locally. */
simulated event bool HasAmmo( byte FireModeNum, optional int Amount=1 )
{
local byte AmmoType;
AmmoType = GetAmmoType(FireModeNum);
if(AmmoType == 1 && Role == ROLE_Authority && UsesSecondaryAmmo() && !Instigator.IsLocallyControlled())
{
if(ServerTotalAltAmmo <= 0)
{
return false;
}
}
return Super.HasAmmo(FireModeNum, Amount );
}
/**
* Overridden so any grenades added will go to the spare ammo and no the clip.
*/
function int AddSecondaryAmmo(int Amount)
{
local int OldAmmo;
// If we can't accept spare ammo, then abort
if( !CanRefillSecondaryAmmo() )
{
return 0;
}
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
{
OldAmmo = ServerTotalAltAmmo;
ServerTotalAltAmmo = Min(ServerTotalAltAmmo + Amount, GetMaxAmmoAmount(1));
ClientGiveSecondaryAmmo(Amount);
return ServerTotalAltAmmo - OldAmmo;
}
else
{
OldAmmo = SpareAmmoCount[1];
ClientGiveSecondaryAmmo(Amount);
return SpareAmmoCount[1] - OldAmmo;
}
}
/** Give client specified amount of ammo (used player picks up ammo on the server) */
reliable client function ClientGiveSecondaryAmmo(byte Amount)
{
SpareAmmoCount[1] = Min(SpareAmmoCount[1] + Amount, GetMaxAmmoAmount(1) - AmmoCount[1]);
TryToAltReload(true);
}
function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon )
{
local KFWeap_AssaultRifle_FAMAS Weap;
Super.SetOriginalValuesFromPickup(PickedUpWeapon);
if(Role == ROLE_Authority && !Instigator.IsLocallyControlled())
{
Weap = KFWeap_AssaultRifle_FAMAS(PickedUpWeapon);
ServerTotalAltAmmo = Weap.ServerTotalAltAmmo;
SpareAmmoCount[1] = ServerTotalAltAmmo - AmmoCount[1];
}
else
{
// If we're locally controlled, don't bother using ServerTotalAltAmmo.
SpareAmmoCount[1] = PickedUpWeapon.SpareAmmoCount[1];
}
}
simulated state WeaponBurstFiring
{
simulated event BeginState(Name PreviousStateName)
{
BurstAmountBegin = GetBurstAmount();
Super.BeginState(PreviousStateName);
}
simulated function name GetWeaponFireAnim(byte FireModeNum)
{
// only do one burst animation instead of a burst animation per shot
// since burst amount gets reduced after each shot, this will only play the one animation based on the number of shots in the burst fire
if (BurstAmount == BurstAmountBegin)
{
if (BurstAmount == 3)
{
if (bUsingSights)
{
return BurstFire3RdSightedAnim;
}
return BurstFire3RdAnim;
}
else if (BurstAmount == 2)
{
if (bUsingSights)
{
return BurstFire2RdSightedAnim;
}
return BurstFire2RdAnim;
}
else
{
return super.GetWeaponFireAnim(FireModeNum);
}
}
// will not play any animation
return '';
}
}
simulated state FiringSecondaryState extends WeaponFiring
{
// Overriden to not call FireAmmunition right at the start of the state
simulated event BeginState( Name PreviousStateName )
{
Super.BeginState(PreviousStateName);
NotifyBeginState();
}
simulated function EndState(Name NextStateName)
{
Super.EndState(NextStateName);
NotifyEndState();
}
/**
* This function returns the world location for spawning the visual effects
* Overridden to use a special offset for using the shotgun
*/
simulated event vector GetMuzzleLoc()
{
local vector MuzzleLocation;
// swap fireoffset temporarily
FireOffset = SecondaryFireOffset;
MuzzleLocation = Global.GetMuzzleLoc();
FireOffset = default.FireOffset;
return MuzzleLocation;
}
/** Get whether we should play the reload anim as well or not */
simulated function name GetWeaponFireAnim(byte FireModeNum)
{
if (AmmoCount[FireModeNum] > 0)
{
return bUsingSights ? SecondaryFireIronAnim : SecondaryFireAnim;
}
return bUsingSights ? SecondaryFireIronAnimLast : SecondaryFireAnimLast;
}
}
/**
* Don't allow secondary fire to make a primary fire shell particle come out of the gun.
*/
simulated function CauseMuzzleFlash(byte FireModeNum)
{
if(FireModeNum == ALTFIRE_FIREMODE)
{
if (ShotgunMuzzleFlash == None)
{
AttachMuzzleFlash();
}
if (ShotgunMuzzleFlash != none)
{
ShotgunMuzzleFlash.CauseMuzzleFlash(FireModeNum);
}
if ( ShotgunMuzzleFlash.bAutoActivateShellEject )
{
ShotgunMuzzleFlash.CauseShellEject();
SetShellEjectsToForeground();
}
}
else
{
Super.CauseMuzzleFlash(FireModeNum);
}
}
simulated function AttachMuzzleFlash()
{
super.AttachMuzzleFlash();
if ( MySkelMesh != none )
{
if (ShotgunMuzzleFlashTemplate != None)
{
ShotgunMuzzleFlash = new(self) Class'KFMuzzleFlash'(ShotgunMuzzleFlashTemplate);
ShotgunMuzzleFlash.AttachMuzzleFlash(MySkelMesh, ShotgunMuzzleSocket,);
}
}
}
/*********************************************************************************************
* State Reloading
* This is the default Reloading State. It's performed on both the client and the server.
*********************************************************************************************/
/** Do not allow alternate fire to tell the weapon to reload. Alt reload occurs in a separate codepath */
simulated function bool ShouldAutoReload(byte FireModeNum)
{
if(FireModeNum == ALTFIRE_FIREMODE)
{
return false;
}
return Super.ShouldAutoReload(FireModeNum);
}
/** Called on local player when reload starts and replicated to server */
simulated function SendToAltReload()
{
ReloadAmountLeft = MagazineCapacity[1] - AmmoCount[1];
GotoState('AltReloading');
if ( Role < ROLE_Authority )
{
ServerSendToAltReload();
}
}
/** Called from client when reload starts */
reliable server function ServerSendToAltReload()
{
ReloadAmountLeft = MagazineCapacity[1] - AmmoCount[1];
GotoState('AltReloading');
}
/**
* State Reloading
* State the weapon is in when it is being reloaded (current magazine replaced with a new one, related animations and effects played).
*/
simulated state AltReloading extends Reloading
{
ignores ForceReload, ShouldAutoReload, AllowSprinting;
simulated function byte GetWeaponStateId()
{
local KFPerk Perk;
local bool bTacticalReload;
Perk = GetPerk();
bTacticalReload = (Perk != None && Perk.GetUsingTactialReload(self));
return (bTacticalReload ? WEP_ReloadSecondary_Elite : WEP_ReloadSecondary);
}
simulated event BeginState(Name PreviousStateName)
{
super.BeginState(PreviousStateName);
bCanceledAltAutoReload = true;
}
// Overridding super so we don't call functions we don't want to call.
simulated function EndState(Name NextStateName)
{
ClearZedTimeResist();
ClearTimer(nameof(ReloadStatusTimer));
ClearTimer(nameof(ReloadAmmoTimer));
CheckBoltLockPostReload();
NotifyEndState();
`DialogManager.PlayAmmoDialog( KFPawn(Instigator), float(SpareAmmoCount[1]) / float(GetMaxAmmoAmount(1)) );
}
// Overridding super so when this reload is called directly after normal reload state there
// are not complications resulting from back to back reloads.
simulated event ReplicatedEvent(name VarName)
{
Global.ReplicatedEvent(Varname);
}
/** Make sure we can inturrupt secondary reload with anything. */
simulated function bool CanOverrideMagReload(byte FireModeNum)
{
return false;
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName( bool bTacticalReload )
{
// magazine relaod
if ( AmmoCount[1] > 0 )
{
return (bTacticalReload) ? SecondaryReloadAnimEliteHalf : SecondaryReloadAnimHalf;
}
else
{
return (bTacticalReload) ? SecondaryReloadAnimEliteEmpty : SecondaryReloadAnimEmpty;
}
}
simulated function PerformReload(optional byte FireModeNum)
{
Global.PerformReload(ALTFIRE_FIREMODE);
if(Instigator.IsLocallyControlled() && Role < ROLE_Authority)
{
ServerSetAltAmmoCount(AmmoCount[1]);
}
bCanceledAltAutoReload = false;
}
simulated function EReloadStatus GetNextReloadStatus(optional byte FireModeNum)
{
return Global.GetNextReloadStatus(ALTFIRE_FIREMODE);
}
}
reliable server function ServerSetAltAmmoCount(byte Amount)
{
AmmoCount[1] = Amount;
}
/** Allow reloads for primary weapon to be interupted by firing secondary weapon. */
simulated function bool CanOverrideMagReload(byte FireModeNum)
{
if(FireModeNum == ALTFIRE_FIREMODE)
{
return true;
}
return Super.CanOverrideMagReload(FireModeNum);
}
/*********************************************************************************************
* State Active
* Try to get weapon to automatically reload secondary fire types when it can.
*********************************************************************************************/
simulated state Active
{
/** Initialize the weapon as being active and ready to go. */
simulated event BeginState(Name PreviousStateName)
{
// do this last so the above code happens before any state changes
Super.BeginState(PreviousStateName);
// If nothing happened, try to reload
TryToAltReload(true);
}
}
/** Network: Local Player */
simulated function bool CanAltAutoReload(bool bIsAuto)
{
if ( !Instigator.IsLocallyControlled() )
{
return false;
}
if(!UsesSecondaryAmmo())
{
return false;
}
// If the weapon wants to fire its primary weapon, and it can fire, do not allow weapon to automatically alt reload
if(PendingFire(DEFAULT_FIREMODE) && HasAmmo(DEFAULT_FIREMODE))
{
return false;
}
if(!CanReload(ALTFIRE_FIREMODE))
{
return false;
}
if (bIsAuto && AmmoCount[1] > 0)
{
return false;
}
if (bCanceledAltAutoReload)
{
return false;
}
return true;
}
simulated function TryToAltReload(bool bIsAuto)
{
if ((IsInState('Active') || IsInState('WeaponSprinting')) && CanAltAutoReload(bIsAuto))
{
SendToAltReload();
}
}
simulated function int GetSecondaryAmmoForHUD()
{
return AmmoCount[1];
}
simulated function int GetSecondarySpareAmmoForHUD()
{
return SpareAmmoCount[1];
}
simulated function ModifyRecoil( out float CurrentRecoilModifier )
{
if( CurrentFireMode == ALTFIRE_FIREMODE )
{
CurrentRecoilModifier *= AltFireRecoilScale;
}
super.ModifyRecoil( CurrentRecoilModifier );
}
defaultproperties
{
bCanRefillSecondaryAmmo = true;
// Content
PackageKey="Famas"
FirstPersonMeshName="wep_1p_famas_mesh.Wep_1stP_Famas_Rig"
FirstPersonAnimSetNames(0)="wep_1p_famas_anim.Wep_1stP_Famas_Anim"
PickupMeshName="WEP_3P_Famas_MESH.WEP_Famas_Pickup"
AttachmentArchetypeName="Wep_Famas_ARCH.Wep_Famas_3P"
MuzzleFlashTemplateName="wep_famas_arch.Wep_Famas_MuzzleFlash"
ShotgunMuzzleFlashTemplate=KFMuzzleFlash'wep_famas_arch.Wep_Famas_Shotgun_MuzzleFlash'
// Scope Render
// 2D scene capture
Begin Object Name=SceneCapture2DComponent0
TextureTarget=TextureRenderTarget2D'Wep_Mat_Lib.WEP_ScopeLense_Target'
FieldOfView=12.5 // "2.0X" = 25.0(our real world FOV determinant)/2.0
End Object
ScopedSensitivityMod = 8.0
ScopeLenseMICTemplate = MaterialInstanceConstant'WEP_1P_FNFAL_MAT.WEP_1P_FNFAL_Scope_MAT'
ScopeMICIndex = 2
// FOV
MeshFov=65
MeshIronSightFOV=60 //45
PlayerIronSightFOV=70
// Depth of field
DOF_BlendInSpeed=3.0
DOF_FG_FocalRadius=0
DOF_FG_MaxNearBlurSize=3.5
// Zooming/Position
PlayerViewOffset=(X=22.0,Y=9.f,Z=-2.f)
IronSightPosition=(X=0,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=24
SpareAmmoCapacity[0]=240
InitialSpareMags[0]=3
bCanBeReloaded=true
bReloadFromMagazine=true
// Shotgun Ammo
MagazineCapacity[1]=6
SpareAmmoCapacity[1]=36 //42
InitialSpareMags[1]=1
// Recoil
maxRecoilPitch=100 //125 //200 //120
minRecoilPitch=75 //100 //150 //70
maxRecoilYaw=40 //80
minRecoilYaw=-40 //-80
RecoilRate=0.085
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
RecoilViewRotationScale=0.25
IronSightMeshFOVCompensationScale=1.7
HippedRecoilModifier=2.0 //1.5
// Inventory / Grouping
InventorySize=6
GroupPriority=80 //75
WeaponSelectTexture=Texture2D'WEP_UI_Famas_TEX.UI_WeaponSelect_Famas'
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletBurst'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponBurstFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_FAMAS_Rifle'
FireInterval(DEFAULT_FIREMODE)=+0.0667 // 900 RPM
InstantHitDamage(DEFAULT_FIREMODE)=35.0
Spread(DEFAULT_FIREMODE)=0.005 //0.0085
BurstAmount=3
BurstFire2RdAnim=Shoot_Burst2
BurstFire3RdAnim=Shoot_Burst
BurstFire2RdSightedAnim=Shoot_Burst2_Iron
BurstFire3RdSightedAnim=Shoot_Burst_Iron
FireOffset=(X=30,Y=4.5,Z=-5)
SecondaryFireOffset=(X=20.f,Y=4.5,Z=-7.f)
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
FiringStatesArray(ALTFIRE_FIREMODE)=FiringSecondaryState
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_Pellet'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_FAMAS_Shotgun'
InstantHitDamage(ALTFIRE_FIREMODE)=25.0
PenetrationPower(DEFAULT_FIREMODE)=2.0
FireInterval(ALTFIRE_FIREMODE)=+1.2 //0.5 //0.7 //85 RPM
NumPellets(ALTFIRE_FIREMODE)=6
Spread(ALTFIRE_FIREMODE)=0.12 //0.07
SecondaryAmmoTexture=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_FAMAS'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_AR15.Play_WEP_SA_AR15_Handling_DryFire'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Fire_1P')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_AA12.Play_WEP_SA_AA12_Handling_DryFire'
// Attachments
bHasIronSights=true
bHasFlashlight=false
AssociatedPerkClasses(0)=class'KFPerk_Commando'
AssociatedPerkClasses(1)=class'KFPerk_Support'
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Damage1, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.25f), (Stat=EWUS_Damage1, Scale=1.25f), (Stat=EWUS_Weight, Add=2)))
bUsesSecondaryAmmoAltHUD=true
AltFireRecoilScale = 4.5 //4.0 //2.5
}

View File

@ -1142,7 +1142,7 @@ defaultproperties
BonesToLockOnEmpty=(RW_Magazine1, RW_BatteryContactLeft, RW_BatteryContactRight) BonesToLockOnEmpty=(RW_Magazine1, RW_BatteryContactLeft, RW_BatteryContactRight)
// Weapon Upgrade stat boosts // Weapon Upgrade stat boosts
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.2f), (Stat=EWUS_Damage1, Scale=1.2f), (Stat=EWUS_Weight, Add=1))) WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.0f), (Stat=EWUS_Damage1, Scale=1.0f), (Stat=EWUS_Weight, Add=0)))
MuzzleFlashEffectL1=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_01' MuzzleFlashEffectL1=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_01'
MuzzleFlashEffectL2=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_02' MuzzleFlashEffectL2=ParticleSystem'WEP_Laser_Cutter_EMIT.FX_Laser_Cutter_Beam_Muzzleflash_02'

View File

@ -727,9 +727,9 @@ defaultproperties
// Ammo // Ammo
MagazineCapacity[0]=1 MagazineCapacity[0]=1
SpareAmmoCapacity[0]=30 SpareAmmoCapacity[0]=35 //30
InitialSpareMags[0]=10 InitialSpareMags[0]=11 //10
AmmoPickupScale[0]=3.0 // 3 arrows AmmoPickupScale[0]=4.0 //3.0
// Recoil // Recoil
maxRecoilPitch=200 maxRecoilPitch=200

View File

@ -0,0 +1,731 @@
//=============================================================================
// KFWeap_HRG_BarrierRifle
//=============================================================================
// A modified version of the Stoner63A rifle.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_BarrierRifle extends KFWeap_LMG_Stoner63A;
`define BARRIERRIFLE_MIC_SHIELD_INDEX 4
/** Amount of shield charge that is consumed per second */
var (Shield) float ShieldConsumptionPerSecond;
/** Amount of shield chared that is recharged per second */
var (Shield) float ShieldRechargePerSecond;
/** Cooldown to apply after the shield is destroyed */
var (Shield) float CooldownAfterShieldDepleted;
/** Cooldown to apply after the shield depleted the charge */
var (Shield) float CooldownAfterShieldDestroyed;
/** VFX and SFX for blocking damage */
var (Shield) AkBaseSoundObject BlockSound;
var (Shield) ParticleSystem BlockParticleSystem;
var (Shield) name BlockEffectsSocketName;
/** Blocking information per damage type */
var (Shield) array<BlockEffectInfo> BlockDamageTypes;
/** Modifier applied to the damage received by the character */
var (Shield) float BlockDamageModifier;
/** Modifier applied to the damager that will affect the shield charge */
var (Shield) float ShieldDamageAbsorbtionModifier;
/** Angle to block with the shield */
var (Shield) float BlockingAngle;
/** Turn ON/OFF VFX duration */
var (Shield) float ShieldFXDuration;
/** Shield Block VFX duration */
var (Shield) float ShieldBlockVFXDuration;
/** Is shield active */
var protected transient bool bIsShieldActive;
/** Was shield charge depleted */
var protected transient bool bWasShieldDepleted;
/** Was the shield destroyed */
var protected transient bool bWasShielDestroyed;
/** Self explanatory */
var protected transient bool bCanRechargeShield;
/** float containing the shield charge to not be lost in the next frame
due to int conversion.
*/
var protected transient float ShieldRechargeIncrement;
var protected transient float ShieldConsumptionIncrement;
/** Cos of the blocking angle (Rads) */
var protected transient float BlockingAngleCos;
/** Wether the timer for activating the shield has expired (using the fire interval) */
var protected transient bool bShieldActionAvailable;
/** Indicates wheter we are activating/deactivating the shield fx */
var protected bool bActivatingShield;
var protected bool bDeactivatingShield;
var protected transient float FXDelta;
var transient float RedOverlayMax;
var transient float RedOverlayMin;
var protected transient float OverlayDelta;
var WeaponFireSndInfo ShieldActivateSound;
var WeaponFireSndInfo ShieldDeactivateSound;
var (Shield) AkBaseSoundObject ShieldEndSound;
var repnotify byte ShieldAmmo;
replication
{
if (bNetDirty && Role == ROLE_Authority)
bActivatingShield, bDeactivatingShield;
if (bNetDirty && Role == ROLE_Authority && bAllowClientAmmoTracking)
ShieldAmmo;
}
simulated event ReplicatedEvent(name VarName)
{
if (VarName == nameof(ShieldAmmo))
{
AmmoCount[ALTFIRE_FIREMODE] = ShieldAmmo;
}
else
{
Super.ReplicatedEvent(VarName);
}
}
simulated event PostBeginPlay()
{
super.PostBeginPlay();
BlockingAngleCos = cos((BlockingAngle / 2.f) * DegToRad);
}
simulated function Activate()
{
super.Activate();
if (WorldInfo.NetMode != NM_DedicatedServer)
{
UpdateShieldFXValue(0.0f);
}
}
simulated function UpdateShieldFXValue(float Value)
{
if( WeaponMICs.Length > `BARRIERRIFLE_MIC_SHIELD_INDEX )
{
WeaponMICs[`BARRIERRIFLE_MIC_SHIELD_INDEX].SetScalarParameterValue('Opacity', Value);
}
}
/**
* Instead of a toggle, just immediately fire alternate fire.
*/
simulated function AltFireMode()
{
// LocalPlayer Only
if ( !Instigator.IsLocallyControlled() )
{
return;
}
if( Role < Role_Authority )
{
// if we're a client, synchronize server
UseShield();
}
CustomFire();
}
reliable server function UseShield()
{
CustomFire();
}
/** Shield deploying */
simulated function CustomFire()
{
if (bWasShieldDepleted || bWasShielDestroyed || !bShieldActionAvailable || AmmoCount[ALTFIRE_FIREMODE] == 0)
{
return;
}
bIsShieldActive ? DeactivateShield() : ActivateShield();
bIsShieldActive = !bIsShieldActive;
bShieldActionAvailable = false;
}
simulated function ActivateShield()
{
PlaySoundBase(ShieldActivateSound.FirstPersonCue);
bActivatingShield = true;
bDeactivatingShield = false;
bNetDirty = true;
NotifyShieldActive(true);
SetTimer(FireInterval[ALTFIRE_FIREMODE], false, nameof(ShieldActivationCompleted));
}
simulated function DeactivateShield()
{
PlaySoundBase(ShieldDeactivateSound.FirstPersonCue);
bDeactivatingShield = true;
bActivatingShield = false;
bCanRechargeShield = false;
bNetDirty=true;
NotifyShieldActive(false);
SetTimer(FireInterval[ALTFIRE_FIREMODE], false, nameof(ShieldDeactivatedTimerCompleted));
}
simulated function ShieldActivationCompleted()
{
bShieldActionAvailable = true;
}
simulated function ShieldDeactivatedTimerCompleted()
{
bShieldActionAvailable = true;
bCanRechargeShield = true;
}
/** Update shield charge - client and server */
simulated event Tick(float DeltaTime)
{
// Update Shield visuals
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if (bActivatingShield && FXDelta < ShieldFXDuration)
{
FXDelta = FMin(FXDelta + DeltaTime, ShieldFXDuration);
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
if (FXDelta == ShieldFXDuration)
{
bActivatingShield = false;
}
}
else if (bDeactivatingShield && FXDelta > 0.0f)
{
FXDelta = FMax(FXDelta - DeltaTime, 0.0f);
UpdateShieldFXValue(FXDelta / ShieldFXDuration);
if (FXDelta == 0.0f)
{
bDeactivatingShield = false;
}
}
}
if (OverlayDelta > RedOverlayMin)
{
OverlayDelta = FMax(OverlayDelta - DeltaTime, RedOverlayMin);
UpdateShieldBlockVFX(RedOverlayMax * (OverlayDelta / ShieldBlockVFXDuration));
}
if ( Role == Role_Authority )
{
// If shield is active it needs to consume charge, otherwise it recharges itself.
if (bIsShieldActive)
{
ConsumeShield(DeltaTime);
}
else if (bCanRechargeShield && AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE])
{
RechargeShield(DeltaTime);
}
}
Super.Tick(DeltaTime);
}
simulated function ConsumeShield(float DeltaTime)
{
local int Charge;
if (Role == ROLE_Authority)
{
ShieldRechargeIncrement = 0.0f;
ShieldConsumptionIncrement += ShieldConsumptionPerSecond * DeltaTime;
if (ShieldConsumptionIncrement >= 1.0f && AmmoCount[ALTFIRE_FIREMODE] > 0)
{
Charge = int(ShieldConsumptionIncrement);
AmmoCount[ALTFIRE_FIREMODE] = Max(AmmoCount[ALTFIRE_FIREMODE] - Charge, 0);
ShieldConsumptionIncrement -= Charge;
ShieldAmmo = AmmoCount[ALTFIRE_FIREMODE];
if (AmmoCount[ALTFIRE_FIREMODE] == 0)
{
OnShieldDepleted();
}
}
}
}
simulated function RechargeShield(float DeltaTime)
{
local int Charge;
if (Role == ROLE_Authority)
{
ShieldConsumptionIncrement = 0.0f;
ShieldRechargeIncrement += ShieldRechargePerSecond * DeltaTime;
if (ShieldRechargeIncrement >= 1.0f && AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE])
{
Charge = int(ShieldRechargeIncrement);
AmmoCount[ALTFIRE_FIREMODE] = Min(AmmoCount[ALTFIRE_FIREMODE] + Charge, MagazineCapacity[ALTFIRE_FIREMODE]);
ShieldRechargeIncrement -= Charge;
ShieldAmmo = AmmoCount[ALTFIRE_FIREMODE];
}
}
}
/** Shield consumed all the charge by itself */
simulated function OnShieldDepleted()
{
bWasShieldDepleted = true;
bActivatingShield = false;
bDeactivatingShield = true;
bCanRechargeShield = false;
bIsShieldActive = false;
ShieldAmmo = 0;
bNetDirty = true;
NotifyShieldActive(false);
PlaySoundBase(ShieldEndSound);
SetTimer(CooldownAfterShieldDepleted, false, nameof(ShieldRepletedTimerCompleted));
}
simulated function ShieldRepletedTimerCompleted()
{
bWasShieldDepleted = false;
bCanRechargeShield = true;
}
/** Shield was destroyed by attacks */
simulated function OnShieldDestroyed()
{
bWasShielDestroyed = true;
bActivatingShield = false;
bDeactivatingShield = true;
bCanRechargeShield = false;
bIsShieldActive = false;
ShieldAmmo = 0;
bNetDirty = true;
NotifyShieldActive(false);
PlaySoundBase(ShieldEndSound);
SetTimer(CooldownAfterShieldDestroyed, false, nameof(ShieldDestroyedTimerCompleted));
}
simulated function ShieldDestroyedTimerCompleted()
{
bWasShielDestroyed = false;
bCanRechargeShield = true;
}
/** Update HUD ammo icon for shield */
simulated function int GetSecondaryAmmoForHUD()
{
return AmmoCount[ALTFIRE_FIREMODE];
}
simulated function ShieldAbsorbDamage(int DamageBase)
{
local int Damage;
// Use the carried shield reduction by time
ShieldConsumptionIncrement += DamageBase*ShieldDamageAbsorbtionModifier;
Damage = int(ShieldConsumptionIncrement);
AmmoCount[ALTFIRE_FIREMODE] = Max(AmmoCount[ALTFIRE_FIREMODE] - Damage, 0);
ShieldConsumptionIncrement -= Damage;
// Check if shield is destroyed.
if (AmmoCount[ALTFIRE_FIREMODE] == 0)
{
OnShieldDestroyed();
}
}
/**
Reduce the damage received and apply it to the shield
*/
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
{
local KFPerk InstigatorPerk;
local byte BlockTypeIndex;
local float DmgCauserDot;
if (!bIsShieldActive)
{
return;
}
// Don't apply block effects for teammates
if (Instigator.IsSameTeam(DamageCauser.Instigator))
{
return;
}
if (CanBlockDamageType(DamageType, BlockTypeIndex))
{
if (ClassIsChildOf(DamageCauser.class, class'Projectile'))
{
// Projectile might be beyond/behind player, resulting in bad dot
// Projectile won't have a velocity to check against, either
// Assume velocity is the vector between projectile and instigator
DmgCauserDot = Normal(DamageCauser.Instigator.Location - DamageCauser.Location) dot vector(Instigator.Rotation);
}
else
{
DmgCauserDot = Normal(DamageCauser.Location - Instigator.Location) dot vector(Instigator.Rotation);
}
if (DmgCauserDot > BlockingAngleCos)
{
ShieldAbsorbDamage(InDamage);
InDamage *= BlockDamageModifier;
ClientPlayBlockEffects(BlockTypeIndex);
NotifyShieldBlockActive(true);
SetTimer(0.1f, false, nameof(ResetShieldBlockVFX));
InstigatorPerk = GetPerk();
if (InstigatorPerk != none)
{
InstigatorPerk.SetSuccessfullBlock();
}
}
}
}
/** Only DT added to BlockDamageTypes can be blocked. Check if the current one is in the list. */
function bool CanBlockDamageType(class<DamageType> DamageType, optional out byte out_Idx)
{
local int Idx;
for (Idx = 0; Idx < BlockDamageTypes.length; ++Idx)
{
if (ClassIsChildOf(DamageType, BlockDamageTypes[Idx].DmgType))
{
out_Idx = Idx;
return true;
}
}
out_Idx = INDEX_NONE;
return false;
}
unreliable client function ClientPlayBlockEffects(optional byte BlockDTIndex=255)
{
local AkBaseSoundObject Sound;
local ParticleSystem PSTemplate;
GetBlockEffects(BlockDTIndex, Sound, PSTemplate);
PlayLocalBlockEffects(Sound, PSTemplate);
UpdateShieldBlockVFX(RedOverlayMax);
OverlayDelta = ShieldBlockVFXDuration;
}
/** Called on the client when successfully block/parry an attack */
simulated function PlayLocalBlockEffects(AKBaseSoundObject Sound, ParticleSystem PSTemplate)
{
local vector Loc;
local rotator Rot;
local ParticleSystemComponent PSC;
if (Sound != None)
{
PlaySoundBase(Sound, true);
}
if (PSTemplate != None)
{
if (MySkelMesh.GetSocketWorldLocationAndRotation(BlockEffectsSocketName, Loc, Rot))
{
PSC = WorldInfo.MyEmitterPool.SpawnEmitter(PSTemplate, Loc, Rot);
PSC.SetDepthPriorityGroup(SDPG_Foreground);
}
else
{
`log(self@GetFuncName()@"missing BlockEffects Socket!");
}
}
}
/** Returns sound and particle system overrides using index into BlockDamageTypes array */
simulated function GetBlockEffects(byte BlockDTIndex, out AKBaseSoundObject outSound, out ParticleSystem outParticleSys)
{
outSound = BlockSound;
outParticleSys = BlockParticleSystem;
if (BlockDTIndex != 255)
{
if (BlockDamageTypes[BlockDTIndex].BlockSound != None)
{
outSound = BlockDamageTypes[BlockDTIndex].BlockSound;
}
if (BlockDamageTypes[BlockDTIndex].BlockParticleSys != None)
{
outParticleSys = BlockDamageTypes[BlockDTIndex].BlockParticleSys;
}
}
}
/**
Should replicate to 3P to show the shield effects
*/
simulated function NotifyShieldActive(bool bActive)
{
local KFPawn KFP;
if (WorldInfo.NetMode != NM_Client)
{
KFP = KFPawn(Instigator);
KFP.OnWeaponSpecialAction(bActive ? 1 : 0);
}
}
simulated function NotifyShieldBlockActive(bool bActive)
{
local KFPawn KFP;
if (WorldInfo.NetMode != NM_Client)
{
KFP = KFPawn(Instigator);
KFP.OnWeaponSpecialAction(bActive ? 3 : 2);
}
}
/*********************************************************************************************
* State WeaponEquipping
* The Weapon is in this state while transitioning from Inactive to Active state.
* Typically, the weapon will remain in this state while its selection animation is being played.
* While in this state, the weapon cannot be fired.
*********************************************************************************************/
simulated state WeaponEquipping
{
simulated function BeginState(Name PreviousStateName)
{
bShieldActionAvailable = true;
super.BeginState(PreviousStateName);
}
}
/*********************************************************************************************
* State WeaponPuttingDown
* Putting down weapon in favor of a new one.
* Weapon is transitioning to the Inactive state.
*********************************************************************************************/
simulated state WeaponPuttingDown
{
simulated event EndState(Name NextStateName)
{
UpdateShieldFXValue(0.0f);
// Reset Values
bIsShieldActive = false;
bWasShieldDepleted = false;
bWasShielDestroyed = false;
bCanRechargeShield = true;
bShieldActionAvailable = false;
bActivatingShield = false;
bDeactivatingShield = false;
FXDelta = 0.0f;
bNetDirty=true;
super.EndState(NextStateName);
}
}
simulated function UpdateShieldBlockVFX(float Value)
{
if( WeaponMICs.Length > `BARRIERRIFLE_MIC_SHIELD_INDEX )
{
WeaponMICs[`BARRIERRIFLE_MIC_SHIELD_INDEX].SetScalarParameterValue('RedOverlay', Value);
}
}
function ResetShieldBlockVFX()
{
NotifyShieldBlockActive(false);
}
/** Shield doesn't count as ammo for purposes of inventory management (e.g. switching) */
simulated function bool HasAnyAmmo()
{
return AmmoCount[0] > 0 || SpareAmmoCount[0] > 0;
}
defaultproperties
{
// Shooting Animations
FireSightedAnims[0]=Shoot_Iron
FireSightedAnims[1]=Shoot_Iron2
FireSightedAnims[2]=Shoot_Iron3
// FOV
MeshFOV=75
MeshIronSightFOV=35
PlayerIronSightFOV=70
// Depth of field
DOF_FG_FocalRadius=85
DOF_FG_MaxNearBlurSize=2.5
// Content
PackageKey="HRG_BarrierRifle"
FirstPersonMeshName="WEP_1P_HRG_BarrierRifle_MESH.WEP_1stP_HRG_BarrielRifle_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_HRG_BarrierRifle_ANIM.Wep_1stP_HRG_BarrierRifle_Anim"
PickupMeshName="WEP_3P_HRG_BarrierRifle_MESH.Wep_3rdP_HRG_BarrierRifle_Pickup"
AttachmentArchetypeName="WEP_HRG_BarrierRifle_ARCH.Wep_HRG_BarrierRifle_3P"
MuzzleFlashTemplateName="WEP_HRG_BarrierRifle_ARCH.Wep_HRG_BarrierRifle_MuzzleFlash"
// Zooming/Position
PlayerViewOffset=(X=4.0,Y=8,Z=-4)
IronSightPosition=(X=8.5,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=60
SpareAmmoCapacity[0]=540 //480
InitialSpareMags[0]=2
bCanBeReloaded=true
bReloadFromMagazine=true
// Shield "Ammo"
MagazineCapacity[1]=100
SpareAmmoCapacity[1]=0
bCanRefillSecondaryAmmo=false
// Recoil
maxRecoilPitch=110 //120
minRecoilPitch=70 //70
maxRecoilYaw=80 //130
minRecoilYaw=-80 //-130
RecoilRate=0.045 //0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=75
RecoilISMinYawLimit=65460
RecoilISMaxPitchLimit=375
RecoilISMinPitchLimit=65460
RecoilViewRotationScale=0.4 //0.25
IronSightMeshFOVCompensationScale=2.3
HippedRecoilModifier=1.5
//WalkingRecoilModifier=1.1
//JoggingRecoilModifier=1.2
// Inventory / Grouping
InventorySize=7
GroupPriority=125
WeaponSelectTexture=Texture2D'wep_ui_hrg_barrierrifle_tex.UI_WeaponSelect_HRG_BarrierRifle'
AssociatedPerkClasses(0)=class'KFPerk_SWAT'
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_BarrierRifle'
FireInterval(DEFAULT_FIREMODE)=+0.066 // 900 RPM
Spread(DEFAULT_FIREMODE)=0.025 //0.0085
InstantHitDamage(DEFAULT_FIREMODE)=33.0 //35.0
FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
AmmoCost(ALTFIRE_FIREMODE)=0
FireInterval(ALTFIRE_FIREMODE)=0.01f
SecondaryAmmoTexture=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_BarrierRifle'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_3P_Loop', FirstPersonCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_1P_Loop')
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_3P_EndLoop', FirstPersonCue=AkEvent'WW_WEP_Stoner.Play_WEP_Stoner_Fire_1P_EndLoop')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_L85A2.Play_WEP_SA_L85A2_Handling_DryFire'
EjectedShellForegroundDuration=0.8f
// Advanced (High RPM) Fire Effects
bLoopingFireAnim(DEFAULT_FIREMODE)=true
bLoopingFireSnd(DEFAULT_FIREMODE)=true
// Attachments
bHasIronSights=true
bHasFlashlight=false
// Ammo belt
AmmoBeltBulletBonePrefix="RW_Bullets"
NumAmmoBeltBullets=14
LastAmmoCount=-1
bIsShieldActive=false
bWasShieldDepleted=false
bWasShielDestroyed=false
bCanRechargeShield=true
ShieldRechargeIncrement=0.0f;
ShieldConsumptionIncrement=0.0f
ShieldConsumptionPerSecond=3.0f //10.0f
ShieldRechargePerSecond=8.0f //10.0f //15.0f
CooldownAfterShieldDepleted=3.0f //3.0f
CooldownAfterShieldDestroyed=3.0f //5.0f
ShieldActivateSound=(DefaultCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_On', FirstPersonCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_On')
ShieldDeactivateSound=(DefaultCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Off', FirstPersonCue=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Off')
ShieldEndSound=AKEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_End';
BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'
BlockParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Block_melee_01'
BlockEffectsSocketName=BlockEffect
RedOverlayMax=1.0f
RedOverlayMin=0.0f
OverlayDelta=0.0f
ShieldBlockVFXDuration=0.5f
BlockDamageTypes.Add((DmgType=class'KFDT_Bludgeon', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Slashing', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Fire_HuskFireball', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Fire_HuskFlamethrower'))
BlockDamageTypes.Add((DmgType=class'KFDT_BloatPuke'))
BlockDamageTypes.Add((DmgType=class'KFDT_EvilDAR_Rocket', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_EvilDAR_Laser', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_DAR_EMPBlast', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Ballistic_PatMinigun', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Explosive_PatMissile', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_Ballistic_HansAK12', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_EMP_MatriarchTeslaBlast', BlockSound=AkEvent'WW_WEP_HRG_BarrierRifle.Play_WEP_HRG_BarrierRifle_1P_Shield_Impact'))
BlockDamageTypes.Add((DmgType=class'KFDT_EMP_MatriarchPlasmaCannon'))
BlockDamageTypes.Add((DmgType=class'KFDT_FleshpoundKing_ChestBeam'))
BlockDamageModifier=0.3f //0.4f
ShieldDamageAbsorbtionModifier=1.2f //0.8f //0.8 = equal to base damage
BlockingAngle=180.f // Adjust with visuals.
bShieldActionAvailable=true
bActivatingShield=false
bDeactivatingShield=false
FXDelta=0.0f
ShieldFXDuration=0.15f
bAllowClientAmmoTracking=true
NumBloodMapMaterials=5
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.0f), (Stat=EWUS_Weight, Add=0)))
}

View File

@ -0,0 +1,482 @@
//=============================================================================
// KFWeap_HRG_BlastBrawlers
//=============================================================================
// Power gloves and shotgun, all in one.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_BlastBrawlers extends KFWeap_Blunt_PowerGloves;
var name ReloadAnimation;
var float ReloadAnimRateModifier;
var float ReloadAnimRateModifierElite;
var protected transient bool bWaitingForSecondShot;
var protected transient int NumAttacks;
/** A muzzle flash instance for left weapon */
var KFMuzzleFlash LeftMuzzleFlash;
simulated event PreBeginPlay()
{
super.PreBeginPlay();
}
simulated function Shoot()
{
// LocalPlayer Only
if ( !Instigator.IsLocallyControlled() )
{
return;
}
if( Role < Role_Authority )
{
// if we're a client, synchronize server
ServerShoot();
}
ProcessShoot();
}
/**
Each attack shoots twice, once with the right and left fists.
Ammo is decremented after the second shot.
*/
reliable server function bool ServerShoot()
{
return ProcessShoot();
}
simulated function bool ProcessShoot()
{
// Shooting only happens when default firing
if(CurrentFireMode != DEFAULT_FIREMODE)
return false;
CustomFire();
if (!bWaitingForSecondShot)
{
// AmmoCount[DEFAULT_FIREMODE] = Max(AmmoCount[DEFAULT_FIREMODE] - 1, 0);
DecrementAmmo();
}
bWaitingForSecondShot = !bWaitingForSecondShot;
return true;
}
simulated function DecrementAmmo()
{
AmmoCount[DEFAULT_FIREMODE] = Max(AmmoCount[DEFAULT_FIREMODE] - 1, 0);
}
simulated state Active
{
/**
* Called from Weapon:Active.BeginState when HasAnyAmmo (which is overridden above) returns false.
*/
simulated function WeaponEmpty()
{
local int i;
// Copied from Weapon:Active.BeginState where HasAnyAmmo returns true.
// Basically, pretend the weapon isn't empty in this case.
for (i=0; i<GetPendingFireLength(); i++)
{
if (PendingFire(i))
{
BeginFire(i);
break;
}
}
}
}
static simulated event bool UsesAmmo()
{
return true;
}
simulated function CustomFire()
{
local byte CachedFireMode;
CachedFireMode = CurrentFireMode;
CurrentFireMode = CUSTOM_FIREMODE;
ProjectileFire();
// Let the accuracy tracking system know that we fired
HandleWeaponShotTaken(CurrentFireMode);
NotifyWeaponFired(CurrentFireMode);
// Play fire effects now (don't wait for WeaponFired to replicate)
PlayFireEffects(CurrentFireMode, vect(0, 0, 0));
CurrentFireMode = CachedFireMode;
}
/** Overriden for the Tight Choke perk */
simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
{
local KFPerk InstigatorPerk;
if (CurrentFireMode == CUSTOM_FIREMODE)
{
InstigatorPerk = GetPerk();
if (InstigatorPerk != none)
{
Spread[CurrentFireMode] = default.Spread[CurrentFireMode] * InstigatorPerk.GetTightChokeModifier();
}
}
return super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir);
}
/** Override for not playing animations (even if noanimation is set it interrupts the melee ones.) */
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
// If we have stopped the looping fire sound to play single fire sounds for zed time
// start the looping sound back up again when the time is back above zed time speed
if( FireModeNum < bLoopingFireSnd.Length && bLoopingFireSnd[FireModeNum] && !bPlayingLoopingFireSnd )
{
StartLoopingFireSound(FireModeNum);
}
PlayFiringSound(CurrentFireMode);
if( Instigator != none )
{
if( Instigator.IsLocallyControlled() )
{
if( Instigator.IsFirstPerson() )
{
// Start muzzle flash effect
CauseMuzzleFlash(FireModeNum);
}
ShakeView();
}
}
}
/**
* @see Weapon::StartFire
*/
simulated function StartFire(byte FireModeNum)
{
// can't start fire because it's in an uninterruptible state
if (StartFireDisabled)
{
return;
}
if (FireModeNum == DEFAULT_FIREMODE)
{
if(AmmoCount[DEFAULT_FIREMODE] > 0)
{
StartMeleeFire(FireModeNum, DIR_FORWARD, ATK_Normal);
}
else
{
super.StartFire(RELOAD_FIREMODE);
// If not cleared, it will loop the animation.
ClearPendingFire(RELOAD_FIREMODE);
}
return;
}
super.StartFire(FireModeNum);
}
/** Avoiding reload anim to interrupt combo */
simulated state MeleeChainAttacking
{
simulated function BeginState(Name PrevStateName)
{
local KFPerk InstigatorPerk;
if( CurrentFireMode == DEFAULT_FIREMODE )
{
StartFireDisabled = true;
bWaitingForSecondShot = false;
NumAttacks = 0;
}
InstigatorPerk = GetPerk();
if (InstigatorPerk != none)
{
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
}
super.BeginState( PrevStateName );
}
simulated function EndState(Name NextStateName)
{
super.EndState(NextStateName);
if( CurrentFireMode == DEFAULT_FIREMODE )
{
StartFireDisabled = false;
}
ClearZedTimeResist();
}
simulated function bool ShouldContinueMelee(optional int ChainCount)
{
if ( CurrentFireMode == DEFAULT_FIREMODE )
{
return false;
}
return super.ShouldContinueMelee(ChainCount);
}
}
/**
* Called on a client, this function Attaches the WeaponAttachment
* to the Mesh.
*
* Overridden to attach LeftMuzzleFlash
*/
simulated function AttachMuzzleFlash()
{
super.AttachMuzzleFlash();
if ( MySkelMesh != none )
{
if (MuzzleFlashTemplate != None)
{
LeftMuzzleFlash = new(self) Class'KFMuzzleFlash'(MuzzleFlashTemplate);
LeftMuzzleFlash.AttachMuzzleFlash(MySkelMesh, 'MuzzleFlash_L');
}
}
}
/**
* Causes the muzzle flash to turn on and setup a time to
* turn it back off again.
*
* Overridden to cause left weapon flash
*/
simulated function CauseMuzzleFlash(byte FireModeNum)
{
if( MuzzleFlash == None || LeftMuzzleFlash == None )
{
AttachMuzzleFlash();
}
if( bWaitingForSecondShot )
{
if (MuzzleFlash != None )
{
// Not ejecting shells for this weapon.
MuzzleFlash.CauseMuzzleFlash(FireModeNum);
}
}
else
{
if( LeftMuzzleFlash != None )
{
// Not ejecting shells for this weapon.
LeftMuzzleFlash.CauseMuzzleFlash(FireModeNum);
}
}
}
/**
* Remove/Detach the muzzle flash components
*/
simulated function DetachMuzzleFlash()
{
super.DetachMuzzleFlash();
if (MySkelMesh != none && LeftMuzzleFlash != None)
{
LeftMuzzleFlash.DetachMuzzleFlash(MySkelMesh);
LeftMuzzleFlash = None;
}
}
/**
* Adjust the FOV for the first person weapon and arms.
*/
simulated event SetFOV( float NewFOV )
{
super.SetFOV( NewFOV );
if( LeftMuzzleFlash != none )
{
LeftMuzzleFlash.SetFOV( NewFOV );
}
}
simulated function StopFireEffects(byte FireModeNum)
{
super.StopFireEffects( FireModeNum );
if (LeftMuzzleFlash != None)
{
LeftMuzzleFlash.StopMuzzleFlash();
}
}
/** Returns true if weapon can potentially be reloaded */
simulated function bool CanReload(optional byte FireModeNum)
{
if ( FiringStatesArray[RELOAD_FIREMODE] == 'WeaponUpkeep' )
{
return true;
}
if ( FireModeNum == CUSTOM_FIREMODE)
{
FireModeNum = DEFAULT_FIREMODE;
}
return Super.CanReload(FireModeNum);
}
simulated function name GetReloadAnimName( bool bTacticalReload )
{
return ReloadAnimation;
}
/** No diferent states */
simulated function EReloadStatus GetNextReloadStatus(optional byte FireModeNum)
{
switch ( ReloadStatus )
{
case RS_None: //drop
case RS_Reloading:
if ( HasSpareAmmo(FiremodeNum) && ReloadAmountLeft > 0 )
{
return RS_Reloading;
}
}
return RS_Complete;
}
/** Returns an anim rate scale for reloading */
simulated function float GetReloadRateScale()
{
local float Modifier;
Modifier = UseTacticalReload() ? ReloadAnimRateModifierElite : ReloadAnimRateModifier;
return super.GetReloadRateScale() * Modifier;
}
simulated function bool HasAnyAmmo()
{
return AmmoCount[0] != 0 && SpareAmmoCount[0] != 0;
}
defaultproperties
{
// Content
PackageKey="HRG_BlastBrawlers"
FirstPersonMeshName="WEP_1P_HRG_BlastBrawlers_MESH.WEP_1stP_HRG_Blast_Brawlers_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_HRG_BlastBrawlers_ANIM.WEP_1P_HRG_BlastBrawlers_ANIM"
PickupMeshName="WEP_3P_HRG_BlastBrawlers_MESH.Wep_HRG_Blast_Brawlers_Pickup"
AttachmentArchetypeName="WEP_HRG_BlastBrawlers_ARCH.Wep_HRG_BlastBrawlers_3P"
MuzzleFlashTemplateName="WEP_HRG_BlastBrawlers_ARCH.Wep_HRG_BlastBrawler_MuzzleFlash"
Begin Object Class=KFMeleeHelperWeaponBlastBrawlers Name=MeleeHelper_0
MaxHitRange=230 //150 //190
// Override automatic hitbox creation (advanced)
HitboxChain.Add((BoneOffset=(Y=+3,Z=150)))
HitboxChain.Add((BoneOffset=(Y=-3,Z=130)))
HitboxChain.Add((BoneOffset=(Y=+3,Z=110)))
HitboxChain.Add((BoneOffset=(Y=-3,Z=90)))
HitboxChain.Add((BoneOffset=(Y=+3,Z=70)))
HitboxChain.Add((BoneOffset=(Y=-3,Z=50)))
HitboxChain.Add((BoneOffset=(Y=+3,Z=30)))
HitboxChain.Add((BoneOffset=(Z=10)))
HitboxChain.Add((BoneOffset=(Z=-10)))
WorldImpactEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Blunted_melee_impact'
// modified combo sequences
bAllowMeleeToFracture=false
bUseDirectionalMelee=true
bHasChainAttacks=false
MeleeImpactCamShakeScale=0.035f //0.4
ChainSequence_F=()
ChainSequence_B=()
ChainSequence_L=()
ChainSequence_R=()
End Object
MeleeAttackHelper=MeleeHelper_0
// FOV
//MeshFOV=95
// Shotgun Ammo
MagazineCapacity[0]=4 //3
SpareAmmoCapacity[0]=36 //28
InitialSpareMags[0]=2
AmmoPickupScale[0]=1.5 //2.0
bCanBeReloaded=true
bReloadFromMagazine=true
bNoMagazine=false
// Zooming/Position
PlayerViewOffset=(X=20,Y=0,Z=0)
// Inventory
GroupPriority=110
InventorySize=9 //7
WeaponSelectTexture=Texture2D'WEP_UI_HRG_BlastBrawlers_TEX.UI_WeaponSelect_HRG_BlastBrawlers'
FireModeIconPaths(CUSTOM_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
FiringStatesArray(CUSTOM_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(CUSTOM_FIREMODE)=EWFT_Projectile
WeaponProjectiles(CUSTOM_FIREMODE)=class'KFProj_Bullet_BlastBrawlers'
FireInterval(CUSTOM_FIREMODE)=0.1f
InstantHitDamageTypes(CUSTOM_FIREMODE)=class'KFDT_Ballistic_BlastBrawlersShotgun'
InstantHitDamage(CUSTOM_FIREMODE)=36.0 //30.0
AmmoCost(CUSTOM_FIREMODE)=0
NumPellets(CUSTOM_FIREMODE)=5
Spread(CUSTOM_FIREMODE)=0.1 //0.15
WeaponFireSnd(CUSTOM_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_BlastBrawlers.Play_WEP_HRG_BlastBrawlers_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_BlastBrawlers.Play_WEP_HRG_BlastBrawlers_Shoot_1P')
InstantHitMomentum(CUSTOM_FIREMODE)=1.0
PenetrationDamageReductionCurve(CUSTOM_FIREMODE)=(Points=((InVal=0.f,OutVal=0.f),(InVal=1.f, OutVal=1.f)))
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
InstantHitDamage(DEFAULT_FIREMODE)=50
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlers'
FireModeIconPaths(HEAVY_ATK_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BluntMelee'
InstantHitDamage(HEAVY_ATK_FIREMODE)=200 //175
InstantHitDamageTypes(HEAVY_ATK_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlersHeavy'
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_BlastBrawlersBash'
InstantHitDamage(BASH_FIREMODE)=100
FiringStatesArray(RELOAD_FIREMODE)=Reloading
AssociatedPerkClasses(0)=class'KFPerk_Support'
// Block Sounds
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Crovel'
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
ParryStrength=5
ParryDamageMitigationPercent=0.40
BlockDamageMitigation=0.40
bWaitingForSecondShot = false
NumAttacks = 0
bAllowClientAmmoTracking=false
ReloadAnimation = "Atk_B"
ReloadAnimRateModifier = 1.6f
ReloadAnimRateModifierElite = 1.0f; //0.5f;
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Damage1, Scale=1.125f), (Stat=EWUS_Damage2, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
}

View File

@ -42,7 +42,7 @@ simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optio
defaultproperties defaultproperties
{ {
//Healing //Healing
HealAmount=20 HealAmount=25 //20
HealFullRechargeSeconds=10 HealFullRechargeSeconds=10
// Inventory / Grouping // Inventory / Grouping
@ -84,7 +84,7 @@ defaultproperties
// Ammo // Ammo
MagazineCapacity[0]=7 MagazineCapacity[0]=7
SpareAmmoCapacity[0]=98 SpareAmmoCapacity[0]=112 //98
InitialSpareMags[0]=4 InitialSpareMags[0]=4
bCanBeReloaded=true bCanBeReloaded=true
bReloadFromMagazine=true bReloadFromMagazine=true
@ -119,7 +119,7 @@ defaultproperties
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Hemogoblin' WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_Hemogoblin'
InstantHitDamage(DEFAULT_FIREMODE)=100.0 InstantHitDamage(DEFAULT_FIREMODE)=120.0 //100.0
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Hemogoblin' InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Hemogoblin'
FireInterval(DEFAULT_FIREMODE)=0.25 FireInterval(DEFAULT_FIREMODE)=0.25
PenetrationPower(DEFAULT_FIREMODE)=0.0 //2.0 PenetrationPower(DEFAULT_FIREMODE)=0.0 //2.0

View File

@ -0,0 +1,324 @@
//=============================================================================
// KFWeap_RocketLauncher_ThermiteBore
//=============================================================================
// Impale, burn, repeat
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_RocketLauncher_ThermiteBore extends KFWeap_GrenadeLauncher_Base;
/** List of spawned harpoons (will be detonated oldest to youngest) */
var array<KFProj_Rocket_ThermiteBore> DeployedHarpoons;
/** Same as DeployedHarpoons.Length, but replicated because harpoons are only tracked on server */
var int NumDeployedHarpoons;
/** Reduction for the amount of damage dealt to the weapon owner (including damage by the explosion) */
var float SelfDamageReductionValue;
var(Animations) const editconst name DetonateAnim;
var(Animations) const editconst name DetonateAnimLast;
var(Animations) const editconst name DetonateAnimIron;
var(Animations) const editconst name DetonateAnimIronLast;
replication
{
if( bNetDirty )
NumDeployedHarpoons;
}
/**
* Toggle between DEFAULT and ALTFIRE
*/
simulated function AltFireMode()
{
// skip super
if (!Instigator.IsLocallyControlled())
{
return;
}
StartFire(ALTFIRE_FIREMODE);
}
/** Overridded to add spawned charge to list of spawned charges */
simulated function Projectile ProjectileFire()
{
local Projectile P;
local KFProj_Rocket_ThermiteBore Harpoon;
P = super.ProjectileFire();
Harpoon = KFProj_Rocket_ThermiteBore(P);
if (Harpoon != none)
{
DeployedHarpoons.AddItem(Harpoon);
NumDeployedHarpoons = DeployedHarpoons.Length;
bForceNetUpdate = true;
}
return P;
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName(bool bTacticalReload)
{
// magazine relaod
if (AmmoCount[0] > 0)
{
return (bTacticalReload) ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim;
}
else
{
return (bTacticalReload) ? ReloadEmptyMagEliteAnim : ReloadEmptyMagAnim;
}
}
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
{
super.AdjustDamage(InDamage, DamageType, DamageCauser);
if (Instigator != none && DamageCauser != none && DamageCauser.Instigator == Instigator)
{
InDamage *= SelfDamageReductionValue;
}
}
/*********************************************************************************************
* State WeaponDetonating
* The weapon is in this state while detonating a charge
*********************************************************************************************/
simulated function GotoActiveState();
simulated state WeaponDetonating
{
ignores AllowSprinting;
simulated event BeginState( name PreviousStateName )
{
PrepareAndDetonate();
}
simulated function GotoActiveState()
{
GotoState('Active');
}
}
// GrenadeLaunchers determine ShouldPlayFireLast based on the spare ammo
// overriding to use the base KFWeapon version since that uses the current ammo in the mag
simulated function bool ShouldPlayFireLast(byte FireModeNum)
{
return Super(KFWeapon).ShouldPlayFireLast(FireModeNum);
}
simulated function PrepareAndDetonate()
{
local name SelectedAnim;
local float AnimDuration;
local bool bInSprintState;
// choose the detonate animation based on whether it is in ironsights and whether it is the last harpoon
if (bUsingSights)
{
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? DetonateAnimIronLast : DetonateAnimIron;
}
else
{
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? DetonateAnimLast : DetonateAnim;
}
AnimDuration = MySkelMesh.GetAnimLength(SelectedAnim);
bInSprintState = IsInState('WeaponSprinting');
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if (bInSprintState)
{
AnimDuration *= 0.25f;
PlayAnimation(SelectedAnim, AnimDuration);
}
else
{
PlayAnimation(SelectedAnim);
}
}
if (Role == ROLE_Authority)
{
Detonate();
}
//AnimDuration value here representes the ALTFIRE FireInterval
AnimDuration = 0.75f; //1.f;
if (bInSprintState)
{
SetTimer(AnimDuration * 0.8f, false, nameof(PlaySprintStart));
}
else
{
SetTimer(AnimDuration * 0.5f, false, nameof(GotoActiveState));
}
}
/** Detonates all the harpoons */
simulated function Detonate()
{
local int i;
// auto switch weapon when out of ammo and after detonating the last deployed charge
if (Role == ROLE_Authority)
{
for (i = DeployedHarpoons.Length - 1; i >= 0; i--)
{
DeployedHarpoons[i].Detonate();
}
if (!HasAnyAmmo() && NumDeployedHarpoons == 0)
{
if (CanSwitchWeapons())
{
Instigator.Controller.ClientSwitchToBestWeapon(false);
}
}
}
}
/** Removes a charge from the list using either an index or an actor and updates NumDeployedHarpoons */
function RemoveDeployedHarpoon(optional int HarpoonIndex = INDEX_NONE, optional Actor HarpoonActor)
{
if (HarpoonIndex == INDEX_NONE)
{
if (HarpoonActor != none)
{
HarpoonIndex = DeployedHarpoons.Find(HarpoonActor);
}
}
if (HarpoonIndex != INDEX_NONE)
{
DeployedHarpoons.Remove(HarpoonIndex, 1);
NumDeployedHarpoons = DeployedHarpoons.Length;
bForceNetUpdate = true;
}
}
/** Allow reloads for primary weapon to be interupted by firing secondary weapon. */
simulated function bool CanOverrideMagReload(byte FireModeNum)
{
if(FireModeNum == ALTFIRE_FIREMODE)
{
return true;
}
return Super.CanOverrideMagReload(FireModeNum);
}
defaultproperties
{
// Content
PackageKey="Thermite"
FirstPersonMeshName="wep_1p_thermite_mesh.WEP_1stP_Thermite_Rig"
FirstPersonAnimSetNames(0)="wep_1p_thermite_anim.WEP_1stP_Thermite_Anim"
PickupMeshName="WEP_3P_Thermite_MESH.WEP_Thermite_Pickup" //@TODO: Replace me
AttachmentArchetypeName="wep_thermite_arch.Wep_Thermite_3P"
MuzzleFlashTemplateName="wep_thermite_arch.Wep_Thermite_MuzzleFlash" //@TODO: Replace me
// Inventory / Grouping
InventorySize=7
GroupPriority=100
WeaponSelectTexture=Texture2D'WEP_UI_Thermite_TEX.UI_WeaponSelect_Thermite'
AssociatedPerkClasses(0)=class'KFPerk_Firebug'
// FOV
MeshFOV=75
MeshIronSightFOV=40
PlayerIronSightFOV=65
// Depth of field
DOF_FG_FocalRadius=50
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=6
SpareAmmoCapacity[0]=36 //42
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
// Zooming/Position
PlayerViewOffset=(X=11.0,Y=8,Z=-2)
IronSightPosition=(X=10,Y=0,Z=0)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=500
minRecoilPitch=400
maxRecoilYaw=150
minRecoilYaw=-150
RecoilRate=0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=1250
RecoilMinPitchLimit=64785
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=500
RecoilISMinPitchLimit=65485
RecoilViewRotationScale=0.6
IronSightMeshFOVCompensationScale=1.5
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Rocket_ThermiteBore'
InstantHitDamage(DEFAULT_FIREMODE)=150
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_ThermiteBoreImpact'
FireInterval(DEFAULT_FIREMODE)=0.8 //100 RPM
Spread(DEFAULT_FIREMODE)=0
PenetrationPower(DEFAULT_FIREMODE)=0
FireOffset=(X=25,Y=3.0,Z=-2.5)
// ALTFIRE_FIREMODE (remote detonate)
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponDetonating
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
AmmoCost(ALTFIRE_FIREMODE)=0
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_ThermiteBore'
InstantHitDamage(BASH_FIREMODE)=26
// Custom animations
FireSightedAnims=(Shoot_Iron)
BonesToLockOnEmpty=(RW_Exhaust, RW_BoltAssembly1, RW_BoltAssembly2, RW_BoltAssembly3)
bHasFireLastAnims=true
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Thermite_Shoot_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Thermite.Play_WEP_Thermite_Dry_Fire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.125f), (Stat=EWUS_Weight, Add=1)))
SelfDamageReductionValue=0.05f //0.25f
DetonateAnim=Alt_Fire
DetonateAnimLast=Alt_Fire_Last
DetonateAnimIron=Alt_Fire_Iron
DetonateAnimIronLast=Alt_Fire_Iron_Last
}

View File

@ -348,7 +348,7 @@ cpptext
defaultproperties defaultproperties
{ {
// as of February 2021 // as of May 2021
ConsumablesCount=80 ConsumablesCount=80
DurablesCount=60 DurablesCount=66
} }