1
0
This commit is contained in:
GenZmeY 2023-05-11 18:55:04 +03:00
parent 688183c1f1
commit d0b2d125ff
108 changed files with 6906 additions and 307 deletions

View File

@ -2609,7 +2609,8 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
local float ColRadius, ColHeight;
@ -2636,9 +2637,13 @@ simulated function TakeRadiusDamage
if (DamageScale > 0.f)
{
`if(`__TW_)
if (bAdjustRadiusDamage)
{
AdjustRadiusDamage(BaseDamage, DamageScale, HurtOrigin);
}
`endif
ScaledDamage = DamageScale * BaseDamage;
TakeDamage
(
ScaledDamage,

View File

@ -84,8 +84,10 @@ simulated native function TakeRadiusDamage
vector HurtOrigin, /* The origin of the damage */
bool bFullDamage, /* Whether or not to apply full damage or attenuated damage */
Actor DamageCauser, /* The actor which caused the damage */
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
);
function OnSetMaterial(SeqAct_SetMaterial Action)
{
StaticDestructibleComponent.SetMaterial( Action.MaterialIndex, Action.NewMaterial );

View File

@ -295,7 +295,8 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
local int Idx;

View File

@ -165,7 +165,8 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
local int Idx;

View File

@ -136,7 +136,8 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
if ( bDamageAppliesImpulse && damageType.default.RadialDamageImpulse > 0 && (Role == ROLE_Authority) )

View File

@ -351,7 +351,8 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
local vector HitLocation, Dir, NewDir;

View File

@ -220,12 +220,13 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
if ( Role == ROLE_Authority )
{
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent);
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent, bAdjustRadiusDamage);
if (Health > 0)
{

View File

@ -30,6 +30,11 @@ var transient Actor ActorToIgnoreForDamage;
/** If set, ignore instigator when doing damage/effects. Can be set in addition to above */
var transient bool bIgnoreInstigator;
var bool bAlwaysFullDamage;
// If we refine the search so we don't include Victim's that are outside the "height" of instigator
var bool bDoCylinderCheck;
`if(`__TW_)
/** The actor class to ignore for damage from this explosion **/
var() class<Actor> ActorClassToIgnoreForDamage<AllowAbstract>;
@ -195,4 +200,7 @@ defaultproperties
CamShakeFalloff=2.f
bAutoControllerVibration=true
bAlwaysFullDamage = false
bDoCylinderCheck = false
}

View File

@ -188,8 +188,8 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau
local Actor Victim, HitActor;
local vector HitL, HitN, Dir, BBoxCenter;//, BBoxExtent;
`endif
local bool bDamageBlocked, bDoFullDamage, bCauseFractureEffects, bCausePawnEffects, bCauseDamageEffects, bHurtSomeone;
local float ColRadius, ColHeight, CheckRadius, VictimDist;
local bool bDamageBlocked, bDoFullDamage, bCauseFractureEffects, bCausePawnEffects, bCauseDamageEffects, bHurtSomeone, bAdjustRadiusDamage;
local float ColRadius, ColHeight, CheckRadius, VictimDist, VictimColRadius, VictimColHeight;
local array<Actor> VictimsList;
local Box BBox;
local Controller ModInstigator;
@ -200,6 +200,8 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau
local KActorFromStatic NewKActor;
local StaticMeshComponent HitStaticMesh;
bAdjustRadiusDamage = true;
// can pre-calculate this condition now
bCauseFractureEffects = bCauseEffects && WorldInfo.NetMode != NM_DedicatedServer && ExplosionTemplate.bCausesFracture;
bCauseEffects = bCauseEffects && WorldInfo.NetMode != NM_Client;
@ -256,6 +258,18 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau
VictimDist = VSize(Location - Victim.Location);
}
if (ExplosionTemplate.bDoCylinderCheck)
{
Victim.GetBoundingCylinder(ColRadius, ColHeight);
Instigator.GetBoundingCylinder(VictimColRadius, VictimColHeight);
// If the distance between them is more than the size of half the height of both cilinders, don't consider as target
if (Abs(Victim.Location.Z - Instigator.Location.Z) >= (ColHeight * 0.5f) + (VictimColHeight * 0.5f))
{
continue;
}
}
// Do fracturing
if( bCauseFractureEffects && (VictimPawn == None) )
{
@ -295,6 +309,12 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau
bDoFullDamage = FALSE;
}
if (ExplosionTemplate.bAlwaysFullDamage)
{
bAdjustRadiusDamage = false;
bDoFullDamage = true;
}
if ( !bDamageBlocked )
{
if ( bCauseDamageEffects )
@ -309,9 +329,9 @@ protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCau
}
`if(`__TW_)
Victim.TakeRadiusDamage(ModInstigator, GetDamageFor(Victim), ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, bDoFullDamage, (Owner != None) ? Owner : self, ExplosionTemplate.DamageFalloffExponent);
Victim.TakeRadiusDamage(ModInstigator, GetDamageFor(Victim), ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, bDoFullDamage, (Owner != None) ? Owner : self, ExplosionTemplate.DamageFalloffExponent, bAdjustRadiusDamage);
`else
Victim.TakeRadiusDamage(ModInstigator, ExplosionTemplate.Damage, ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, bDoFullDamage, (Owner != None) ? Owner : self, ExplosionTemplate.DamageFalloffExponent);
Victim.TakeRadiusDamage(ModInstigator, ExplosionTemplate.Damage, ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, bDoFullDamage, (Owner != None) ? Owner : self, ExplosionTemplate.DamageFalloffExponent, bAdjustRadiusDamage);
`endif
VictimsList[VictimsList.Length] = Victim;

View File

@ -160,10 +160,19 @@ function NotifyMeleeDamageDealt()
function NotifyTakeHit( Controller InstigatedBy, vector HitLocation, int Damage, class<DamageType> damageType, vector Momentum )
{
local class<KFDamageType> KFDT;
super.NotifyTakeHit( InstigatedBy, HitLocation, Damage, damageType, Momentum );
if( RagePlugin != none && InstigatedBy != self )
{
KFDT = class<KFDamageType>(DamageType);
if (KFDT != none && KFDT.default.bCanEnrage == false)
{
return;
}
RagePlugin.AccumulatedDOT += Damage;
}
}

View File

@ -226,6 +226,8 @@ static function string ZedTypeToString(EAIType AiTypeToConvert)
return "FleshpoundMini";
case AT_Bloat:
return "Bloat";
case AT_EliteCrawler:
return "CrawlerKing";
case AT_Siren:
return "Siren";
case AT_Husk:

View File

@ -264,19 +264,19 @@ protected function ProcessSpecialMoveAfflictions(KFPerk InstigatorPerk, vector H
}
if (StunPower > 0 && CanDoSpecialmove(SM_Stunned))
{
AccrueAffliction(AF_Stun, StunPower, BodyPart, InstigatorPerk);
AccrueAffliction(AF_Stun, StunPower, BodyPart, InstigatorPerk, DamageType);
}
if (StumblePower > 0 && CanDoSpecialmove(SM_Stumble))
{
AccrueAffliction(AF_Stumble, StumblePower, BodyPart, InstigatorPerk);
AccrueAffliction(AF_Stumble, StumblePower, BodyPart, InstigatorPerk, DamageType);
}
if (FreezePower > 0 && CanDoSpecialMove(SM_Frozen))
{
AccrueAffliction(AF_Freeze, FreezePower, BodyPart, InstigatorPerk);
AccrueAffliction(AF_Freeze, FreezePower, BodyPart, InstigatorPerk, DamageType);
}
if (SnarePower > 0)
{
AccrueAffliction(AF_Snare, SnarePower, BodyPart, InstigatorPerk);
AccrueAffliction(AF_Snare, SnarePower, BodyPart, InstigatorPerk, DamageType);
}
}
@ -325,17 +325,17 @@ protected function ProcessHitReactionAfflictions(KFPerk InstigatorPerk, class<KF
// Check hard hit reaction
if (MeleeHitPower > 0)
{
AccrueAffliction(AF_MeleeHit, MeleeHitPower * ReactionModifier, BodyPart, InstigatorPerk);
AccrueAffliction(AF_MeleeHit, MeleeHitPower * ReactionModifier, BodyPart, InstigatorPerk, DamageType);
}
// Force recovery time for the headless hit. GetTimerCount() is a dirty way to do this only on the frame of CauseHeadTrauma()
if (HitZoneIdx == HZI_Head && IsHeadless() && GetTimerCount('BleedOutTimer', Outer) == 0.f)
{
AccrueAffliction(AF_MeleeHit, 100.f, BodyPart, InstigatorPerk);
AccrueAffliction(AF_MeleeHit, 100.f, BodyPart, InstigatorPerk, DamageType);
}
// Check medium hit reaction
if (GunHitPower > 0)
{
AccrueAffliction(AF_GunHit, GunHitPower * ReactionModifier, BodyPart, InstigatorPerk);
AccrueAffliction(AF_GunHit, GunHitPower * ReactionModifier, BodyPart, InstigatorPerk, DamageType);
}
}
}
@ -389,18 +389,18 @@ protected function ProcessEffectBasedAfflictions(KFPerk InstigatorPerk, class<KF
// so we can do the burn effects
if (BurnPower > 0)
{
AccrueAffliction(AF_FirePanic, BurnPower);
AccrueAffliction(AF_FirePanic, BurnPower, , InstigatorPerk, DamageType);
}
}
else
{
if (EMPPower > 0)
{
AccrueAffliction(AF_EMP, EMPPower);
AccrueAffliction(AF_EMP, EMPPower, , InstigatorPerk, DamageType);
}
else if (InstigatorPerk != none && InstigatorPerk.ShouldGetDaZeD(DamageType))
{
AccrueAffliction(AF_EMP, InstigatorPerk.GetDaZedEMPPower());
AccrueAffliction(AF_EMP, InstigatorPerk.GetDaZedEMPPower(), , InstigatorPerk, DamageType);
}
if (BurnPower > 0)
@ -409,7 +409,7 @@ protected function ProcessEffectBasedAfflictions(KFPerk InstigatorPerk, class<KF
}
if (PoisonPower > 0 || DamageType.static.AlwaysPoisons())
{
AccrueAffliction(AF_Poison, PoisonPower);
AccrueAffliction(AF_Poison, PoisonPower, , InstigatorPerk, DamageType);
}
if (MicrowavePower > 0)
{
@ -417,15 +417,15 @@ protected function ProcessEffectBasedAfflictions(KFPerk InstigatorPerk, class<KF
}
if (BleedPower > 0)
{
AccrueAffliction(AF_Bleed, BleedPower);
AccrueAffliction(AF_Bleed, BleedPower, , InstigatorPerk, DamageType);
}
if (BigHeadPower > 0)
{
AccrueAffliction(AF_BigHead, BigHeadPower);
AccrueAffliction(AF_BigHead, BigHeadPower, , InstigatorPerk, DamageType);
}
if (ShrinkPower > 0)
{
AccrueAffliction(AF_Shrink, ShrinkPower,,InstigatorPerk);
AccrueAffliction(AF_Shrink, ShrinkPower,,InstigatorPerk, DamageType);
}
}
}
@ -440,6 +440,10 @@ protected function ProcessEffectBasedAfflictions(KFPerk InstigatorPerk, class<KF
*/
function AccrueAffliction(EAfflictionType Type, float InPower, optional EHitZoneBodyPart BodyPart, optional KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
{
local bool bCanApplyRadial;
bCanApplyRadial = true;
if ( InPower <= 0 || Type >= IncapSettings.Length )
{
return; // immune
@ -450,8 +454,13 @@ function AccrueAffliction(EAfflictionType Type, float InPower, optional EHitZone
return; // cannot create instance
}
if (DamageType != none && DamageType.default.bCanApplyRadialCalculationtoAffliction == false)
{
bCanApplyRadial = false;
}
// for radius damage apply falloff using most recent HitFxInfo
if ( HitFxInfo.bRadialDamage && HitFxRadialInfo.RadiusDamageScale != 255 )
if (bCanApplyRadial && HitFxInfo.bRadialDamage && HitFxRadialInfo.RadiusDamageScale != 255)
{
InPower *= ByteToFloat(HitFxRadialInfo.RadiusDamageScale);
`log(Type@"Applied damage falloff modifier of"@ByteToFloat(HitFxRadialInfo.RadiusDamageScale), bDebugLog);

View File

@ -25,12 +25,12 @@ defaultproperties
DoT_Interval=0.5
DoT_DamageScale=0.5
BleedPower = 20
PoisonPower = 25
BleedPower = 15
PoisonPower = 20
ModifierPerkList(0)=class'KFPerk_Survivalist'
WeaponDef=class'KFWeapDef_HRG_Locust'
SpreadOnTouchDamage=30
SpreadOnTouchDamage=25
}

View File

@ -0,0 +1,31 @@
//=============================================================================
// KFDT_WeeklyContamination
//=============================================================================
// Killing Floor 2
// Copyright (C) 2022 Tripwire Interactive LLC
//=============================================================================
class KFDT_WeeklyContamination extends KFDT_Bleeding
abstract
hidedropdown;
var int Damage;
static function int GetDamage()
{
return default.Damage;
}
defaultproperties
{
// CameraLensEffectTemplate=class'KFCameraLensEmit_Puke'
DoT_Type=DOT_Bleeding
DoT_Duration=3.0
DoT_Interval=0.5
DoT_DamageScale=0.5
BleedPower = 2
PoisonPower = 0
Damage=7
}

View File

@ -239,6 +239,15 @@ var bool bIsTrapDamage;
//When doing armour piercing damage (this is a % of total damage received, the rest is considered as base if defined)
var float DamageModifierAP;
// If killing with this damage type can trigger zed time
var bool bCanZedTime;
// If damaging with this can trigger rage
var bool bCanEnrage;
// If applies radial impulse an it affect the affliction power as well?
var bool bCanApplyRadialCalculationtoAffliction;
/**
* Take the primary HitDirection and modify it to add more spread.
* Use the BloodSpread property to calculate the spread amount
@ -459,4 +468,9 @@ Defaultproperties
DamageModifierAP=0.f
bCanPlayDeadHitEffects=true
bCanZedTime=true
bCanEnrage=true
bCanApplyRadialCalculationtoAffliction=true
}

View File

@ -646,11 +646,12 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
bIsRadiusDamage = true;
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent);
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent, bAdjustRadiusDamage);
bIsRadiusDamage = false;
}

View File

@ -147,10 +147,11 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, true, DamageCauser, DamageFalloffExponent);
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, true, DamageCauser, DamageFalloffExponent, bAdjustRadiusDamage);
}
defaultproperties

View File

@ -0,0 +1,27 @@
class KFGFXSpecialEventObjectivesContainer_Summer2023 extends KFGFxSpecialEventObjectivesContainer;
function Initialize(KFGFxObject_Menu NewParentMenu)
{
super.Initialize(NewParentMenu);
}
DefaultProperties
{
ObjectiveIconURLs[0] = "Summer2023_UI.UI_Objetives_Summer2023_TheBoomestofBuddies" // Kill 1500 Zeds with HRG Bombardier
ObjectiveIconURLs[1] = "Xmas2022_UI.Black_Weekly" // Complete the Weekly on Subduction
ObjectiveIconURLs[2] = "Summer2023_UI.UI_Objectives_Summer2023_ClassicWaterShockCombo" // Stun 2500 Zeds with EMP affliction
ObjectiveIconURLs[3] = "Summer2023_UI.UI_Objectives_Summer2023_DeepWaterareNotStill" // Complete 25 Stand your Ground objectives
ObjectiveIconURLs[4] = "Summer2023_UI.UI_Objectives_Summer2023_SomewhereBeyondtheZ" // Complete wave 15 on Endless Hard or higher difficulty on Subduction
//defaults
AllCompleteRewardIconURL="CHR_CosmeticSet39_Item_TEX.sharkjaw.sharkjaw_precious"
ChanceDropIconURLs[0]="CHR_CosmeticSet_SS_01_ItemTex.Sideshow_Prize_Ticket"
ChanceDropIconURLs[1]="CHR_CosmeticSet_SS_01_ItemTex.SideshowGoldenTicket_Small"
IconURL="Summer2023_UI.KF2_Summer_2023_DeepBlueZ"
UsesProgressList[0] = true
UsesProgressList[1] = false
UsesProgressList[2] = true
UsesProgressList[3] = true
UsesProgressList[4] = false
}

View File

@ -20,6 +20,7 @@ var config array<string> CombatBindList;
var config array<string> WeaponSelectBindList;
var config array<string> InteractionBindList;
var config array<string> VoiceCommBindList;
var config array<string> OtherBindList;
var KeyBind PendingKeyBind;
var KeyBind OldKeyBind;
@ -37,7 +38,7 @@ var bool bModAlt;
var bool bWaitForInput;
var const string SectionName;
const MAX_SECTIONS = 5;
const MAX_SECTIONS = 6;
var byte TotalBindSections;
var localized array<string> SectionHeaders;
@ -70,6 +71,7 @@ function Initialize( KFGFxObject_Menu NewParentMenu )
InitalizeCommandList(CombatBindList);
InitalizeCommandList(WeaponSelectBindList);
InitalizeCommandList(VoiceCommBindList);
InitalizeCommandList(OtherBindList);
UpdateAllBindings();
}
@ -106,6 +108,8 @@ function UpdateAllBindings()
UpdateBindList( CombatBindList, 2 );
UpdateBindList( WeaponSelectBindList, 3 );
UpdateBindList( VoiceCommBindList, 4 );
UpdateBindList( OtherBindList, 5);
Manager.UpdateDynamicIgnoreKeys();
}
@ -156,6 +160,7 @@ function SetSectionBindings( int i, GFxObject bindData )
/** Wait for player input to modify the current bind command */
function ChangeBind( string ChangedCommand, byte SelectedSection )
{
`Log("Change BIND Command " $ChangedCommand);
BindCommand = ChangedCommand;
CurrentlySelectedSection = SelectedSection;
bWaitForInput = true;
@ -265,6 +270,8 @@ function SetKeyBind(KeyBind NewKeyBind)
}
else
{
`Log("BIND BindCommand " $BindCommand);
KFInput.BindKey( NewKeyBind, BindCommand, false );
UpdateAllBindings();
}

View File

@ -25,16 +25,88 @@ function InitializeHUD()
function LocalizeContainer()
{
local GFxObject TextObject;
local KFGameReplicationInfo KFGRI;
KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI);
TextObject = CreateObject("Object");
if (CurrentObjectiveInterface != none)
{
TextObject.SetString("failedString", Localize("Objectives", "FailedString", "KFGame"));
TextObject.SetString("objectiveTitle", Localize("Objectives", "ObjectiveTitle", "KFGame"));
if (KFGRI.IsContaminationMode())
{
TextObject.SetBool("HideBonus", true);
TextObject.SetString("objectiveDesc", Localize("Objectives", "ContaminationModeDescriptionShort", "KFGame"));
}
else
{
TextObject.SetString("objectiveDesc", CurrentObjectiveInterface.GetLocalizedShortDescription());
}
}
SetObject("localizedText", TextObject);
}
function ContaminationModeSetPlayerIn(bool PlayerIsIn, bool Pulsate)
{
local GFxObject TextObject;
TextObject = CreateObject("Object");
//if (CurrentObjectiveInterface != none)
//{
TextObject.SetString("failedString", Localize("Objectives", "FailedString", "KFGame"));
TextObject.SetString("objectiveTitle", Localize("Objectives", "ObjectiveTitle", "KFGame"));
TextObject.SetBool("HideBonus", true);
if (PlayerIsIn)
{
TextObject.SetBool("ContaminationModeIn", true);
TextObject.SetString("objectiveDesc", Localize("Objectives", "ContaminationModeDescriptionShortPlayerIn", "KFGame"));
}
else
{
TextObject.SetBool("ContaminationModeOut", true);
if (Pulsate)
{
TextObject.SetString("objectiveDesc", Localize("Objectives", "ContaminationModeDescriptionShortPlayerOut", "KFGame"));
}
else
{
TextObject.SetString("objectiveDesc", "");
}
}
//}
SetObject("localizedText", TextObject);
}
function ContaminationModeTimer(int Timer)
{
local GFxObject TextObject;
TextObject = CreateObject("Object");
//if (CurrentObjectiveInterface != none)
//{
TextObject.SetString("failedString", Localize("Objectives", "FailedString", "KFGame"));
TextObject.SetString("objectiveTitle", Localize("Objectives", "ObjectiveTitle", "KFGame"));
TextObject.SetBool("HideBonus", true);
TextObject.SetString("objectiveDesc", Localize("Objectives", "ContaminationModeDescriptionShort", "KFGame"));
TextObject.SetInt("ContaminationTimer", Timer);
//}
SetObject("localizedText", TextObject);
}
@ -42,6 +114,7 @@ function LocalizeContainer()
simulated function SetActive(bool bActive)
{
SetVisible(bActive);
if (bActive)
{
CurrentObjectiveInterface = KFGameReplicationInfo(GetPC().WorldInfo.GRI).ObjectiveInterface;
@ -72,12 +145,18 @@ simulated function SetActive(bool bActive)
function SetCompleted(bool bComplete)
{
local GFxObject DataObject;
local KFGameReplicationInfo KFGRI;
KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI);
if (KFGRI.IsContaminationMode() == false)
{
DataObject = CreateObject("Object");
DataObject.SetBool("bComplete", bComplete);
DataObject.SetString("completeString", bComplete ? Localize("Objectives", "SuccessString", "KFGame") : "");
SetObject("completeStatus", DataObject);
}
if (!bComplete)
{
@ -119,6 +198,14 @@ function TickHud(float DeltaTime)
local int bStatusWarning, bStatusNotification;
local string StatusMessage;
local GFxObject DataObject;
local KFGameReplicationInfo KFGRI;
KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI);
if (KFGRI.IsContaminationMode())
{
return;
}
if (CurrentObjectiveInterface != none)
{
@ -144,6 +231,7 @@ function TickHud(float DeltaTime)
{
UpdateIcon();
}
SetMissionCritical(CurrentObjectiveInterface.GetIsMissionCritical());
}
}
@ -179,6 +267,11 @@ function SetFailState(bool bFailed)
}
}
function ShowObjectiveUI()
{
SetVisible(true);
}
function ClearObjectiveUI()
{
SetActive(false);
@ -187,6 +280,15 @@ function ClearObjectiveUI()
//pass a value from 0-1
function SetCurrentProgress(float CurrentProgress)
{
local KFGameReplicationInfo KFGRI;
KFGRI=KFGameReplicationInfo(KFPC.WorldInfo.GRI);
if (KFGRI.IsContaminationMode())
{
return;
}
if (LastProgress != CurrentProgress)
{
CurrentProgress = FClamp(CurrentProgress, 0, 1);

View File

@ -242,6 +242,11 @@ function UpdateGlobalDamage()
}
}
function UpdateContaminationModeIconVisible(bool bisVisible)
{
SetBool("ContaminationModeIconVisible", bisVisible);
}
DefaultProperties
{
LastUpdateTime = 0.f;

View File

@ -58,6 +58,10 @@ var localized string RarityFilterString;
var localized string WeaponTypeFilterString;
var localized string PerkFilterString;
var localized string SearchText;
var localized string ClearSearchText;
var int SearchMaxChars;
var GFxObject CraftingSubMenu;
var GFxObject ItemListContainer;
@ -133,7 +137,7 @@ struct InventoryHelper
var int ItemCount;
var ItemType Type;
var GFxObject GfxItemObject;
var string FullName;
// For ordering in weapon skins
var int WeaponDef;
var int Price;
@ -188,6 +192,8 @@ struct ByTypeItemsHelper
var() array<InventoryHelper> ItemsOnType;
};
var ByTypeItemsHelper ByTypeItems[7];
var EInventoryWeaponType_Filter CurrentWeaponTypeFilter;
var int CurrentPerkIndexFilter;
var ItemRarity CurrentRarityFilter;
@ -198,6 +204,8 @@ var ExchangeRuleSets RuleToExchange;
var private int CrcTable[256];
var transient string SearchKeyword;
function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
{
super.InitializeMenu( InManager );
@ -383,7 +391,6 @@ function InitInventory()
local ItemProperties TempItemDetailsHolder;
local GFxObject ItemArray, ItemObject;
local bool bActiveItem;
local ByTypeItemsHelper ByTypeItems[7];
local InventoryHelper HelperItem;
local array<ExchangeRuleSets> ExchangeRules;
local class<KFWeaponDefinition> WeaponDef;
@ -391,6 +398,11 @@ function InitInventory()
local GFxObject PendingItem;
for (i = 0; i < ArrayCount(ByTypeItems); ++i)
{
ByTypeItems[i].ItemsOnType.Length = 0;
}
ItemArray = CreateArray();
if(OnlineSub == none)
@ -424,7 +436,7 @@ function InitInventory()
if (HelperIndex == INDEX_NONE)
{
HelperItem.Type = TempItemDetailsHolder.Type;
//HelperItem.FullName = TempItemDetailsHolder.Name;
HelperItem.FullName = TempItemDetailsHolder.Name;
HelperItem.ItemDefinition = onlineSub.CurrentInventory[i].Definition;
HelperItem.ItemCount = onlineSub.CurrentInventory[i].Quantity;
@ -823,6 +835,12 @@ function InitInventory()
z = 0;
if (SearchKeyword != "")
{
InventorySearch(SearchKeyword);
}
else
{
for (i = 0; i < ArrayCount(ByTypeItems); i++)
{
for (j = 0 ; j < ByTypeItems[i].ItemsOnType.Length; j++)
@ -834,6 +852,7 @@ function InitInventory()
}
SetObject("inventoryList", ItemArray);
}
if(Manager.SelectIDOnOpen != INDEX_NONE )
{
@ -1071,6 +1090,11 @@ function LocalizeText()
LocalizedObject.SetString("filterName_1", PerkFilterString);
LocalizedObject.SetString("filterName_2", WeaponTypeFilterString);
LocalizedObject.SetString("searchTitle", SearchText);
LocalizedObject.SetString("searchText", SearchText$"...");
LocalizedObject.SetBool("bIsConsoleBuild", class'WorldInfo'.static.IsConsoleBuild());
LocalizedObject.SetInt("searchMaxChars", SearchMaxChars);
RarityList = CreateArray();
for (i = 0; i <= ITR_NONE; i++)
@ -1129,6 +1153,7 @@ function LocalizeText()
LocalizedObject.SetObject("filterData_1", PerkList);
LocalizedObject.SetObject("filterData_2", WeaponTypeList);
SetObject("localizedText", LocalizedObject);
}
@ -1398,6 +1423,119 @@ function Callback_RequestInitialnventory()
InitInventory();
}
function Callback_InventorySearch(string searchStr)
{
InventorySearch(searchStr, true);
}
function Callback_Log(string str)
{
`Log("From AS: " $str);
}
function Callback_OpenKeyboard()
{
OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem();
OnlineSub.PlayerInterface.AddKeyboardInputDoneDelegate(KeyboardInputComplete);
OnlineSub.PlayerInterface.ShowKeyboardUI(0, "Search", "Search");
}
function KeyboardInputComplete(bool bWasSuccessful)
{
local byte bWasCancelled;
local string UserInput;
OnlineSub = Class'GameEngine'.static.GetOnlineSubsystem();
UserInput = OnlineSub.PlayerInterface.GetKeyboardInputResults(bWasCancelled);
Callback_InventorySearch(UserInput);
OnlineSub.PlayerInterface.ClearKeyboardInputDoneDelegate(KeyboardInputComplete);
}
function InventorySearch(string searchStr, bool bForceInitIfClear = false)
{
local array<ItemType> ItemTypes;
local int i, j, k, ItemCounter;
local array<InventoryHelper> ItemsOnType;
local GFxObject ItemArray;
local array<string> SearchKeywords;
local bool Accepted;
SearchKeyword = searchStr;
if (searchStr == "")
{
if (bForceInitIfClear)
{
InitInventory();
}
return;
}
SearchKeywords = SplitString( searchStr, " ", true);
ItemCounter = 0;
ItemArray = CreateArray();
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins)
{
ItemTypes.AddItem(ITP_WeaponSkin);
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Cosmetics)
{
ItemTypes.AddItem(ITP_CharacterSkin);
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables)
{
ItemTypes.AddItem(ITP_KeyCrate);
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_CraftingMats)
{
ItemTypes.AddItem(ITP_CraftingComponent);
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Emotes)
{
ItemTypes.AddItem(ITP_Emote);
}
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_SFX)
{
ItemTypes.AddItem(ITP_SFX);
}
for (i = 0; i < ItemTypes.Length; ++i)
{
ItemsOnType = ByTypeItems[ItemTypes[i]].ItemsOnType;
for (j = 0; j < ItemsOnType.Length; ++j)
{
Accepted = true;
for (k = 0; k < SearchKeywords.Length; ++k)
{
if (InStr(Locs(ItemsOnType[j].FullName), Locs(SearchKeywords[k])) == -1)
{
Accepted = false;
break;
}
}
if (Accepted)
{
ItemArray.SetElementObject(ItemCounter, ItemsOnType[j].GfxItemObject);
++ItemCounter;
}
}
}
SetObject("inventoryList", ItemArray);
}
function Callback_InventoryFilter( int FilterIndex )
{
local EINventory_Filter NewFilter;
@ -1809,4 +1947,6 @@ defaultproperties
KeylessCrateIDs(0)=5313
KillThatDangSoundEvent=AkEvent'WW_UI_Menu.Play_UI_Trader_Build_Stop_No_Sound'
SearchMaxChars=128
}

View File

@ -1016,13 +1016,28 @@ simulated function DisplayNewObjective()
ObjectiveObject=CreateObject("Object");
ObjectiveObject.SetString("titleString", class'KFLocalMessage_Priority'.default.ObjectiveStartMessage);
if (KFGRI.IsContaminationMode())
{
ObjectiveObject.SetString("nameString", Localize("Objectives", "ContaminationModeObjective", "KFGame"));
ObjectiveObject.SetString("descString", Localize("Objectives", "ContaminationModeDescription", "KFGame"));
// TODO :: CHANGE ICON
ObjectiveObject.SetString("iconPath", "img://"$PathName(ObjectiveInterface.GetIcon()));
}
else
{
ObjectiveObject.SetString("nameString", ObjectiveInterface.GetLocalizedName());
ObjectiveObject.SetString("descString", ObjectiveInterface.GetLocalizedDescription());
ObjectiveObject.SetString("requireString", ObjectiveInterface.GetLocalizedRequirements());
ObjectiveObject.SetString("rewardNum", string(ObjectiveInterface.GetMaxDoshReward()));
ObjectiveObject.SetString("xpBonus", string(ObjectiveInterface.GetMaxXPReward()));
ObjectiveObject.SetString("voshBonus", string(ObjectiveInterface.GetMaxVoshReward()));
ObjectiveObject.SetString("iconPath", "img://"$PathName(ObjectiveInterface.GetIcon()));
}
ObjectiveObject.SetBool("isBonus", false);
KFGRI.PreviousObjectiveResult=INDEX_NONE;
@ -1190,6 +1205,50 @@ function UpdateVIP(ReplicatedVIPGameInfo VIPInfo, bool bIsVIP)
}
}
function UpdateContaminationMode(bool IsPlayerIn, bool Pulsate)
{
if (KFPC.CanUseContaminationMode())
{
if (WaveInfoWidget.ObjectiveContainer != none)
{
WaveInfoWidget.ObjectiveContainer.ContaminationModeSetPlayerIn(IsPlayerIn, Pulsate);
}
}
}
function UpdateContaminationMode_Timer(int Timer)
{
if (KFPC.CanUseContaminationMode())
{
if (WaveInfoWidget.ObjectiveContainer != none)
{
WaveInfoWidget.ObjectiveContainer.ContaminationModeTimer(Timer);
}
}
}
function ShowContaminationMode()
{
if (KFPC.CanUseContaminationMode())
{
if (WaveInfoWidget.ObjectiveContainer != none)
{
WaveInfoWidget.ObjectiveContainer.ShowObjectiveUI();
}
}
}
function HideContaminationMode()
{
if (KFPC.CanUseContaminationMode())
{
if (WaveInfoWidget.ObjectiveContainer != none)
{
WaveInfoWidget.ObjectiveContainer.ClearObjectiveUI();
}
}
}
function ResetSyringe(float Ammo, float MaxAmmo)
{
if (PlayerStatusContainer != none)

View File

@ -20,7 +20,9 @@ const MapNightmare = 'KF-Nightmare';
const MapPowerCore = 'KF-PowerCore_Holdout';
const MapDescent = 'KF-TheDescent';
const MapKrampus = 'KF-KrampusLair';
const MapSantas = 'KF-SantasWorkshop';
const MapSteam = 'KF-SteamFortress';
const MapElysium = 'KF-Elysium';
//==============================================================
// Initialization
@ -56,6 +58,7 @@ function SetMapOptions()
local bool IsBrokenTrader;
local bool IsBossRush;
local bool IsGunGame;
local bool IsContaminationMode;
local bool bShouldSkipMaps;
local name MapName;
@ -71,6 +74,7 @@ function SetMapOptions()
IsBrokenTrader = KFGRI.CurrentWeeklyIndex == 11;
IsBossRush = KFGRI.CurrentWeeklyIndex == 14;
IsGunGame = KFGRI.CurrentWeeklyIndex == 16;
IsContaminationMode = KFGRI.CurrentWeeklyIndex == 19;
bShouldSkipMaps = IsWeeklyMode && (IsBrokenTrader || IsBossRush || IsGunGame);
@ -80,6 +84,7 @@ function SetMapOptions()
for (i = 0; i < ServerMapList.length; i++)
{
MapName = name(ServerMapList[i]);
if ( bShouldSkipMaps && ( MapName == MapBiolapse ||
MapName == MapNightmare ||
MapName == MapPowerCore ||
@ -89,6 +94,20 @@ function SetMapOptions()
continue;
}
if (IsWeeklyMode && IsContaminationMode)
{
if (MapName == MapBiolapse ||
MapName == MapNightmare ||
MapName == MapPowerCore ||
MapName == MapDescent ||
MapName == MapKrampus ||
MapName == MapElysium ||
MapName == MapSantas)
{
continue;
}
}
/* Temporary removal of SteamFrotress for BossRush */
if (IsWeeklyMode && IsBossRush && MapName == MapSteam)
{

View File

@ -182,7 +182,7 @@ function FillWhatsNew()
local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
WhatsNewItems.AddItem(item);
// Featured Ultimate Edition
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2022_UltimateEdition_Upgrade", "FeaturedItemBundle", "https://store.steampowered.com/app/1914560/KF2__Ultimate_Edition_Upgrade_DLC/");
@ -193,32 +193,29 @@ function FillWhatsNew()
// 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");
WhatsNewItems.AddItem(item);
// Featured Weapon Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_WeaponsBundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9557");
// KF2 Armory Season Pass 2023
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_CosmeticsSeasonPass", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9661");
WhatsNewItems.AddItem(item);
// Featured Weapon
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_ZEDMKIII", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9555");
WhatsNewItems.AddItem(item);
// Featured Weapon
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_HVStormCannon","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9556");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_S12Shockgun", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9655");
WhatsNewItems.AddItem(item);
// Featured Outfit Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_TrainConductorOutfit", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9554");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_HorzineDiver_Uniforms", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9653");
WhatsNewItems.AddItem(item);
// Featured Time Limited Item
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5588");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_SS_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/4928");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Tacticool_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9553");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_Predator_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9651");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Retro_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9552");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_JunkyardMKII_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9646");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Mediaval_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9503");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_JaegerMKIV_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9645");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_ChamaleonIII_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9502");
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer2023_Stingray_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9649");
WhatsNewItems.AddItem(item);
// Misc Community Links
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");

View File

@ -304,6 +304,17 @@ function FilterWeeklyMaps(out array<string> List)
List.RemoveItem("KF-KrampusLair");
}
if (WeeklyIndex == 19)
{
List.RemoveItem("KF-Biolapse");
List.RemoveItem("KF-Nightmare");
List.RemoveItem("KF-PowerCore_Holdout");
List.RemoveItem("KF-TheDescent");
List.RemoveItem("KF-KrampusLair");
List.RemoveItem("KF-SantasWorkshop");
List.RemoveItem("KF-Elysium");
}
/* Temporary removal of SteamFrotress for BossRush */
if (WeeklyIndex == 14)
{

View File

@ -447,25 +447,21 @@ DefaultProperties
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
FeaturedItemIDs[0]=7944 //Whatsnew Gold Ticket
FeaturedItemIDs[1]=9557
FeaturedItemIDs[2]=9556
FeaturedItemIDs[3]=9555
FeaturedItemIDs[4]=9554
FeaturedItemIDs[5]=9502
FeaturedItemIDs[6]=9503
FeaturedItemIDs[7]=9553
FeaturedItemIDs[8]=9552
FeaturedItemIDs[0]=8178 //Whatsnew Gold Ticket
FeaturedItemIDs[1]=9655
FeaturedItemIDs[2]=9646
FeaturedItemIDs[3]=9649
FeaturedItemIDs[4]=9645
FeaturedItemIDs[5]=9653
FeaturedItemIDs[6]=9651
ConsoleFeaturedItemIDs[0]=7947 //Whatsnew Gold Ticket PSN
ConsoleFeaturedItemIDs[1]=9557
ConsoleFeaturedItemIDs[2]=9556
ConsoleFeaturedItemIDs[3]=9555
ConsoleFeaturedItemIDs[4]=9554
ConsoleFeaturedItemIDs[5]=9502
ConsoleFeaturedItemIDs[6]=9503
ConsoleFeaturedItemIDs[7]=9553
ConsoleFeaturedItemIDs[8]=9552
ConsoleFeaturedItemIDs[0]=8181 //Whatsnew Gold Ticket PSN
ConsoleFeaturedItemIDs[1]=9655
ConsoleFeaturedItemIDs[2]=9646
ConsoleFeaturedItemIDs[3]=9649
ConsoleFeaturedItemIDs[4]=9645
ConsoleFeaturedItemIDs[5]=9653
ConsoleFeaturedItemIDs[6]=9651
MaxFeaturedItems=5
}

View File

@ -27,6 +27,8 @@ function LocalizeWidget()
LocalizedObject.SetString("cancel", CancelString);
LocalizedObject.SetString("confirm", ConfirmString);
LocalizedObject.SetString("search", Localize("KFGFxMenu_Inventory", "SearchText", "KFGame"));
LocalizedObject.SetString("clearsearch", Localize("KFGFxMenu_Inventory", "ClearSearchText", "KFGame"));
LocalizedObject.SetString("reset",Localize("KFGFxOptionsMenu_Graphics","DefaultString","KFGame"));
LocalizedObject.SetString("party", Localize("KFGFxWidget_BaseParty", "SquadString", "KFGame"));
LocalizedObject.SetString("config", Localize("KFGFxPerksContainer_SkillsSummary", "ConfigureString", "KFGame"));

View File

@ -48,6 +48,12 @@ function SetLocalizedText()
}
SetObject("textOptions", DataProvider);
TempObj = CreateObject("Object");
TempObj.SetString("text", class'KFLocalMessage_VoiceComms'.default.ToggleFriendlyHUDString);
SetObject("toggleFriendlyText", TempObj);
SetBool("toggleFriendlyVisibility", GetPC().WorldInfo.NetMode != NM_StandAlone);
}
function SaveVoiceCommSelection( int CommsIndex )

View File

@ -450,7 +450,9 @@ const MapNightmare = 'KF-Nightmare';
const MapPowerCore = 'KF-PowerCore_Holdout';
const MapDescent = 'KF-TheDescent';
const MapKrampus = 'KF-KrampusLair';
const MapSantas = 'KF-SantasWorkshop';
const MapSteam = 'KF-SteamFortress';
const MapElysium = 'KF-Elysium';
/************************************************************************************
* @name Native
@ -2795,6 +2797,12 @@ function CheckZedTimeOnKill(Controller Killer, Controller KilledPlayer, Pawn Kil
return;
}
// Skip for certain damage types we want to discard
if (KFDT != none && KFDT.default.bCanZedTime == false)
{
return;
}
// If already in zed time, check for zed time extensions
if ( IsZedTimeActive() )
{
@ -3011,6 +3019,22 @@ function string GetNextMap()
}
}
if (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 19 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[19]) // Contamination
{
MapName = name(GameMapCycles[ActiveMapCycle].Maps[MapCycleIndex]);
if (MapName == MapBiolapse ||
MapName == MapNightmare ||
MapName == MapPowerCore ||
MapName == MapDescent ||
MapName == MapKrampus ||
MapName == MapElysium ||
MapName == MapSantas)
{
continue;
}
}
/* Temporary removal of SteamFrotress for BossRush */
if (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 14 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[14] &&
MapName == MapSteam)

View File

@ -1970,6 +1970,7 @@ function ChooseNextObjective(int NextWaveNum)
return;
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if (KFMI != none && NextWaveNum != WaveMax)
{
if (KFMI.bUsePresetObjectives && NextWaveNum <= GetPresetObjectiveLength(KFMI))
@ -2047,12 +2048,13 @@ function int GetPresetObjectiveLength(KFMapInfo KFMI)
}
}
function bool ChooseNextRandomObjective(KFMapInfo KFMI, int NextWaveNum)
function bool ChooseNextRandomObjective(KFMapInfo KFMI, int NextWaveNum, optional bool bWaveCanDisable = true)
{
local int Idx;
Idx = INDEX_NONE;
//Start a random objective if we have any set
if (KFMI.RandomWaveObjectives.Length > 0 && KFMI.RandomObjectiveWavesToDisable.Find(NextWaveNum) == INDEX_NONE)
if (KFMI.RandomWaveObjectives.Length > 0 && (bWaveCanDisable == false || KFMI.RandomObjectiveWavesToDisable.Find(NextWaveNum) == INDEX_NONE))
{
//Attempt to reset if we've run out
if (KFMI.CurrentAvailableRandomWaveObjectives.Length == 0)
@ -2084,7 +2086,10 @@ function int SetNextObjective(array<KFInterface_MapObjective> PossibleObjectives
if (PossibleObjectives[RandID].CanActivateObjectiveByWeekly())
{
PctChanceToActivate = PossibleObjectives[RandID].GetActivationPctChance();
if (bForceNextObjective || (PossibleObjectives[RandID].CanActivateObjective() && PreviousObjective != PossibleObjectives[RandID] && (PctChanceToActivate >= 1.f || DieRoll <= PctChanceToActivate)))
if (bForceNextObjective || (PossibleObjectives[RandID].CanActivateObjective()
&& PreviousObjective != PossibleObjectives[RandID]
&& (PctChanceToActivate >= 1.f || DieRoll <= PctChanceToActivate)))
{
if (bActivateImmediately)
{
@ -2096,6 +2101,7 @@ function int SetNextObjective(array<KFInterface_MapObjective> PossibleObjectives
NextObjectiveIsEndless = bUseEndlessSpawning;
KFInterface_MapObjective(NextObjective).NotifyObjectiveSelected();
}
return RandID;
}
}
@ -2406,6 +2412,43 @@ simulated function bool IsRandomPerkMode()
return bIsWeeklyMode && CurrentWeeklyIndex == 18;
}
simulated function bool IsContaminationMode()
{
return bIsWeeklyMode && CurrentWeeklyIndex == 19;
}
simulated function int ContaminationModeZedsToFinish()
{
local KFGameInfo KFGI;
if (IsContaminationMode())
{
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none && KFGI.OutbreakEvent != none)
{
return KFGI.OutbreakEvent.ActiveEvent.ContaminationModeZedsToFinish;
}
}
return 0;
}
simulated function int ContaminationModeExtraDosh()
{
local KFGameInfo KFGI;
if (IsContaminationMode())
{
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGI != none && KFGI.OutbreakEvent != none)
{
return KFGI.OutbreakEvent.ActiveEvent.ContaminationModeExtraDosh;
}
}
return 0;
}
defaultproperties
{
TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems"

View File

@ -78,7 +78,7 @@ defaultproperties
ButtonCommands[5]=(Name="XboxTypeS_RightX",Command="GBA_TurnLeft_Gamepad"),
ButtonCommands[6]=(Name="XboxTypeS_RightY",Command="GBA_Look_Gamepad"),
ButtonCommands[7]=(Name="XboxTypeS_RightThumbStick",Command="GBA_TertiaryFire"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_Grenade"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_Grenade | GBA_ToggleFriendlyUIFromHUD"),
ButtonCommands[9]=(Name="XboxTypeS_RightShoulder",Command="GBA_AltFire_Gamepad"),
ButtonCommands[10]=(Name="XboxTypeS_LeftTrigger",Command="GBA_IronsightsHold"),
ButtonCommands[11]=(Name="XboxTypeS_RightTrigger",Command="GBA_Fire")
@ -94,7 +94,7 @@ defaultproperties
ButtonCommands[5]=(Name="XboxTypeS_RightX",Command="GBA_TurnLeft_Gamepad"),
ButtonCommands[6]=(Name="XboxTypeS_RightY",Command="GBA_Look_Gamepad"),
ButtonCommands[7]=(Name="XboxTypeS_RightThumbStick",Command="GBA_Grenade"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_Jump"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_Jump | GBA_ToggleFriendlyUIFromHUD"),
ButtonCommands[9]=(Name="XboxTypeS_RightShoulder",Command="GBA_AltFire_Gamepad"),
ButtonCommands[10]=(Name="XboxTypeS_LeftTrigger",Command="GBA_IronsightsHold"),
ButtonCommands[11]=(Name="XboxTypeS_RightTrigger",Command="GBA_Fire"),
@ -111,7 +111,7 @@ defaultproperties
ButtonCommands[5]=(Name="XboxTypeS_RightX",Command="GBA_TurnLeft_Gamepad"),
ButtonCommands[6]=(Name="XboxTypeS_RightY",Command="GBA_Look_Gamepad"),
ButtonCommands[7]=(Name="XboxTypeS_RightThumbStick",Command="GBA_Grenade"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_WeaponSelect_Gamepad"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_WeaponSelect_Gamepad | GBA_ToggleFriendlyUIFromHUD"),
ButtonCommands[9]=(Name="XboxTypeS_RightShoulder",Command="GBA_AltFire_Gamepad"),
ButtonCommands[10]=(Name="XboxTypeS_LeftTrigger",Command="GBA_IronsightsHold"),
ButtonCommands[11]=(Name="XboxTypeS_RightTrigger",Command="GBA_Fire"),
@ -127,7 +127,7 @@ defaultproperties
ButtonCommands[5]=(Name="XboxTypeS_RightX",Command="GBA_StrafeLeft_Gamepad"),
ButtonCommands[6]=(Name="XboxTypeS_RightY",Command="GBA_MoveForward_GamepadSouthpaw"),
ButtonCommands[7]=(Name="XboxTypeS_RightThumbStick",Command="GBA_SprintAndCrouch"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_AltFire_Gamepad"),
ButtonCommands[8]=(Name="XboxTypeS_LeftShoulder",Command="GBA_AltFire_Gamepad | GBA_ToggleFriendlyUIFromHUD"),
ButtonCommands[9]=(Name="XboxTypeS_RightShoulder",Command="GBA_Grenade"),
ButtonCommands[10]=(Name="XboxTypeS_LeftTrigger",Command="GBA_Fire"),
ButtonCommands[11]=(Name="XboxTypeS_RightTrigger",Command="GBA_IronsightsHold"),

View File

@ -206,7 +206,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
case SEI_Spring:
return class'KFGFxSpecialEventObjectivesContainer_Spring2021';
case SEI_Summer:
return class'KFGFxSpecialEventObjectivesContainer_Summer2022';
return class'KFGFxSpecialEventObjectivesContainer_Summer2023';
case SEI_Fall:
return class'KFGFxSpecialEventObjectivesContainer_Fall2022';
case SEI_Winter:

View File

@ -56,6 +56,7 @@ var float PrestigeIconScale;
********************************************************************************************* */
var config float FriendlyHudScale;
var config bool bFriendlyHUDVisible;
/*********************************************************************************************
DrawGlowText()
@ -240,7 +241,7 @@ function DrawCrosshair()
}
// Skip if weapon is missing spread settings
if ( KFWP.Spread.Length == 0 && !bForceDrawCrosshair )
if ( KFWP.Spread.Length == 0 && !bForceDrawCrosshair && !KFWP.bForceCrosshair)
{
return;
}
@ -280,7 +281,7 @@ function DrawCrosshair()
if( KFWP != none )
{
if( !bForceDrawCrosshair )
if( !bForceDrawCrosshair && !KFWP.bForceCrosshair)
{
WeaponAccuracyAdjust = EvalInterpCurveFloat(CrosshairAccuracyScale, KFWP.GetUpgradedSpread());
// Scale spread based on weapon accuracy
@ -587,8 +588,6 @@ function DrawHUD()
local rotator ViewRotation;
local array<PlayerReplicationInfo> VisibleHumanPlayers;
local array<sHiddenHumanPawnInfo> HiddenHumanPlayers;
local float ThisDot;
local vector TargetLocation;
local Actor LocActor;
// Draw weapon HUD underneath everything else
@ -620,6 +619,8 @@ function DrawHUD()
// Friendly player status
if( PlayerOwner.GetTeamNum() == 0 )
{
if (KFPlayerOwner.bFriendlyUIEnabled)
{
if( KFPlayerOwner != none )
{
@ -672,12 +673,67 @@ function DrawHUD()
// Draw last remaining zeds
CheckAndDrawRemainingZedIcons();
if (KFGRI.IsContaminationMode())
{
// While on trader time we let previsualize the next objective icon, so players can get ready
if (KFGRI.bWaveIsActive == false)
{
if (KFGRI.WaveNum != (KFGRI.WaveMax - 1))
{
CheckDrawContaminationModeObjectiveHUD(ViewLocation, ViewVector);
}
}
else if (KFGRI.ObjectiveInterface != none && KFGRI.ObjectiveInterface.IsActive())
{
//Draw our current objective location
CheckDrawObjectiveHUD(ViewLocation, ViewVector, LocActor);
}
}
else
{
//Draw our current objective location
CheckDrawObjectiveHUD(ViewLocation, ViewVector, LocActor);
}
}
Canvas.EnableStencilTest(false);
}
}
}
function CheckDrawContaminationModeObjectiveHUD(vector ViewLocation, vector ViewVector)
{
local float ThisDot;
local vector TargetLocation;
local KFInterface_MapObjective Objective;
Objective = KFInterface_MapObjective(KFGRI.NextObjective);
if (Objective != none)
{
TargetLocation = Objective.GetIconLocation();
ThisDot = Normal((TargetLocation + (class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 1))) - ViewLocation) dot ViewVector;
if (ThisDot > 0)
{
DrawContaminationModeObjectiveHUD();
}
}
}
function CheckDrawObjectiveHUD(vector ViewLocation, vector ViewVector, Actor LocActor)
{
local float ThisDot;
local vector TargetLocation;
if (KFGRI.CurrentObjective != none && KFGRI.ObjectiveInterface != none)
{
KFGRI.ObjectiveInterface.DrawHUD(self, Canvas);
TargetLocation = KFGRI.ObjectiveInterface.GetIconLocation();
ThisDot = Normal((TargetLocation + (class'KFPawn_Human'.default.CylinderComponent.CollisionHeight * vect(0, 0, 1))) - ViewLocation) dot ViewVector;
if (ThisDot > 0 &&
@ -689,10 +745,6 @@ function DrawHUD()
}
}
Canvas.EnableStencilTest(false);
}
}
simulated function DrawPerkIcons(KFPawn_Human KFPH, float PerkIconSize, float PerkIconPosX, float PerkIconPosY, float SupplyIconPosX, float SupplyIconPosY, bool bDropShadow)
{
local byte PrestigeLevel;
@ -955,6 +1007,37 @@ simulated function color GetHealthStateColor(const out KFPawn_Scripted KFPS)
}
}
simulated function bool DrawContaminationModeObjectiveHUD()
{
local float IconCenteringLength;
local vector ScreenPos, TargetLocation;
local float ResModifier;
local KFInterface_MapObjective Objective;
Objective = KFInterface_MapObjective(KFGRI.NextObjective);
ResModifier = WorldInfo.static.GetResolutionBasedHUDScale() * FriendlyHudScale;
TargetLocation = Objective.GetIconLocation();
ScreenPos = Canvas.Project( TargetLocation );
// if not using the progress bar, center the remaining icon
IconCenteringLength = PlayerStatusIconSize * ResModifier * 0.5;
if (Objective.GetIcon() != none)
{
Canvas.SetDrawColorStruct(PlayerBarShadowColor);
Canvas.SetPos((ScreenPos.X - IconCenteringLength) + 1, ScreenPos.Y + 1);
Canvas.DrawTile(Objective.GetIcon(), PlayerStatusIconSize * ResModifier, PlayerStatusIconSize * ResModifier, 0, 0, 256, 256);
Canvas.SetDrawColorStruct(Objective.GetIconColor());
Canvas.SetPos(ScreenPos.X - IconCenteringLength, ScreenPos.Y);
Canvas.DrawTile(Objective.GetIcon(), PlayerStatusIconSize * ResModifier, PlayerStatusIconSize * ResModifier, 0, 0, 256, 256);
}
return true;
}
simulated function bool DrawObjectiveHUD()
{
local float Percentage;
@ -1008,6 +1091,7 @@ simulated function bool DrawObjectiveHUD()
Canvas.SetPos(ScreenPos.X - (BarLength * 0.75) - IconCenteringLength, ScreenPos.Y - BarHeight * 2.0);
Canvas.DrawTile(KFGRI.ObjectiveInterface.GetIcon(), PlayerStatusIconSize * ResModifier, PlayerStatusIconSize * ResModifier, 0, 0, 256, 256);
}
return true;
}

View File

@ -27,6 +27,8 @@ enum EVoiceCommsType
};
var localized array<string> VoiceCommsOptionStrings;
var localized string ToggleFriendlyHUDString;
var array<Texture2D> VoiceCommsIcons;
static function string GetString(

View File

@ -73,6 +73,7 @@ defaultproperties
ColumnIds.Add(STATID_ACHIEVE_RigCollectibles)
ColumnIds.Add(STATID_ACHIEVE_BarmwichCollectibles)
ColumnIds.Add(STATID_ACHIEVE_CrashCollectibles);
ColumnIds.Add(STATID_ACHIEVE_SubductionCollectibles);
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
@ -134,5 +135,6 @@ defaultproperties
ColumnMappings.Add((Id=STATID_ACHIEVE_RigCollectibles,Name="AchievementCollectRig"))
ColumnMappings.Add((Id=STATID_ACHIEVE_BarmwichCollectibles,Name="AchievementCollectBarmwichTown"))
ColumnMappings.Add((Id=STATID_ACHIEVE_CrashCollectibles,Name="AchievementCollectCrash"))
ColumnMappings.Add((Id=STATID_ACHIEVE_SubductionCollectibles,Name="AchievementCollectSubduction"))
}

View File

@ -453,6 +453,10 @@ const KFACHID_CrashHard = 298;
const KFACHID_CrashHellOnEarth = 299;
const KFACHID_CrashCollectibles = 300;
const KFACHID_SubductionHard = 301;
const KFACHID_SubductionHellOnEarth = 302;
const KFACHID_SubductionCollectibles = 303;
/* __TW_ANALYTICS_ */
var int PerRoundWeldXP;
var int PerRoundHealXP;
@ -2120,6 +2124,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_SealSqueal, KFDT_Bludgeon_SealSqueal, KFDT_Explosive_SealSqueal, KFDT_Ballistic_SealSquealImpact),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_Seeker6, KFDT_Explosive_Seeker6, KFDT_Bludgeon_Seeker6, KFDT_Ballistic_Seeker6Impact),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_M32, KFDT_Bludgeon_M32, KFDT_Explosive_M32, KFDT_Ballistic_M32Impact),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Warthog, KFDT_Bludgeon_HRG_Warthog, KFDT_Explosive_HRG_Warthog, KFDT_Explosive_HRG_Warthog_HighExplosive, KFDT_Ballistic_HRG_Warthog),CompletionAmount=7000))
//Firebug Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Flame_CaulkBurn, KFDT_Bludgeon_CaulkBurn,KFDT_Fire_CaulkBurn,KFDT_Fire_Ground_CaulkNBurn),CompletionAmount=5000)) //3000
@ -2325,6 +2330,10 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CRASH),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CRASH),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-CRASH),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SUBDUCTION),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SUBDUCTION),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-SUBDUCTION),CompletionAmount=3))
//Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount

View File

@ -75,4 +75,5 @@ defaultproperties
Properties.Add((PropertyId = STATID_ACHIEVE_RigCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_BarmwichCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_CrashCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_SubductionCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
}

View File

@ -464,6 +464,12 @@ struct WeeklyOverrides
/** Time between waves override. */
var() float TimeBetweenWaves;
/** Contamination mode Zeds to finish */
var() int ContaminationModeZedsToFinish;
/** Contamination mode Extra Dosh */
var() int ContaminationModeExtraDosh;
structdefaultproperties
{
GameLength = GL_Short
@ -529,6 +535,8 @@ struct WeeklyOverrides
TraderTimeModifier = 1.f;
TimeBetweenWaves = -1.f;
bForceShowSkipTrader = false;
ContaminationModeZedsToFinish = 0;
ContaminationModeExtraDosh = 0;
}
};
@ -1101,8 +1109,23 @@ function class<KFPawn_Monster> GetAISpawnOverrideInner(array <SpawnReplacement>
{
local SpawnReplacement Replacement;
local float RandF;
local int IndexReplace;
// Check if our current weekly event has any overrides available
// We generate random number with the Elite Zed replacement we need
// If that replacement has a new EAIType we need to use it for the comparison
IndexReplace = AIClassList[AIType].static.IndexOverrideReplaceSpawnWithElite();
if (IndexReplace >= 0)
{
if (AIClassList[AIType].default.EliteAIType.length > IndexReplace)
{
AIType = EAIType(AIClassList[AIType].default.EliteAIType[IndexReplace]);
}
}
foreach SpawnReplacementList(Replacement)
{
if (Replacement.SpawnEntry == AIType)

View File

@ -2694,11 +2694,12 @@ simulated function TakeRadiusDamage
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{
bTakingRadiusDamage = true;
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent);
Super.TakeRadiusDamage(InstigatedBy, BaseDamage, DamageRadius, DamageType, Momentum, HurtOrigin, bFullDamage, DamageCauser, DamageFalloffExponent, bAdjustRadiusDamage);
bTakingRadiusDamage = false;
}
@ -5550,6 +5551,16 @@ simulated function StopLocustVFX()
}
}
simulated function bool CanInteractWithPawnGrapple()
{
return true;
}
simulated function bool CanInteractWithZoneVelocity()
{
return true;
}
defaultproperties
{
InventoryManagerClass=class'KFInventoryManager'

View File

@ -39,6 +39,7 @@ var private const KFCharacterInfo_Monster CharacterMonsterArch;
var transient bool bArchLoaded;
/** List of variants that this pawn can be spawned as */
var const array<int> EliteAIType; // can't use EAIType enumerator, use integer instead
var const array<class<KFPawn_Monster> > ElitePawnClass;
/** Custom third person camera offsets */
@ -718,16 +719,51 @@ simulated static function float GetXPValue(byte Difficulty)
return default.XPValues[Difficulty];
}
// This is used to precalculate Elite Zed replacement at the Spawn Manager level decision, so Weeklies can infer a change via the SpawnReplacementList
static function int IndexOverrideReplaceSpawnWithElite()
{
local WorldInfo WI;
local KFGameReplicationInfo KFGRI;
WI = class'WorldInfo'.static.GetWorldInfo();
KFGRI = KFGameReplicationInfo(WI.GRI);
// We only use this feature in this weekly for now, we pregenerate the Random so we can replace the Zed with Elite version
// And use the Weekly SpawnReplacementList to replace correctly
if (KFGRI.IsContaminationMode())
{
if (default.ElitePawnClass.length > 0
&& default.DifficultySettings != none
&& fRand() < default.DifficultySettings.static.GetSpecialSpawnChance(KFGRI))
{
return Rand(default.ElitePawnClass.length);
}
}
return -1;
}
/** Gets the actual classes used for spawning. Can be overridden to replace this monster with another */
static event class<KFPawn_Monster> GetAIPawnClassToSpawn()
{
local WorldInfo WI;
local KFGameReplicationInfo KFGRI;
WI = class'WorldInfo'.static.GetWorldInfo();
if (default.ElitePawnClass.length > 0 && default.DifficultySettings != none && fRand() < default.DifficultySettings.static.GetSpecialSpawnChance(KFGameReplicationInfo(WI.GRI)))
KFGRI = KFGameReplicationInfo(WI.GRI);
// We already generated the random for this mode when calling IndexOverrideReplaceSpawnWithElite, so no need to roll the dice again
if (KFGRI.IsContaminationMode() == false)
{
if (default.ElitePawnClass.length > 0
&& default.DifficultySettings != none
&& fRand() < default.DifficultySettings.static.GetSpecialSpawnChance(KFGRI))
{
return default.ElitePawnClass[Rand(default.ElitePawnClass.length)];
}
}
return default.class;
}

View File

@ -1287,7 +1287,7 @@ simulated function bool IsCallOutActive(){ return false; }
simulated function bool IsShootAndMoveActive(){ return false; }
simulated function bool HasNightVision(){ return false; }
simulated protected function bool IsRapidFireActive(){ return false; }
simulated function float GetZedTimeModifier( KFWeapon W ){ return 0.f; }
simulated event float GetZedTimeModifier( KFWeapon W ){ return 0.f; }
simulated function float GetZedTimeModifierForWindUp(){ return 0.f; }
simulated function ModifySpread( out float InSpread );
@ -1349,8 +1349,6 @@ simulated function bool DoorShouldNuke(){ return false; }
simulated function bool ShouldGetDaZeD( class<KFDamageType> DamageType ){ return false; }
simulated function float GetDaZedEMPPower(){ return 0; }
simulated function bool ShouldNeverDud(){ return false; }
simulated function SetLastHX25NukeTime( float NewTime );
simulated function float GetLastHX25NukeTime() { return 0.f; }
/** "Rack 'em Up" perk skill functions (Gunslinger, Sharpshooter) */
simulated function bool GetIsUberAmmoActive( KFWeapon KFW ){ return false; }

View File

@ -48,9 +48,6 @@ var private const float ProfessionalAoEModifier;
var private bool bUsedSacrifice;
var private const class<KFDamagetype> LingeringNukeDamageType;
/** The last time an HX25 projectile spawned by our owner caused a nuke */
var private transient float LastHX25NukeTime;
enum EDemoSkills
{
EDemoDamage,
@ -406,15 +403,6 @@ static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional fl
}
}
simulated function SetLastHX25NukeTime( float NewTime )
{
LastHX25NukeTime = NewTime;
}
simulated function float GetLastHX25NukeTime()
{
return LastHX25NukeTime;
}
simulated function float GetAoERadiusModifier()
{
local float RadiusModifier;
@ -1171,9 +1159,13 @@ DefaultProperties
ZedTimeModifyingStates(9)="BlunderbussDeployAndDetonate"
PassiveExtraAmmoIgnoredClassNames(0)="KFProj_DynamiteGrenade"
PassiveExtraAmmoIgnoredClassNames(1)="KFWeap_HRG_Warthog"
PassiveExtraAmmoIgnoredClassNames(2)="KFWeap_HRG_WarthogWeapon"
ExtraAmmoIgnoredClassNames(0)="KFProj_DynamiteGrenade"
ExtraAmmoIgnoredClassNames(1)="KFWeap_Thrown_C4"
ExtraAmmoIgnoredClassNames(2)="KFWeap_HRG_Warthog"
ExtraAmmoIgnoredClassNames(3)="KFWeap_HRG_WarthogWeapon"
TacticalReloadAsReloadRateClassNames(0)="KFWeap_GrenadeLauncher_M32"

View File

@ -650,8 +650,8 @@ DefaultProperties
ProgressStatID=STATID_Medic_Progress
PerkBuildStatID=STATID_Medic_Build
SelfHealingSurgePct=0.06f //0.1f
MaxSurvivalistResistance=0.60f //0.70f //0.5f //0.8
SelfHealingSurgePct=0.03f //0.1f
MaxSurvivalistResistance=0.30f //0.70f //0.5f //0.8
CombatantSpeedModifier=0.1f
MaxHealingSpeedBoost=30 //15 //50
@ -730,7 +730,7 @@ DefaultProperties
HealerRecharge=(Name="Healer Recharge",Increment=0.08f,Rank=0,StartingValue=1.f,MaxValue=3.f)
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)
MovementSpeed=(Name="Movement Speed",Increment=0.004f,Rank=0,StartingValue=0.f,MaxValue=0.1f)
MovementSpeed=(Name="Movement Speed",Increment=0.002f,Rank=0,StartingValue=0.f,MaxValue=0.1f)
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)

View File

@ -757,6 +757,7 @@ var transient bool bShotgunJumping;
var bool bAllowSeasonalSkins;
var bool bFriendlyUIEnabled;
cpptext
{
@ -2855,6 +2856,12 @@ public function bool CanUseVIP()
return false;
}
public function bool CanUseContaminationMode()
{
return KFGameReplicationInfo(WorldInfo.GRI) != none
&& KFGameReplicationInfo(WorldInfo.GRI).IsContaminationMode();
}
/*********************************************************************************************
* @name Skill Tracking
********************************************************************************************* */
@ -12169,6 +12176,12 @@ simulated function ClearShotgunJumpFlag()
bShotgunJumping = false;
}
exec function ToggleFriendlyUI()
{
bFriendlyUIEnabled = !bFriendlyUIEnabled;
`Log("Toggle Friendly UI " $bFriendlyUIEnabled);
}
defaultproperties
{
EarnedDosh=0
@ -12377,4 +12390,6 @@ defaultproperties
StormCannonIDCounter = 0
bShotgunJumping = false
bAllowSeasonalSkins = false
bFriendlyUIEnabled = true
}

View File

@ -111,6 +111,12 @@ var transient VIPGameInfo VIPGameData;
// RandomPerk weekly
var byte InitialRandomPerk;
// Contamination Mode weekly
var float ContaminationModeGraceCurrentTimer;
var bool ContaminationModePlayerIsInside;
var int ContaminationModeLastTimePlayerOutPulsate;
var bool ContaminationModeLastPulsate;
cpptext
{
virtual UBOOL TestZedTimeVisibility(APawn* P, UNetConnection* Connection, UBOOL bLocalPlayerTest) override;
@ -208,6 +214,64 @@ simulated function UpdateVIPWidget(ReplicatedVIPGameInfo VIPInfo)
}
}
reliable client function UpdateContaminationModeWidget(bool IsPlayerIn)
{
// Reset pulsate
if (IsPlayerIn != ContaminationModePlayerIsInside)
{
ContaminationModeLastPulsate = true;
ContaminationModeLastTimePlayerOutPulsate = WorldInfo.TimeSeconds;
}
// Pulsate ping pongs for showing text when player is out or not
if (IsPlayerIn == false && WorldInfo.TimeSeconds - ContaminationModeLastTimePlayerOutPulsate > 1.f)
{
ContaminationModeLastTimePlayerOutPulsate = WorldInfo.TimeSeconds;
ContaminationModeLastPulsate = !ContaminationModeLastPulsate;
}
ContaminationModePlayerIsInside = IsPlayerIn;
if (MyGFxHUD != none)
{
MyGFxHUD.UpdateContaminationMode(IsPlayerIn, ContaminationModeLastPulsate);
if (MyGFxHUD.PlayerStatusContainer != none)
{
MyGFxHUD.PlayerStatusContainer.UpdateContaminationModeIconVisible(IsPlayerIn == false);
}
}
}
reliable client function UpdateContaminationModeWidget_Timer(int Timer)
{
if (MyGFxHUD != none)
{
MyGFxHUD.UpdateContaminationMode_Timer(Timer);
}
}
reliable client Function ShowContaminationMode()
{
if (MyGFxHUD != none)
{
MyGFxHUD.ShowContaminationMode();
}
}
reliable client function HideContaminationMode()
{
if (MyGFxHUD != none)
{
MyGFxHUD.HideContaminationMode();
if (MyGFxHUD.PlayerStatusContainer != none)
{
MyGFxHUD.PlayerStatusContainer.UpdateContaminationModeIconVisible(false);
}
}
}
reliable client function ResetSyringe()
{
local KFInventoryManager InventoryManager;
@ -709,4 +773,8 @@ defaultProperties
VIPLowHealthSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyVIPAlarm'
VIPLowHealthLastTimePlayed = 0.f
InitialRandomPerk=255
ContaminationModeGraceCurrentTimer=0.f
ContaminationModePlayerIsInside=false
ContaminationModeLastTimePlayerOutPulsate=0
ContaminationModeLastPulsate=false
}

View File

@ -2968,6 +2968,19 @@ exec function LogPerkInfo()
}
`endif
exec function ToggleFriendlyUI()
{
Outer.ToggleFriendlyUI();
}
exec function ToggleFriendlyUIFromHUD()
{
if( MyGFxHUD != none && MyGFxHUD.VoiceCommsWidget != none && MyGFxHUD.VoiceCommsWidget.bActive )
{
Outer.ToggleFriendlyUI();
}
}
defaultproperties
{
bEnableFOVScaling=true

View File

@ -14,6 +14,8 @@ class KFProj_ExplosiveSubmunition_HX25 extends KFProj_BallisticExplosive
/** Cached reference to owner weapon */
var protected KFWeapon OwnerWeapon;
var bool bCanNuke;
/** Initialize the projectile */
function Init( vector Direction )
{
@ -37,25 +39,9 @@ function bool ShouldWarnAIWhenFired()
*/
simulated protected function PrepareExplosionTemplate()
{
local KFPawn KFP;
local KFPerk CurrentPerk;
ExplosionTemplate.bIgnoreInstigator = true;
super.PrepareExplosionTemplate();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
KFP = KFPawn( Instigator );
if( KFP != none )
{
CurrentPerk = KFP.GetPerk();
if( CurrentPerk != none )
{
CurrentPerk.SetLastHX25NukeTime( WorldInfo.TimeSeconds );
}
}
}
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
@ -73,23 +59,9 @@ simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallCom
Super.HitWall(HitNormal, Wall, WallComp);
}
/** Only allow this projectile to cause a nuke if there hasn't been another nuke very recently */
simulated function bool AllowNuke()
{
local KFPawn KFP;
local KFPerk CurrentPerk;
KFP = KFPawn( Instigator );
if( KFP != none )
{
CurrentPerk = KFP.GetPerk();
if( CurrentPerk != none && `TimeSince(CurrentPerk.GetLastHX25NukeTime()) < 0.25f )
{
return false;
}
}
return super.AllowNuke();
return bCanNuke;
}
defaultproperties
@ -162,5 +134,7 @@ defaultproperties
//AmbientSoundStopEvent=AkEvent'WW_WEP_Bullet_FlyBys.Stop_WEP_Bullet_Flyby_Small'
AlwaysRelevantDistanceSquared=2250000 // 15m
bCanNuke = true
}

View File

@ -214,6 +214,12 @@ function Pawn FindPlayerGrabTarget()
function bool CanInteractWithPawn(KFPawn OtherPawn)
{
// Prevent interaction if potentiail victim is dead, not on our team, in Phys_Falling, or busy with another special move
if (OtherPawn.CanInteractWithPawnGrapple() == false)
{
return false;
}
return( (OtherPawn.IsAliveAndWell() && !KFPOwner.IsSameTeam(OtherPawn) && OtherPawn.Physics != PHYS_Falling && !OtherPawn.IsDoingSpecialMove())
&& Super.CanInteractWithPawn(OtherPawn) );
}

View File

@ -38,7 +38,8 @@ enum ESharedContentUnlock
SCU_Scythe,
SCU_G36C,
SCU_HVStormCannon,
SCU_ZedMKIII
SCU_ZedMKIII,
SCU_Saiga12
};
@ -393,4 +394,8 @@ defaultproperties
Name=KFWeap_ZedMKIII,
IconPath="wep_ui_zedmkiii_tex.UI_WeaponSelect_ZEDMKIII",
ID=9575)}
SharedContentList(SCU_Saiga12)={(
Name=KFWeap_Shotgun_S12,
IconPath="WEP_UI_Saiga12_TEX.UI_WeaponSelect_Saiga12",
ID=9666)}
}

View File

@ -14,7 +14,7 @@ DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_Locust"
BuyPrice=900
BuyPrice=1400
AmmoPricePerMag=40
ImagePath="wep_ui_hrg_locust_tex.UI_WeaponSelect_HRG_Locust"
@ -22,9 +22,7 @@ DefaultProperties
EffectiveRange=100
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradePrice[0]=1500
UpgradeSellPrice[0]=525
UpgradeSellPrice[1]=1650
UpgradeSellPrice[0]=1125
}

View File

@ -0,0 +1,28 @@
//=============================================================================
// KFWeapDef_HRGWarthog
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_Warthog extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_Warthog"
BuyPrice=500
AmmoPricePerMag=60 // 27
ImagePath="WEP_UI_HRG_Warthog_TEX.UI_WeaponSelect_HRG_Warthog"
IsPlayGoHidden=true;
EffectiveRange=18
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradeSellPrice[0]=525
UpgradeSellPrice[1]=1650
}

View File

@ -0,0 +1,19 @@
//=============================================================================
// KFWeapDef_HRG_WarthogWeapon
//=============================================================================
// Weapon attached to a drone
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_WarthogWeapon extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_WarthogWeapon"
BuyPrice=0
AmmoPricePerMag=0
ImagePath="ui_weaponselect_tex.UI_WeaponSelect_AR15"
}

View File

@ -14,7 +14,7 @@ DefaultProperties
WeaponClassPath="KFGameContent.KFWeap_Minigun"
BuyPrice=2000 //2500
AmmoPricePerMag= 90//125 //175 //250
AmmoPricePerMag= 120//125 //175 //250
ImagePath="WEP_UI_Minigun_TEX.UI_WeaponSelect_Minigun"
IsPlayGoHidden=true;

View File

@ -0,0 +1,35 @@
//=============================================================================
// KFWeaponDefintion
//=============================================================================
// A lightweight container for basic weapon properties that can be safely
// accessed without a weapon actor (UI, remote clients).
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_Shotgun_S12 extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_Shotgun_S12"
BuyPrice=1500
AmmoPricePerMag=40 //110 //82
ImagePath="WEP_UI_Saiga12_TEX.UI_WeaponSelect_Saiga12"
IsPlayGoHidden=true;
SecondaryAmmoMagSize=1
SecondaryAmmoMagPrice=30 //13
EffectiveRange=30
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
SharedUnlockId=SCU_Saiga12
}

View File

@ -12,7 +12,7 @@ DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_ShrinkRayGun"
BuyPrice=1200
BuyPrice=900
AmmoPricePerMag=50
ImagePath="WEP_UI_ShrinkRay_Gun_TEX.UI_Weapon_Select_Shrink_Ray_Gun"

View File

@ -117,8 +117,6 @@ function GivenTo(Pawn NewOwner, optional bool bDoNotActivate)
KFInvManger = KFInventoryManager(InvManager);
if( InvManager != none && KFInvManger != none )
{
`Log("GivenToGivenToGivenToGivenToGivenToGivenToGivenToGivenToGivenToGivenToGivenToGivenTo");
KFInvManger.HealerWeapon = self;
}
}

View File

@ -354,6 +354,15 @@ static simulated function float CalculateTraderWeaponStatDamage()
return BaseDamage + DoTDamage;
}
simulated state WeaponPuttingDown
{
simulated function BeginState( Name PreviousStateName )
{
super.BeginState(PreviousStateName);
ClearTimer(nameOf(PerformArtificialReload) );
}
}
defaultproperties
{
// Anim

View File

@ -985,6 +985,9 @@ var class<KFTargetingWeaponComponent> TargetingCompClass;
var KFTargetingWeaponComponent TargetingComp;
var repnotify Actor TargetingCompRepActor;
// To force the crosshair for showing up even if there's no spread
var bool bForceCrosshair;
cpptext
{
// Actor
@ -1846,6 +1849,11 @@ simulated function bool DenyPerkResupply()
return false;
}
if (Class.Name == 'KFWeap_HRG_Warthog')
{
return false;
}
return true;
}
@ -3931,6 +3939,11 @@ static simulated function class<KFProjectile> GetKFProjectileClassByFiringMode(i
MyProjectileClass = GetKFProjectileClass();
if (MyProjectileClass == none)
{
return none;
}
if( Role == ROLE_Authority || (MyProjectileClass.default.bUseClientSideHitDetection
&& MyProjectileClass.default.bNoReplicationToInstigator && Instigator != none
&& Instigator.IsLocallyControlled()) )
@ -6087,7 +6100,8 @@ simulated state WeaponEquipping
CurrentPerk = GetPerk();
if( CurrentPerk != none )
{
if( CurrentPerk.IsWeaponOnPerk( self,, CurrentPerk.class ) )
// Ignore weapon on perk for survivalist
if( CurrentPerk.IsWeaponOnPerk( self,, CurrentPerk.class ) || CurrentPerk.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass() )
{
CurrentPerk.ModifyWeaponSwitchTime( ScaledRate );
}
@ -6116,7 +6130,8 @@ simulated function TimeWeaponEquipping()
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
if( InstigatorPerk.IsWeaponOnPerk( self,, InstigatorPerk.class ) )
// Ignore weapon on perk for survivalist
if( InstigatorPerk.IsWeaponOnPerk( self,, InstigatorPerk.class ) || InstigatorPerk.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass() )
{
InstigatorPerk.ModifyWeaponSwitchTime( ModifiedEquipTime );
}
@ -6196,7 +6211,8 @@ simulated state WeaponPuttingDown
CurrentPerk = GetPerk();
if( CurrentPerk != none )
{
if( CurrentPerk.IsWeaponOnPerk( self,, CurrentPerk.class ) )
// Ignore weapon on perk for survivalist
if( CurrentPerk.IsWeaponOnPerk( self,, CurrentPerk.class ) || CurrentPerk.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass() )
{
CurrentPerk.ModifyWeaponSwitchTime( ScaledRate );
}
@ -6375,7 +6391,8 @@ simulated function TimeWeaponPutDown()
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
if( InstigatorPerk.IsWeaponOnPerk( self,, InstigatorPerk.class ) )
// Ignore weapon on perk for survivalist
if( InstigatorPerk.IsWeaponOnPerk( self,, InstigatorPerk.class ) || InstigatorPerk.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass() )
{
InstigatorPerk.ModifyWeaponSwitchTime( ModifiedPutDownTime );
}
@ -8070,5 +8087,7 @@ defaultproperties
bForceHandleImpacts=false
UseFixedPhysicalFireLocation=false
bForceCrosshair=false
}

View File

@ -4532,4 +4532,208 @@ defaultproperties
//Retro Precious Railgun
Skins.Add((Id=9539, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroPrecious_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroPrecious_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroPrecious_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroPrecious_Railgun_3P_Pickup_MIC"))
//Jaeger Dynamic M14EBR
Skins.Add((Id=9582, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M14EBR', MIC_1P=("WEP_SkinSet72_MAT.dynamic_m14ebr.Dynamic_M14EBR_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamic_m14ebr.Dynamic_M14EBR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamic_m14ebr.Dynamic_M14EBR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamic_m14ebr.Dynamic_M14EBR_3P_Pickup_MIC"))
//Jaeger Dynamic Seeker Six
Skins.Add((Id=9583, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Seeker6', MIC_1P=("WEP_SkinSet72_MAT.dynamic_seekersix.Dynamic_SeekerSix_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamic_seekersix.Dynamic_SeekerSix_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamic_seekersix.Dynamic_SeekerSix_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamic_seekersix.Dynamic_SeekerSix_3P_Pickup_MIC"))
//Jaeger Dynamic Railgun
Skins.Add((Id=9584, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet72_MAT.dynamic_railgun.Dynamic_Railgun_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamic_railgun.Dynamic_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamic_railgun.Dynamic_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamic_railgun.Dynamic_Railgun_3P_Pickup_MIC"))
//Jaeger Dynamic MP5RAS
Skins.Add((Id=9585, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet72_MAT.dynamic_mp5ras.Dynamic_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamic_mp5ras.Dynamic_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamic_mp5ras.Dynamic_MP5RAS_3P_Pickup_MIC"))
//Jaeger Dynamic RGB M14EBR
Skins.Add((Id=9586, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M14EBR', MIC_1P=("WEP_SkinSet72_MAT.dynamicrgb_m14ebr.DynamicRGB_M14EBR_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamicrgb_m14ebr.DynamicRGB_M14EBR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamicrgb_m14ebr.DynamicRGB_M14EBR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamicrgb_m14ebr.DynamicRGB_M14EBR_3P_Pickup_MIC"))
//Jaeger Dynamic RGB Seeker Six
Skins.Add((Id=9587, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Seeker6', MIC_1P=("WEP_SkinSet72_MAT.dynamicrgb_seekersix.DynamicRGB_SeekerSix_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamicrgb_seekersix.DynamicRGB_SeekerSix_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamicrgb_seekersix.DynamicRGB_SeekerSix_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamicrgb_seekersix.DynamicRGB_SeekerSix_3P_Pickup_MIC"))
//Jaeger Dynamic RGB Railgun
Skins.Add((Id=9588, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet72_MAT.dynamicrgb_railgun.DynamicRGB_Railgun_1P_Mint_MIC", "WEP_SkinSet72_MAT.dynamicrgb_railgun.DynamicRGB_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamicrgb_railgun.DynamicRGB_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamicrgb_railgun.DynamicRGB_Railgun_3P_Pickup_MIC"))
//Jaeger Dynamic RGB MP5RAS
Skins.Add((Id=9589, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet72_MAT.dynamicrgb_mp5ras.DynamicRGB_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet72_MAT.dynamicrgb_mp5ras.DynamicRGB_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet72_MAT.dynamicrgb_mp5ras.DynamicRGB_MP5RAS_3P_Pickup_MIC"))
//Junkyard Mint RPG-7
Skins.Add((Id=9590, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet73_MAT.junkyard_rpg7.Junkyard_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyard_rpg7.Junkyard_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyard_rpg7.Junkyard_RPG7_3P_Pickup_MIC"))
//Junkyard Mint M99
Skins.Add((Id=9591, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet73_MAT.junkyard_m99.Junkyard_M99_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyard_m99.Junkyard_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyard_m99.Junkyard_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyard_m99.Junkyard_M99_3P_Pickup_MIC"))
//Junkyard Mint Heckler & Koch UMP
Skins.Add((Id=9592, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet73_MAT.junkyard_hk_ump.Junkyard_HK_UMP_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyard_hk_ump.Junkyard_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyard_hk_ump.Junkyard_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyard_hk_ump.Junkyard_HK_UMP_3P_Pickup_MIC"))
//Junkyard Mint FN FAL
Skins.Add((Id=9593, Weapondef=class'KFWeapDef_FNFAL', MIC_1P=("WEP_SkinSet73_MAT.junkyard_fnfal.Junkyard_FNFAL_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyard_fnfal.Junkyard_FNFAL_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyard_fnfal.Junkyard_FNFAL_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyard_fnfal.Junkyard_FNFAL_3P_Pickup_MIC"))
//Junkyard Precious RPG-7
Skins.Add((Id=9594, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet73_MAT.junkyardprecious_rpg7.JunkyardPrecious_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyardprecious_rpg7.JunkyardPrecious_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyardprecious_rpg7.JunkyardPrecious_RPG7_3P_Pickup_MIC"))
//Junkyard Precious M99
Skins.Add((Id=9595, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet73_MAT.junkyardprecious_m99.JunkyardPrecious_M99_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyardprecious_m99.JunkyardPrecious_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyardprecious_m99.JunkyardPrecious_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyardprecious_m99.JunkyardPrecious_M99_3P_Pickup_MIC"))
//Junkyard Precious Heckler & Koch UMP
Skins.Add((Id=9596, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet73_MAT.junkyardprecious_hk_ump.JunkyardPrecious_HK_UMP_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyardprecious_hk_ump.JunkyardPrecious_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyardprecious_hk_ump.JunkyardPrecious_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyardprecious_hk_ump.JunkyardPrecious_HK_UMP_3P_Pickup_MIC"))
//Junkyard Precious FN FAL
Skins.Add((Id=9597, Weapondef=class'KFWeapDef_FNFAL', MIC_1P=("WEP_SkinSet73_MAT.junkyardprecious_fnfal.JunkyardPrecious_FNFAL_1P_Mint_MIC", "WEP_SkinSet73_MAT.junkyardprecious_fnfal.JunkyardPrecious_FNFAL_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet73_MAT.junkyardprecious_fnfal.JunkyardPrecious_FNFAL_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet73_MAT.junkyardprecious_fnfal.JunkyardPrecious_FNFAL_3P_Pickup_MIC"))
//Predator Forest M16 M203
Skins.Add((Id=9637, Weapondef=class'KFWeapDef_M16M203', MIC_1P=("WEP_SkinSet74_MAT.camo_m16m203.Camo_M16_1P_Mint_MIC", "WEP_SkinSet74_MAT.camo_m16m203.Camo_M203_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camo_m16m203.Camo_M16M203_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_m16m203.Camo_M16M203_3P_Pickup_MIC"))
//Predator Forest M79
Skins.Add((Id=9638, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet74_MAT.camo_m79.Camo_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camo_m79.Camo_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_m79.Camo_M79_3P_Pickup_MIC"))
//Predator Forest Kriss SMG
Skins.Add((Id=9639, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("WEP_SkinSet74_MAT.camo_kriss.Camo_Kriss_1P_Mint_MIC", "WEP_SkinSet74_MAT.camo_kriss.Camo_Kriss_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camo_kriss.Camo_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_kriss.Camo_Kriss_3P_Pickup_MIC"))
//Predator Forest 9MM
Skins.Add((Id=9640, Weapondef=class'KFWeapDef_9mm', MIC_1P=("WEP_SkinSet74_MAT.camo_9mm.Camo_9MM_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camo_9mm.Camo_9MM_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_9mm.Camo_9MM_3P_Pickup_MIC"))
//Predator Desert M16 M203
Skins.Add((Id=9641, Weapondef=class'KFWeapDef_M16M203', MIC_1P=("WEP_SkinSet74_MAT.camodesert_m16m203.CamoDesert_M16_1P_Mint_MIC", "WEP_SkinSet74_MAT.camodesert_m16m203.CamoDesert_M203_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camodesert_m16m203.CamoDesert_M16M203_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_m16m203.CamoDesert_M16M203_3P_Pickup_MIC"))
//Predator Desert M79
Skins.Add((Id=9642, Weapondef=class'KFWeapDef_M79', MIC_1P=("WEP_SkinSet74_MAT.camodesert_m79.CamoDesert_M79_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camodesert_m79.CamoDesert_M79_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_m79.CamoDesert_M79_3P_Pickup_MIC"))
//Predator Desert Kriss SMG
Skins.Add((Id=9643, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("WEP_SkinSet74_MAT.camodesert_kriss.CamoDesert_Kriss_1P_Mint_MIC", "WEP_SkinSet74_MAT.camodesert_kriss.CamoDesert_Kriss_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camodesert_kriss.CamoDesert_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_kriss.CamoDesert_Kriss_3P_Pickup_MIC"))
//Predator Desert 9MM
Skins.Add((Id=9644, Weapondef=class'KFWeapDef_9mm', MIC_1P=("WEP_SkinSet74_MAT.camodesert_9mm.CamoDesert_9MM_1P_Mint_MIC"), MIC_3P="WEP_SkinSet74_MAT.camodesert_9mm.CamoDesert_9MM_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet74_MAT.camo_9mm.CamoDesert_9MM_3P_Pickup_MIC"))
//Stingray Infantry Heckler & Koch UMP
Skins.Add((Id=9601, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverVar1_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverVar1_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar1_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar1_HK_UMP_3P_Pickup_MIC"))
//Stingray Navy Heckler & Koch UMP
Skins.Add((Id=9602, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverVar2_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverVar2_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar2_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar2_HK_UMP_3P_Pickup_MIC"))
//Stingray Engineer Heckler & Koch UMP
Skins.Add((Id=9603, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_3P_Pickup_MIC"))
//Stingray Artillery Heckler & Koch UMP
Skins.Add((Id=9604, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverVar4_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverVar4_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar4_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar4_HK_UMP_3P_Pickup_MIC"))
//Stingray Engineer Heckler & Koch UMP
Skins.Add((Id=9605, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverVar3_HK_UMP_3P_Pickup_MIC"))
//Stingray Precious Heckler & Koch UMP
Skins.Add((Id=9606, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("WEP_SkinSet75_MAT.diver_hk_ump.DiverPrecious_HK_UMP_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_hk_ump.DiverPrecious_HK_UMP_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_hk_ump.DiverPrecious_HK_UMP_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_hk_ump.DiverPrecious_HK_UMP_3P_Pickup_MIC"))
//Stingray Infantry Hemoclobber
Skins.Add((Id=9607, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverVar1_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverVar1_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverVar1_MedicBat_3P_Pickup_MIC"))
//Stingray Navy Hemoclobber
Skins.Add((Id=9608, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverVar2_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverVar2_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverVar2_MedicBat_3P_Pickup_MIC"))
//Stingray Engineer Hemoclobber
Skins.Add((Id=9609, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverVar3_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverVar3_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverVar3_MedicBat_3P_Pickup_MIC"))
//Stingray Artillery Hemoclobber
Skins.Add((Id=9610, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverVar4_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverVar4_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverVar4_MedicBat_3P_Pickup_MIC"))
//Stingray Logistic Hemoclobber
Skins.Add((Id=9611, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverVar5_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverVar5_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverVar5_MedicBat_3P_Pickup_MIC"))
//Stingray Precious Hemoclobber
Skins.Add((Id=9612, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet75_MAT.diver_medicbat.DiverPrecious_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_medicbat.DiverPrecious_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_medicbat.DiverPrecious_MedicBat_3P_Pickup_MIC"))
//Stingray Infantry SCAR
Skins.Add((Id=9613, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverVar1_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverVar1_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverVar1_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverVar1_SCAR_3P_Pickup_MIC"))
//Stingray Navy SCAR
Skins.Add((Id=9614, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverVar2_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverVar2_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverVar2_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverVar2_SCAR_3P_Pickup_MIC"))
//Stingray Engineer SCAR
Skins.Add((Id=9615, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverVar3_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverVar3_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverVar3_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverVar3_SCAR_3P_Pickup_MIC"))
//Stingray Artillery SCAR
Skins.Add((Id=9616, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverVar4_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverVar4_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverVar4_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverVar4_SCAR_3P_Pickup_MIC"))
//Stingray Logistic SCAR
Skins.Add((Id=9617, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverVar5_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverVar5_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverVar5_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverVar5_SCAR_3P_Pickup_MIC"))
//Stingray Precious SCAR
Skins.Add((Id=9618, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet75_MAT.diver_scar.DiverPrecious_SCAR_1P_Mint_MIC", "WEP_SkinSet75_MAT.diver_scar.DiverPrecious_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_scar.DiverPrecious_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_scar.DiverPrecious_SCAR_3P_Pickup_MIC"))
//Stingray Infantry M4
Skins.Add((Id=9619, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverVar1_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverVar1_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverVar1_M4_3P_Pickup_MIC"))
//Stingray Navy M4
Skins.Add((Id=9620, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverVar2_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverVar2_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverVar2_M4_3P_Pickup_MIC"))
//Stingray Engineer M4
Skins.Add((Id=9621, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverVar3_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverVar3_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverVar3_M4_3P_Pickup_MIC"))
//Stingray Artillery M4
Skins.Add((Id=9622, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverVar4_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverVar4_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverVar4_M4_3P_Pickup_MIC"))
//Stingray Logistic M4
Skins.Add((Id=9623, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverVar5_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverVar5_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverVar5_M4_3P_Pickup_MIC"))
//Stingray Precious M4
Skins.Add((Id=9624, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M4', MIC_1P=("WEP_SkinSet75_MAT.diver_m4.DiverPrecious_M4_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_m4.DiverPrecious_M4_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_m4.DiverPrecious_M4_3P_Pickup_MIC"))
//Stingray Infantry Desert Eagle
Skins.Add((Id=9625, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverVar1_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverVar1_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverVar1_Deagle_3P_Pickup_MIC"))
//Stingray Navy Desert Eagle
Skins.Add((Id=9626, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverVar2_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverVar2_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverVar2_Deagle_3P_Pickup_MIC"))
//Stingray Engineer Desert Eagle
Skins.Add((Id=9627, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverVar3_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverVar3_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverVar3_Deagle_3P_Pickup_MIC"))
//Stingray Artillery Desert Eagle
Skins.Add((Id=9628, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverVar4_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverVar4_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverVar4_Deagle_3P_Pickup_MIC"))
//Stingray Logistic Desert Eagle
Skins.Add((Id=9629, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverVar5_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverVar5_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverVar5_Deagle_3P_Pickup_MIC"))
//Stingray Precious Desert Eagle
Skins.Add((Id=9630, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet75_MAT.diver_deagle.DiverPrecious_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_deagle.DiverPrecious_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_deagle.DiverPrecious_Deagle_3P_Pickup_MIC"))
//Stingray Infantry Pulverizer
Skins.Add((Id=9631, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverVar1_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar1_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar1_Pulverizer_3P_Pickup_MIC"))
//Stingray Navy Pulverizer
Skins.Add((Id=9632, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverVar2_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar2_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar2_Pulverizer_3P_Pickup_MIC"))
//Stingray Engineer Pulverizer
Skins.Add((Id=9633, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverVar3_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar3_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar3_Pulverizer_3P_Pickup_MIC"))
//Stingray Artillery Pulverizer
Skins.Add((Id=9634, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverVar4_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar4_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar4_Pulverizer_3P_Pickup_MIC"))
//Stingray Logistic Pulverizer
Skins.Add((Id=9635, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverVar5_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar5_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverVar5_Pulverizer_3P_Pickup_MIC"))
//Stingray Precious Pulverizer
Skins.Add((Id=9636, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet75_MAT.diver_pulverizer.DiverPrecious_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet75_MAT.diver_pulverizer.DiverPrecious_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet75_MAT.diver_pulverizer.DiverPrecious_Pulverizer_3P_Pickup_MIC"))
//Contamination Zone Precious Healer
Skins.Add((Id=9659, Weapondef=class'KFWeapDef_Healer', MIC_1P=("WEP_SkinSet77_MAT.contamination_healer.Contamination_Healer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet77_MAT.contamination_healer.Contamination_Healer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet77_MAT.contamination_healer.Contamination_Healer_3P_Pickup_MIC"))
//Contamination Zone Precious Welder
Skins.Add((Id=9658, Weapondef=class'KFWeapDef_Welder', MIC_1P=("WEP_SkinSet77_MAT.contamination_welder.Contamination_Welder_1P_Mint_MIC"), MIC_3P="WEP_SkinSet77_MAT.contamination_welder.Contamination_Welder_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet77_MAT.contamination_welder.Contamination_Welder_3P_Pickup_MIC"))
//S12 Shockgun Standard
Skins.Add((Id=9666, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_1P_Saiga12_MAT.Wep_1stP_Saiga12_MIC"), MIC_3P="WEP_3P_Saiga12_MAT.WEP_3P_Saiga12_MIC", MIC_Pickup="WEP_3P_Saiga12_MAT.3P_Pickup_Saiga12_MIC"))
//S12 Shockgun Guppy
Skins.Add((Id=9667, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_SkinSet76_MAT.Wep_1stP_Saiga12_Guppy_MIC"), MIC_3P="WEP_SkinSet76_MAT.WEP_3P_Saiga12_Guppy_MIC", MIC_Pickup="WEP_SkinSet76_MAT.Weo_3P_Pickup_Saiga12_Guppy_MIC"))
//S12 Shockgun Lux
Skins.Add((Id=9668, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_SkinSet76_MAT.Wep_1stP_Saiga12_Lux_MIC"), MIC_3P="WEP_SkinSet76_MAT.WEP_3P_Saiga12_Lux_MIC", MIC_Pickup="WEP_SkinSet76_MAT.Wep_3P_Pickup_Saiga12_Lux_MIC"))
//S12 Shockgun Navy Camo
Skins.Add((Id=9669, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_SkinSet76_MAT.Wep_1stP_Saiga12_Ocean_MIC"), MIC_3P="WEP_SkinSet76_MAT.WEP_3P_Saiga12_Ocean_MIC", MIC_Pickup="WEP_SkinSet76_MAT.Wep_3P_Pickup_Saiga12_Ocean_MIC"))
//S12 Shockgun Showstopper
Skins.Add((Id=9670, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_SkinSet76_MAT.Wep_1stP_Saiga12_Racing_MIC"), MIC_3P="WEP_SkinSet76_MAT.WEP_3P_Saiga12_Racing_MIC", MIC_Pickup="WEP_SkinSet76_MAT.Wep_3P_Pickup_Saiga12_Racing_MIC"))
//S12 Shockgun Tiger
Skins.Add((Id=9671, Weapondef=class'KFWeapDef_Shotgun_S12', MIC_1P=("WEP_SkinSet76_MAT.Wep_1stP_Saiga12_Tiger_MIC"), MIC_3P="WEP_SkinSet76_MAT.WEP_3P_Saiga12_Tiger_MIC", MIC_Pickup="WEP_SkinSet76_MAT.Wep_3P_Pickup_Saiga12_Tiger_MIC"))
}

View File

@ -27,7 +27,7 @@ var localized array<string> ModifierDescriptions;
cpptext
{
/** Num of Weekly events available */
static const int NumWeeklyEvents = 19;
static const int NumWeeklyEvents = 20;
}
DefaultProperties
{

View File

@ -159,4 +159,5 @@ const STATID_ACHIEVE_CarillonHamletCollectibles = 4061;
const STATID_ACHIEVE_RigCollectibles = 4062;
const STATID_ACHIEVE_BarmwichCollectibles = 4063;
const STATID_ACHIEVE_CrashCollectibles = 4064;
const STATID_ACHIEVE_SubductionCollectibles = 4065;
/** `endif */

View File

@ -24,4 +24,7 @@ defaultproperties
//Perk
ModifierPerkList(0)=class'KFPerk_Commando'
bCanZedTime=false
bCanEnrage=false
}

View File

@ -0,0 +1,30 @@
//=============================================================================
// KFDT_Ballistic_HRG_Warthog
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Warthog extends KFDT_Ballistic_Shell
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=750
KDeathVel=350
KnockdownPower=125
StumblePower=340
GunHitPower=275
WeaponDef=class'KFWeapDef_HRG_Warthog'
//Perk
ModifierPerkList(0)=class'KFPerk_Demolitionist'
bCanZedTime=false
}

View File

@ -0,0 +1,53 @@
//=============================================================================
// KFDT_Ballistic_Shotgun_S12
//=============================================================================
// Damage type class for the S12 shotgun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_Shotgun_S12 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=5
GunHitPower=0
ModifierPerkList(0)=class'KFPerk_Support'
WeaponDef=class'KFWeapDef_Shotgun_S12'
}

View File

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

View File

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

View File

@ -24,7 +24,9 @@ defaultproperties
KnockdownPower = 100
StumblePower = 300
WeaponDef=class'KFWeapDef_AutoTurret'
ModifierPerkList(0)=class'KFPerk_Commando'
bCanZedTime=false
bCanEnrage=false
}

View File

@ -0,0 +1,32 @@
//=============================================================================
// KFDT_Explosive_HRG_Warthog
//=============================================================================
// Explosive damage type for HRG Warthog explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_HRG_Warthog extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood = true
// physics impact
RadialDamageImpulse = 2000
GibImpulseScale = 0.15
KDeathUpKick = 1000
KDeathVel = 300
KnockdownPower = 50
StumblePower = 150
WeaponDef=class'KFWeapDef_HRG_Warthog'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
bCanZedTime=false
bCanEnrage=false
}

View File

@ -0,0 +1,32 @@
//=============================================================================
// KFDT_Explosive_HRG_Warthog_HighExplosive
//=============================================================================
// Explosive damage type for HRG Warthog Projectile Explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_HRG_Warthog_HighExplosive extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood = true
// physics impact
RadialDamageImpulse = 2000
GibImpulseScale = 0.15
KDeathUpKick = 1000
KDeathVel = 300
KnockdownPower = 50
StumblePower = 150
WeaponDef=class'KFWeapDef_HRG_Warthog'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
bCanZedTime=false
bCanEnrage=false
}

View File

@ -0,0 +1,39 @@
//=============================================================================
// KFDT_Explosive_Shotgun_S12
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_Shotgun_S12 extends KFDT_EMP
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood=true
// physics impact
RadialDamageImpulse=3000 //5000 //20000
GibImpulseScale=0.15
KDeathUpKick=1000
KDeathVel=300
// unreal physics momentum
bExtraMomentumZ=True
bCanGib=true
KnockdownPower=100
StunPower=25
StumblePower=200
EMPPower=100
//Perk
ModifierPerkList(0)=class'KFPerk_Support'
WeaponDef=class'KFWeapDef_Shotgun_S12'
bCanApplyRadialCalculationtoAffliction=false
}

View File

@ -0,0 +1,36 @@
//=============================================================================
// KFExplosion_HRG_Warthog
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_HRG_Warthog extends KFExplosionActor;
var private int HealingValue;
// Disable Knockdown for friendlies
protected function bool KnockdownPawn(BaseAiPawn Victim, float DistFromExplosion)
{
if (Victim.GetTeamNum() != Instigator.GetTeamNum())
{
return Super.KnockdownPawn(Victim, DistFromExplosion);
}
return false;
}
// Disable Stumble for friendlies
protected function bool StumblePawn(BaseAiPawn Victim, float DistFromExplosion)
{
if (Victim.GetTeamNum() != Instigator.GetTeamNum())
{
return Super.StumblePawn(Victim, DistFromExplosion);
}
return false;
}
DefaultProperties
{
}

View File

@ -882,14 +882,35 @@ function StartWave()
WaveNum++;
MyKFGRI.WaveNum = WaveNum;
if (IsMapObjectiveEnabled())
if (MyKFGRI.IsContaminationMode())
{
if (WaveNum == 1) // Only on first wave..
{
MyKFGRI.ChooseNextObjective(WaveNum);
}
MyKFGRI.ClearPreviousObjective();
if (WaveNum != WaveMax)
{
if (MyKFGRI.StartNextObjective())
{
WaveBuffer = ObjectiveSpawnDelay;
}
}
}
else
{
if (IsMapObjectiveEnabled())
{
MyKFGRI.ClearPreviousObjective();
if (MyKFGRI.StartNextObjective())
{
WaveBuffer = ObjectiveSpawnDelay;
}
}
}
SetupNextWave(WaveBuffer);

View File

@ -33,6 +33,32 @@ var array<PerkRoulette_PlayerMessageDelegate> PerkRoulette_PlayersDelegateData;
var array<KFPlayerController_WeeklySurvival> PerkRoulette_PlayersDelegateInventory;
struct ContaminationModeData
{
var() float FirstWaveInitialTimer;
var() float WaveInitialTimer;
var() float WaveCurrentTimer;
var() float GraceTimer; // We store on each Player the GraceCurrentTimer
var() float DamageTimer;
var() float DamageCurrentTimer;
var() bool ObjectiveHidden;
var() bool CanUpdate;
structdefaultproperties
{
FirstWaveInitialTimer = 45.f
WaveInitialTimer = 30.f
WaveCurrentTimer = 0.f
GraceTimer = 5.f
DamageTimer = 1.f
DamageCurrentTimer = 0.f
ObjectiveHidden = false
CanUpdate = false
}
};
var ContaminationModeData ContaminationMode;
//-----------------------------------------------------------------------------
// Statics
static event class<GameInfo> SetGameType(string MapName, string Options, string Portal)
@ -538,6 +564,18 @@ function Tick(float DeltaTime)
// This deals with players joining at any time (lobby, or in wave)
ChooseRandomPerks(false);
}
if (MyKFGRI.IsContaminationMode())
{
if (ContaminationMode.CanUpdate)
{
UpdateContaminationMode(DeltaTime);
}
else if (WaveNum < (WaveMax - 1))
{
UpdateContaminationModeTrader();
}
}
}
function TickZedTime( float DeltaTime )
@ -576,6 +614,11 @@ function WaveEnded(EWaveEndCondition WinCondition)
ChooseRandomPerks(true);
}
if (MyKFGRI.IsContaminationMode())
{
ContaminationMode.CanUpdate = false;
}
super.WaveEnded(WinCondition);
if (OutbreakEvent.ActiveEvent.bPermanentZedTime && ZedTimeRemaining > ZedTimeBlendOutTime)
@ -614,6 +657,19 @@ function GrantExtraDoshOnWaveWon()
KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo).AddDosh(ExtraDosh, true);
}
}
if (MyKFGRI.IsContaminationMode())
{
ExtraDosh = MyKFGRI.ContaminationModeExtraDosh();
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
{
if (KFPC.IsInState('Spectating') == false
&& KFPC.PlayerReplicationInfo.bOnlySpectator == false)
{
KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo).AddDosh(ExtraDosh, true);
}
}
}
}
function ClearZedTimePCTimers()
@ -687,6 +743,22 @@ function StartWave()
{
OverridePickupList();
}
if (MyKFGRI.IsContaminationMode())
{
if (WaveNum == 1)
{
ContaminationMode.WaveCurrentTimer = ContaminationMode.FirstWaveInitialTimer;
}
else
{
ContaminationMode.WaveCurrentTimer = ContaminationMode.WaveInitialTimer;
}
ContaminationMode.DamageCurrentTimer = ContaminationMode.DamageTimer;
ContaminationMode.ObjectiveHidden = false;
ContaminationMode.CanUpdate = true;
}
}
function bool OverridePickupList()
@ -1187,6 +1259,14 @@ function NotifyKilled(Controller Killer, Controller Killed, Pawn KilledPawn, cla
PerkRoulette_PlayersDelegateInventory.AddItem(KFPC_WS_Killed);
}
}
if (MyKFGRI.IsContaminationMode())
{
if (KFPC_WS_Killed != none)
{
KFPC_WS_Killed.HideContaminationMode();
}
}
}
function GunGameLevelGrantWeapon(KFPlayerController_WeeklySurvival KFPC_WS, class<KFWeaponDefinition> ToGrantWeaponDefinition)
@ -1827,6 +1907,189 @@ function BroadcastCustomDelegate()
}
}
/*
* Weekly 19: Contamination Mode
*/
function UpdatePlayersState(KFMapObjective_DoshHold Area
, out array<KFPlayerController_WeeklySurvival> ValidPlayers
, out array<KFPlayerController_WeeklySurvival> PlayersInsideArea
, out array<KFPlayerController_WeeklySurvival> PlayersOutsideArea)
{
local KFPlayerController_WeeklySurvival KFPC_WS;
local int i;
// Get available players
foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS)
{
if (KFPC_WS.Pawn.IsAliveAndWell() == false
|| KFPC_WS.PlayerReplicationInfo.bOnlySpectator
|| KFPC_WS.IsInState('Spectating'))
{
continue;
}
ValidPlayers.AddItem(KFPC_WS);
}
// Update who's in and who's out
for (i = 0 ; i < ValidPlayers.Length ; ++i)
{
// If is inside..
if (Area.TouchingHumans.Find(KFPawn_Human(ValidPlayers[i].Pawn)) != INDEX_NONE)
{
PlayersInsideArea.AddItem(ValidPlayers[i]);
}
else
{
PlayersOutsideArea.AddItem(ValidPlayers[i]);
}
}
}
function UpdateContaminationModeTrader()
{
local KFMapObjective_DoshHold Area;
local array<KFPlayerController_WeeklySurvival> ValidPlayers, PlayersInsideArea, PlayersOutsideArea;
local int i;
Area = KFMapObjective_DoshHold(MyKFGRI.NextObjective);
if (Area != none)
{
UpdatePlayersState(Area, ValidPlayers, PlayersInsideArea, PlayersOutsideArea);
for (i = 0 ; i < PlayersInsideArea.Length ; ++i)
{
PlayersInsideArea[i].ShowContaminationMode();
PlayersInsideArea[i].UpdateContaminationModeWidget(true);
}
for (i = 0 ; i < PlayersOutsideArea.Length ; ++i)
{
PlayersOutsideArea[i].ShowContaminationMode();
PlayersOutsideArea[i].ContaminationModePlayerIsInside = false;
PlayersOutsideArea[i].UpdateContaminationModeWidget_Timer(ContaminationMode.WaveInitialTimer);
}
}
}
function UpdateContaminationMode(float DeltaTime)
{
local KFMapObjective_DoshHold Area;
local array<KFPlayerController_WeeklySurvival> ValidPlayers, PlayersInsideArea, PlayersOutsideArea;
local KFPlayerController_WeeklySurvival KFPC_WS;
local int i;
local bool CheckPlayersInArea, CanApplyDamage;
CheckPlayersInArea = false;
// Update wave timer..
if (ContaminationMode.WaveCurrentTimer > 0.f)
{
ContaminationMode.WaveCurrentTimer -= DeltaTime;
}
if (MyKFGRI.CurrentObjective != none)
{
foreach WorldInfo.AllActors(class'KFMapObjective_DoshHold', Area)
{
if (Area.IsActive())
{
CheckPlayersInArea = true;
UpdatePlayersState(Area, ValidPlayers, PlayersInsideArea, PlayersOutsideArea);
break;
}
}
}
// If there's a valid area an objective..
if (CheckPlayersInArea && WaveNum != WaveMax)
{
// Trigger logic depending on state of game
if (ContaminationMode.WaveCurrentTimer > 0.f)
{
// If we are still on safe time to reach area, we can only notify Player if you are inside or outside, no Grace Timer, and No Damage applied
for (i = 0 ; i < PlayersInsideArea.Length ; ++i)
{
PlayersInsideArea[i].UpdateContaminationModeWidget(true);
}
for (i = 0 ; i < PlayersOutsideArea.Length ; ++i)
{
PlayersOutsideArea[i].ContaminationModePlayerIsInside = false;
PlayersOutsideArea[i].UpdateContaminationModeWidget_Timer(ContaminationMode.WaveCurrentTimer);
}
}
else
{
// If Time finished, we must Damage Players that are outside (use Grace Timer)
if (ContaminationMode.DamageCurrentTimer > 0.f)
{
ContaminationMode.DamageCurrentTimer -= DeltaTime;
}
CanApplyDamage = ContaminationMode.DamageCurrentTimer <= 0.f;
// Reset damage tick
if (CanApplyDamage)
{
ContaminationMode.DamageCurrentTimer = ContaminationMode.DamageTimer;
}
for (i = 0 ; i < PlayersInsideArea.Length ; ++i)
{
PlayersInsideArea[i].ContaminationModeGraceCurrentTimer = ContaminationMode.GraceTimer;
PlayersInsideArea[i].UpdateContaminationModeWidget(true);
}
for (i = 0 ; i < PlayersOutsideArea.Length ; ++i)
{
if (PlayersOutsideArea[i].ContaminationModeGraceCurrentTimer > 0.f)
{
PlayersOutsideArea[i].ContaminationModeGraceCurrentTimer -= DeltaTime;
}
PlayersOutsideArea[i].UpdateContaminationModeWidget(false);
if (CanApplyDamage && PlayersOutsideArea[i].ContaminationModeGraceCurrentTimer <= 0.f)
{
PlayersOutsideArea[i].Pawn.TakeDamage(class'KFDT_WeeklyContamination'.static.GetDamage(), none, vect(0,0,0), vect(0,0,0), class'KFDT_WeeklyContamination');
}
}
}
}
else
{
// Hide UIs if no more objective
if (ContaminationMode.ObjectiveHidden == false)
{
ContaminationMode.ObjectiveHidden = true;
foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC_WS)
{
if (KFPC_WS.Pawn.IsAliveAndWell() == false
|| KFPC_WS.PlayerReplicationInfo.bOnlySpectator
|| KFPC_WS.IsInState('Spectating'))
{
continue;
}
KFPC_WS.HideContaminationMode();
}
}
}
}
//
defaultproperties

View File

@ -62,6 +62,25 @@ simulated function NotifyWaveStart()
super.NotifyWaveStart();
}
function ChooseNextObjective(int NextWaveNum)
{
local KFMapInfo KFMI;
if (IsContaminationMode() == false)
{
super.ChooseNextObjective(NextWaveNum);
}
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if (KFMI != none && NextWaveNum != WaveMax)
{
bForceNextObjective = true; // this overrides the objective chance, so it just chooses randomnly between all them
ChooseNextRandomObjective(KFMI, NextWaveNum, false);
}
}
DefaultProperties
{
bIsWeeklyMode=True

View File

@ -95,7 +95,7 @@ simulated function AddToOwnerArray()
}
}
simulated function TakeRadiusDamage(Controller InstigatedBy, float BaseDamage, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HurtOrigin, bool bFullDamage, Actor DamageCauser, optional float DamageFalloffExponent = 1.f)
simulated function TakeRadiusDamage(Controller InstigatedBy, float BaseDamage, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HurtOrigin, bool bFullDamage, Actor DamageCauser, optional float DamageFalloffExponent = 1.f, optional bool bAdjustRadiusDamage=true)
{
if (!bIgnoreRadiusDamage || AcceptedDamageTypes.Find(DamageType) != INDEX_NONE)
{

View File

@ -94,6 +94,7 @@ var() float RemindPlayersTime;
var transient float PrevWaveProgress;
var transient bool bRemindPlayers;
var Texture2D ContaminationIcon;
simulated event ReplicatedEvent(name VarName)
{
@ -125,11 +126,95 @@ event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vecto
}
}
simulated function bool ShouldDrawIcon()
{
local KFGameReplicationInfo KFGRI;
if (WorldInfo != None && WorldInfo.Game != none && WorldInfo.Game.GameReplicationInfo != none)
{
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI != none && KFGRI.IsContaminationMode())
{
return KFGRI.AIRemaining > KFGRI.ContaminationModeZedsToFinish();
}
}
return Super.ShouldDrawIcon();
}
simulated function GrantReward(KFPlayerReplicationInfo KFPRI, KFPlayerController KFPC)
{
local KFGameReplicationInfo KFGRI;
Super.GrantReward(KFPRI, KFPC);
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI == none)
{
return;
}
if (KFGRI.IsContaminationMode() == false)
{
if (KFPRI == none)
{
return;
}
if (KFPRI.bOnlySpectator)
{
return;
}
if (KFPC != none)
{
// Summer 2023 objective
KFPC.ClientOnTryCompleteObjective(3, SEI_Summer);
}
}
}
function NotifyZedKilled(Controller Killer, Pawn KilledPawn, bool bIsBoss)
{
local int i;
local KFGameInfo KFGI;
local KFGameReplicationInfo KFGRI;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo KFPRI;
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI != none && KFGRI.IsContaminationMode())
{
if (ROLE == Role_Authority)
{
if (bActive)
{
if (KFGRI.AIRemaining <= KFGRI.ContaminationModeZedsToFinish())
{
DeactivateObjective();
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
{
if (KFPC != none)
{
KFPRI = KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo);
if (KFPRI != none && KFPRI.bOnlySpectator == false)
{
// Summer 2023 objective
KFPC.ClientOnTryCompleteObjective(3, SEI_Summer);
}
}
}
}
}
}
return;
}
if (ROLE == Role_Authority)
{
@ -144,7 +229,6 @@ function NotifyZedKilled(Controller Killer, Pawn KilledPawn, bool bIsBoss)
{
if (RewardPerZed == 0)
{
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
RewardPerZed = GetMaxDoshReward() / (PctOfWaveZedsKilledForMaxReward * KFGRI.WaveTotalAICount);
}
CurrentRewardAmount = FMin(CurrentRewardAmount + RewardPerZed, float(GetMaxDoshReward()));
@ -237,6 +321,16 @@ function StartPenaltyCheck()
function ActivationVO()
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI != none && KFGRI.IsContaminationMode())
{
PlaySoundBase(AkEvent'WW_VOX_NPC_Trader.Play_Trader_DEFA_Area', false, WorldInfo.NetMode == NM_DedicatedServer);
return;
}
if (ActivationSoundEventOverride != none)
{
PlaySoundBase(ActivationSoundEventOverride, false, WorldInfo.NetMode == NM_DedicatedServer);
@ -373,6 +467,15 @@ simulated function DeactivateObjective()
function PlayDeactivationDialog()
{
local KFGameReplicationInfo KFGRI;
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI != none && KFGRI.IsContaminationMode())
{
return;
}
if (CurrentRewardAmount <= 0)
{
if (FailureSoundEventOverride != none)
@ -499,6 +602,23 @@ simulated function bool ShouldShowObjectiveHUD()
return !IsComplete();
}
simulated function Texture2D GetIcon()
{
local KFGameReplicationInfo KFGRI;
if (WorldInfo != None && WorldInfo.Game != none && WorldInfo.Game.GameReplicationInfo != none)
{
KFGRI = KFGameReplicationInfo(WorldInfo.Game.GameReplicationInfo);
if (KFGRI != none && KFGRI.IsContaminationMode())
{
return ContaminationIcon;
}
}
return ObjectiveIcon;
}
defaultproperties
{
DescriptionLocKey="DescriptionDoshHold"
@ -561,7 +681,7 @@ defaultproperties
ZedThresholds[5]=0
ObjectiveIcon=Texture2D'Objectives_UI.UI_Objectives_ObjectiveMode'
ContaminationIcon=Texture2D'Objectives_UI.UI_Objectives_Xmas_DefendObj'
RemindPlayersTime=30.f
bUseEarlyTrail=false

View File

@ -1235,6 +1235,21 @@ defaultproperties
)}
)}
// Contamination Mode
SetEvents[19]={(
EventDifficulty=2,
GameLength=GL_Normal,
ContaminationModeZedsToFinish=5,
ContaminationModeExtraDosh=200,
SpawnReplacementList={(
(SpawnEntry=AT_EliteCrawler,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=0.9),
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedDAR_Laser'),PercentChance=0.2),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedDAR_Rocket'),PercentChance=0.2)
)}
)}
//Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8

View File

@ -105,6 +105,9 @@ const NoAmmoSocketName = 'malfunction';
const NoAmmoFXTemplate = ParticleSystem'WEP_AutoTurret_EMIT.FX_NoAmmo_Sparks';
var transient ParticleSystemComponent NoAmmoFX;
var transient vector DeployLastLocation;
var transient float LastMoveExpectedSize;
replication
{
if( bNetDirty )
@ -374,7 +377,7 @@ simulated state Deploy
SetTimer(AnimDuration, false, nameof(StartIdleAnim));
}
SetPhysics(PHYS_FLYING);
SetPhysics(PHYS_NONE);
if (Role == ROLE_Authority)
{
@ -390,16 +393,28 @@ simulated state Deploy
super.Tick(DeltaTime);
// If we didn't move..
if (VSize(Location - DeployLastLocation) < (LastMoveExpectedSize * 0.8f))
{
SetTurretState(ETS_TargetSearch);
return;
}
LocationNext = Location;
LocationNext.z += Velocity.z * DeltaTime;
// If there's little to no movement or we are going to collide
if (Velocity.z <= 0.01f || !FastTrace(LocationNext, Location, vect(25,25,25)))
// If we are going to collide stop
if (!FastTrace(LocationNext, Location, vect(25,25,25)))
{
SetTurretState(ETS_TargetSearch);
return;
}
else
{
DeployLastLocation = Location;
LastMoveExpectedSize = VSize(LocationNext - Location);
SetLocation(LocationNext);
// Check height to change state
CurrentHeight = Location.Z - GroundLocation.Z;
if (CurrentHeight >= DeployHeight)
@ -407,7 +422,6 @@ simulated state Deploy
SetTurretState(ETS_TargetSearch);
}
}
}
simulated function EndState(name NextStateName)
{
@ -425,6 +439,8 @@ simulated state Deploy
SetTimer(0.25f, true, nameof(CheckEnemiesWithinExplosionRadius));
}
}
SetPhysics(PHYS_NONE);
}
}
@ -533,6 +549,8 @@ simulated state Combat
local float NewAmmoPercentage;
local bool bIsSpotted;
if (Role == ROLE_Authority)
{
TurretWeapon.GetMuzzleLocAndRot(MuzzleLoc, MuzzleRot);
@ -565,11 +583,14 @@ simulated state Combat
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, EnemyTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
/** Search for new enemies if current is dead, cloaked or too far, or something between the drone and the target except a player */
// Visible by local player or team
bIsSpotted = (EnemyTarget.bIsCloakingSpottedByLP || EnemyTarget.bIsCloakingSpottedByTeam);
/** Search for new enemies if current is dead, cloaked or too far, or something between the drone that's world geometry */
if (!EnemyTarget.IsAliveAndWell()
|| EnemyTarget.bIsCloaking
|| (EnemyTarget.bIsCloaking && bIsSpotted == false)
|| VSizeSq(EnemyTarget.Location - Location) > EffectiveRadius * EffectiveRadius
|| (HitActor != none && KFPawn_Monster(HitActor) == none && KFPawn_Human(HitActor) == none))
|| (HitActor != none && HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
{
EnemyTarget = none;
CheckForTargets();
@ -590,13 +611,13 @@ simulated state Combat
RotateBySpeed(DesiredRotationRot);
if (Role == ROLE_Authority)
if (Role == ROLE_Authority && ReachedRotation())
{
HitActor = Trace(HitLocation, HitNormal, MuzzleLoc + vector(Rotation) * EffectiveRadius, MuzzleLoc, , , HitInfo, TRACEFLAG_Bullet);
if (TurretWeapon != none)
{
if (KFPawn_Monster(HitActor) != none)
if (HitActor != none && HitActor.bWorldGeometry == false)
{
TurretWeapon.Fire();
@ -641,6 +662,7 @@ simulated state Detonate
{
ExploActor.InstigatorController = Instigator.Controller;
ExploActor.Instigator = Instigator;
ExploActor.bIgnoreInstigator = true;
ExploActor.Explode(ExplosionTemplate);
}
@ -732,6 +754,8 @@ function CheckForTargets()
local vector HitLocation, HitNormal;
local Actor HitActor;
local bool bIsSpotted;
if (EnemyTarget != none)
{
CurrentDistance = VSizeSq(Location - EnemyTarget.Location);
@ -745,10 +769,19 @@ function CheckForTargets()
foreach CollidingActors(class'KFPawn_Monster', CurrentTarget, EffectiveRadius, Location, true,, HitInfo)
{
// Visible by local player or team
bIsSpotted = (CurrentTarget.bIsCloakingSpottedByLP || CurrentTarget.bIsCloakingSpottedByTeam);
if (!CurrentTarget.IsAliveAndWell()
|| (CurrentTarget.bIsCloaking && bIsSpotted == false))
{
continue;
}
// Trace from the Target reference to MuzzleLoc, because MuzzleLoc could be already inside physics, as it's outside the collider of the Drone!
HitActor = Trace(HitLocation, HitNormal, CurrentTarget.Mesh.GetBoneLocation('Spine1'), MuzzleLoc,,,,TRACEFLAG_Bullet);
if (!CurrentTarget.IsAliveAndWell() || CurrentTarget.bIsCloaking || HitActor == none || KFPawn_Monster(HitActor) == none)
if (HitActor == none || (HitActor.bWorldGeometry && KFFracturedMeshGlass(HitActor) == None))
{
continue;
}
@ -992,7 +1025,8 @@ simulated function TakeRadiusDamage(
vector HurtOrigin,
bool bFullDamage,
Actor DamageCauser,
optional float DamageFalloffExponent=1.f
optional float DamageFalloffExponent=1.f,
optional bool bAdjustRadiusDamage=true
)
{}
@ -1001,6 +1035,16 @@ function bool CanAITargetThisPawn(Controller TargetingController)
return false;
}
simulated function bool CanInteractWithPawnGrapple()
{
return false;
}
simulated function bool CanInteractWithZoneVelocity()
{
return false;
}
simulated function UpdateTurretMeshMaterialColor(float Value)
{
if (TurretWeaponAttachment == none)
@ -1104,6 +1148,9 @@ defaultproperties
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
bIgnoreInstigator=true
ActorClassToIgnoreForDamage = class'KFPawn_Human'
End Object
ExplosionTemplate=ExploTemplate0
@ -1163,4 +1210,7 @@ defaultproperties
bAlwaysRelevant=true
AutoTurretFlashCount=0
DeployLastLocation=(X=-9999.f, Y=-9999.f, Z=-9999.f)
LastMoveExpectedSize= 0.f
}

File diff suppressed because it is too large Load Diff

View File

@ -391,6 +391,7 @@ defaultproperties
// ---------------------------------------------
// AI / Navigation
EliteAIType.Add(14); // AT_EliteCrawler
ElitePawnClass.Add(class'KFPawn_ZedCrawlerKing')
ControllerClass=class'KFAIController_ZedCrawler'
bDebugCrawlerPhysics=false

View File

@ -124,10 +124,19 @@ simulated function CreateExhaustFx()
event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
local class<KFDamageType> KFDT;
super.TakeDamage( Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser );
if( bCanRage && !bPlayedDeath && (GetHealthPercentage() < RageHealthThreshold || GetHeadHealthPercent() < RageHealthThreshold) )
{
KFDT = class<KFDamageType>(DamageType);
if (KFDT != none && KFDT.default.bCanEnrage == false)
{
return;
}
SetEnraged( true );
}
}

View File

@ -35,6 +35,20 @@ function CausePainTo(Actor Other)
}
}
simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
local KFPawn KFP;
KFP = KFPawn(Other);
if (KFP != none && KFP.CanInteractWithZoneVelocity() == false)
{
return;
}
Super.Touch(Other, OtherComp, HitLocation, HitNormal);
}
simulated event UnTouch(Actor Other)
{
local int RecentHitIdx;

View File

@ -205,7 +205,7 @@ defaultproperties
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=350
DamageRadius=200
DamageRadius=250
DamageFalloffExponent=1.f
DamageDelay=0.f
@ -240,7 +240,7 @@ defaultproperties
End Object
StickHelper=StickHelper0
SecondsBeforeDetonation=0.5f
SecondsBeforeDetonation=0.2f
bIsProjActive=true
bCanDisintegrate=true
bAlwaysReplicateExplosion=true

View File

@ -241,7 +241,7 @@ defaultproperties
End Object
StickHelper=StickHelper0
SecondsBeforeDetonation=0.5f
SecondsBeforeDetonation=0.2f
bIsProjActive=true
bCanDisintegrate=true
bAlwaysReplicateExplosion=true

View File

@ -0,0 +1,137 @@
//=============================================================================
// KFProj_Bullet_Shotgun_S12_Alt
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_Shotgun_S12_Alt extends KFProj_BallisticExplosive
hidedropdown;
var protected KFWeapon OwnerWeapon;
/** Initialize the projectile */
function Init( vector Direction )
{
super.Init( Direction );
OwnerWeapon = KFWeapon( Owner );
if( OwnerWeapon != none )
{
OwnerWeapon.LastPelletFireTime = WorldInfo.TimeSeconds;
}
if (KFPawn(Instigator) != none)
{
// Explode right away
ForceExplode();
}
}
reliable client function ForceExplode()
{
local vector Normal, MuzzleLocation;
if (KFPawn(Instigator) != none)
{
Normal.X = 0.f;
Normal.Y = 0.f;
Normal.Z = 1.f;
KFSkeletalMeshComponent(OwnerWeapon.Mesh).GetSocketWorldLocationAndRotation('MuzzleFlashAlt', MuzzleLocation);
Explode(MuzzleLocation, Normal);
Detonate();
}
}
simulated function bool CanDud()
{
return false;
}
/** Don't allow more than one pellet projectile to perform this check in a single frame */
function bool ShouldWarnAIWhenFired()
{
return super.ShouldWarnAIWhenFired() && OwnerWeapon != none && OwnerWeapon.LastPelletFireTime < WorldInfo.TimeSeconds;
}
simulated protected function PrepareExplosionTemplate()
{
super.PrepareExplosionTemplate();
/** Since bIgnoreInstigator is transient, its value must be defined here */
ExplosionTemplate.bIgnoreInstigator = true;
}
simulated function AdjustCanDisintigrate() {}
/** Can be overridden in subclasses to exclude specific projectiles from nuking */
simulated function bool AllowNuke()
{
return false;
}
defaultproperties
{
ArmDistSquared=0.f
MaxSpeed=0.0
Speed=0.0
DamageRadius=0
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=252,G=218,B=171,A=255)
Brightness=0.5f
Radius=400.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=200
DamageRadius=800
DamageFalloffExponent=0.f
DamageDelay=0.f
MomentumTransferScale=10000
bAlwaysFullDamage=true
bDoCylinderCheck=true
// Damage Effects
MyDamageType=class'KFDT_Explosive_Shotgun_S12'
KnockDownStrength=150
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionSound=AkEvent'WW_WEP_Saiga12.Play_WEP_Saiga12_Alt_Fire_1P'
ExplosionEffects=KFImpactEffectInfo'WEP_Saiga12_ARCH.WEP_Saiga12_Impacts'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.3
bIgnoreInstigator=true
ActorClassToIgnoreForDamage = class'KFPawn_Human'
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=0
CamShakeOuterRadius=300
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ExploTemplate0
}

View File

@ -14,6 +14,8 @@ class KFProj_Explosive_HRG_Kaboomstick extends KFProj_BallisticExplosive
/** Cached reference to owner weapon */
var protected KFWeapon OwnerWeapon;
var bool bCanNuke;
/** Initialize the projectile */
function Init( vector Direction )
{
@ -37,25 +39,9 @@ function bool ShouldWarnAIWhenFired()
*/
simulated protected function PrepareExplosionTemplate()
{
local KFPawn KFP;
local KFPerk CurrentPerk;
ExplosionTemplate.bIgnoreInstigator = true;
super.PrepareExplosionTemplate();
if( ExplosionActorClass == class'KFPerk_Demolitionist'.static.GetNukeExplosionActorClass() )
{
KFP = KFPawn( Instigator );
if( KFP != none )
{
CurrentPerk = KFP.GetPerk();
if( CurrentPerk != none )
{
CurrentPerk.SetLastHX25NukeTime( WorldInfo.TimeSeconds );
}
}
}
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
@ -76,20 +62,7 @@ simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallCom
/** Only allow this projectile to cause a nuke if there hasn't been another nuke very recently */
simulated function bool AllowNuke()
{
local KFPawn KFP;
local KFPerk CurrentPerk;
KFP = KFPawn( Instigator );
if( KFP != none )
{
CurrentPerk = KFP.GetPerk();
if( CurrentPerk != none && `TimeSince(CurrentPerk.GetLastHX25NukeTime()) < 0.25f )
{
return false;
}
}
return super.AllowNuke();
return bCanNuke;
}
defaultproperties
@ -164,4 +137,6 @@ defaultproperties
AmbientSoundPlayEvent=none
AmbientSoundStopEvent=none
bCanNuke = true
}

View File

@ -137,7 +137,7 @@ defaultproperties
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=60
Damage=45
DamageRadius=200
DamageFalloffExponent=0.5f
DamageDelay=0.f

View File

@ -0,0 +1,422 @@
//=============================================================================
// KFProj_HighExplosive_HRG_Warthog
//=============================================================================
// High explosive grenade launcher grenade for the HRG Warthog
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFProj_HighExplosive_HRG_Warthog extends KFProj_BallisticExplosive
hidedropdown;
var transient bool bHitWall;
simulated event PreBeginPlay()
{
local KFPawn InstigatorPawn;
local KFPawn_HRG_Warthog InstigatorPawnWarthog;
InstigatorPawnWarthog = KFPawn_HRG_Warthog(Instigator);
if (InstigatorPawnWarthog != none)
{
InstigatorPawn = KFPawn(InstigatorPawnWarthog.OwnerWeapon.Instigator);
if (InstigatorPawn != none)
{
Instigator = InstigatorPawn;
}
}
Super.PreBeginPlay();
}
simulated function bool AllowNuke()
{
return true;
}
simulated function bool AllowDemolitionistConcussive()
{
return true;
}
simulated function bool AllowDemolitionistExplosionChangeRadius()
{
return true;
}
// Used by Demolitionist Nuke and Mad Bomber skills
simulated function bool CanDud()
{
return false;
}
simulated function SetupDetonationTimer(float FuseTime)
{
if (FuseTime > 0)
{
bIsTimedExplosive = true;
SetTimer(FuseTime, false, 'ExplodeTimer');
}
}
function ExplodeTimer()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
GetExplodeEffectLocation(HitLocation, HitNormal, HitActor);
TriggerExplosion(HitLocation, HitNormal, HitActor);
}
/**
* 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);
}
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
local Vector VNorm;
local rotator NewRotation;
local Vector Offset;
bHitWall = true;
if (bIsTimedExplosive)
{
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
if (WorldInfo.NetMode != NM_DedicatedServer && Pawn(Wall) == none)
{
// do the impact effects
`ImpactEffectManager.PlayImpactEffects(Location, Instigator, HitNormal, GrenadeBounceEffectInfo, true );
}
// if we hit a pawn or we are moving too slowly stop moving and lay down flat
if ( Speed < MinSpeedBeforeStop )
{
ImpactedActor = Wall;
SetPhysics(PHYS_None);
if( ProjEffects != none )
{
ProjEffects.SetTranslation(LandedTranslationOffset);
}
// Position the shell on the ground
RotationRate.Yaw = 0;
RotationRate.Pitch = 0;
RotationRate.Roll = 0;
NewRotation = Rotation;
NewRotation.Pitch = 0;
if(ResetRotationOnStop)
{
SetRotation(NewRotation);
}
Offset.Z = LandedTranslationOffset.X;
SetLocation(Location + Offset);
}
return;
}
if( WorldInfo.NetMode == NM_Standalone ||
(WorldInfo.NetMode == NM_ListenServer && Instigator != none && Instigator.IsLocallyControlled()) )
{
TriggerExplosion(Location, HitNormal, None);
Shutdown(); // cleanup/destroy projectile
return;
}
if( Owner != none && KFWeapon( Owner ) != none && Instigator != none )
{
if( Instigator.Role == ROLE_Authority)
{
KFWeap_HRG_WarthogWeapon(Owner).ForceExplosionReplicateKill(Location, self);
}
}
StopSimulating(); // cleanup/destroy projectile
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
// If we collided with a Siren shield, let the shield code handle touches
if( Other.IsA('KFTrigger_SirenProjectileShield') )
{
return;
}
if ( !bCollideWithTeammates && Pawn(Other) != None )
{
// Don't hit teammates
if( Other.GetTeamNum() == GetTeamNum() )
{
return;
}
}
// Process impact hits
if (Other != Instigator && !Other.bStatic)
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
if (bIsTimedExplosive)
{
return;
}
if( WorldInfo.NetMode == NM_Standalone ||
(WorldInfo.NetMode == NM_ListenServer && Instigator != none && Instigator.IsLocallyControlled()) )
{
// Call KFProjectile base code.. as we don't want to repeat the KFProj_BallisticExplosive base again
TriggerExplosion(HitLocation, HitNormal, Other);
Shutdown(); // cleanup/destroy projectile
return;
}
if( Owner != none && KFWeapon( Owner ) != none && Instigator != none )
{
// Special case, for some very complicate reason around replication, instigators and the Warthog pawn
// This code on the base class was never triggered on Clients: (IsLocallyControlled() always fails, also on the rightful owner of he projectile)
// if( Instigator.Role < ROLE_Authority && Instigator.IsLocallyControlled() )
// Hence we call here a reliable client function on the Owner
// That will call exactly the same code that's inside that If on the base class of this file
if( Instigator.Role == ROLE_Authority)
{
KFWeap_HRG_WarthogWeapon(Owner).ForceExplosionReplicate(Other, HitLocation, HitNormal, self);
}
}
StopSimulating();
}
simulated event Tick(float DeltaTime)
{
Super.Tick(DeltaTime);
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if (bHitWall == false)
{
SetRotation(rotator(Normal(Velocity)));
}
}
}
/** This will cause the projectile to move to the Original Spawn location when first replicated. This solves the issue of the projectile spawning some distance away from the player when first replicated */
simulated function SyncOriginalLocation()
{
local vector MuzzleLocation, PredictedHitLocation, AimDir, EndTrace, MuzzleToPredictedHit;
if ( WorldInfo.NetMode == NM_DedicatedServer )
{
return;
}
// For remote pawns, have the projectile look like its actually
// coming from the muzzle of the third person weapon
if( bSyncToThirdPersonMuzzleLocation && Instigator != none
&& !Instigator.IsFirstPerson() && KFPawn(Owner) != none
&& KFPawn(Owner).WeaponAttachment != none )
{
MuzzleLocation = KFPawn(Owner).WeaponAttachment.GetMuzzleLocation(bFiredFromLeftHandWeapon ? 1 : 0);
// Set the aim direction to the vector along the line where the
// projectile would hit based on velocity. This is the most accurate
if( !IsZero(Velocity) )
{
AimDir = Normal(Velocity);
}
// Set the aim direction to the vector along the line where the
// projectile would hit based on where it has moved away from
// the original location
if( IsZero(Velocity) )
{
AimDir = Normal(Location-OriginalLocation);
}
// Use the rotation if the location calcs give a zero direction
if( IsZero(AimDir) )
{
AimDir = Normal(Vector(Rotation));
}
if( Location != MuzzleLocation )
{
// if projectile is spawned at different location than the third
// person muzzle location, then simulate an instant trace where
// the projectile would hit
EndTrace = Location + AimDir * 16384;
PredictedHitLocation = GetPredictedHitLocation(Location, EndTrace);
MuzzleToPredictedHit = Normal(PredictedHitLocation - MuzzleLocation);
// only adjust AimDir if PredictedHitLocation is "forward" (i.e. don't let projectile fire back towards the shooter)
//@todo: still need to make this less wonky (can still shoot straight up sometimes when using long weapons, like the sawblade shooter)
if( MuzzleToPredictedHit dot vector(Rotation) > 0.f )
{
// Then we realign projectile aim direction to match where the projectile would hit.
AimDir = MuzzleToPredictedHit;
}
}
// Move the projectile to the MuzzleLocation
SetLocation(MuzzleLocation);
// If the Velocity is zero (usually because the projectile impacted
// something on the server in its first tick before replicating)
// then turn its phyics and collion back on
if( IsZero(Velocity) )
{
SetPhysics(default.Physics);
SetCollision( default.bCollideActors, default.bBlockActors );
}
// Adjust the velocity of the projectile so it will hit where
// it is supposed to
Velocity = Speed * Normal(AimDir);
}
// set location based on 'OriginalLocation'
else if ( Role < ROLE_Authority )
{
// If the Velocity is zero (usually because the projectile impacted
// something on the server in its first tick before replicating)
// then turn its physics and collion back on and give it velocity
// again so the simulation will work properly on the client
if( IsZero(Velocity) )
{
SetPhysics(default.Physics);
// Set the aim direction to the vector along the line where the
// projectile would hit
AimDir = Normal(Location-OriginalLocation);
// Use the rotation if the location calcs give a zero direction
if( IsZero(AimDir) )
{
AimDir = Vector(Rotation);
}
Velocity = Speed * AimDir;
SetCollision( default.bCollideActors, default.bBlockActors );
}
SetLocation(OriginalLocation);
}
}
defaultproperties
{
bCollideWithTeammates = false
Physics=PHYS_Falling
Speed=2000
MaxSpeed=2000
TerminalVelocity=2000
TossZ=0
GravityScale=1.0
MomentumTransfer=50000.0
ArmDistSquared=0
LifeSpan=25.0f
bIsTimedExplosive = false
bWarnAIWhenFired=true
ProjFlightTemplate=ParticleSystem'WEP_HRG_Warthog_EMIT.FX_HRG_Warthog_Projectile'
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Warthog_EMIT.FX_HRG_Warthog_Projectile_ZEDTIME'
ProjDudTemplate=ParticleSystem'WEP_HRG_Warthog_EMIT.FX_HRG_Warthog_Projectile_Dud'
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_HRG_Warthog_ARCH.HRG_Warthog_Explosion_Concussive_Force'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=252,G=218,B=171,A=255)
Brightness=4.f
Radius=2000.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
ExplosionActorClass=class'KFExplosion_HRG_Warthog'
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=35
DamageRadius=200
DamageFalloffExponent=1
DamageDelay=0.f
// Damage Effects
MyDamageType=class'KFDT_Explosive_HRG_Warthog_HighExplosive'
KnockDownStrength=0
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_WarthogWeapon_ARCH.HRG_WarthogWeapon_GrenadeExplosion'
ExplosionSound=AkEvent'WW_WEP_HRG_Warthog.Play_WEP_HRG_Warthog_Explosion'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.2
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=200
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
bIgnoreInstigator=true
ActorClassToIgnoreForDamage = class'KFPawn_Human'
End Object
ExplosionTemplate=ExploTemplate0
AmbientSoundPlayEvent=AkEvent'WW_WEP_HRG_Warthog.Play_WEP_HRG_Warthog_Projectile_LP'
AmbientSoundStopEvent=AkEvent'WW_WEP_HRG_Warthog.Stop_WEP_HRG_Warthog_Projectile'
// The higher the more bouncing
DampenFactor=0.4f
DampenFactorParallel=0.4f
bHitWall = false
}

View File

@ -83,7 +83,7 @@ defaultproperties
AmbientSoundPlayEvent=AkEvent'WW_WEP_HRG_MedicMissile.Play_WEP_HRG_MedicMissile_Projectile_Loop'
AmbientSoundStopEvent=AkEvent'WW_WEP_HRG_MedicMissile.Stop_WEP_HRG_MedicMissile_Projectile_Loop'
AltExploEffects=KFImpactEffectInfo'WEP_HRG_MedicMissile_ARCH.HRG_MedicMissile_Explosion_Concussive_Force'
AltExploEffects=KFImpactEffectInfo'WEP_HRG_MedicMissile_ARCH.HRG_MedicMissile_Explosion'
ExplosionActorClass=class'KFExplosion_HRG_MedicMissile'

View File

@ -0,0 +1,170 @@
//=============================================================================
// KFSeasonalEventStats_Summer2023
//=============================================================================
// Tracks event-specific challenges/accomplishments for Summer 2023
//=============================================================================
// Killing Floor 2
// Copyright (C) 2022 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Summer2023 extends KFSeasonalEventStats;
var transient private const int HRGBombardierZedsRequired, EMPRequired, StandYourGroundRequired, EndlessWaveRequired, SummerEventIndex;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
bObjectiveIsValidForMap[0] = 1; // Kill 1500 Zeds with HRG Bombardier
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Subduction
bObjectiveIsValidForMap[2] = 1; // Stun 2500 Zeds with EMP affliction
bObjectiveIsValidForMap[3] = 1; // Complete 25 Stand your Ground objectives
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Subduction
if (CapsMapName == "KF-SUBDUCTION")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(HRGBombardierZedsRequired, 0, EMPRequired, StandYourGroundRequired, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
// TODO
GrantEventItem(9672);
}
}
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
local int ObjIdx;
// Complete the Weekly on Subduction
ObjIdx = 1;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SummerEventIndex, ObjIdx);
}
}
}
simulated function OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
{
local int HRGBombardierIdx, EMPIdx, StandYourGroundIdx, ObjectiveLimit;
local bool bValidIdx;
HRGBombardierIdx = 0;
EMPIdx = 2;
StandYourGroundIdx = 3;
bValidIdx = false;
if (EventIndex == SummerEventIndex)
{
if (ObjectiveIndex == HRGBombardierIdx)
{
ObjectiveLimit = HRGBombardierZedsRequired;
bValidIdx = true;
}
else if (ObjectiveIndex == EMPIdx)
{
ObjectiveLimit = EMPRequired;
bValidIdx = true;
}
else if (ObjectiveIndex == StandYourGroundIdx)
{
ObjectiveLimit = StandYourGroundRequired;
bValidIdx = true;
}
if (bValidIdx && bObjectiveIsValidForMap[ObjectiveIndex] != 0)
{
IncrementSeasonalEventStat(ObjectiveIndex, 1);
if (Outer.GetSeasonalEventStatValue(ObjectiveIndex) >= ObjectiveLimit)
{
FinishedObjective(SummerEventIndex, ObjectiveIndex);
}
}
}
}
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
// Complete wave 15 on Endless Hard or higher difficulty on Subduction
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SummerEventIndex, ObjIdx);
}
}
}
simulated function OnAfflictionCaused(EAfflictionType Type)
{
local int ObjIdx;
// Stun 2500 Zeds with EMP affliction
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (Type == AF_EMP)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= EMPRequired)
{
FinishedObjective(SummerEventIndex, ObjIdx);
}
}
}
}
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
// Kill 1500 Zeds with HRG Bombardier
ObjIdx = 0;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (DT == class'KFDT_Explosive_HRG_Warthog' ||
DT == class'KFDT_Explosive_HRG_Warthog_HighExplosive' ||
DT == class'KFDT_Ballistic_HRG_Warthog')
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= HRGBombardierZedsRequired)
{
FinishedObjective(SummerEventIndex, ObjIdx);
}
}
}
}
defaultproperties
{
HRGBombardierZedsRequired=1500
EMPRequired=2500
StandYourGroundRequired=25
EndlessWaveRequired=15
SummerEventIndex=SEI_Summer
}

View File

@ -0,0 +1,113 @@
//=============================================================================
// KFWeapAttach_HRG_Warthog
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_Warthog extends KFWeapAttach_DualBase;
`define AUTOTURRET_ATTACH_MIC_LED_INDEX 2
const ThrowAnim = 'Drone_Throw';
const CrouchThrowAnim = 'Drone_Throw_CH';
const DetonateAnim = 'Shoot';
const CrouchDetonateAnim = 'CH_Shoot';
const TransitionParamName = 'transition_full_to_empty';
const EmptyParamName = 'Blinking_0_off___1_on';
/** Completely overridden to play anims for both C4 firemodes (throw and detonate), also doesn't need to play effects */
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local float Duration;
// Effects below this point are culled based on visibility and distance
if ( !ActorEffectIsRelevant(P, false, MaxFireEffectDistance) )
{
return false;
}
DecodeThirdPersonAnimRate( ThirdPersonAnimRateByte );
// Weapon shoot anims
if (P.FiringMode == 0)
{
// anim simply hides and unhides bone
Duration = WeapMesh.GetAnimLength( ThrowAnim );
WeapMesh.PlayAnim( ThrowAnim, Duration / ThirdPersonAnimRate,, true );
// use timer to make sure bone gets un-hidden (in case anim gets interrupted)
SetTimer( 0.75f, false, nameof(UnHide) );
}
else if (P.FiringMode == 5)
{
Duration = WeapMesh.GetAnimLength( DetonateAnim );
LeftWeapMesh.PlayAnim( DetonateAnim, Duration / ThirdPersonAnimRate,, true );
}
// Additive character shoot anims
if ( !P.IsDoingSpecialMove() )
{
if( P.FiringMode == 0 )
{
if ( P.bIsCrouched )
{
P.PlayBodyAnim(CrouchThrowAnim, EAS_CH_UpperBody, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else
{
P.PlayBodyAnim(ThrowAnim, EAS_UpperBody, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
}
else if( P.FiringMode == 5 )
{
if ( P.bIsCrouched )
{
P.PlayBodyAnim(CrouchDetonateAnim, EAS_CH_UpperBody, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else
{
P.PlayBodyAnim(DetonateAnim, EAS_UpperBody, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
}
}
// prevent using "aiming" KFAnim_BlendByTargetingMode since we don't have/need the aim anims for C4
P.LastWeaponFireTime = -1.f;
return true;
}
/** Unhides the C4 unit in hand (basically the same as the notify, but don't use the notify) */
simulated function UnHide()
{
if( WeapMesh != none )
{
WeapMesh.UnHideBoneByName( 'RW_Weapon' );
}
}
/** Special event added for weap attachments. Free for use */
function OnSpecialEvent(int Arg)
{
local float Value;
Value = (Arg - 1) / 100.0f;
if (Value >= 0)
{
if ( WeaponMIC == None && LeftWeapMesh != None )
{
WeaponMIC = LeftWeapMesh.CreateAndSetMaterialInstanceConstant(`AUTOTURRET_ATTACH_MIC_LED_INDEX);
}
WeaponMIC.SetScalarParameterValue(TransitionParamName, 1.0f - Value);
WeaponMIC.SetScalarParameterValue(EmptyParamName, Value == 0 ? 1 : 0);
}
}
defaultproperties
{
bHasLaserSight=false
}

View File

@ -0,0 +1,271 @@
//=============================================================================
// KFWeapAttach_HRG_WarthogWeapon
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_WarthogWeap extends KFWeaponAttachment;
const DeployAnimName = 'Drone_Deploy';
const DroneFireAnim = 'Drone_Shoot';
const DroneEmptyStartAnim = 'Drone_Start_Empty';
const DroneEmptyAnim = 'Drone_Empty';
const DroneIdleAnim = 'Drone_Idle';
const DroneClosedAnim = 'Drone_IdleClose';
const LaserSightSocketName = 'LaserSightSocket';
const LaserColorParamName = '0blue_1red';
var transient MaterialInstanceConstant LaserDotMIC;
var transient MaterialInstanceConstant LaserBeamMIC;
simulated function float PlayDeployAnim()
{
local float Duration;
Duration = WeapMesh.GetAnimLength( DeployAnimName );
WeapMesh.PlayAnim( DeployAnimName, Duration / ThirdPersonAnimRate, false, true );
return Duration;
}
simulated function PlayEmptyState()
{
local float Duration;
ClearTimer(nameof(PlayIdleAnim));
Duration = WeapMesh.GetAnimLength( DroneEmptyStartAnim );
WeapMesh.PlayAnim( DroneEmptyStartAnim, Duration / ThirdPersonAnimRate, true, false);
SetTimer(Duration, false, 'PlayEmptyAnim');
}
simulated function PlayEmptyAnim()
{
local float Duration;
Duration = WeapMesh.GetAnimLength( DroneEmptyAnim );
WeapMesh.PlayAnim( DroneEmptyAnim, Duration / ThirdPersonAnimRate, true, false);
if (LaserSight != none)
{
LaserSight.ChangeVisibility(false);
}
}
simulated function PlayIdleAnim()
{
local float Duration;
Duration = WeapMesh.GetAnimLength( DroneIdleAnim );
WeapMesh.PlayAnim( DroneIdleAnim, Duration / ThirdPersonAnimRate, true, false );
}
simulated function PlayCloseAnim()
{
local float Duration;
Duration = WeapMesh.GetAnimLength( DroneClosedAnim );
WeapMesh.PlayAnim( DroneClosedAnim, Duration / ThirdPersonAnimRate, true, false );
}
/**
* Spawn all of the effects that will be seen in behindview/remote clients. This
* function is called from the pawn, and should only be called when on a remote client or
* if the local client is in a 3rd person mode.
* @return TRUE if the effect culling check passes
*/
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
// local EAnimSlotStance AnimType;
SpawnTracer(GetMuzzleLocation(), HitLocation);
// Effects below this point are culled based on visibility and distance
if ( !ActorIsRelevant(self, false, MaxFireEffectDistance) )
{
return false;
}
DecodeThirdPersonAnimRate( ThirdPersonAnimRateByte );
// Weapon shoot anims
if( !bWeapMeshIsPawnMesh )
{
PlayWeaponFireAnim();
}
/*
if( P.IsDoingSpecialMove() && P.SpecialMoves[P.SpecialMove].bAllowFireAnims )
{
AnimType = EAS_Additive;
}
else
{
AnimType = EAS_FullBody;
}
*/
// AnimType = EAS_FullBody;
// Character shoot anims
/*
if ( 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);
}
}
*/
// Always DEFAULT_FIREMODE
CauseMuzzleFlash(0);
return true;
}
simulated function bool ActorIsRelevant(Actor EffectInstigator, bool bForceDedicated, optional float VisibleCullDistance=5000.0, optional float HiddenCullDistance=350.0 )
{
local PlayerController P;
local float DistSq;
local vector CameraLoc;
local rotator CameraRot;
if ( EffectInstigator == None )
{
return FALSE;
}
// No local player, so only spawn on dedicated server if bForceDedicated
if ( WorldInfo.NetMode == NM_DedicatedServer )
{
return bForceDedicated;
}
if ( bForceDedicated && (WorldInfo.NetMode == NM_ListenServer) && (WorldInfo.Game.NumPlayers > 1) )
{
// Is acting as server, so spawn effect if bForceDedicated
return TRUE;
}
// Determine how far to the nearest local viewer
DistSq = 10000000000.0;
ForEach LocalPlayerControllers(class'PlayerController', P)
{
if ( P.GetViewTarget() == self )
{
return true;
}
P.GetPlayerViewPoint(CameraLoc, CameraRot);
DistSq = FMin(DistSq, VSizeSq(Location - CameraLoc)*Square(P.LODDistanceFactor));
}
if ( DistSq > VisibleCullDistance*VisibleCullDistance )
{
// never spawn beyond cull distance
return FALSE;
}
else if ( DistSq < HiddenCullDistance*HiddenCullDistance )
{
// If close enough, always spawn even if hidden
return TRUE;
}
/* This doesn't seem to be updating the render time, so ignore it */
return TRUE;
}
/** Plays fire animation on weapon mesh */
simulated function PlayWeaponFireAnim()
{
local float Duration;
local bool bAnimPlayed;
Duration = WeapMesh.GetAnimLength( DroneFireAnim );
bAnimPlayed = WeapMesh.PlayAnim( DroneFireAnim, Duration / ThirdPersonAnimRate, false, false );
if (bAnimPlayed)
{
ClearTimer(nameof(PlayIdleAnim));
SetTimer(Duration, false, nameof(PlayIdleAnim));
}
}
/**
Laser
*/
simulated function AttachLaserSight()
{
if ( WeapMesh != none && LaserSight == None && LaserSightArchetype != None )
{
LaserSight = new(self) Class'KFLaserSightAttachment' (LaserSightArchetype);
LaserSight.AttachLaserSight(WeapMesh, false, LaserSightSocketName);
}
}
simulated function UpdateLaserColor(bool bInCombat)
{
if (LaserSight != none)
{
if (LaserDotMIC == none)
{
LaserDotMIC = LaserSight.LaserDotMeshComp.CreateAndSetMaterialInstanceConstant(0);
}
if (LaserBeamMIC == none)
{
LaserBeamMIC = LaserSight.LaserBeamMeshComp.CreateAndSetMaterialInstanceConstant(0);
}
}
if (LaserDotMIC != none)
{
LaserDotMIC.SetScalarParameterValue(LaserColorParamName, bInCombat ? 1 : 0);
}
if (LaserBeamMIC != none)
{
LaserBeamMIC.SetScalarParameterValue(LaserColorParamName, bInCombat ? 1 : 0);
}
}
/**
* Assign weapon skin to 3rd person mesh
*/
simulated event SetWeaponSkin(int ItemId, optional bool bFinishedLoading = false)
{
local array<MaterialInterface> SkinMICs;
if ( ItemId > 0 && WorldInfo.NetMode != NM_DedicatedServer && !bWaitingForWeaponSkinLoad)
{
if (!bFinishedLoading && StartLoadWeaponSkin(ItemId))
{
return;
}
SkinMICs = class'KFWeaponSkinList'.static.GetWeaponSkin(ItemId, WST_ThirdPerson);
if ( SkinMICs.Length > 0 )
{
WeapMesh.SetMaterial(0, SkinMICs[0]);
}
}
}
defaultproperties
{
//defaults
bHasLaserSight=true
}

View File

@ -0,0 +1,153 @@
//=============================================================================
// KFWeapAttach_shotgun_s12
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2023 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_Shotgun_S12 extends KFWeaponAttachment;
const SecondaryMuzzleSocket = 'MuzzleFlashAlt';
const SecondaryReloadAnim = 'Reload_Secondary';
const SecondaryReloadCHAnim = 'Reload_Secondary_CH';
const SecondaryReloadEliteAnim = 'Reload_Secondary_Elite';
const SecondaryReloadEliteCHAnim = 'Reload_Secondary_Elite_CH';
var transient ParticleSystemComponent ExplosionPSC;
var transient ParticleSystem ExplosionEffect;
var protected transient KFMuzzleFlash SecondaryMuzzleFlash;
var protected transient bool bWasSecondaryShot;
simulated function bool ThirdPersonFireEffects( vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local vector SocketLocation;
bWasSecondaryShot = P.FiringMode == 1;
if (Super.ThirdPersonFireEffects(HitLocation, P, ThirdPersonAnimRateByte))
{
if (P.FiringMode == 1 && !P.IsLocallyControlled())
{
if (ExplosionEffect != None)
{
WeapMesh.GetSocketWorldLocationAndRotation('MuzzleFlashAlt', SocketLocation);
ExplosionPSC = WorldInfo.MyEmitterPool.SpawnEmitter(class'KFWeap_Shotgun_S12'.default.ExplosionEffect, SocketLocation, rotator(vect(0,0,1)));
ExplosionPSC.ActivateSystem();
}
}
return true;
}
return false;
}
/** @return the starting location for effects (e.g. tracers) */
simulated function vector GetMuzzleLocation(optional byte MuzzleID)
{
if (bWasSecondaryShot)
{
return GetAltMuzzleLocation();
}
else
{
return Super.GetMuzzleLocation(MuzzleID);
}
}
simulated function vector GetAltMuzzleLocation(optional byte MuzzleID)
{
local vector SocketLocation;
if (SecondaryMuzzleFlash == None)
{
AttachMuzzleFlash();
}
if( SecondaryMuzzleFlash != none )
{
WeapMesh.GetSocketWorldLocationAndRotation(SecondaryMuzzleFlash.GetSocketName(), SocketLocation);
return SocketLocation;
}
return Super.GetMuzzleLocation(MuzzleID);
}
simulated event Tick(float DeltaTime)
{
local vector SocketLocation;
Super.Tick(DeltaTime);
if (ExplosionPSC != none && ExplosionPSC.bIsActive)
{
WeapMesh.GetSocketWorldLocationAndRotation('MuzzleFlashAlt', SocketLocation);
ExplosionPSC.SetVectorParameter('WeaponEndpoint', SocketLocation);
}
}
simulated function CauseMuzzleFlash(byte FiringMode)
{
if ( FiringMode == 1 ) // AltFire
{
if (SecondaryMuzzleFlash == None)
{
AttachMuzzleFlash();
}
if (SecondaryMuzzleFlash != None )
{
SecondaryMuzzleFlash.CauseMuzzleFlash(FiringMode);
if ( SecondaryMuzzleFlash.bAutoActivateShellEject )
{
SecondaryMuzzleFlash.CauseShellEject();
}
}
}
else
{
Super.CauseMuzzleFlash(FiringMode);
}
}
simulated function AttachMuzzleFlash()
{
Super.AttachMuzzleFlash();
if ( WeapMesh != none && SecondaryMuzzleFlash == None )
{
SecondaryMuzzleFlash = new(self) Class'KFMuzzleFlash'(class'KFWeap_Shotgun_S12'.default.SecondaryMuzzleFlashTemplate);
SecondaryMuzzleFlash.AttachMuzzleFlash(WeapMesh, SecondaryMuzzleSocket,);
}
}
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
{
local name AnimName;
switch (NewWeaponState)
{
case WEP_ReloadSecondary:
AnimName = (P.bIsCrouched) ? SecondaryReloadCHAnim : SecondaryReloadAnim;
break;
case WEP_ReloadSecondary_Elite:
AnimName = (P.bIsCrouched) ? SecondaryReloadEliteCHAnim : SecondaryReloadEliteAnim;
break;
}
if (AnimName != '')
{
PlayCharacterMeshAnim(P, AnimName, true);
}
else
{
Super.PlayReloadMagazineAnim(NewWeaponState, P);
}
}
defaultproperties
{
ExplosionEffect=ParticleSystem'WEP_1P_Saiga12_EMIT.FX_Saiga12_Explosion_3P'
bWasSecondaryShot=false
}

View File

@ -192,7 +192,14 @@ simulated function Detonate(optional bool bKeepTurret = false)
continue;
}
KFPawn_AutoTurret(TurretsCopy[i]).SetTurretState(ETS_Detonate);
if (KFPawn_HRG_Warthog(TurretsCopy[i]) != none)
{
KFPawn_HRG_Warthog(TurretsCopy[i]).SetTurretState(ETS_Detonate);
}
else if (KFPawn_Autoturret(TurretsCopy[i]) != none)
{
KFPawn_Autoturret(TurretsCopy[i]).SetTurretState(ETS_Detonate);
}
}
KFPC.DeployedTurrets.Remove(bKeepTurret ? 1 : 0, KFPC.DeployedTurrets.Length);
@ -231,6 +238,7 @@ function RemoveDeployedTurret( optional int Index = INDEX_NONE, optional Actor T
function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon )
{
local int i;
local Actor WeaponPawn;
super.SetOriginalValuesFromPickup( PickedUpWeapon );
@ -255,14 +263,25 @@ function SetOriginalValuesFromPickup( KFWeapon PickedUpWeapon )
bForceNetUpdate = true;
for( i = 0; i < NumDeployedTurrets; ++i )
{
WeaponPawn = KFPC.DeployedTurrets[i];
if (WeaponPawn != none)
{
// charge alerts (beep, light) need current instigator
KFPC.DeployedTurrets[i].Instigator = Instigator;
KFPC.DeployedTurrets[i].SetOwner(self);
WeaponPawn.Instigator = Instigator;
WeaponPawn.SetOwner(self);
if (Instigator.Controller != none)
{
KFPawn_AutoTurret(KFPC.DeployedTurrets[i]).InstigatorController = Instigator.Controller;
if (KFPawn_HRG_Warthog(KFPC.DeployedTurrets[i]) != none)
{
KFPawn_HRG_Warthog(KFPC.DeployedTurrets[i]).InstigatorController = Instigator.Controller;
}
else if (KFPawn_Autoturret(KFPC.DeployedTurrets[i]) != none)
{
KFPawn_Autoturret(KFPC.DeployedTurrets[i]).InstigatorController = Instigator.Controller;
}
}
}
}
}
@ -343,6 +362,8 @@ simulated function bool HasAmmo( byte FireModeNum, optional int Amount )
simulated function BeginFire( byte FireModeNum )
{
local bool bCanDetonate;
// Clear any pending detonate if we pressed the main fire
// That prevents strange holding right click behaviour and sound issues
if (FireModeNum == DEFAULT_FIREMODE)
@ -358,12 +379,22 @@ simulated function BeginFire( byte FireModeNum )
}
if (NumDeployedTurrets > 0 && bTurretReadyToUse)
{
bCanDetonate = NumDeployedTurrets > 0;
if (bCanDetonate)
{
PrepareAndDetonate();
}
}
}
else
{
if (KFPC != none)
{
NumDeployedTurrets = KFPC.DeployedTurrets.Length;
}
if (FireModeNum == DEFAULT_FIREMODE
&& NumDeployedTurrets >= MaxTurretsDeployed
&& HasAnyAmmo())
@ -573,7 +604,15 @@ function CheckTurretAmmo()
if (KFPC.DeployedTurrets.Length > 0)
{
Weapon = KFWeapon(KFPawn_AutoTurret(KFPC.DeployedTurrets[0]).Weapon);
if (KFPawn_HRG_Warthog(KFPC.DeployedTurrets[0]) != none)
{
Weapon = KFWeapon(KFPawn_HRG_Warthog(KFPC.DeployedTurrets[0]).Weapon);
}
else if (KFPawn_Autoturret(KFPC.DeployedTurrets[0]) != none)
{
Weapon = KFWeapon(KFPawn_Autoturret(KFPC.DeployedTurrets[0]).Weapon);
}
if (Weapon != none)
{
Percentage = float(Weapon.AmmoCount[0]) / Weapon.MagazineCapacity[0];
@ -797,4 +836,5 @@ defaultproperties
NumBloodMapMaterials=3
bDetonateLocked=false
CurrentAmmoPercentage=-1.0f
}

View File

@ -45,13 +45,13 @@ defaultproperties
End Object
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_ChainBat'
InstantHitDamage(DEFAULT_FIREMODE)=68// 34
InstantHitDamage(DEFAULT_FIREMODE)=75// 34
InstantHitDamageTypes(HEAVY_ATK_FIREMODE)=class'KFDT_Bludgeon_ChainBatHeavy'
InstantHitDamage(HEAVY_ATK_FIREMODE)=90 //68
InstantHitDamage(HEAVY_ATK_FIREMODE)=100 //68
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_ChainBatBash'
InstantHitDamage(BASH_FIREMODE)=68
InstantHitDamage(BASH_FIREMODE)=75
// Inventory
GroupPriority=50

View File

@ -40,7 +40,7 @@ defaultproperties
End Object
// Inventory
GroupPriority=25
GroupPriority=47
InventorySize=4
WeaponSelectTexture=Texture2D'ui_weaponselect_tex.UI_WeaponSelect_Crovel'

View File

@ -22,6 +22,11 @@ var bool bLastFireWasAlt;
var const bool bDebugDrawVortex;
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Explosive;
}
simulated function Activate()
{
super.Activate();

View File

@ -15,6 +15,8 @@ var protected const array<vector2D> PelletSpread;
/** Last time a submunition projectile was fired from this weapon */
var float LastSubmunitionFireTime;
var transient bool AlreadyIssuedCanNuke;
/*********************************************************************************************
Firing / Projectile
********************************************************************************************* */
@ -79,6 +81,38 @@ static simulated event EFilterTypeUI GetAltTraderFilter()
return FT_Pistol;
}
simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
{
local KFProjectile Proj;
AlreadyIssuedCanNuke = false;
Proj = Super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir);
AlreadyIssuedCanNuke = false;
return Proj;
}
simulated function KFProjectile SpawnProjectile( class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir )
{
local KFProj_ExplosiveSubMunition_HX25 Proj;
Proj = KFProj_ExplosiveSubMunition_HX25(Super.SpawnProjectile(KFProjClass, RealStartLoc, AimDir));
if (AlreadyIssuedCanNuke == false)
{
Proj.bCanNuke = true;
AlreadyIssuedCanNuke = true;
}
else
{
Proj.bCanNuke = false;
}
return Proj;
}
defaultproperties
{
ForceReloadTime=0.3f
@ -200,4 +234,6 @@ defaultproperties
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.4f), (Stat=EWUS_Weight, Add=2)))
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.6f), (Stat=EWUS_Weight, Add=3)))
WeaponUpgrades[4]=(Stats=((Stat=EWUS_Damage0, Scale=1.9f), (Stat=EWUS_Weight, Add=4)))
AlreadyIssuedCanNuke = false
}

View File

@ -55,6 +55,11 @@ Replication
ChargeTime;
}
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Projectile;
}
simulated event PostInitAnimTree( SkeletalMeshComponent SkelComp )
{
local vector vec;

Some files were not shown because too many files have changed in this diff Show More