upload
This commit is contained in:
parent
2893490576
commit
ea1d43f08f
@ -139,6 +139,8 @@ var const int SecondsDeallocatedBucketSize;
|
||||
var databinding string Region;
|
||||
//@HSL_END
|
||||
|
||||
var databinding bool bNoSeasonalSkins;
|
||||
|
||||
/** Represents a player in the game */
|
||||
struct native PlayerResult
|
||||
{
|
||||
@ -183,4 +185,5 @@ defaultproperties
|
||||
//@SABER_BEGIN "Exiling" servers which kicks/bans
|
||||
bServerExiled=false
|
||||
//@SABER_END
|
||||
bNoSeasonalSkins=false
|
||||
}
|
@ -2314,6 +2314,7 @@ static function DumpGameSettings(const OnlineGameSettings GameSettings)
|
||||
`Log(" bAllowJoinViaPresence: "$GameSettings.bAllowJoinViaPresence);
|
||||
`Log(" bAllowJoinViaPresenceFriendsOnly: "$GameSettings.bAllowJoinViaPresenceFriendsOnly);
|
||||
`Log(" GameState: "$GameSettings.GameState);
|
||||
`Log(" bNoSeasonalSkins: "$GameSettings.bNoSeasonalSkins);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,7 +15,7 @@ var float Duration;
|
||||
var bool bIsActive;
|
||||
|
||||
/** Default Effect Socket */
|
||||
var protected name EffectSocketName;
|
||||
var name EffectSocketName;
|
||||
|
||||
/** Copy incap settings we're going to need */
|
||||
function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
@ -25,11 +25,11 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
}
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
if ( !bIsActive )
|
||||
{
|
||||
super.Activate();
|
||||
super.Activate(InstigatorPerk, DamageType);
|
||||
PawnOwner.SetTimer(Duration, false, nameof(DeActivate), self);
|
||||
bIsActive = true;
|
||||
}
|
||||
|
@ -42,12 +42,17 @@ var float LastDissipationTime;
|
||||
/** Enable debug logging */
|
||||
var bool bDebug;
|
||||
|
||||
/** Cache the affliction type for passing to Seasonal objectives */
|
||||
var EAfflictionType AfflictionType;
|
||||
|
||||
/** */
|
||||
function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
{
|
||||
PawnOwner = P;
|
||||
MonsterOwner = KFPawn_Monster(P);
|
||||
|
||||
AfflictionType = Type;
|
||||
|
||||
Cooldown = P.IncapSettings[Type].Cooldown;
|
||||
|
||||
if ( bNeedsTick && DissipationRate > 0 )
|
||||
@ -57,7 +62,7 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
}
|
||||
|
||||
/** */
|
||||
function Accrue(float InPower, optional class<KFDamageType> DamageType = none)
|
||||
function Accrue(float InPower, KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
// total immunity during cooldown
|
||||
if ( LastActivationTime > 0 && `TimeSinceEx(PawnOwner, LastActivationTime) < Cooldown )
|
||||
@ -80,14 +85,14 @@ function Accrue(float InPower, optional class<KFDamageType> DamageType = none)
|
||||
CurrentStrength = fClamp(CurrentStrength + InPower, InPower, INCAP_THRESHOLD);
|
||||
if ( CurrentStrength >= INCAP_THRESHOLD )
|
||||
{
|
||||
Activate(DamageType);
|
||||
Activate(InstigatorPerk, DamageType);
|
||||
}
|
||||
|
||||
`log(Class.Name@"Added="$InPower@"NewStrength="$CurrentStrength, bDebug);
|
||||
}
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
if ( SpecialMove != SM_None )
|
||||
{
|
||||
@ -100,6 +105,14 @@ function Activate(optional class<KFDamageType> DamageType = none)
|
||||
|
||||
LastActivationTime = PawnOwner.WorldInfo.TimeSeconds;
|
||||
`log(Class.Name@"was activated", bDebug);
|
||||
|
||||
if (InstigatorPerk != none)
|
||||
{
|
||||
if (InstigatorPerk.OwnerPC != none)
|
||||
{
|
||||
InstigatorPerk.OwnerPC.AddAfflictionCaused(AfflictionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** For subclass special instructions */
|
||||
|
@ -469,7 +469,7 @@ function AccrueAffliction(EAfflictionType Type, float InPower, optional EHitZone
|
||||
|
||||
if ( InPower > 0 )
|
||||
{
|
||||
Afflictions[Type].Accrue(InPower, DamageType);
|
||||
Afflictions[Type].Accrue(InPower, InstigatorPerk, DamageType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -510,7 +510,7 @@ function AccrueAfflictionMicrowave(EAfflictionType Type, float InPower, bool bHa
|
||||
if ( InPower > 0 )
|
||||
{
|
||||
KFAffliction_Microwave(Afflictions[Type]).bHasToSpawnFire = bHasToSpawnFire;
|
||||
Afflictions[Type].Accrue(InPower);
|
||||
Afflictions[Type].Accrue(InPower, InstigatorPerk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,11 +44,11 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
CurrentMaxStack = bIsBobbleHeadMode ? MaxStackBobbleHead : MaxStack;
|
||||
}
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
if (CurrentStack < CurrentMaxStack)
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
|
||||
if (!bIsBobbleHeadMode && !bIsShrunkenHeads)
|
||||
{
|
||||
|
@ -115,9 +115,9 @@ function float GetAttackSpeedModifier()
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
function Accrue(float InPower, optional class<KFDamageType> DamageType = none)
|
||||
function Accrue(float InPower, KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
super.Accrue(InPower);
|
||||
super.Accrue(InPower, InstigatorPerk);
|
||||
if (PawnOwner != none)
|
||||
{
|
||||
PawnOwner.SetAfflictionSpeedModifier();
|
||||
|
@ -21,13 +21,13 @@ var protected ParticleSystemComponent EMPDisruptEffect;
|
||||
var protected name EMPDisruptSocketName;
|
||||
|
||||
/** Sound to play when this pawn has been EMP'd */
|
||||
var protected AkEvent OnEMPSound;
|
||||
var AkEvent OnEMPSound;
|
||||
/** Sound to play when this pawn stops being EMP'd */
|
||||
var protected AkEvent OnEMPEndSound;
|
||||
var AkEvent OnEMPEndSound;
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
SetEMPPanicked(true);
|
||||
}
|
||||
|
||||
|
@ -20,9 +20,9 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
DisruptCooldown = P.IncapSettings[Type].ChildAfflictionCooldown;
|
||||
}
|
||||
|
||||
function Accrue(float InPower, optional class<KFDamageType> DamageType = none)
|
||||
function Accrue(float InPower, KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
Super.Accrue(InPower);
|
||||
Super.Accrue(InPower, InstigatorPerk, DamageType);
|
||||
|
||||
if (!PawnOwner.IsTimerActive(nameof(Timer_DisruptCooldown), self))
|
||||
{
|
||||
|
@ -44,12 +44,12 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
}
|
||||
}
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
// fire can accrue after death, but cannot trigger panic
|
||||
if ( !PawnOwner.bPlayedDeath )
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
SetFirePanicked(true);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
class KFAffliction_HeavyRecovery extends KFAfflictionBase;
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
// Attempt to interrupt the special move
|
||||
if( PawnOwner.SpecialMove != SM_None )
|
||||
@ -23,7 +23,7 @@ function Activate(optional class<KFDamageType> DamageType = none)
|
||||
PawnOwner.MyKFAIC.DoPauseAI( PawnOwner.DamageRecoveryTimeHeavy, true );
|
||||
}
|
||||
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
|
@ -9,14 +9,14 @@
|
||||
class KFAffliction_Knockdown extends KFAfflictionBase;
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
ActivateKnockdown(DamageType,
|
||||
PawnOwner.HitFxInfo.HitLocation,
|
||||
PawnOwner.DecodeUnitVector( PawnOwner.HitFxInfo.EncodedHitDirection ),
|
||||
PawnOwner.HitFxInfo.HitBoneIndex);
|
||||
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
}
|
||||
|
||||
/** Apply a knockdown (on hit) to this character */
|
||||
|
@ -9,7 +9,7 @@
|
||||
class KFAffliction_MediumRecovery extends KFAfflictionBase;
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
// Attempt to interrupt the special move
|
||||
if( PawnOwner.SpecialMove != SM_None )
|
||||
@ -23,7 +23,7 @@ function Activate(optional class<KFDamageType> DamageType = none)
|
||||
PawnOwner.MyKFAIC.DoPauseAI( PawnOwner.DamageRecoveryTimeHeavy, true );
|
||||
}
|
||||
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
|
@ -30,9 +30,9 @@ var protected AkEvent OnSteamSound;
|
||||
/** Sound to play when this pawn stops being on fire */
|
||||
var protected AkEvent OnSteamEndSound;
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
SetMicrowavePanicked(true);
|
||||
}
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
||||
//=============================================================================
|
||||
class KFAffliction_Poison extends KFAfflictionAdvanced;
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
SetPoisoned(true);
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
}
|
||||
}
|
||||
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
local float StackModifier;
|
||||
|
||||
@ -64,7 +64,7 @@ function Activate(optional class<KFDamageType> DamageType = none)
|
||||
|
||||
if (CurrentEffect < MaxEffect)
|
||||
{
|
||||
Super.Activate();
|
||||
Super.Activate(InstigatorPerk, DamageType);
|
||||
|
||||
StackModifier = 1.0f;
|
||||
|
||||
|
@ -24,11 +24,11 @@ function Init(KFPawn P, EAfflictionType Type, KFPerk InstigatorPerk)
|
||||
}
|
||||
|
||||
/** */
|
||||
function Activate(optional class<KFDamageType> DamageType = none)
|
||||
function Activate(KFPerk InstigatorPerk, optional class<KFDamageType> DamageType = none)
|
||||
{
|
||||
if( !bIsActive )
|
||||
{
|
||||
super.Activate();
|
||||
super.Activate(InstigatorPerk, DamageType);
|
||||
PawnOwner.SetTimer(Duration, false, nameof(DeActivate), self);
|
||||
bIsActive = true;
|
||||
PawnOwner.SetAfflictionSpeedModifier();
|
||||
|
@ -6455,6 +6455,7 @@ simulated function ClearFakeDramaEvent()
|
||||
exec function DBJump()
|
||||
{
|
||||
local vector UsedKickMomentum;
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
// Push the player back when they fire both barrels
|
||||
if (Pawn != none )
|
||||
@ -6473,6 +6474,12 @@ exec function DBJump()
|
||||
}
|
||||
|
||||
Pawn.AddVelocity(UsedKickMomentum,Pawn.Location,none);
|
||||
|
||||
KFPC = KFPlayerController(Pawn.Controller);
|
||||
if (KFPC != none)
|
||||
{
|
||||
KFPC.SetShotgunJump(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ var localized array<string> ServerTypeStrings;
|
||||
var localized array<string> PermissionStrings;
|
||||
var localized array<string> ConsolePermissionStrings;
|
||||
var localized array<string> ModeStrings;
|
||||
var localized array<string> AllowSeasonalSkinsStrings;
|
||||
|
||||
var localized string TeamSwappedString;
|
||||
var localized string NoPreferenceString;
|
||||
@ -187,7 +188,21 @@ static function array<string> GetPermissionStringsArray(bool bConsoleBuild)
|
||||
{
|
||||
return default.PermissionStrings;
|
||||
}
|
||||
}
|
||||
|
||||
static function string GetAllowSeasonalSkinsString( float Index )
|
||||
{
|
||||
if( 0 < default.AllowSeasonalSkinsStrings.length && Index < default.AllowSeasonalSkinsStrings.length )
|
||||
{
|
||||
return default.AllowSeasonalSkinsStrings[Index];
|
||||
}
|
||||
|
||||
return default.NoPreferenceString;
|
||||
}
|
||||
|
||||
static function array<string> GetAllowSeasonalSkinsStringsArray()
|
||||
{
|
||||
return default.AllowSeasonalSkinsStrings;
|
||||
}
|
||||
|
||||
static function array<string> GetGameModeStringsArray()
|
||||
|
26
KFGame/Classes/KFDT_HVStormCannonSpread.uc
Normal file
26
KFGame/Classes/KFDT_HVStormCannonSpread.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFDT_HVStormCannonSpread
|
||||
//=============================================================================
|
||||
// Damage caused by HV Storm Cannon Spread
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2015 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_HVStormCannonSpread extends KFDamageType
|
||||
abstract;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bCausedByWorld=false
|
||||
bArmorStops=false
|
||||
|
||||
KnockdownPower=20
|
||||
StunPower=50
|
||||
StumblePower=200
|
||||
GunHitPower=150
|
||||
MeleeHitPower=100
|
||||
EMPPower=50
|
||||
|
||||
WeaponDef=class'KFWeapDef_HVStormCannon'
|
||||
}
|
23
KFGame/Classes/KFDT_Toxic_HRG_MedicMissile.uc
Normal file
23
KFGame/Classes/KFDT_Toxic_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,23 @@
|
||||
//=============================================================================
|
||||
// KFDT_Toxic_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Toxic_HRG_MedicMissile extends KFDT_Toxic
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
DoT_Type=DOT_Toxic
|
||||
DoT_Duration=4.0
|
||||
DoT_Interval=1.0
|
||||
DoT_DamageScale=0.2
|
||||
|
||||
PoisonPower=100
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_FieldMedic'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_MedicMissile'
|
||||
}
|
@ -308,6 +308,7 @@ simulated function DrawDebug()
|
||||
local Color C;
|
||||
local float Angle;
|
||||
local float ClotKillRadius, HalfFalloffRadius;
|
||||
local float SafeDamage, SafeDamageFallOffExponent;
|
||||
|
||||
FlushPersistentDebugLines();
|
||||
|
||||
@ -324,13 +325,16 @@ simulated function DrawDebug()
|
||||
}
|
||||
else
|
||||
{
|
||||
SafeDamage = ExplosionTemplate.Damage > 0.f ? ExplosionTemplate.Damage : 1.f;
|
||||
SafeDamageFallOffExponent = ExplosionTemplate.DamageFalloffExponent > 0.f ? ExplosionTemplate.DamageFalloffExponent : 1.f;
|
||||
|
||||
DrawDebugSphere(Location, ExplosionTemplate.DamageRadius, 10, 255, 128, 16, TRUE);
|
||||
|
||||
ClotKillRadius = ExplosionTemplate.DamageRadius * (1.f - FClamp((100 / ExplosionTemplate.Damage) ** (1/ExplosionTemplate.DamageFallOffExponent), 0.f, 1.f));
|
||||
ClotKillRadius = ExplosionTemplate.DamageRadius * (1.f - FClamp((100 / SafeDamage) ** (1 / SafeDamageFallOffExponent), 0.f, 1.f));
|
||||
|
||||
DrawDebugSphere(Location, ClotKillRadius, 10, 255, 0, 0, TRUE);
|
||||
|
||||
HalfFalloffRadius = ExplosionTemplate.DamageRadius * (1.f - FClamp((0.5 ** (1.f/ExplosionTemplate.DamageFalloffExponent)), 0.f, 1.f));
|
||||
HalfFalloffRadius = ExplosionTemplate.DamageRadius * (1.f - FClamp((0.5 ** (1.f / SafeDamageFallOffExponent)), 0.f, 1.f));
|
||||
|
||||
DrawDebugSphere( Location, HalfFalloffRadius, 10, 255, 63, 0, true );
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
class KFGFXSpecialEventObjectivesContainer_Xmas2022 extends KFGFxSpecialEventObjectivesContainer;
|
||||
|
||||
function Initialize(KFGFxObject_Menu NewParentMenu)
|
||||
{
|
||||
super.Initialize(NewParentMenu);
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
ObjectiveIconURLs[0] = "Xmas2022_UI.UI_Objectives_Xmas_2022_Frozen_Hearts" // Freeze 500 Zeds using ice arsenal
|
||||
ObjectiveIconURLs[1] = "Xmas2022_UI.Black_Weekly" // Complete the Weekly on Crash
|
||||
ObjectiveIconURLs[2] = "Xmas2022_UI.UI_Objective_Xmas_2022_Shotgun_Jump" // Use 4 Boomstick Jumps in a same match on Crash
|
||||
ObjectiveIconURLs[3] = "Xmas2022_UI.UI_Objective_Xmas_2022_Not_a_Snowball" // Hit 3 Zeds with a shot of HRG Ballistic Bouncer (15 times)
|
||||
ObjectiveIconURLs[4] = "Xmas2022_UI.UI_Objective_Xmas_2022_Withstand_the_Tempest" // Complete wave 15 on Endless Hard or higher difficulty on Crash
|
||||
|
||||
//defaults
|
||||
AllCompleteRewardIconURL="CHR_TrainConductorUniform_Item_TEX.trainbackpack.trainconductorbackpack_precious"
|
||||
ChanceDropIconURLs[0]="CHR_Cosmetic_XMAS_Item_TEX.Tickets.Krampus_Ticket"
|
||||
ChanceDropIconURLs[1]="CHR_Cosmetic_XMAS_Item_TEX.Tickets.Krampus_Ticket_Golden"
|
||||
IconURL="Xmas2022_UI.Polar_distress_small_logo"
|
||||
|
||||
UsesProgressList[0] = true
|
||||
UsesProgressList[1] = false
|
||||
UsesProgressList[2] = true
|
||||
UsesProgressList[3] = true
|
||||
UsesProgressList[4] = false
|
||||
}
|
@ -137,19 +137,51 @@ struct InventoryHelper
|
||||
// For ordering in weapon skins
|
||||
var int WeaponDef;
|
||||
var int Price;
|
||||
//var string FullName;
|
||||
var int SkinType;
|
||||
var int SkinType; // also used in Cosmetics
|
||||
var ItemRarity Rarity;
|
||||
var int Quality;
|
||||
|
||||
// For ordering cosmetics
|
||||
var string CosmeticType;
|
||||
|
||||
// For ordering crafting
|
||||
var int CraftingType;
|
||||
var int CraftingRarity;
|
||||
var int CraftingTicketType;
|
||||
|
||||
// For ordering items
|
||||
var string KeyName;
|
||||
var bool IsKey;
|
||||
};
|
||||
|
||||
var array<InventoryHelper> SkinListWeaponsSearchCache;
|
||||
var array<InventoryHelper> SkinListOrderedCache;
|
||||
var bool NeedToRegenerateSkinList;
|
||||
struct WeaponSkinListCacheState
|
||||
{
|
||||
var array<InventoryHelper> SearchCache;
|
||||
|
||||
var array<InventoryHelper> OrderedCache;
|
||||
|
||||
var bool NeedToRegenerate;
|
||||
|
||||
var EInventoryWeaponType_Filter WeaponTypeFilter;
|
||||
var int PerkIndexFilter;
|
||||
var ItemRarity RarityFilter;
|
||||
|
||||
structdefaultproperties
|
||||
{
|
||||
NeedToRegenerate = false
|
||||
|
||||
WeaponTypeFilter = EInvWT_None
|
||||
PerkIndexFilter = 0
|
||||
RarityFilter = ITR_NONE
|
||||
}
|
||||
};
|
||||
|
||||
var WeaponSkinListCacheState WeaponSkinListCache;
|
||||
|
||||
var array<InventoryHelper> CosmeticSkinListSearchCache;
|
||||
|
||||
var array<InventoryHelper> CraftingListSearchCache;
|
||||
|
||||
var array<InventoryHelper> ItemListSearchCache;
|
||||
|
||||
struct ByTypeItemsHelper
|
||||
{
|
||||
@ -291,7 +323,7 @@ final function int Crc(coerce string Text)
|
||||
return CrcValue;
|
||||
}
|
||||
|
||||
delegate int SortSkinList(InventoryHelper A, InventoryHelper B)
|
||||
delegate int SortWeaponSkinList(InventoryHelper A, InventoryHelper B)
|
||||
{
|
||||
/** Format: Compare lower ? -1 : (Compare upper) : 1 : (Equal case, repeat formula with the next sort condition) */
|
||||
return A.Price > B.Price ? -1 : (A.Price < B.Price ? 1 : (
|
||||
@ -305,6 +337,26 @@ delegate int SortSkinList(InventoryHelper A, InventoryHelper B)
|
||||
));
|
||||
}
|
||||
|
||||
delegate int SortCosmeticsList(InventoryHelper A, InventoryHelper B)
|
||||
{
|
||||
/** Format: Compare lower ? -1 : (Compare upper) : 1 : (Equal case, repeat formula with the next sort condition) */
|
||||
return A.CosmeticType > B.CosmeticType ? -1 : (A.CosmeticType < B.CosmeticType ? 1 : (
|
||||
A.SkinType < B.SkinType ? -1 : (A.SkinType > B.SkinType ? 1 : (
|
||||
A.Rarity > B.Rarity ? -1 : (A.Rarity < B.Rarity ? 1 : 1)
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
delegate int SortCraftingList(InventoryHelper A, InventoryHelper B)
|
||||
{
|
||||
/** Format: Compare lower ? -1 : (Compare upper) : 1 : (Equal case, repeat formula with the next sort condition) */
|
||||
return A.CraftingType > B.CraftingType ? -1 : (A.CraftingType < B.CraftingType ? 1 : (
|
||||
A.CraftingRarity > B.CraftingRarity ? -1 : (A.CraftingRarity < B.CraftingRarity ? 1 : (
|
||||
A.CraftingTicketType > B.CraftingTicketType ? -1 : (A.CraftingTicketType < B.CraftingTicketType ? 1 : 1)
|
||||
))
|
||||
));
|
||||
}
|
||||
|
||||
delegate int SortItemList(InventoryHelper A, InventoryHelper B)
|
||||
{
|
||||
if (A.IsKey && B.IsKey)
|
||||
@ -327,7 +379,7 @@ delegate int SortItemList(InventoryHelper A, InventoryHelper B)
|
||||
|
||||
function InitInventory()
|
||||
{
|
||||
local int i, j, z, ItemIndex, HelperIndex, WeaponItemID, SearchWeaponSkinIndex, SearchKeyKeywordIndex;
|
||||
local int i, j, z, ItemIndex, HelperIndex, ItemID, SearchIndex;
|
||||
local ItemProperties TempItemDetailsHolder;
|
||||
local GFxObject ItemArray, ItemObject;
|
||||
local bool bActiveItem;
|
||||
@ -335,7 +387,7 @@ function InitInventory()
|
||||
local InventoryHelper HelperItem;
|
||||
local array<ExchangeRuleSets> ExchangeRules;
|
||||
local class<KFWeaponDefinition> WeaponDef;
|
||||
local string SkinType;
|
||||
local string SkinType, CosmeticType, KeyType;
|
||||
|
||||
local GFxObject PendingItem;
|
||||
|
||||
@ -378,40 +430,43 @@ function InitInventory()
|
||||
|
||||
if (TempItemDetailsHolder.Type == ITP_WeaponSkin)
|
||||
{
|
||||
// Copy required stuff
|
||||
HelperItem.Rarity = TempItemDetailsHolder.Rarity;
|
||||
HelperItem.Quality = TempItemDetailsHolder.Quality;
|
||||
|
||||
if (bool(OnlineSub.CurrentInventory[i].NewlyAdded))
|
||||
{
|
||||
NeedToRegenerateSkinList = true;
|
||||
WeaponSkinListCache.NeedToRegenerate = true;
|
||||
}
|
||||
|
||||
// Search on the cache, to speed up
|
||||
WeaponItemID = SkinListWeaponsSearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
|
||||
// Now find the name of the weapon skin
|
||||
|
||||
if (WeaponItemID != INDEX_NONE)
|
||||
// Search on the cache, to speed up
|
||||
ItemID = WeaponSkinListCache.SearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
|
||||
|
||||
if (ItemID != INDEX_NONE)
|
||||
{
|
||||
HelperItem.WeaponDef = SkinListWeaponsSearchCache[WeaponItemID].WeaponDef;
|
||||
HelperItem.Price = SkinListWeaponsSearchCache[WeaponItemID].Price;
|
||||
HelperItem.SkinType = SkinListWeaponsSearchCache[WeaponItemID].SkinType;
|
||||
HelperItem.WeaponDef = WeaponSkinListCache.SearchCache[ItemID].WeaponDef;
|
||||
HelperItem.Price = WeaponSkinListCache.SearchCache[ItemID].Price;
|
||||
HelperItem.SkinType = WeaponSkinListCache.SearchCache[ItemID].SkinType;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skin Type
|
||||
|
||||
// Get right part of the string without from the first "| "
|
||||
SearchWeaponSkinIndex = InStr(TempItemDetailsHolder.Name, "|");
|
||||
SkinType = Right(TempItemDetailsHolder.Name, Len(TempItemDetailsHolder.Name) - SearchWeaponSkinIndex - 2);
|
||||
SearchIndex = InStr(TempItemDetailsHolder.Name, "|");
|
||||
SkinType = Right(TempItemDetailsHolder.Name, Len(TempItemDetailsHolder.Name) - SearchIndex - 2);
|
||||
|
||||
// Get the left part of the string without the next "| "
|
||||
SearchWeaponSkinIndex = InStr(SkinType, "|");
|
||||
SearchIndex = InStr(SkinType, "|");
|
||||
// Store as CRC, that speeds up comparisons later
|
||||
HelperItem.SkinType = CrC(Left(SkinType, SearchWeaponSkinIndex));
|
||||
HelperItem.SkinType = CrC(Left(SkinType, SearchIndex));
|
||||
|
||||
WeaponItemID = class'KFWeaponSkinList'.default.Skins.Find('Id', HelperItem.ItemDefinition);
|
||||
ItemID = class'KFWeaponSkinList'.default.Skins.Find('Id', HelperItem.ItemDefinition);
|
||||
|
||||
if (WeaponItemID != INDEX_NONE)
|
||||
if (ItemID != INDEX_NONE)
|
||||
{
|
||||
WeaponDef = class'KFWeaponSkinList'.default.Skins[WeaponItemID].WeaponDef;
|
||||
WeaponDef = class'KFWeaponSkinList'.default.Skins[ItemID].WeaponDef;
|
||||
|
||||
// All Weapons start by KFGameContent.KFWeap_ Skip that prefix.
|
||||
// Store as CRC, that speeds up comparisons later
|
||||
@ -424,12 +479,202 @@ function InitInventory()
|
||||
HelperItem.Price = 0;
|
||||
}
|
||||
|
||||
SkinListWeaponsSearchCache.AddItem(HelperItem);
|
||||
WeaponSkinListCache.SearchCache.AddItem(HelperItem);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (TempItemDetailsHolder.Type == ITP_CharacterSkin)
|
||||
{
|
||||
HelperItem.KeyName = TempItemDetailsHolder.KeyName;
|
||||
// Search on the cache, to speed up
|
||||
ItemID = CosmeticSkinListSearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
|
||||
|
||||
if (ItemID != INDEX_NONE)
|
||||
{
|
||||
HelperItem.Rarity = CosmeticSkinListSearchCache[ItemID].Rarity;
|
||||
HelperItem.CosmeticType = CosmeticSkinListSearchCache[ItemID].CosmeticType;
|
||||
HelperItem.SkinType = CosmeticSkinListSearchCache[ItemID].SkinType;
|
||||
}
|
||||
else
|
||||
{
|
||||
HelperItem.Rarity = TempItemDetailsHolder.Rarity;
|
||||
|
||||
// Cosmetic Type
|
||||
|
||||
// Get left part of the string from the first "| "
|
||||
SearchIndex = InStr(TempItemDetailsHolder.Name, "|");
|
||||
|
||||
// If we can't find the substring the equipment doesn't fit the pattern, we use the whole string as Cosmetic Type
|
||||
if (SearchIndex < 0)
|
||||
{
|
||||
CosmeticType = TempItemDetailsHolder.Name;
|
||||
HelperItem.CosmeticType = CosmeticType;
|
||||
|
||||
HelperItem.SkinType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CosmeticType = Left(TempItemDetailsHolder.Name, SearchIndex);
|
||||
HelperItem.CosmeticType = CosmeticType;
|
||||
|
||||
// Skin Type
|
||||
|
||||
// Get right part of the string without from the first "| "
|
||||
SearchIndex = InStr(TempItemDetailsHolder.Name, "|");
|
||||
SkinType = Right(TempItemDetailsHolder.Name, Len(TempItemDetailsHolder.Name) - SearchIndex - 2);
|
||||
|
||||
// Get the left part of the string without the next "| "
|
||||
SearchIndex = InStr(SkinType, "|");
|
||||
SkinType = Left(SkinType, SearchIndex);
|
||||
|
||||
// Store as CRC, that speeds up comparisons later
|
||||
HelperItem.SkinType = CrC(SkinType);
|
||||
}
|
||||
|
||||
CosmeticSkinListSearchCache.AddItem(HelperItem);
|
||||
}
|
||||
}
|
||||
else if (TempItemDetailsHolder.Type == ITP_CraftingComponent)
|
||||
{
|
||||
ItemId = CraftingListSearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
|
||||
|
||||
if (ItemID != INDEX_NONE)
|
||||
{
|
||||
HelperItem.CraftingType = CraftingListSearchCache[ItemID].CraftingType;
|
||||
HelperItem.CraftingRarity = CraftingListSearchCache[ItemID].CraftingRarity;
|
||||
HelperItem.CraftingTicketType = CraftingListSearchCache[ItemID].CraftingTicketType;
|
||||
}
|
||||
else
|
||||
{
|
||||
HelperItem.CraftingType = 999;
|
||||
HelperItem.CraftingRarity = 999;
|
||||
HelperItem.CraftingTicketType = 0;
|
||||
|
||||
// We don't have information to stick to.. so we have to search on the Name.. we use KeyName, as it contains the unmodified language Key
|
||||
|
||||
// Type
|
||||
|
||||
SearchIndex = InStr(TempItemDetailsHolder.KeyName, ":");
|
||||
|
||||
KeyType = Left(TempItemDetailsHolder.KeyName, SearchIndex);
|
||||
|
||||
SearchIndex = InStr(KeyType, "CosmeticMaterial");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "WeaponSkinMaterial");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingType = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "VaultCraftingMaterial");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingType = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rarity
|
||||
|
||||
SearchIndex = InStr(KeyType, "Uncommon");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingRarity = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Common");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingRarity = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Rare");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingRarity = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Exceptional");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingRarity = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ticket Type
|
||||
|
||||
SearchIndex = InStr(KeyType, "CyberPunk");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingTicketType = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Sideshow");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingTicketType = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Hllwn");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingTicketType = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchIndex = InStr(KeyType, "Christmas");
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.CraftingTicketType = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CraftingListSearchCache.AddItem(HelperItem);
|
||||
}
|
||||
}
|
||||
else if (TempItemDetailsHolder.Type == ITP_KeyCrate)
|
||||
{
|
||||
ItemId = ItemListSearchCache.Find('ItemDefinition', HelperItem.ItemDefinition);
|
||||
|
||||
if (ItemID != INDEX_NONE)
|
||||
{
|
||||
HelperItem.IsKey = ItemListSearchCache[ItemID].IsKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to distinguish if the Item is a KEY or not, we use KeyName, as it contains the unmodified language Key
|
||||
|
||||
// KeyName is something like : "NameItem:KeyCrate", we first remove the part from the : to the right
|
||||
SearchIndex = InStr(TempItemDetailsHolder.KeyName, ":");
|
||||
KeyType = Left(TempItemDetailsHolder.KeyName, SearchIndex);
|
||||
|
||||
// Then we search if the name of the Item contains "Key"
|
||||
SearchIndex = InStr(KeyType, "Key");
|
||||
|
||||
if (SearchIndex != -1)
|
||||
{
|
||||
HelperItem.IsKey = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HelperItem.IsKey = false;
|
||||
}
|
||||
|
||||
ItemListSearchCache.AddItem(HelperItem);
|
||||
}
|
||||
}
|
||||
|
||||
ByTypeItems[TempItemDetailsHolder.Type].ItemsOnType.AddItem(HelperItem);
|
||||
@ -481,30 +726,36 @@ function InitInventory()
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_WeaponSkins)
|
||||
{
|
||||
// If need to refresh... we regenerate the list, if not reuse our Cache
|
||||
NeedToRegenerateSkinList = NeedToRegenerateSkinList || ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length != SkinListOrderedCache.Length;
|
||||
|
||||
if (NeedToRegenerateSkinList)
|
||||
if (WeaponSkinListCache.NeedToRegenerate
|
||||
|| WeaponSkinListCache.WeaponTypeFilter != CurrentWeaponTypeFilter
|
||||
|| WeaponSkinListCache.PerkIndexFilter != CurrentPerkIndexFilter
|
||||
|| WeaponSkinListCache.RarityFilter != CurrentRarityFilter
|
||||
|| ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length != WeaponSkinListCache.OrderedCache.Length)
|
||||
{
|
||||
NeedToRegenerateSkinList = false;
|
||||
WeaponSkinListCache.NeedToRegenerate = false;
|
||||
|
||||
WeaponSkinListCache.WeaponTypeFilter = CurrentWeaponTypeFilter;
|
||||
WeaponSkinListCache.PerkIndexFilter = CurrentPerkIndexFilter;
|
||||
WeaponSkinListCache.RarityFilter = CurrentRarityFilter;
|
||||
|
||||
// We want to order by Price - Weapon Def - Rarity - Quality
|
||||
// So we order inverse that way we keep the final list with the design intention
|
||||
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType.Sort(SortSkinList);
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType.Sort(SortWeaponSkinList);
|
||||
|
||||
SkinListOrderedCache = ByTypeItems[ITP_WeaponSkin].ItemsOnType;
|
||||
WeaponSkinListCache.OrderedCache = ByTypeItems[ITP_WeaponSkin].ItemsOnType;
|
||||
|
||||
/*`Log("----------");*/
|
||||
/*`Log("----------");
|
||||
|
||||
/*for (i = 0 ; i < SkinListOrderedCache.Length; i++)
|
||||
for (i = 0 ; i < ByTypeItems[ITP_WeaponSkin].ItemsOnType.Length; i++)
|
||||
{
|
||||
`Log("ID : " $SkinListOrderedCache[i].ItemDefinition);
|
||||
`Log("Weapon Def : " $SkinListOrderedCache[i].WeaponDef);
|
||||
`Log("Price : " $SkinListOrderedCache[i].Price);
|
||||
`Log("Full Name : " $SkinListOrderedCache[i].FullName);
|
||||
`Log("Skin : " $SkinListOrderedCache[i].SkinType);
|
||||
`Log("Rarity : " $SkinListOrderedCache[i].Rarity);
|
||||
`Log("Quality : " $SkinListOrderedCache[i].Quality);
|
||||
`Log("ID : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].ItemDefinition);
|
||||
`Log("Weapon Def : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].WeaponDef);
|
||||
`Log("Price : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].Price);
|
||||
`Log("Full Name : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].FullName);
|
||||
`Log("Skin : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].SkinType);
|
||||
`Log("Rarity : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].Rarity);
|
||||
`Log("Quality : " $ByTypeItems[ITP_WeaponSkin].ItemsOnType[i].Quality);
|
||||
`Log("----------");
|
||||
}
|
||||
|
||||
@ -514,35 +765,58 @@ function InitInventory()
|
||||
{
|
||||
//`Log("USING SKIN LIST CACHE!!!");
|
||||
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType = SkinListOrderedCache;
|
||||
ByTypeItems[ITP_WeaponSkin].ItemsOnType = WeaponSkinListCache.OrderedCache;
|
||||
}
|
||||
}
|
||||
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Cosmetics)
|
||||
{
|
||||
ByTypeItems[ITP_CharacterSkin].ItemsOnType.Sort(SortCosmeticsList);
|
||||
|
||||
/*`Log("----------");
|
||||
|
||||
for (i = 0 ; i < ByTypeItems[ITP_CharacterSkin].ItemsOnType.Length; i++)
|
||||
{
|
||||
`Log("Cosmetic Name : " $ByTypeItems[ITP_CharacterSkin].ItemsOnType[i].CosmeticType);
|
||||
`Log("Skin : " $ByTypeItems[ITP_CharacterSkin].ItemsOnType[i].SkinType);
|
||||
`Log("Rarity : " $ByTypeItems[ITP_CharacterSkin].ItemsOnType[i].Rarity);
|
||||
`Log("----------");
|
||||
}
|
||||
|
||||
`Log("----------");*/
|
||||
}
|
||||
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_CraftingMats)
|
||||
{
|
||||
ByTypeItems[ITP_CraftingComponent].ItemsOnType.Sort(SortCraftingList);
|
||||
|
||||
/*`Log("----------");
|
||||
|
||||
for (i = 0 ; i < ByTypeItems[ITP_CraftingComponent].ItemsOnType.Length; i++)
|
||||
{
|
||||
`Log("Crafting Type : " $ByTypeItems[ITP_CraftingComponent].ItemsOnType[i].CraftingType);
|
||||
`Log("Rarity : " $ByTypeItems[ITP_CraftingComponent].ItemsOnType[i].CraftingRarity);
|
||||
`Log("Ticket Type : " $ByTypeItems[ITP_CraftingComponent].ItemsOnType[i].CraftingTicketType);
|
||||
`Log("----------");
|
||||
}
|
||||
|
||||
`Log("----------");*/
|
||||
}
|
||||
|
||||
if (CurrentInventoryFilter == EInv_All || CurrentInventoryFilter == EInv_Consumables)
|
||||
{
|
||||
// Consumables is the type for the "Items" category on the UI
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList);
|
||||
|
||||
// First we have to distinguish if the Item is a KEY or not
|
||||
for (i = 0; i < ByTypeItems[ITP_KeyCrate].ItemsOnType.Length; i++)
|
||||
/*`Log("----------");
|
||||
|
||||
for (i = 0 ; i < ByTypeItems[ITP_KeyCrate].ItemsOnType.Length; i++)
|
||||
{
|
||||
// KeyName is something like : "NameItem:KeyCrate", we first remove the part from the : to the right
|
||||
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, ":");
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName = Left(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, SearchKeyKeywordIndex);
|
||||
|
||||
// Then we search if the name of the Item contains "Key"
|
||||
SearchKeyKeywordIndex = InStr(ByTypeItems[ITP_KeyCrate].ItemsOnType[i].KeyName, "Key");
|
||||
|
||||
if (SearchKeyKeywordIndex != -1)
|
||||
{
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey = false;
|
||||
}
|
||||
`Log("Is Key : " $ByTypeItems[ITP_KeyCrate].ItemsOnType[i].IsKey);
|
||||
`Log("----------");
|
||||
}
|
||||
|
||||
ByTypeItems[ITP_KeyCrate].ItemsOnType.Sort(SortItemList);
|
||||
`Log("----------");*/
|
||||
}
|
||||
|
||||
//`Log("--------------------------------");
|
||||
@ -617,8 +891,7 @@ function FinishCraft()
|
||||
{
|
||||
SetVisible(true);
|
||||
|
||||
`Log("FinishCraft");
|
||||
NeedToRegenerateSkinList = true;
|
||||
WeaponSkinListCache.NeedToRegenerate = true;
|
||||
}
|
||||
|
||||
function SetMatineeColor(int ItemRarity)
|
||||
@ -1198,7 +1471,8 @@ function Callback_Equip( int ItemDefinition )
|
||||
}
|
||||
|
||||
//refresh inventory
|
||||
NeedToRegenerateSkinList = true; // need to regenerate as the equipped state changed
|
||||
WeaponSkinListCache.NeedToRegenerate = true; // need to regenerate as the equipped state changed
|
||||
|
||||
InitInventory();
|
||||
}
|
||||
|
||||
@ -1495,8 +1769,6 @@ function Callback_PreviewItem( int ItemDefinition )
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
NeedToRegenerateSkinList=false
|
||||
|
||||
CurrentWeaponTypeFilter = EInvWT_None;
|
||||
CurrentRarityFilter = ITR_NONE;
|
||||
|
||||
|
@ -458,11 +458,16 @@ function Callback_ReadyClicked( bool bReady )
|
||||
|
||||
function Callback_PerkSelected(byte NewPerkIndex, bool bClickedIndex)
|
||||
{
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
|
||||
KFGRI = KFGameReplicationInfo( KFPC.WorldInfo.GRI );
|
||||
if (KFGRI != none && KFGRI.IsRandomPerkMode())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// bClickedIndex let's us know if the index was clicked and needs to be changed or if it was just selected and we should look at other perk info.
|
||||
PerkChanged(NewPerkIndex,bClickedIndex);
|
||||
if(bClickedIndex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function Callback_SkillSelected( byte TierIndex, byte SkillIndex )
|
||||
|
@ -784,7 +784,7 @@ function DisplayMapCounterText(string MessageText, float DisplayTime)
|
||||
}
|
||||
}
|
||||
|
||||
function DisplayPriorityMessage(string InPrimaryMessageString, string InSecondaryMessageString, int LifeTime, optional EGameMessageType MessageType)
|
||||
function DisplayPriorityMessage(string InPrimaryMessageString, string InSecondaryMessageString, int LifeTime, optional EGameMessageType MessageType, optional string SpecialIconPath)
|
||||
{
|
||||
local GFxObject PriorityMessageObject;
|
||||
|
||||
@ -797,6 +797,11 @@ function DisplayPriorityMessage(string InPrimaryMessageString, string InSecondar
|
||||
PriorityMessageObject.SetString("priorityTextSecondaryString", InSecondaryMessageString);
|
||||
PriorityMessageObject.SetInt("priorityTextDisplayTime", LifeTime);
|
||||
|
||||
if (SpecialIconPath != "")
|
||||
{
|
||||
PriorityMessageObject.SetString("specialIconPath", "img://"$SpecialIconPath);
|
||||
}
|
||||
|
||||
PriorityMessageContainer.SetObject("priorityMessage", PriorityMessageObject);
|
||||
}
|
||||
}
|
||||
@ -911,7 +916,11 @@ function int GetWaveTier()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (KFGRI.IsFinalWave())
|
||||
if (KFGRI.IsRandomPerkMode())
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
else if (KFGRI.IsFinalWave())
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
@ -1393,6 +1402,11 @@ function Callback_ObjMessageFired()
|
||||
PlayObjectiveAudio();
|
||||
}
|
||||
|
||||
function Callback_Log(string text)
|
||||
{
|
||||
`Log("Received log from actionscript: " $text);
|
||||
}
|
||||
|
||||
function Callback_PriorityMessageComplete()
|
||||
{
|
||||
local KFInterface_MapObjective ObjectiveInterface;
|
||||
@ -1508,6 +1522,7 @@ function Callback_VoteKick(bool Vote)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
SoundThemes.Add((ThemeName = "UI",Theme = UISoundTheme'SoundsShared_UI.SoundTheme_UI'))
|
||||
|
@ -13,13 +13,13 @@ class KFGFxServerBrowser_Filters extends KFGFxObject_Container
|
||||
config(UI);
|
||||
|
||||
var KFGFxMenu_ServerBrowser ServerMenu;
|
||||
var localized string NoPasswordString, NoMutatorsString, NotFullString, NotEmptyString, NoRankedStandardString, NoRankedCustomString, NoUnrankedString, DedicatedString, VACSecureString, InLobbyString, InProgressString, OnlyStockMapsString, OnlyCustomMapsString, LimitServerResultsString, NotServerExiledString;
|
||||
var localized string NoPasswordString, NoMutatorsString, NotFullString, NotEmptyString, NoRankedStandardString, NoRankedCustomString, NoUnrankedString, DedicatedString, VACSecureString, InLobbyString, InProgressString, OnlyStockMapsString, OnlyCustomMapsString, LimitServerResultsString, NotServerExiledString, NoSeasonalSkinsString;
|
||||
var array<string> FilterStrings;
|
||||
|
||||
var config Bool bNoPassword, bNoMutators, bNotFull, bNotEmpty, bUsesStats, bCustom, bDedicated, bVAC_Secure, bInLobby, bInProgress, bOnlyStockMaps, bOnlyCustomMaps, bLimitServerResults, bNoLocalAdmin;
|
||||
var config Bool bNoPassword, bNoMutators, bNotFull, bNotEmpty, bUsesStats, bCustom, bDedicated, bVAC_Secure, bInLobby, bInProgress, bOnlyStockMaps, bOnlyCustomMaps, bLimitServerResults, bNoLocalAdmin, bNoSeasonalSkins;
|
||||
var config byte SavedGameModeIndex, SavedMapIndex, SavedDifficultyIndex, SavedLengthIndex, SavedPingIndex;
|
||||
|
||||
var Bool bNoPasswordPending, bNoMutatorsPending, bNotFullPending, bNotEmptyPending, bUsesStatsPending, bCustomPending, bDedicatedPending, bVAC_SecurePending, bInLobbyPending, bInProgressPending, bOnlyStockMapsPending, bOnlyCustomMapsPending, bLimitServerResultsPending, bNoLocalAdminPending;
|
||||
var Bool bNoPasswordPending, bNoMutatorsPending, bNotFullPending, bNotEmptyPending, bUsesStatsPending, bCustomPending, bDedicatedPending, bVAC_SecurePending, bInLobbyPending, bInProgressPending, bOnlyStockMapsPending, bOnlyCustomMapsPending, bLimitServerResultsPending, bNoLocalAdminPending, bNoSeasonalSkinsPending;
|
||||
var byte SavedGameModeIndexPending, SavedMapIndexPending, SavedDifficultyIndexPending, SavedLengthIndexPending, SavedPingIndexPending;
|
||||
|
||||
var transient string CachedMapName, CachedModeName;
|
||||
@ -29,6 +29,8 @@ var transient array<string> MapList;
|
||||
|
||||
var int NumDifficultyStrings;
|
||||
|
||||
// if you change this also update ServerBrowserFilterContainer.as -> NUM_OF_FILTERS
|
||||
|
||||
enum EFilter_Key
|
||||
{
|
||||
NO_PASSWORD,
|
||||
@ -46,6 +48,7 @@ enum EFilter_Key
|
||||
/*ONLY_STOCK_MAPS, //Not using for EA
|
||||
ONLY_CUSTOM_MAPS,*/ //Not using for EA
|
||||
NO_LOCAL_ADMIN,
|
||||
NO_SEASONAL_SKINS,
|
||||
FILTERS_MAX,
|
||||
};
|
||||
|
||||
@ -119,6 +122,7 @@ function InitFiltersArray()
|
||||
FilterStrings[NO_LOCAL_ADMIN] = NotServerExiledString;
|
||||
/*FilterStrings[ONLY_STOCK_MAPS] = OnlyStockMapsString;
|
||||
FilterStrings[ONLY_CUSTOM_MAPS] = OnlyCustomMapsString;*/
|
||||
FilterStrings[NO_SEASONAL_SKINS] = NoSeasonalSkinsString;
|
||||
}
|
||||
|
||||
function LocalizeText()
|
||||
@ -155,9 +159,22 @@ function LocalizeCheckBoxes()
|
||||
local byte i;
|
||||
local GFxObject FiltersArray;
|
||||
local GFxObject TempObject;
|
||||
local bool bShowAllowSeasonalSkins;
|
||||
|
||||
bShowAllowSeasonalSkins = true;
|
||||
|
||||
if (ServerMenu.Manager.StartMenu.GetStartMenuState() == EMatchmaking
|
||||
|| class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None)
|
||||
{
|
||||
bShowAllowSeasonalSkins = false; // Default if we don't have a season or it's find a match menu
|
||||
}
|
||||
|
||||
SetBool("SetAllowSkinsVisibility", bShowAllowSeasonalSkins);
|
||||
|
||||
FiltersArray = CreateArray();
|
||||
|
||||
// If you plan to disable a filter don't do it here, do it on ServerBrowserFilterContainer.as
|
||||
|
||||
for ( i = 0; i < FILTERS_MAX; i++ )
|
||||
{
|
||||
TempObject = CreateObject( "Object" );
|
||||
@ -319,6 +336,7 @@ function ApplyFilters()
|
||||
bOnlyCustomMaps = bOnlyCustomMapsPending;
|
||||
bLimitServerResults = bLimitServerResultsPending;
|
||||
bNoLocalAdmin = bNoLocalAdminPending;
|
||||
bNoSeasonalSkins = bNoSeasonalSkinsPending;
|
||||
|
||||
SavedGameModeIndex = SavedGameModeIndexPending;
|
||||
SavedMapIndex = SavedMapIndexPending;
|
||||
@ -345,6 +363,7 @@ function ClearPendingValues()
|
||||
bOnlyCustomMapsPending = bOnlyCustomMaps;
|
||||
bLimitServerResultsPending = bLimitServerResults;
|
||||
bNoLocalAdminPending = bNoLocalAdmin;
|
||||
bNoSeasonalSkinsPending = bNoSeasonalSkins;
|
||||
SavedGameModeIndexPending = SavedGameModeIndex;
|
||||
SavedMapIndexPending = SavedMapIndex;
|
||||
SavedDifficultyIndexPending = SavedDifficultyIndex;
|
||||
@ -369,6 +388,7 @@ function ResetFilters()
|
||||
bOnlyCustomMaps = false;
|
||||
bLimitServerResults = true;
|
||||
bNoLocalAdmin = true;
|
||||
bNoSeasonalSkins = false;
|
||||
|
||||
SavedGameModeIndex = 255;
|
||||
SavedMapIndex = 255;
|
||||
@ -428,6 +448,9 @@ function SetBoolByEFilter_Key(EFilter_Key Filter, bool FilterValue)
|
||||
case NO_LOCAL_ADMIN:
|
||||
bNoLocalAdminPending = FilterValue;
|
||||
break;
|
||||
case NO_SEASONAL_SKINS:
|
||||
bNoSeasonalSkinsPending = FilterValue;
|
||||
break;
|
||||
/*case ONLY_STOCK_MAPS:
|
||||
bOnlyStockMapsPending = FilterValue;
|
||||
break;
|
||||
@ -479,6 +502,9 @@ function bool GetBoolByEFilter_Key(EFilter_Key Filter)
|
||||
case NO_LOCAL_ADMIN:
|
||||
return bNoLocalAdmin;
|
||||
|
||||
case NO_SEASONAL_SKINS:
|
||||
return bNoSeasonalSkins;
|
||||
|
||||
/*case ONLY_STOCK_MAPS:
|
||||
return bOnlyStockMaps;
|
||||
|
||||
|
@ -17,6 +17,8 @@ var localized string ServerInfoString;
|
||||
var localized string JoinGameString;
|
||||
var localized string SpectateGameString;
|
||||
var localized string UnfavoriteString;
|
||||
var localized string SeasonalSkinsString;
|
||||
var localized string NoSeasonalSkinsString;
|
||||
|
||||
function Initialize( KFGFxObject_Menu NewParentMenu )
|
||||
{
|
||||
@ -42,6 +44,8 @@ function LocalizeText()
|
||||
LocalizedObject.SetString("mutators", MutatorsString);
|
||||
LocalizedObject.SetString("joinGame", JoinGameString);
|
||||
LocalizedObject.SetString("spectateGame", SpectateGameString);
|
||||
LocalizedObject.SetString("seasonalString", SeasonalSkinsString);
|
||||
LocalizedObject.SetString("noseasonalString", NoSeasonalSkinsString);
|
||||
|
||||
SetObject("localizedText", LocalizedObject);
|
||||
}
|
||||
@ -87,6 +91,7 @@ function SetDetails(KFOnlineGameSettings ServerResult)
|
||||
TempObj.SetBool("vacEnable", TempOnlingGamesSettings.bAntiCheatProtected);
|
||||
TempObj.SetBool("mutators", TempOnlingGamesSettings.bMutators);
|
||||
TempObj.SetBool("ranked", TempOnlingGamesSettings.bUsesStats);
|
||||
TempObj.SetBool("seasonalSkins", TempOnlingGamesSettings.bNoSeasonalSkins == false);
|
||||
|
||||
Ping = TempOnlingGamesSettings.PingInMs;
|
||||
TempObj.SetString("ping", (Ping < 0) ? ("-") : (String(Ping)) );
|
||||
|
@ -272,6 +272,7 @@ function BuildServerFilters(KFGFxServerBrowser_Filters Filters, OnlineGameSearch
|
||||
local string GametagSearch;
|
||||
local string MapName;
|
||||
local int Mode, Difficulty, Length;
|
||||
local bool DisableSeasonalSkins;
|
||||
|
||||
Search.ClearServerFilters();
|
||||
|
||||
@ -280,6 +281,15 @@ function BuildServerFilters(KFGFxServerBrowser_Filters Filters, OnlineGameSearch
|
||||
Search.TestAddServerFilter( Filters.bNotEmpty, "hasplayers");
|
||||
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bNoLocalAdmin, 'bServerExiled', 0);
|
||||
|
||||
DisableSeasonalSkins = Filters.bNoSeasonalSkins;
|
||||
|
||||
if (class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None)
|
||||
{
|
||||
DisableSeasonalSkins = false;
|
||||
}
|
||||
|
||||
Search.TestAddBoolGametagFilter(GametagSearch, DisableSeasonalSkins, 'bNoSeasonalSkins', 1);
|
||||
|
||||
if( !class'WorldInfo'.static.IsConsoleBuild() )
|
||||
{
|
||||
Search.TestAddServerFilter( Filters.bDedicated, "dedicated");
|
||||
|
@ -117,6 +117,9 @@ static function GetObjectiveProgressValues(int ObjectiveID, out int CurrentValue
|
||||
local KFPlayerController LocalKFPC;
|
||||
local int TempCurrentValue, TempMaxValue;
|
||||
|
||||
TempCurrentValue = 0;
|
||||
TempMaxValue = 0;
|
||||
|
||||
LocalKFPC = KFPlayerController(class'WorldInfo'.static.GetWorldInfo().GetALocalPlayerController());
|
||||
LocalKFPC.GetSeasonalEventStatInfo(ObjectiveID, TempCurrentValue, TempMaxValue);
|
||||
|
||||
|
@ -13,7 +13,7 @@ dependson(KFUnlockManager);
|
||||
|
||||
|
||||
var KFGFxMenu_StartGame StartMenu;
|
||||
var byte LastDifficultyIndex, LastLengthIndex, LastPrivacyIndex;
|
||||
var byte LastDifficultyIndex, LastLengthIndex, LastPrivacyIndex, LastAllowSeasonalSkinsIndex;
|
||||
|
||||
var localized string OverviewString;
|
||||
var localized string ChangeString;
|
||||
@ -90,7 +90,6 @@ function LocalizeContainer()
|
||||
LocalizedObject.SetString("infoTitle", StartMenu.InfoTitle);
|
||||
LocalizedObject.SetString("permissionsTitle", StartMenu.PermissionsTitle);
|
||||
|
||||
|
||||
WI = class'WorldInfo'.static.GetWorldInfo();
|
||||
if( WI != none && WI.NetMode != NM_Standalone && !GetPC().WorldInfo.IsConsoleBuild() )
|
||||
{
|
||||
@ -115,6 +114,17 @@ function LocalizeContainer()
|
||||
|
||||
LocalizedObject.SetObject("permissionOptions", DataProvider);
|
||||
|
||||
DataProvider = CreateArray();
|
||||
|
||||
for (i = 0; i < class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsStringsArray().length; i++)
|
||||
{
|
||||
TempObj = CreateObject("Object");
|
||||
TempObj.SetString("label", class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsString(i));
|
||||
DataProvider.SetElementObject(i, TempObj);
|
||||
}
|
||||
|
||||
LocalizedObject.SetObject("allowSeasonalSkinsOptions", DataProvider);
|
||||
|
||||
if( !class'WorldInfo'.static.IsMenuLevel() )
|
||||
{
|
||||
LocalizedObject.SetString("authorName", AuthorString$GetPC().WorldInfo.Author);
|
||||
@ -335,12 +345,17 @@ function UpdatePrivacy( string Privacy )
|
||||
SetString("permissionsText", Privacy);
|
||||
}
|
||||
|
||||
function UpdateAllowSeasonalSkins(string AllowSeasonalStrings)
|
||||
{
|
||||
SetString("allowSeasonalSkinsText", AllowSeasonalStrings);
|
||||
}
|
||||
|
||||
function UpdateOverviewInGame()
|
||||
{
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
local string GameDifficultyString;
|
||||
local Float CurrentGameDifficulty;
|
||||
local int CurrentLengthIndex, CurrentPrivacyIndex;
|
||||
local int CurrentLengthIndex, CurrentPrivacyIndex, CurrentAllowSeasonalSkinsIndex;
|
||||
local bool bCustomDifficulty;
|
||||
local bool bCustomLength;
|
||||
|
||||
@ -405,6 +420,13 @@ function UpdateOverviewInGame()
|
||||
UpdatePrivacy( class'KFCommon_LocalizedStrings'.static.GetPermissionString(CurrentPrivacyIndex) );
|
||||
LastPrivacyIndex = CurrentPrivacyIndex;
|
||||
}
|
||||
|
||||
CurrentAllowSeasonalSkinsIndex = StartMenu.OptionsComponent.GetAllowSeasonalSkinsIndex();
|
||||
if (LastAllowSeasonalSkinsIndex != CurrentAllowSeasonalSkinsIndex)
|
||||
{
|
||||
UpdateAllowSeasonalSkins( class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsString(CurrentAllowSeasonalSkinsIndex) );
|
||||
LastAllowSeasonalSkinsIndex = CurrentAllowSeasonalSkinsIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,6 +447,7 @@ DefaultProperties
|
||||
LastPrivacyIndex=255
|
||||
LastLengthIndex=255
|
||||
LastDifficultyIndex=255
|
||||
LastAllowSeasonalSkinsIndex=255
|
||||
|
||||
ObjectiveClassName=KFGameInfo_Objective
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ function FillWhatsNew()
|
||||
local SWhatsNew item;
|
||||
WhatsNewItems.Remove(0, WhatsNewItems.Length);
|
||||
// Latest Update
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_BloodBonfire", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_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/");
|
||||
@ -194,31 +194,31 @@ function FillWhatsNew()
|
||||
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_Blodd_Bornfires_Weapon_Bundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9471");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_WeaponsBundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9557");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Weapon
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Blood_Sickle_Weapon_bundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9469");
|
||||
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_G36C_Weapon_Bundle","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9467");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_HVStormCannon","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9556");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Outfit Bundle
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_PlagueDoctor_Uniforms", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9465");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_TrainConductorOutfit", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9554");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Time Limited Item
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5246");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5588");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Weapon Skin Bundle
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Plague_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9457");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Tacticool_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9553");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Weapon Skin Bundle
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Weapon_skins_XenoPack", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9459");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Retro_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9552");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Weapon Skin Bundle
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Classic2_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9461");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_Mediaval_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9503");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Featured Weapon Skin Bundle
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween2022_Chamaleon2_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9463");
|
||||
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas2022_ChamaleonIII_Weapon_Skin", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9502");
|
||||
WhatsNewItems.AddItem(item);
|
||||
// Misc Community Links
|
||||
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");
|
||||
|
@ -74,6 +74,7 @@ var GFxObject LengthButton;
|
||||
var GFxObject DifficultyButton;
|
||||
var GfxObject MapButton;
|
||||
var GFxObject RegionButton;
|
||||
var GFxObject AllowSeasonalSkinsButton;
|
||||
|
||||
//==============================================================
|
||||
// Initialization
|
||||
@ -94,6 +95,7 @@ function GetButtons()
|
||||
DifficultyButton = GetObject("difficultyButton");
|
||||
MapButton = GetObject("mapButton");
|
||||
RegionButton = GetObject("regionButton");
|
||||
AllowSeasonalSkinsButton = GetObject("allowSeasonalSkinsButton");
|
||||
}
|
||||
|
||||
function UpdateButtonsEnabled()
|
||||
@ -241,6 +243,18 @@ function InitializeGameOptions()
|
||||
TextObject.SetString("length",StartMenu.LengthTitle);
|
||||
TextObject.SetString("privacy",StartMenu.PermissionsTitle);
|
||||
TextObject.SetString("inProgress", InProgressString);
|
||||
|
||||
if (class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None)
|
||||
{
|
||||
TextObject.SetBool("bShowAllowSeasonalSkins", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
TextObject.SetBool("bShowAllowSeasonalSkins", true);
|
||||
}
|
||||
|
||||
TextObject.SetString("allowSeasonalSkins", StartMenu.AllowSeasonalSkinsTitle);
|
||||
|
||||
// Since the Mode list can include "ANY" we need to just accept that the selected index could be the length of the supported modes. Otherwise when "ANY" is selected we push the index to 1.
|
||||
// Also don't include the "ANY" option on Console since PlayGo doesn't support searching multiple game types. HSL_BB
|
||||
TextObject.SetObject("modeList", CreateList(SupportedGameModeStrings, Min(ParentMenu.Manager.GetModeIndex() , SupportedGameModeStrings.Length), false));
|
||||
@ -249,6 +263,7 @@ function InitializeGameOptions()
|
||||
TextObject.SetObject("mapList", CreateList(StartMenu.MapStringList, bIsSoloGame ? InitialMapIndex : InitialMapIndex+1, true, true));
|
||||
TextObject.SetObject("difficultyList", CreateList(class'KFCommon_LocalizedStrings'.static.GetDifficultyStringsArray(), GetDifficultyIndex(), false));
|
||||
TextObject.SetObject("privacyList", CreateList(class'KFCommon_LocalizedStrings'.static.GetPermissionStringsArray(class'WorldInfo'.static.IsConsoleBuild()), Profile.GetProfileInt(KFID_SavedPrivacyIndex), false));
|
||||
TextObject.SetObject("allowSeasonalSkinsList", CreateList(class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsStringsArray(), Profile.GetProfileInt(KFID_SavedAllowSeasonalSkinsIndex), false));
|
||||
|
||||
if (class'WorldInfo'.static.IsConsoleBuild())
|
||||
{
|
||||
@ -293,8 +308,6 @@ function FilterWeeklyMaps(out array<string> List)
|
||||
{
|
||||
List.RemoveItem("KF-SteamFortress");
|
||||
}
|
||||
/**/
|
||||
|
||||
}
|
||||
|
||||
function GFxObject CreateList( array<string> TextArray, byte SelectedIndex, bool bAddNoPrefString, optional bool bIsMapList, optional byte MaxLength)
|
||||
@ -465,6 +478,20 @@ function PrivacyChanged( int Index, optional bool bSetText )
|
||||
}
|
||||
}
|
||||
|
||||
function AllowSeasonalSkinsChanged( int Index, optional bool bSetText )
|
||||
{
|
||||
if(Index != GetCachedProfile().GetProfileInt(KFID_SavedAllowSeasonalSkinsIndex))
|
||||
{
|
||||
SaveConfig();
|
||||
if(bSetText)
|
||||
{
|
||||
AllowSeasonalSkinsButton.SetString("infoString", class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsStringsArray()[Index]);
|
||||
}
|
||||
|
||||
GetCachedProfile().SetProfileSettingValueInt(KFID_SavedAllowSeasonalSkinsIndex, Index);
|
||||
}
|
||||
}
|
||||
|
||||
function SetRegionIndex(int InRegionIndex, optional bool bSetText)
|
||||
{
|
||||
local array<String> PlayfabRegionList;
|
||||
@ -579,6 +606,11 @@ function int GetPrivacyIndex()
|
||||
return GetCachedProfile().GetProfileInt(KFID_SavedPrivacyIndex);
|
||||
}
|
||||
|
||||
function int GetAllowSeasonalSkinsIndex()
|
||||
{
|
||||
return GetCachedProfile().GetProfileInt(KFID_SavedAllowSeasonalSkinsIndex);
|
||||
}
|
||||
|
||||
function string GetMapName()
|
||||
{
|
||||
local string SavedMapString;
|
||||
|
@ -448,24 +448,24 @@ DefaultProperties
|
||||
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
|
||||
|
||||
FeaturedItemIDs[0]=7944 //Whatsnew Gold Ticket
|
||||
FeaturedItemIDs[1]=9471
|
||||
FeaturedItemIDs[2]=9469
|
||||
FeaturedItemIDs[3]=9467
|
||||
FeaturedItemIDs[4]=9465
|
||||
FeaturedItemIDs[5]=9457
|
||||
FeaturedItemIDs[6]=9459
|
||||
FeaturedItemIDs[7]=9461
|
||||
FeaturedItemIDs[8]=9463
|
||||
FeaturedItemIDs[1]=9557
|
||||
FeaturedItemIDs[2]=9556
|
||||
FeaturedItemIDs[3]=9555
|
||||
FeaturedItemIDs[4]=9554
|
||||
FeaturedItemIDs[5]=9502
|
||||
FeaturedItemIDs[6]=9503
|
||||
FeaturedItemIDs[7]=9553
|
||||
FeaturedItemIDs[8]=9552
|
||||
|
||||
ConsoleFeaturedItemIDs[0]=7947 //Whatsnew Gold Ticket PSN
|
||||
ConsoleFeaturedItemIDs[1]=9471
|
||||
ConsoleFeaturedItemIDs[2]=9469
|
||||
ConsoleFeaturedItemIDs[3]=9467
|
||||
ConsoleFeaturedItemIDs[4]=9465
|
||||
ConsoleFeaturedItemIDs[5]=9457
|
||||
ConsoleFeaturedItemIDs[6]=9459
|
||||
ConsoleFeaturedItemIDs[7]=9461
|
||||
ConsoleFeaturedItemIDs[8]=9463
|
||||
ConsoleFeaturedItemIDs[1]=9557
|
||||
ConsoleFeaturedItemIDs[2]=9556
|
||||
ConsoleFeaturedItemIDs[3]=9555
|
||||
ConsoleFeaturedItemIDs[4]=9554
|
||||
ConsoleFeaturedItemIDs[5]=9502
|
||||
ConsoleFeaturedItemIDs[6]=9503
|
||||
ConsoleFeaturedItemIDs[7]=9553
|
||||
ConsoleFeaturedItemIDs[8]=9552
|
||||
|
||||
MaxFeaturedItems=5
|
||||
}
|
@ -66,9 +66,11 @@ function LocalizeContainer()
|
||||
//Updates the ablility to change the perk
|
||||
function UpdateLock()
|
||||
{
|
||||
local bool bLocked;
|
||||
if (KFPC != none)
|
||||
{
|
||||
SetBool("perkChangeLocked", !KFPC.CanUpdatePerkInfo());
|
||||
bLocked = !KFPC.CanUpdatePerkInfo() || KFGameReplicationInfo(KFPC.WorldInfo.GRI).IsRandomPerkMode();
|
||||
SetBool("perkChangeLocked", bLocked);
|
||||
}
|
||||
}
|
||||
|
||||
|
79
KFGame/Classes/KFGFxWorld_WeaponRadar.uc
Normal file
79
KFGame/Classes/KFGFxWorld_WeaponRadar.uc
Normal file
@ -0,0 +1,79 @@
|
||||
//=============================================================================
|
||||
// KFGFxHUD_WeaponRadar
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFGFxWorld_WeaponRadar extends GFxMoviePlayer;
|
||||
|
||||
struct RadarObject
|
||||
{
|
||||
var vector Location;
|
||||
var string IconPath;
|
||||
};
|
||||
|
||||
var array<RadarObject> ObjectsInRadar;
|
||||
|
||||
var GFxObject RadarContainer;
|
||||
|
||||
/** Ties the GFxClikWidget variables to the .swf components and handles events */
|
||||
event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
|
||||
{
|
||||
switch(WidgetName)
|
||||
{
|
||||
case ('radarContainer'):
|
||||
if ( RadarContainer == none )
|
||||
{
|
||||
RadarContainer = Widget;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
simulated function AddRadarElements(array<vector> Elements)
|
||||
{
|
||||
local int i;
|
||||
local GFxObject DataObject;
|
||||
local GFxObject DataProvider;
|
||||
|
||||
if (Elements.Length == 0 || RadarContainer == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DataProvider = CreateArray();
|
||||
for (i = 0; i < Elements.Length; ++i)
|
||||
{
|
||||
DataObject = CreateObject( "Object" );
|
||||
DataObject.SetFloat("UIX", Elements[i].X);
|
||||
DataObject.SetFloat("UIY", Elements[i].Y);
|
||||
|
||||
DataProvider.SetElementObject(i, DataObject);
|
||||
}
|
||||
|
||||
RadarContainer.SetObject("RadarElements", DataProvider);
|
||||
}
|
||||
|
||||
simulated function Clear()
|
||||
{
|
||||
if (RadarContainer != none)
|
||||
{
|
||||
RadarContainer.ActionScriptVoid("Clear");
|
||||
}
|
||||
}
|
||||
|
||||
simulated function PrintLog(string text)
|
||||
{
|
||||
`Log("ActionScript Log: " $text);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
RenderTexture=TextureRenderTarget2D'WEP_1P_Optics_TEX.Wep_1stP_Optics_R2T'
|
||||
MovieInfo=SwfMovie'UI_World.RadarWorld_SWF'
|
||||
bAutoPlay=false
|
||||
}
|
@ -143,7 +143,7 @@ cpptext
|
||||
{
|
||||
// static members
|
||||
static FString GetSeasonalEventPrefix();
|
||||
static FString GetSeasonalEventPackageName(INT EventId = -1, UMapInfo* MapInfo = NULL);
|
||||
static FString GetSeasonalEventPackageName(INT EventId = -1, UMapInfo* MapInfo = NULL, bool bUnload = false);
|
||||
static FString GetSeasonalEventStatsClassPath();
|
||||
|
||||
// UEngine interface.
|
||||
|
@ -211,6 +211,8 @@ var protected const array< class<KFPawn_Monster> > AITestBossClassList; //List
|
||||
|
||||
var protected int BossIndex; //Index into boss array, only preload content for the boss we want - PC builds can handle DLO cost much better
|
||||
|
||||
var int AllowSeasonalSkinsIndex;
|
||||
|
||||
/** Class replacements for each zed type */
|
||||
struct native SpawnReplacement
|
||||
{
|
||||
@ -677,6 +679,7 @@ event InitGame( string Options, out string ErrorMessage )
|
||||
GameLength = Clamp(GetIntOption(Options, "GameLength", GameLength), 0, SpawnManagerClasses.Length - 1);
|
||||
}
|
||||
|
||||
AllowSeasonalSkinsIndex = GetIntOption(Options, "AllowSeasonalSkins", AllowSeasonalSkinsIndex);
|
||||
|
||||
if( OnlineSub != none && OnlineSub.GetLobbyInterface() != none )
|
||||
{
|
||||
@ -713,6 +716,36 @@ event InitGame( string Options, out string ErrorMessage )
|
||||
CreateDifficultyInfo(Options);
|
||||
}
|
||||
|
||||
function UpdateGameSettings()
|
||||
{
|
||||
local name SessionName;
|
||||
local KFOnlineGameSettings KFGameSettings;
|
||||
|
||||
super.UpdateGameSettings();
|
||||
|
||||
if (WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.NetMode == NM_ListenServer)
|
||||
{
|
||||
if (GameInterface != None)
|
||||
{
|
||||
SessionName = PlayerReplicationInfoClass.default.SessionName;
|
||||
|
||||
if (PlayfabInter != none && PlayfabInter.GetGameSettings() != none)
|
||||
{
|
||||
KFGameSettings = KFOnlineGameSettings(PlayfabInter.GetGameSettings());
|
||||
}
|
||||
else
|
||||
{
|
||||
KFGameSettings = KFOnlineGameSettings(GameInterface.GetGameSettings(SessionName));
|
||||
}
|
||||
|
||||
if (KFGameSettings != none)
|
||||
{
|
||||
KFGameSettings.bNoSeasonalSkins = AllowSeasonalSkinsIndex == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//for difficulty override
|
||||
function bool UsesModifiedLength()
|
||||
{
|
||||
@ -1095,6 +1128,8 @@ function InitGRIVariables()
|
||||
MyKFGRI.ReceivedGameLength();
|
||||
MyKFGRI.bVersusGame = bIsVersusGame;
|
||||
MyKFGRI.MaxHumanCount = MaxPlayers;
|
||||
MyKFGRI.NotifyAllowSeasonalSkins(AllowSeasonalSkinsIndex);
|
||||
|
||||
SetBossIndex();
|
||||
}
|
||||
|
||||
@ -2071,25 +2106,28 @@ function Killed(Controller Killer, Controller KilledPlayer, Pawn KilledPawn, cla
|
||||
{
|
||||
LastHitByDamageType = GetLastHitByDamageType( DT, MonsterPawn, Killer );
|
||||
|
||||
//Chris: We have to do it earlier here because we need a damage type
|
||||
KFPC.AddZedKill( MonsterPawn.class, GameDifficulty, LastHitByDamageType, true );
|
||||
|
||||
KFPCP = KFPC.GetPerk();
|
||||
if( KFPCP != none )
|
||||
if (LastHitByDamageType != none)
|
||||
{
|
||||
if( KFPCP.CanEarnSmallRadiusKillXP( LastHitByDamageType ) )
|
||||
{
|
||||
if(KFPCP.GetPerkClass() == class'KFPerk_Berserker'.static.GetPerkClass())
|
||||
{
|
||||
CheckForSmallRadiusKill( MonsterPawn, KFPC, class'KFPerk_Berserker' );
|
||||
}
|
||||
else if(KFPCP.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass())
|
||||
{
|
||||
CheckForSmallRadiusKill( MonsterPawn, KFPC, class'KFPerk_Survivalist' );
|
||||
}
|
||||
}
|
||||
//Chris: We have to do it earlier here because we need a damage type
|
||||
KFPC.AddZedKill( MonsterPawn.class, GameDifficulty, LastHitByDamageType, true );
|
||||
|
||||
KFPCP.AddVampireHealth( KFPC, LastHitByDamageType );
|
||||
KFPCP = KFPC.GetPerk();
|
||||
if( KFPCP != none )
|
||||
{
|
||||
if( KFPCP.CanEarnSmallRadiusKillXP( LastHitByDamageType ) )
|
||||
{
|
||||
if(KFPCP.GetPerkClass() == class'KFPerk_Berserker'.static.GetPerkClass())
|
||||
{
|
||||
CheckForSmallRadiusKill( MonsterPawn, KFPC, class'KFPerk_Berserker' );
|
||||
}
|
||||
else if(KFPCP.GetPerkClass() == class'KFPerk_Survivalist'.static.GetPerkClass())
|
||||
{
|
||||
CheckForSmallRadiusKill( MonsterPawn, KFPC, class'KFPerk_Survivalist' );
|
||||
}
|
||||
}
|
||||
|
||||
KFPCP.AddVampireHealth( KFPC, LastHitByDamageType );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2900,6 +2938,11 @@ simulated function ForceWWLMusicTrack()
|
||||
MyKFGRI.ForceNewMusicTrack( default.ForcedMusicTracks[EFM_WWL] );
|
||||
}
|
||||
|
||||
function bool IsWeekly()
|
||||
{
|
||||
return MyKFGRI.IsA('KFGameReplicationInfo_WeeklySurvival');
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Map rotation
|
||||
*********************************************************************************************/
|
||||
@ -2933,7 +2976,7 @@ function string GetNextMap()
|
||||
/**
|
||||
This could be changed to read replicated values instead of engine ones.
|
||||
*/
|
||||
if (MyKFGRI.IsA('KFGameReplicationInfo_WeeklySurvival'))
|
||||
if (IsWeekly())
|
||||
{
|
||||
if ((class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 11 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[11]) || // Scavenger
|
||||
(class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 14 || OutbreakEvent.ActiveEvent == OutbreakEvent.SetEvents[14]) || // Boss Rush
|
||||
@ -3912,6 +3955,11 @@ function ClearActorFromBonfire(Actor Other);
|
||||
**********************************************/
|
||||
simulated function ModifyDamageGiven(out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx );
|
||||
|
||||
/***********************************************
|
||||
* @name Notify a player is initialized
|
||||
**********************************************/
|
||||
simulated function NotifyPlayerStatsInitialized(KFPlayerController_WeeklySurvival KFPC){}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
/** Scoring */
|
||||
@ -3957,6 +4005,7 @@ defaultproperties
|
||||
bRestartLevel=false
|
||||
bWaitingToStartMatch=true
|
||||
bDelayedStart=true
|
||||
AllowSeasonalSkinsIndex=0
|
||||
|
||||
ActionMusicDelay=5.0
|
||||
ForcedMusicTracks(0)=KFMusicTrackInfo'WW_MMNU_Login.TrackInfo' // menu
|
||||
|
@ -385,6 +385,7 @@ var repnotify int VIPRepCurrentHealth;
|
||||
var repnotify int VIPRepMaxHealth;
|
||||
var repnotify KFPlayerReplicationInfo VIPRepPlayer;
|
||||
|
||||
var bool bAllowSeasonalSkins;
|
||||
|
||||
/************************************
|
||||
* Steam heartbeat
|
||||
@ -422,7 +423,7 @@ replication
|
||||
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader, bIsWeeklyMode,
|
||||
CurrentWeeklyIndex, bIsEndlessPaused, bForceSkipTraderUI, VIPRepCurrentHealth, VIPRepMaxHealth, VIPRepPlayer; //@HSL - JRO - 3/21/2016 - PS4 Sessions
|
||||
if ( bNetInitial )
|
||||
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled, bForceShowSkipTrader;
|
||||
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled, bForceShowSkipTrader, bAllowSeasonalSkins;
|
||||
if ( bNetInitial || bNetDirty )
|
||||
PerksAvailableData;
|
||||
if ( bNetInitial && Role == ROLE_Authority )
|
||||
@ -2302,6 +2303,11 @@ simulated function NotifyWeeklyEventIndex(int EventIndex)
|
||||
bNetDirty = true;
|
||||
}
|
||||
|
||||
simulated function NotifyAllowSeasonalSkins(int AllowSeasonalSkinsIndex)
|
||||
{
|
||||
bAllowSeasonalSkins = (AllowSeasonalSkinsIndex == 0);
|
||||
bNetDirty = true;
|
||||
}
|
||||
|
||||
/** VIP weekly */
|
||||
simulated function UpdateVIPMaxHealth(int NewMaxHealth)
|
||||
@ -2392,6 +2398,11 @@ simulated function bool IsVIPMode()
|
||||
return bIsWeeklyMode && CurrentWeeklyIndex == 17;
|
||||
}
|
||||
|
||||
simulated function bool IsRandomPerkMode()
|
||||
{
|
||||
return bIsWeeklyMode && CurrentWeeklyIndex == 18;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems"
|
||||
@ -2413,6 +2424,7 @@ defaultproperties
|
||||
bIsBrokenTrader=false
|
||||
bIsWeeklyMode=false
|
||||
bForceShowSkipTrader=false
|
||||
bAllowSeasonalSkins=true
|
||||
bForceSkipTraderUI=false
|
||||
GunGameWavesCurrent=1
|
||||
bWaveGunGameIsFinal=false
|
||||
|
@ -32,6 +32,7 @@ var transient int CurrentSearchIndex;
|
||||
|
||||
var const string ModeKey, DifficultyKey, MapKey, WhitelistedKey, InProgressKey, PermissionsKey, ServerTypeKey;
|
||||
var const string GameLengthKey;
|
||||
var const string AllowSeasonalSkinsKey;
|
||||
|
||||
var KFGFxStartGameContainer_FindGame FindGameContainer;
|
||||
var KFGFxStartGameContainer_Options OptionsComponent;
|
||||
@ -66,6 +67,7 @@ var localized string LengthTitle;
|
||||
var localized string MapTitle;
|
||||
var localized string MutatorTitle;
|
||||
var localized string PermissionsTitle;
|
||||
var localized string AllowSeasonalSkinsTitle;
|
||||
var localized string ServerTypeString;
|
||||
var localized string WhiteListedTitle;
|
||||
var localized string InfoTitle;
|
||||
@ -208,7 +210,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
|
||||
case SEI_Fall:
|
||||
return class'KFGFxSpecialEventObjectivesContainer_Fall2022';
|
||||
case SEI_Winter:
|
||||
return class'KFGFXSpecialEventObjectivesContainer_Xmas2021';
|
||||
return class'KFGFXSpecialEventObjectivesContainer_Xmas2022';
|
||||
}
|
||||
|
||||
return class'KFGFxSpecialEventObjectivesContainer';
|
||||
@ -605,6 +607,7 @@ function SendLeaderOptions()
|
||||
SetLobbyData(MapKey, OptionsComponent.GetMapName());
|
||||
SetLobbyData(ModeKey, String(Manager.GetModeIndex()));
|
||||
SetLobbyData(PermissionsKey, String(OptionsComponent.GetPrivacyIndex()));
|
||||
SetLobbyData(AllowSeasonalSkinsKey, String(OptionsComponent.GetAllowSeasonalSkinsIndex()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,6 +637,9 @@ function ReceiveLeaderOptions()
|
||||
|
||||
OptionIndex = Int(OnlineLobby.GetLobbyData(0, PermissionsKey));
|
||||
OverviewContainer.UpdatePrivacy(class'KFCommon_LocalizedStrings'.static.GetPermissionString(OptionIndex));
|
||||
|
||||
OptionIndex = Int(OnlineLobby.GetLobbyData(0, AllowSeasonalSkinsKey));
|
||||
OverviewContainer.UpdateAllowSeasonalSkins(class'KFCommon_LocalizedStrings'.static.GetAllowSeasonalSkinsString(OptionIndex));
|
||||
}
|
||||
|
||||
function ApproveMatchMakingLeave()
|
||||
@ -1081,6 +1087,11 @@ function Callback_Region(int RegionIndex)
|
||||
OptionsComponent.SetRegionIndex(RegionIndex);
|
||||
}
|
||||
|
||||
function Callback_AllowSeasonalSkins(int Index)
|
||||
{
|
||||
OptionsComponent.AllowSeasonalSkinsChanged(Index);
|
||||
}
|
||||
|
||||
function SetLobbyData( string KeyName, string ValueData )
|
||||
{
|
||||
OnlineLobby.SetLobbyData( KeyName, ValueData );
|
||||
@ -1089,7 +1100,7 @@ function SetLobbyData( string KeyName, string ValueData )
|
||||
function string MakeMapURL(KFGFxStartGameContainer_Options InOptionsComponent)
|
||||
{
|
||||
local string MapName;
|
||||
local int LengthIndex, ModeIndex;
|
||||
local int LengthIndex, ModeIndex, AllowSeasonalSkinsIndex;
|
||||
|
||||
// this is ugly, but effectively makes sure that the player isn't solo with versus selected
|
||||
// or other error cases such as when the game isn't fully installed
|
||||
@ -1130,9 +1141,17 @@ function string MakeMapURL(KFGFxStartGameContainer_Options InOptionsComponent)
|
||||
}
|
||||
}
|
||||
|
||||
AllowSeasonalSkinsIndex = InOptionsComponent.GetAllowSeasonalSkinsIndex();
|
||||
|
||||
if (GetStartMenuState() == EMatchmaking || class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None)
|
||||
{
|
||||
AllowSeasonalSkinsIndex = 0; // Default if we don't have a season or it's find a match menu
|
||||
}
|
||||
|
||||
return MapName$"?Game="$class'KFGameInfo'.static.GetGameModeClassFromNum( ModeIndex )
|
||||
$"?Difficulty="$class'KFGameDifficultyInfo'.static.GetDifficultyValue( InOptionsComponent.GetDifficultyIndex() )
|
||||
$"?GameLength="$LengthIndex;
|
||||
$"?GameLength="$LengthIndex
|
||||
$"?AllowSeasonalSkins="$AllowSeasonalSkinsIndex;
|
||||
}
|
||||
|
||||
native function bool GetSearchComplete(KFOnlineGameSearch GameSearch);
|
||||
@ -1481,6 +1500,7 @@ function BuildServerFilters(OnlineGameInterface GameInterfaceSteam, KFGFxStartGa
|
||||
local int GameLength;
|
||||
local string GameTagFilters;
|
||||
local ActiveLobbyInfo LobbyInfo;
|
||||
//local bool bAllowSeasonal;
|
||||
|
||||
Search.ClearServerFilters();
|
||||
|
||||
@ -1497,6 +1517,18 @@ function BuildServerFilters(OnlineGameInterface GameInterfaceSteam, KFGFxStartGa
|
||||
//TestAddBoolGametagFilter Explanation: if set to true the second param, it will add the property to the search filters. But this property may interest us to search it as "false" or "true" so that is the purpose of the fourth param.
|
||||
}
|
||||
|
||||
// We don't want to force a search with the Seasonal Skins filter, we find any available server
|
||||
// then we do a takeover, that's when we change the server settings
|
||||
|
||||
//bAllowSeasonal = OptionsComponent.GetAllowSeasonalSkinsIndex() == 0;
|
||||
|
||||
//if (GetStartMenuState() == EMatchmaking || class'KFGameEngine'.static.GetSeasonalEventID() == SEI_None)
|
||||
//{
|
||||
// bAllowSeasonal = true; // Default if we don't have a season or it's find a match menu
|
||||
//}
|
||||
|
||||
//Search.TestAddBoolGametagFilter(GameTagFilters, bAllowSeasonal == false, 'bNoSeasonalSkins', 1);
|
||||
|
||||
if (OptionsComponent.GetMakeNewServer() || bAttemptingServerCreate )
|
||||
{
|
||||
Search.AddGametagFilter( GameTagFilters, 'bAvailableForTakeover', "1");
|
||||
@ -1915,6 +1947,8 @@ defaultproperties
|
||||
ServerTypeKey="ServerTypeKey"
|
||||
InProgressKey="InProgress"
|
||||
PermissionsKey="PermissionsKey"
|
||||
AllowSeasonalSkinsKey="AllowSeasonalSkinsKey"
|
||||
|
||||
SearchDSName=KFGameSearch
|
||||
|
||||
CurrentSearchIndex=0
|
||||
|
@ -56,6 +56,8 @@ var float LastCreatedWeaponTime;
|
||||
/** This stores any GFxMoviePlayers that are inventory may be using */
|
||||
var array<GFxMoviePlayer> OpticsUIMovies;
|
||||
|
||||
var array<GFxMoviePlayer> RadarUIMovies;
|
||||
|
||||
var bool bAutoswitchWeapon;
|
||||
|
||||
var const float StartedWithWeaponPriceModifier; // The selling price reduction for a weapon that we were given at the start of the game
|
||||
@ -191,6 +193,29 @@ simulated function GFxMoviePlayer GetOpticsUIMovie(class<GFxMoviePlayer> OpticsC
|
||||
return OpticsUIMovies[OpticsIndex];
|
||||
}
|
||||
|
||||
simulated function GFxMoviePlayer GetRadarUIMovie(class<GFxMoviePlayer> RadarClass)
|
||||
{
|
||||
local byte RadarIndex;
|
||||
|
||||
for (RadarIndex = 0; RadarIndex < RadarUIMovies.Length; RadarIndex++)
|
||||
{
|
||||
if (RadarUIMovies[RadarIndex].class == RadarClass)
|
||||
{
|
||||
return RadarUIMovies[RadarIndex];
|
||||
}
|
||||
}
|
||||
|
||||
// Create the screen's UI piece
|
||||
RadarUIMovies.AddItem(new( self ) RadarClass);
|
||||
|
||||
// Initialize the new movie
|
||||
RadarIndex = RadarUIMovies.length - 1;
|
||||
RadarUIMovies[RadarIndex].Init();
|
||||
RadarUIMovies[RadarIndex].Start();
|
||||
|
||||
return RadarUIMovies[RadarIndex];
|
||||
}
|
||||
|
||||
/** Create a GFxMoviePlayer for weapon optics if it doesn't exist, otherwise grab the existing GFxMoviePlayer */
|
||||
simulated function RemoveOpticsUIMovie(class<KFGFxWorld_MedicOptics> OpticsClass)
|
||||
{
|
||||
@ -206,6 +231,21 @@ simulated function RemoveOpticsUIMovie(class<KFGFxWorld_MedicOptics> OpticsClass
|
||||
}
|
||||
}
|
||||
|
||||
/** Create a GFxMoviePlayer for weapon optics if it doesn't exist, otherwise grab the existing GFxMoviePlayer */
|
||||
simulated function RemoveRadarUIMovie(class<KFGFxWorld_WeaponRadar> RadarClass)
|
||||
{
|
||||
local byte RadarIndex;
|
||||
|
||||
for (RadarIndex = 0; RadarIndex < RadarUIMovies.Length; RadarIndex++)
|
||||
{
|
||||
if (RadarUIMovies[RadarIndex].class == RadarClass)
|
||||
{
|
||||
RadarUIMovies[RadarIndex].Close();
|
||||
RadarUIMovies.Remove(RadarIndex, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InitFOV. Handle setting FOV values for inventory when the resolution changes
|
||||
*
|
||||
@ -2782,5 +2822,5 @@ defaultproperties
|
||||
SwitchFireModeEvent=AkEvent'WW_UI_PlayerCharacter.Play_WEP_ModeSwitch'
|
||||
|
||||
bLogInventory=false
|
||||
DoshinegunSellModifier=0.167f
|
||||
DoshinegunSellModifier=0.25f
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ var localized string NextRoundBeginString;
|
||||
var localized string PlayerCanChangePerksString;
|
||||
var localized string ZedWaitingForNextRoundString;
|
||||
var localized string LastPlayerStandingString;
|
||||
var localized string NewPerkAssignedMessage;
|
||||
|
||||
struct SDelayedPriorityMessage
|
||||
{
|
||||
@ -75,14 +76,19 @@ static function ClientReceive(
|
||||
optional Object OptionalObject
|
||||
)
|
||||
{
|
||||
local string MessageString,SecondaryMessageString;
|
||||
local string MessageString,SecondaryMessageString, SpecialIconPath;
|
||||
local KFGFxMoviePlayer_HUD myGfxHUD;
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
local TeamInfo TeamInfo;
|
||||
local byte TeamIndex;
|
||||
local KFPlayerController KFPC;
|
||||
local class<KFPerk> ReceivedPerkClass;
|
||||
local bool bIsRandomPerkMode;
|
||||
|
||||
KFPC = KFPlayerController(class'WorldInfo'.static.GetWorldInfo().GetALocalPlayerController());
|
||||
|
||||
bIsRandomPerkMode = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI).IsRandomPerkMode();
|
||||
|
||||
TeamIndex = P.PlayerReplicationInfo.GetTeamNum();
|
||||
if( OptionalObject != none )
|
||||
{
|
||||
@ -94,12 +100,23 @@ static function ClientReceive(
|
||||
}
|
||||
|
||||
MessageString = static.GetMessageString( Switch, SecondaryMessageString, TeamIndex );
|
||||
|
||||
if (bIsRandomPerkMode)
|
||||
{
|
||||
ReceivedPerkClass = class<KFPerk>(OptionalObject);
|
||||
if (ReceivedPerkClass != none)
|
||||
{
|
||||
MessageString = ReceivedPerkClass.default.PerkName;
|
||||
SpecialIconPath = ReceivedPerkClass.static.GetPerkIconPath();
|
||||
}
|
||||
}
|
||||
|
||||
if ( MessageString != "" && KFGFxHudWrapper(p.myHUD) != none && ShouldShowPriortyMessage(P, Switch))
|
||||
{
|
||||
myGfxHUD = KFGFxHudWrapper(p.myHUD).HudMovie;
|
||||
if ( myGfxHUD != None )
|
||||
{
|
||||
myGfxHUD.DisplayPriorityMessage(MessageString,SecondaryMessageString,static.GetMessageLifeTime(Switch), EGameMessageType(Switch));
|
||||
myGfxHUD.DisplayPriorityMessage(MessageString,SecondaryMessageString,static.GetMessageLifeTime(Switch), EGameMessageType(Switch), SpecialIconPath);
|
||||
}
|
||||
else if(KFPC.MyGFxManager != none) //store it off so we can queue it
|
||||
{
|
||||
@ -271,7 +288,15 @@ static function string GetMessageString(int Switch, optional out String Secondar
|
||||
}
|
||||
else
|
||||
{
|
||||
SecondaryString = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI).bTradersEnabled ? default.GetToTraderMessage : default.ScavengeMessage;
|
||||
if ( KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI).IsRandomPerkMode() )
|
||||
{
|
||||
SecondaryString = default.NewPerkAssignedMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
SecondaryString = KFGameReplicationInfo(class'WorldInfo'.static.GetWorldInfo().GRI).bTradersEnabled ? default.GetToTraderMessage : default.ScavengeMessage;
|
||||
}
|
||||
|
||||
return default.WaveEndMessage;
|
||||
}
|
||||
case GMT_MatchWon:
|
||||
|
@ -72,6 +72,7 @@ defaultproperties
|
||||
ColumnIds.Add(STATID_ACHIEVE_CarillonHamletCollectibles)
|
||||
ColumnIds.Add(STATID_ACHIEVE_RigCollectibles)
|
||||
ColumnIds.Add(STATID_ACHIEVE_BarmwichCollectibles)
|
||||
ColumnIds.Add(STATID_ACHIEVE_CrashCollectibles);
|
||||
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
|
||||
@ -132,4 +133,6 @@ defaultproperties
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_CarillonHamletCollectibles,Name="AchievementCollectCarillonHamlet"))
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_RigCollectibles,Name="AchievementCollectRig"))
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_BarmwichCollectibles,Name="AchievementCollectBarmwichTown"))
|
||||
ColumnMappings.Add((Id=STATID_ACHIEVE_CrashCollectibles,Name="AchievementCollectCrash"))
|
||||
|
||||
}
|
||||
|
@ -449,6 +449,10 @@ const KFACHID_BarmwichHard = 295;
|
||||
const KFACHID_BarmwichHellOnEarth = 296;
|
||||
const KFACHID_BarmwichCollectibles = 297;
|
||||
|
||||
const KFACHID_CrashHard = 298;
|
||||
const KFACHID_CrashHellOnEarth = 299;
|
||||
const KFACHID_CrashCollectibles = 300;
|
||||
|
||||
/* __TW_ANALYTICS_ */
|
||||
var int PerRoundWeldXP;
|
||||
var int PerRoundHealXP;
|
||||
@ -1182,6 +1186,11 @@ private event AddToWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Pri
|
||||
SeasonalEventStats_OnWeaponPurchased(WeaponDef, Price);
|
||||
}
|
||||
|
||||
private event AddAfflictionCaused(EAfflictionType Type)
|
||||
{
|
||||
SeasonalEventStats_OnAfflictionCaused(Type);
|
||||
}
|
||||
|
||||
private native function AddToKillObjectives(class<KFPawn_Monster> ZedClass);
|
||||
private native function AddToVersusKillObjectives(class<Pawn> KillerClass);
|
||||
|
||||
@ -1810,6 +1819,14 @@ native final function MapObjectiveCompleted();
|
||||
* @name Seasonal Events
|
||||
********************************************************************************************* */
|
||||
|
||||
final simulated function SeasonalEventStats_OnStatsInitialized()
|
||||
{
|
||||
if (SeasonalEventIsValid())
|
||||
{
|
||||
SeasonalEvent.OnStatsInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
final native simulated function bool SeasonalEventIsValid();
|
||||
|
||||
final simulated function SeasonalEventStats_OnMapObjectiveDeactivated(Actor ObjectiveInterfaceActor)
|
||||
@ -1896,6 +1913,14 @@ final simulated function SeasonalEventStats_OnWeaponPurchased(class<KFWeaponDefi
|
||||
}
|
||||
}
|
||||
|
||||
final simulated function SeasonalEventStats_OnAfflictionCaused(EAfflictionType Type)
|
||||
{
|
||||
if (SeasonalEventIsValid())
|
||||
{
|
||||
SeasonalEvent.OnAfflictionCaused(Type);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Dailies and daily-specific tracking
|
||||
********************************************************************************************* */
|
||||
@ -2069,6 +2094,7 @@ defaultproperties
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_AA12, KFDT_Ballistic_AA12Shotgun,KFDT_Bludgeon_AA12Shotgun),CompletionAmount=10000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_ElephantGun, KFDT_Ballistic_ElephantGun,KFDT_Bludgeon_ElephantGun),CompletionAmount=10000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BlastBrawlers, KFDT_Ballistic_BlastBrawlersShotgun,KFDT_Bludgeon_BlastBrawlers,KFDT_Bludgeon_BlastBrawlersHeavy,KFDT_Bludgeon_BlastBrawlersBash),CompletionAmount=10000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_BallisticBouncer, KFDT_Bludgeon_HRG_BallisticBouncer_Shot,KFDT_Bludgeon_HRG_BallisticBouncer),CompletionAmount=10000))
|
||||
|
||||
//Medic Weapons
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Medic, KFDT_Ballistic_Pistol_Medic,KFDT_Bludgeon_Pistol_Medic),CompletionAmount=5000)) //3000
|
||||
@ -2080,6 +2106,7 @@ defaultproperties
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_HRGIncision, KFDT_Ballistic_HRGIncisionHurt, KFDT_Ballistic_HRGIncisionHeal,KFDT_Bludgeon_HRGIncision),CompletionAmount=5000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Vampire, KFDT_Bleeding_HRG_Vampire_BloodSuck, KFDT_Ballistic_HRG_Vampire_BloodBallImpact, KFDT_Ballistic_HRG_Vampire_BloodBallHeavyImpact, KFDT_Toxic_HRG_Vampire_BloodBall, KFDT_Piercing_HRG_Vampire_CrystalSpike, KFDT_Bludgeon_HRG_Vampire),CompletionAmount=9000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_MedicRifleGrenadeLauncher, KFDT_Ballistic_MedicRifleGrenadeLauncher, KFDT_Bludgeon_MedicRifleGrenadeLauncher, KFDT_Toxic_MedicGrenadeLauncher, KFDT_Ballistic_MedicRifleGrenadeLauncherImpact),CompletionAmount=10000))
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_MedicMissile, KFDT_Explosive_HRG_MedicMissile, KFDT_Bludgeon_HRG_MedicMissile, KFDT_Toxic_HRG_MedicMissile, KFDT_Ballistic_HRG_MedicMissile),CompletionAmount=9000))
|
||||
|
||||
//Demo Weapons
|
||||
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_HX25, KFDT_ExplosiveSubmunition_HX25,KFDT_Ballistic_HX25Impact,KFDT_Ballistic_HX25SubmunitionImpact,KFDT_Bludgeon_HX25),CompletionAmount=5000)) //3000
|
||||
@ -2295,6 +2322,9 @@ defaultproperties
|
||||
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=1))
|
||||
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=2))
|
||||
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-BARMWICHTOWN),CompletionAmount=3))
|
||||
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))
|
||||
|
||||
//Versus Damage
|
||||
// Per design doc that I have right now, these are x class damage y players, not damage y amount
|
||||
|
@ -74,5 +74,5 @@ defaultproperties
|
||||
Properties.Add((PropertyId = STATID_ACHIEVE_CarillonHamletCollectibles, Data = (Type = SDT_Int32, Value1 = 0)))
|
||||
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)))
|
||||
}
|
||||
|
@ -2248,18 +2248,25 @@ function UpdateActiveSkillsPath(string IconPath, int Multiplier, bool Active, fl
|
||||
|
||||
event Landed(vector HitNormal, actor FloorActor)
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC;
|
||||
local KFPlayerController KFPC;
|
||||
local KFPlayerController_WeeklySurvival KFPC_WS;
|
||||
|
||||
super.Landed(HitNormal, FloorActor);
|
||||
|
||||
if (KFPawn_Monster(FloorActor) == none)
|
||||
{
|
||||
KFPC = KFPlayerController_WeeklySurvival(Controller);
|
||||
if (KFPC != none)
|
||||
KFPC_WS = KFPlayerController_WeeklySurvival(Controller);
|
||||
if (KFPC_WS != none)
|
||||
{
|
||||
KFPC.ResetGoompaStreak();
|
||||
KFPC_WS.ResetGoompaStreak();
|
||||
}
|
||||
}
|
||||
|
||||
KFPC = KFPlayerController(Controller);
|
||||
if (KFPC != none)
|
||||
{
|
||||
KFPC.ResetShotgunJump();
|
||||
}
|
||||
}
|
||||
|
||||
// Used for override aesthetics
|
||||
|
@ -4859,7 +4859,7 @@ function ZedExplodeArmor(int ArmorZoneIdx, name ArmorZoneName)
|
||||
/*********************************************************************************************
|
||||
* @name Armor
|
||||
********************************************************************************************* */
|
||||
server reliable function AddParasiteSeed(KFProjectile Proj)
|
||||
simulated function AddParasiteSeed(KFProjectile Proj)
|
||||
{
|
||||
local int i;
|
||||
|
||||
|
@ -560,6 +560,16 @@ static function bool IsAutoTurret( KFWeapon KFW )
|
||||
return KFW != none && KFW.Class.Name == 'KFWeap_AutoTurret';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return if a weapon is HRG Ballistic Bouncer
|
||||
*
|
||||
* @param KFW Weapon to check
|
||||
* @return true if backup weapon
|
||||
*/
|
||||
static function bool IsHRGBallisticBouncer( KFWeapon KFW )
|
||||
{
|
||||
return KFW != none && KFW.Class.Name == 'KFWeap_HRG_BallisticBouncer';
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Build / Level Management - Apply and save the updated build and level
|
||||
|
@ -214,7 +214,7 @@ simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacit
|
||||
TempCapacity = MagazineCapacity;
|
||||
|
||||
// Fix this function on the trader because KFW is None and the check cannot look for bNoMagazine = true
|
||||
if(WeaponClassname != 'KFWeap_Rifle_HRGIncision')
|
||||
if(WeaponClassname != 'KFWeap_Rifle_HRGIncision' && WeaponClassName != 'KFWeap_HRG_MedicMissile')
|
||||
{
|
||||
if( IsWeaponOnPerk( KFW, WeaponPerkClass, self.class ) && (KFW == none || !KFW.bNoMagazine) && !bSecondary )
|
||||
{
|
||||
|
@ -562,10 +562,12 @@ simulated function float GetZedTimeModifier( KFWeapon W )
|
||||
|
||||
// Blast Brawlers use a different state for shooting (combining melee + firing). Needs a special case for this
|
||||
// FAMAS uses alt fire as common firing. Another special case added
|
||||
// HRG Ballistic Bouncer uses a special state of charging when shooting
|
||||
if( IsWeaponOnPerk( W,, self.class ) && CouldBarrageActive() &&
|
||||
(ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE ||
|
||||
(StateName == 'MeleeChainAttacking' && IsBlastBrawlers(W)) ||
|
||||
(IsFAMAS(W) && StateName == 'FiringSecondaryState')))
|
||||
(IsFAMAS(W) && StateName == 'FiringSecondaryState')) ||
|
||||
(IsHRGBallisticBouncer(W) && StateName == 'MineReconstructorCharge'))
|
||||
{
|
||||
return BarrageFiringRate;
|
||||
}
|
||||
|
@ -279,8 +279,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
|
||||
if( KFW != none )
|
||||
{
|
||||
// KFDT_Bludgeon_Doshinegun_Shot is a special case of Bludgeon damage that doesn't apply this mod.
|
||||
if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW ) ||
|
||||
((!IsDoshinegun(KFW) && ClassIsChildOf(DamageType, class'KFDT_Bludgeon') ) || (IsDoshinegun(KFW) && DamageType.Name != 'KFDT_Bludgeon_Doshinegun_Shot' ))))
|
||||
if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW ) || ShouldAffectBackupToDamage(KFW, DamageType)))
|
||||
{
|
||||
`QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk );
|
||||
TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] );
|
||||
@ -296,6 +295,29 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
|
||||
InDamage = Round(TempDamage);
|
||||
}
|
||||
|
||||
/**
|
||||
Check whether the damage and weapon are valid for the Backup skill:
|
||||
Doshinegun and HRGBallisticBouncer have bludgeon projectiles that shouldn't get their damage modified
|
||||
*/
|
||||
simulated function bool ShouldAffectBackupToDamage(KFWeapon KFW, class<KFDamageType> DamageType)
|
||||
{
|
||||
if (!ClassIsChildOf(DamageType, class'KFDT_Bludgeon'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IsDoshinegun(KFW))
|
||||
{
|
||||
return DamageType.Name != 'KFDT_Bludgeon_Doshinegun_Shot';
|
||||
}
|
||||
else if (IsHRGBallisticBouncer(KFW))
|
||||
{
|
||||
return DamageType.Name != 'KFDT_Bludgeon_HRG_BallisticBouncer_Shot';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Modifies the max spare ammo
|
||||
*
|
||||
|
@ -728,6 +728,33 @@ var transient byte StoredLocalUserNum;
|
||||
**********************************************************************************************/
|
||||
var transient array<Actor> DeployedTurrets;
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name HV Storm Cannon
|
||||
|
||||
Keep track of the electricity VFX Chain (Client Only)
|
||||
********************************************************************************************* */
|
||||
struct native KFStormCannonBeamData
|
||||
{
|
||||
var KFPawn_Monster SourcePawn;
|
||||
var ParticleSystemComponent ParticleSystemPawn;
|
||||
var ParticleSystemComponent ParticleSystemBeam;
|
||||
var int ID;
|
||||
|
||||
structdefaultproperties
|
||||
{
|
||||
SourcePawn = none
|
||||
ParticleSystemPawn = none
|
||||
ParticleSystemBeam = none
|
||||
ID = 255
|
||||
}
|
||||
};
|
||||
|
||||
var array<KFStormCannonBeamData> StormCannonBeamData;
|
||||
|
||||
var byte StormCannonIDCounter;
|
||||
|
||||
var transient bool bShotgunJumping;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual UBOOL Tick( FLOAT DeltaSeconds, ELevelTick TickType );
|
||||
@ -7045,8 +7072,15 @@ function SetUIScale(float fScale)
|
||||
|
||||
function GetSeasonalEventStatInfo(int StatIdx, out int CurrentValue, out int MaxValue)
|
||||
{
|
||||
CurrentValue = StatsWrite.GetSeasonalEventStatValue(StatIdx);
|
||||
MaxValue = StatsWrite.GetSeasonalEventStatMaxValue(StatIdx);
|
||||
if (StatsWrite != none)
|
||||
{
|
||||
CurrentValue = StatsWrite.GetSeasonalEventStatValue(StatIdx);
|
||||
MaxValue = StatsWrite.GetSeasonalEventStatMaxValue(StatIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
`warn( "GetSeasonalEventStatInfo() No StatsWrite ??");
|
||||
}
|
||||
}
|
||||
|
||||
simulated event CompletedDaily(int Index)
|
||||
@ -7297,6 +7331,8 @@ simulated function OnStatsInitialized( bool bWasSuccessful )
|
||||
{
|
||||
`RecordAARPerkXPGain(self, PerkList[i].PerkClass, 0, 0);
|
||||
}
|
||||
|
||||
StatsWrite.SeasonalEventStats_OnStatsInitialized();
|
||||
}
|
||||
|
||||
|
||||
@ -7556,6 +7592,12 @@ function AddWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Price )
|
||||
}
|
||||
native reliable client private function ClientAddWeaponPurchased( class<KFWeaponDefinition> WeaponDef, int Price );
|
||||
|
||||
function AddAfflictionCaused(EAfflictionType Type)
|
||||
{
|
||||
ClientAddAfflictionCaused(Type);
|
||||
}
|
||||
native reliable client private function ClientAddAfflictionCaused(EAfflictionType Type);
|
||||
|
||||
function AddZedAssist(class<KFPawn_Monster> MonsterClass)
|
||||
{
|
||||
ClientAddZedAssist(MonsterClass);
|
||||
@ -11944,6 +11986,137 @@ simulated function InitPerkLoadout()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* HV Storm Cannon RPCs
|
||||
*/
|
||||
|
||||
client reliable function AddStormCannonVFX(KFPawn_Monster Target, int ID)
|
||||
{
|
||||
local int i, DataIndex;
|
||||
local KFStormCannonBeamData BeamData;
|
||||
local ParticleSystemComponent PawnParticleSystem, BeamParticleSystem;
|
||||
local KFPawn_Monster Origin;
|
||||
|
||||
if (Target == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DataIndex = INDEX_NONE;
|
||||
BeamParticleSystem = none;
|
||||
|
||||
for (i = 0; i < StormCannonBeamData.Length; ++i)
|
||||
{
|
||||
if (StormCannonBeamData[i].ID == ID)
|
||||
{
|
||||
DataIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (DataIndex == INDEX_NONE)
|
||||
{
|
||||
BeamData.SourcePawn = Target;
|
||||
BeamData.ID = ID;
|
||||
|
||||
// Simulated EMP affliction Effects
|
||||
Target.PlaySoundBase(class'KFAffliction_EMP'.default.OnEMPSound, true, true, true);
|
||||
BeamData.ParticleSystemPawn = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'FX_Gameplay_EMIT.FX_Char_Emp_clot'
|
||||
, Target.Mesh
|
||||
, class'KFAffliction_EMP'.default.EffectSocketName
|
||||
, false);
|
||||
|
||||
StormCannonBeamData.AddItem(BeamData);
|
||||
}
|
||||
else if (StormCannonBeamData[DataIndex].SourcePawn != none && StormCannonBeamData[DataIndex].SourcePawn != Target)
|
||||
{
|
||||
Origin = StormCannonBeamData[DataIndex].SourcePawn;
|
||||
StormCannonBeamData[DataIndex].SourcePawn = Target;
|
||||
|
||||
// Deactivate old VFX on SourcePawn
|
||||
if (StormCannonBeamData[DataIndex].ParticleSystemPawn != none)
|
||||
{
|
||||
Origin.PlaySoundBase(class'KFAffliction_EMP'.default.OnEMPEndSound, true, true);
|
||||
|
||||
PawnParticleSystem = StormCannonBeamData[DataIndex].ParticleSystemPawn; // Need to do this as UE doesn't allow passing an index into an array as out parameter
|
||||
Origin.DetachEmitter(PawnParticleSystem);
|
||||
}
|
||||
|
||||
// Activate new VFX on Target Pawn
|
||||
Target.PlaySoundBase(class'KFAffliction_EMP'.default.OnEMPSound, true, true, true);
|
||||
StormCannonBeamData[DataIndex].ParticleSystemPawn = WorldInfo.MyEmitterPool.SpawnEmitterMeshAttachment(ParticleSystem'FX_Gameplay_EMIT.FX_Char_Emp_clot'
|
||||
, Target.Mesh
|
||||
, class'KFAffliction_EMP'.default.EffectSocketName
|
||||
, false);
|
||||
|
||||
if (StormCannonBeamData[DataIndex].ParticleSystemBeam == none)
|
||||
{
|
||||
StormCannonBeamData[DataIndex].ParticleSystemBeam = WorldInfo.MyEmitterPool.SpawnEmitter(ParticleSystem'WEP_HVStormCannon_EMIT.FX_HVStormCannon_Beam'
|
||||
, Origin.Mesh.GetBoneLocation('head'));
|
||||
}
|
||||
|
||||
// Reuse Particle System
|
||||
BeamParticleSystem = StormCannonBeamData[DataIndex].ParticleSystemBeam;
|
||||
}
|
||||
|
||||
if (BeamParticleSystem == none || Origin == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//`Log("SpawnBeamStormCannon with ID: " $ID $" from : " $Origin $" To: " $self);
|
||||
|
||||
BeamParticleSystem.SetBeamSourcePoint(0, Origin.Mesh.GetBoneLocation('head'), 0);
|
||||
BeamParticleSystem.SetBeamTargetPoint(0, Target.Mesh.GetBoneLocation('head'), 0);
|
||||
BeamParticleSystem.SetAbsolute(false, false, false);
|
||||
}
|
||||
|
||||
client reliable function RemoveStormCannonVFX(int ID)
|
||||
{
|
||||
local int i;
|
||||
local ParticleSystemComponent PawnParticleSystem;
|
||||
|
||||
for (i = 0; i < StormCannonBeamData.Length; ++i)
|
||||
{
|
||||
if (StormCannonBeamData[i].ID == ID)
|
||||
{
|
||||
if (StormCannonBeamData[i].ParticleSystemPawn != none)
|
||||
{
|
||||
PawnParticleSystem = StormCannonBeamData[i].ParticleSystemPawn; // Need to do this as UE doesn't allow passing an index into an array as out parameter
|
||||
StormCannonBeamData[i].SourcePawn.DetachEmitter(PawnParticleSystem);
|
||||
|
||||
StormCannonBeamData[i].ParticleSystemPawn.SetActive(false);
|
||||
StormCannonBeamData[i].ParticleSystemPawn = none;
|
||||
}
|
||||
|
||||
if (StormCannonBeamData[i].ParticleSystemBeam != none)
|
||||
{
|
||||
StormCannonBeamData[i].ParticleSystemBeam.DeactivateSystem();
|
||||
StormCannonBeamData[i].ParticleSystemBeam.KillParticlesForced();
|
||||
StormCannonBeamData[i].ParticleSystemBeam = none;
|
||||
}
|
||||
|
||||
StormCannonBeamData.Remove(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function SetShotgunJump(bool bJumping)
|
||||
{
|
||||
bShotgunJumping = bJumping;
|
||||
}
|
||||
|
||||
simulated function ResetShotgunJump()
|
||||
{
|
||||
SetTimer(0.1, false, nameof(ClearShotgunJumpFlag));
|
||||
}
|
||||
|
||||
simulated function ClearShotgunJumpFlag()
|
||||
{
|
||||
bShotgunJumping = false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
EarnedDosh=0
|
||||
@ -12144,8 +12317,11 @@ defaultproperties
|
||||
|
||||
BeginningRoundVaultAmount=INDEX_NONE
|
||||
|
||||
RotationSpeedLimit=-1.f;
|
||||
RotationSpeedLimit=-1.f
|
||||
|
||||
RotationAdjustmentInterval = 0.1f;
|
||||
CurrentRotationAdjustmentTime = 0.0f;
|
||||
RotationAdjustmentInterval = 0.1f
|
||||
CurrentRotationAdjustmentTime = 0.0f
|
||||
|
||||
StormCannonIDCounter = 0
|
||||
bShotgunJumping=false
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ var protected const AKEvent VIPChosenSoundEvent;
|
||||
var protected const AKEvent VIPLowHealthSoundEvent;
|
||||
var protected float VIPLowHealthLastTimePlayed;
|
||||
|
||||
var protected const AKEvent RandomPerkChosenSoundEvent;
|
||||
|
||||
struct native GunGameInfo
|
||||
{
|
||||
var transient byte Level;
|
||||
@ -106,6 +108,9 @@ struct native VIPGameInfo
|
||||
};
|
||||
var transient VIPGameInfo VIPGameData;
|
||||
|
||||
// RandomPerk weekly
|
||||
var array<class<KFPerk> > LockedPerks;
|
||||
|
||||
cpptext
|
||||
{
|
||||
virtual UBOOL TestZedTimeVisibility(APawn* P, UNetConnection* Connection, UBOOL bLocalPlayerTest) override;
|
||||
@ -601,6 +606,64 @@ function UpdateVIPDamage()
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ForceNewPerk(class<KFPerk> NewPerk)
|
||||
{
|
||||
local int NewPerkIndex;
|
||||
NewPerkIndex = Perklist.Find('PerkClass', NewPerk);
|
||||
ServerSelectPerk(NewPerkIndex, Perklist[NewPerkIndex].PerkLevel, Perklist[NewPerkIndex].PrestigeLevel, true);
|
||||
SavedPerkIndex = NewPerkIndex;
|
||||
ForceNewSavedPerkIndex(NewPerkIndex);
|
||||
}
|
||||
|
||||
unreliable client function PlayRandomPerkChosenSound(optional float delay = 0.0f)
|
||||
{
|
||||
if (delay > 0.0f)
|
||||
{
|
||||
SetTimer(delay, false, nameof(PlayRandomPerkChosenSound_Internal));
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayRandomPerkChosenSound_Internal();
|
||||
}
|
||||
}
|
||||
|
||||
simulated function PlayRandomPerkChosenSound_Internal()
|
||||
{
|
||||
if (RandomPerkChosenSoundEvent != none)
|
||||
{
|
||||
PlaySoundBase(RandomPerkChosenSoundEvent);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnStatsInitialized( bool bWasSuccessful )
|
||||
{
|
||||
local KFGameReplicationInfo KFGRI;
|
||||
|
||||
Super.OnStatsInitialized(bWasSuccessful);
|
||||
|
||||
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
|
||||
if (KFGRI != none && KFGRI.IsRandomPerkMode())
|
||||
{
|
||||
ServerOnStatsInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
reliable server function ServerOnStatsInitialized()
|
||||
{
|
||||
local KFGameInfo KFGI;
|
||||
|
||||
KFGI = KFGameInfo(WorldInfo.Game);
|
||||
if (KFGI != none)
|
||||
{
|
||||
KFGI.NotifyPlayerStatsInitialized(self);
|
||||
}
|
||||
}
|
||||
|
||||
reliable client function ForceNewSavedPerkIndex(byte NewPerkIndex)
|
||||
{
|
||||
SavedPerkIndex = NewPerkIndex;
|
||||
}
|
||||
|
||||
//
|
||||
defaultProperties
|
||||
{
|
||||
@ -615,6 +678,7 @@ defaultProperties
|
||||
GunGameLevelUpSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyAALevelUp'
|
||||
GunGameLevelUpFinalWeaponSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyAALevelFinal'
|
||||
VIPChosenSoundEvent=AkEvent'WW_UI_Menu.Play_AAR_TOPWEAPON_SLIDEIN_B'
|
||||
RandomPerkChosenSoundEvent=AkEvent'WW_UI_Menu.Play_AAR_TOPWEAPON_SLIDEIN_B'
|
||||
VIPLowHealthSoundEvent=AkEvent'WW_GLO_Runtime.WeeklyVIPAlarm'
|
||||
VIPLowHealthLastTimePlayed = 0.f
|
||||
}
|
||||
|
@ -247,6 +247,7 @@ defaultproperties
|
||||
ProfileMappings.Add((Id=KFID_SavedDifficultyIndex, Name="SavedDifficultyIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_SavedLengthIndex, Name="SavedLengthIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_SavedPrivacyIndex, Name="SavedPrivacyIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_SavedAllowSeasonalSkinsIndex, Name="SavedAllowSeasonalSkinsIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_SavedServerTypeIndex, Name="SavedServerTypeIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_SavedInProgressIndex, Name="SavedInProgressIndex", MappingType=PVMT_RawValue))
|
||||
ProfileMappings.Add((Id=KFID_ControllerSoundEnabled, Name="Controller Sound Enabled", MappingType=PVMT_RawValue))
|
||||
@ -332,6 +333,7 @@ defaultproperties
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedDifficultyIndex,Data=(Type=SDT_Int32,Value1=0))))
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedLengthIndex,Data=(Type=SDT_Int32,Value1=0)))) //default to any
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedPrivacyIndex,Data=(Type=SDT_Int32,Value1=0))))
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedAllowSeasonalSkinsIndex,Data=(Type=SDT_Int32,Value1=0))))
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedServerTypeIndex,Data=(Type=SDT_Int32,Value1=0))))
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_SavedInProgressIndex,Data=(Type=SDT_Int32,Value1=0))))
|
||||
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_ControllerSoundEnabled,Data=(Type=SDT_Int32,Value1=0))))
|
||||
|
@ -56,6 +56,8 @@ var() vector LandedTranslationOffset;
|
||||
//to keep track if we are hitting an actor multiple times.
|
||||
var array<Actor> ImpactList;
|
||||
|
||||
var() bool bCanApplyDemolitionistPerks;
|
||||
|
||||
replication
|
||||
{
|
||||
if ( Role == ROLE_Authority && !bNetOwner )
|
||||
@ -388,7 +390,10 @@ simulated function bool TraceProjHitZones(Pawn P, vector EndTrace, vector StartT
|
||||
// for nukes && concussive force
|
||||
simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
class'KFPerk_Demolitionist'.static.PrepareExplosive( Instigator, self );
|
||||
if (bCanApplyDemolitionistPerks)
|
||||
{
|
||||
class'KFPerk_Demolitionist'.static.PrepareExplosive( Instigator, self );
|
||||
}
|
||||
|
||||
super.PrepareExplosionTemplate();
|
||||
}
|
||||
@ -474,5 +479,7 @@ defaultproperties
|
||||
bCollideWithTeammates=false
|
||||
|
||||
bDamageDestructiblesOnTouch=true
|
||||
|
||||
bCanApplyDemolitionistPerks=true
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ var protected int bObjectiveIsValidForMap[5];
|
||||
// whether this seasonal stats object is the stats object that is being tracked right now
|
||||
final native function bool IsValid();
|
||||
final protected native function IncrementSeasonalEventStat(int StatIdx, int Inc);
|
||||
final protected native function ResetSeasonalEventStat(int StatIdx);
|
||||
final protected native function SetSeasonalEventStatsMax(int StatMax1, int StatMax2, int StatMax3, int StatMax4, int StatMax5);
|
||||
final protected native function GrantEventItem(int ItemId);
|
||||
|
||||
@ -31,6 +32,10 @@ private event Initialize(string MapName);
|
||||
static private event bool AllowEventBossOverrideForMap(string MapName);
|
||||
private event GrantEventItems();
|
||||
|
||||
simulated event OnStatsInitialized()
|
||||
{
|
||||
}
|
||||
|
||||
final protected simulated function FinishedObjective(int EventIndex, int ObjectiveIndex)
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
@ -75,3 +80,4 @@ simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex);
|
||||
simulated function OnHitTaken();
|
||||
simulated function OnHitGiven(class<DamageType> DT);
|
||||
simulated function OnWeaponPurchased(class<KFWeaponDefinition> WeaponDef, int Price);
|
||||
simulated function OnAfflictionCaused(EAfflictionType Type);
|
@ -36,7 +36,9 @@ enum ESharedContentUnlock
|
||||
SCU_AutoTurret,
|
||||
SCU_ShrinkRayGun,
|
||||
SCU_Scythe,
|
||||
SCU_G36C
|
||||
SCU_G36C,
|
||||
SCU_HVStormCannon,
|
||||
SCU_ZedMKIII
|
||||
};
|
||||
|
||||
|
||||
@ -383,4 +385,12 @@ defaultproperties
|
||||
Name=KFWeap_AssaultRifle_G36C,
|
||||
IconPath="WEP_UI_G36C_TEX.UI_WeaponSelect_G36C",
|
||||
ID=9484)}
|
||||
SharedContentList(SCU_HVStormCannon)={(
|
||||
Name=KFWeap_HVStormCannon,
|
||||
IconPath="wep_ui_hvstormcannon_tex.UI_WeaponSelect_HVStormCannon",
|
||||
ID=9569)}
|
||||
SharedContentList(SCU_ZedMKIII)={(
|
||||
Name=KFWeap_ZedMKIII,
|
||||
IconPath="wep_ui_zedmkiii_tex.UI_WeaponSelect_ZEDMKIII",
|
||||
ID=9575)}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_Doshinegun"
|
||||
|
||||
BuyPrice=600 //750
|
||||
BuyPrice=400 //600 //750
|
||||
ImagePath="WEP_UI_Doshinegun_TEX.UI_Weapon_Select_Doshinegun"
|
||||
|
||||
EffectiveRange=68
|
||||
|
26
KFGame/Classes/KFWeapDef_HRG_BallisticBouncer.uc
Normal file
26
KFGame/Classes/KFWeapDef_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_BallisticBouncer extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_BallisticBouncer"
|
||||
|
||||
BuyPrice=900
|
||||
AmmoPricePerMag=40
|
||||
ImagePath="WEP_UI_HRG_BallisticBouncer_TEX.UI_WeaponSelect_HRG_BallisticBouncer"
|
||||
|
||||
EffectiveRange=70
|
||||
|
||||
UpgradePrice[0]=700
|
||||
UpgradePrice[1]=1500
|
||||
|
||||
UpgradeSellPrice[0]=525
|
||||
UpgradeSellPrice[1]=1650
|
||||
}
|
24
KFGame/Classes/KFWeapDef_HRG_MedicMissile.uc
Normal file
24
KFGame/Classes/KFWeapDef_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,24 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HRG_MedicMissile extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HRG_MedicMissile"
|
||||
|
||||
BuyPrice=1600
|
||||
AmmoPricePerMag=25
|
||||
ImagePath="WEP_UI_HRG_MedicMissile_TEX.UI_WeaponSelect_HRG_MedicMissile"
|
||||
|
||||
EffectiveRange=100
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
}
|
25
KFGame/Classes/KFWeapDef_HVStormCannon.uc
Normal file
25
KFGame/Classes/KFWeapDef_HVStormCannon.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_HVStormCannon
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_HVStormCannon extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_HVStormCannon"
|
||||
|
||||
BuyPrice=1400
|
||||
AmmoPricePerMag=40
|
||||
ImagePath="wep_ui_hvstormcannon_tex.UI_WeaponSelect_HVStormCannon"
|
||||
EffectiveRange=100
|
||||
|
||||
UpgradePrice[0]=1500
|
||||
|
||||
UpgradeSellPrice[0]=1125
|
||||
|
||||
SharedUnlockId=SCU_HVStormCannon
|
||||
}
|
22
KFGame/Classes/KFWeapDef_ZedMKIII.uc
Normal file
22
KFGame/Classes/KFWeapDef_ZedMKIII.uc
Normal file
@ -0,0 +1,22 @@
|
||||
//=============================================================================
|
||||
// KFWeapDef_ZedMKIII
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeapDef_ZedMKIII extends KFWeaponDefinition
|
||||
abstract;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
WeaponClassPath="KFGameContent.KFWeap_ZedMKIII"
|
||||
|
||||
BuyPrice=2000
|
||||
AmmoPricePerMag=60
|
||||
ImagePath="wep_ui_zedmkiii_tex.UI_WeaponSelect_ZEDMKIII"
|
||||
|
||||
EffectiveRange=100
|
||||
|
||||
SharedUnlockId=SCU_ZedMKIII
|
||||
}
|
@ -28,6 +28,42 @@ simulated function KFProjectile SpawnAllProjectiles(class<KFProjectile> KFProjCl
|
||||
return super.SpawnAllProjectiles(KFProjClass, RealStartLoc, AimDir);
|
||||
}
|
||||
|
||||
simulated function ApplyKickMomentum(float Momentum, float FallingMomentumReduction)
|
||||
{
|
||||
local vector UsedKickMomentum;
|
||||
|
||||
if (Instigator != none )
|
||||
{
|
||||
UsedKickMomentum.X = -Momentum;
|
||||
|
||||
if( Instigator.Physics == PHYS_Falling )
|
||||
{
|
||||
UsedKickMomentum = UsedKickMomentum >> Instigator.GetViewRotation();
|
||||
UsedKickMomentum *= FallingMomentumReduction;
|
||||
|
||||
NotifyShotgunJump();
|
||||
}
|
||||
else
|
||||
{
|
||||
UsedKickMomentum = UsedKickMomentum >> Instigator.Rotation;
|
||||
UsedKickMomentum.Z = 0;
|
||||
}
|
||||
|
||||
Instigator.AddVelocity(UsedKickMomentum,Instigator.Location,none);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function NotifyShotgunJump()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
KFPC = KFPlayerController(Instigator.Controller);
|
||||
if (KFPC != none)
|
||||
{
|
||||
KFPC.SetShotgunJump(true);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************
|
||||
* @name Trader
|
||||
*********************************************************************************************/
|
||||
|
@ -4387,7 +4387,10 @@ event RecieveClientImpact(byte FiringMode, const out ImpactInfo Impact, optional
|
||||
event RecieveClientProjectileExplosion(vector ExplosionLocation, KFProjectile ExplodingProjectile)
|
||||
{
|
||||
// TODO: maybe validate the explosion normal on the client?
|
||||
ExplodingProjectile.CallExplode( ExplosionLocation, vect(0,0,1) );
|
||||
if (ExplodingProjectile != none)
|
||||
{
|
||||
ExplodingProjectile.CallExplode( ExplosionLocation, vect(0,0,1) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3711,6 +3711,42 @@ defaultproperties
|
||||
//G36C Sahara
|
||||
Skins.Add((Id=9479, Weapondef=class'KFWeapDef_G36C', MIC_1P=("wep_skinset64_mat.Wep_1P_Sahara_G36C_MIC","wep_skinset64_mat.Wep_1P_Sahara_Scope_G36C_MIC"), MIC_3P="wep_skinset64_mat.Wep_3P_Sahara_G36C_MIC", MIC_Pickup="wep_skinset64_mat.Wep_3P_Sahara_G36C_Pickup_MIC"))
|
||||
|
||||
//HVStormCannon Standard
|
||||
Skins.Add((Id=9569, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("WEP_1P_HVStormCannon_MAT.Wep_1P_HVStormCannon_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","WEP_1P_HVStormCannon_MAT.Wep_1P_HVStormCannon_MIC"), MIC_3P="wep_3p_hvstormcannon_mat.WEP_3P_HVStormCannon_MIC", MIC_Pickup="wep_3p_hvstormcannon_mat.3P_Pickup_HVStormCannon_MIC"))
|
||||
|
||||
//HVStormCannon Lost Planet
|
||||
Skins.Add((Id=9570, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("wep_skinset70_mat.Wep_1P_StormCannon_LostPlanet_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","wep_skinset70_mat.Wep_1P_StormCannon_LostPlanet_MIC"), MIC_3P="wep_skinset70_mat.Wep_3P_StormCannon_LostPlanet_MIC", MIC_Pickup="wep_skinset70_mat.Wep_3P_StormCannon_LostPlanet_Pickup_MIC"))
|
||||
|
||||
//HVStormCannon Morph
|
||||
Skins.Add((Id=9571, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("wep_skinset70_mat.Wep_1P_StormCannon_Xeno_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","wep_skinset70_mat.Wep_1P_StormCannon_Xeno_MIC"), MIC_3P="wep_skinset70_mat.Wep_3P_StormCannon_Xeno_MIC", MIC_Pickup="wep_skinset70_mat.Wep_3P_StormCannon_Xeno_Pickup_MIC"))
|
||||
|
||||
//HVStormCannon Rebel
|
||||
Skins.Add((Id=9572, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("wep_skinset70_mat.Wep_1P_StormCannon_Rebel_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","wep_skinset70_mat.Wep_1P_StormCannon_Rebel_MIC"), MIC_3P="wep_skinset70_mat.Wep_3P_StormCannon_Rebel_MIC", MIC_Pickup="wep_skinset70_mat.Wep_3P_StormCannon_Rebel_Pickup_MIC"))
|
||||
|
||||
//HVStormCannon Space Man
|
||||
Skins.Add((Id=9573, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("wep_skinset70_mat.Wep_1P_StormCannon_SpaceMan_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","wep_skinset70_mat.Wep_1P_StormCannon_SpaceMan_MIC"), MIC_3P="wep_skinset70_mat.Wep_3P_StormCannon_SpaceMan_MIC", MIC_Pickup="wep_skinset70_mat.Wep_3P_StormCannon_SpaceMan_Pickup_MIC"))
|
||||
|
||||
//HVStormCannon Tycho
|
||||
Skins.Add((Id=9574, Weapondef=class'KFWeapDef_HVStormCannon', MIC_1P=("wep_skinset70_mat.Wep_1P_StormCannon_Tycho_Scope_MIC","WEP_1P_HVStormCannon_MAT.Wep_1stP_HVStormCannon_Lens_MIC","wep_skinset70_mat.Wep_1P_StormCannon_Tycho_MIC"), MIC_3P="wep_skinset70_mat.Wep_3P_StormCannon_Tycho_MIC", MIC_Pickup="wep_skinset70_mat.Wep_3P_StormCannon_Tycho_Pickup_MIC"))
|
||||
|
||||
//ZEDMKIII Standard
|
||||
Skins.Add((Id=9575, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_1P_ZEDMKIII_MAT.Wep_1stP_ZEDMKIII_MIC"), MIC_3P="Wep_3P_ZEDMKIII_MAT.Wep_3rdP_ZEDMKIII_MIC", MIC_Pickup="wep_3p_zedmkiii_mat.Wep_3rdP_ZEDMKIII_Pickup_MIC"))
|
||||
|
||||
//ZEDMKIII Army
|
||||
Skins.Add((Id=9576, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_SkinSet71_MAT.Wep_1P_ZEDMKIII_Army_MIC"), MIC_3P="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Army_MIC", MIC_Pickup="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Army_Pickup_MIC"))
|
||||
|
||||
//ZEDMKIII Delux
|
||||
Skins.Add((Id=9577, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_SkinSet71_MAT.Wep_1P_ZEDMKIII_Deluxe_MIC"), MIC_3P="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Deluxe_MIC", MIC_Pickup="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Deluxe_MIC"))
|
||||
|
||||
//ZEDMKIII Ice Storm
|
||||
Skins.Add((Id=9578, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_SkinSet71_MAT.Wep_1P_ZEDMKIII_Ice_MIC"), MIC_3P="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Ice_MIC", MIC_Pickup="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Ice_Pickup_MIC"))
|
||||
|
||||
//ZEDMKIII Industrial
|
||||
Skins.Add((Id=9579, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_SkinSet71_MAT.Wep_1P_ZEDMKIII_Industrial_MIC"), MIC_3P="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Industrial_MIC", MIC_Pickup="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Industrial_Pickup_MIC"))
|
||||
|
||||
//ZEDMKIII Tiger
|
||||
Skins.Add((Id=9580, Weapondef=class'KFWeapDef_ZedMKIII', MIC_1P=("WEP_SkinSet71_MAT.Wep_1P_ZEDMKIII_Tiger_MIC"), MIC_3P="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Tiger_MIC", MIC_Pickup="WEP_SkinSet71_MAT.Wep_3P_ZEDMKIII_Tiger_MIC"))
|
||||
|
||||
//BeyondHorizon AA12
|
||||
Skins.Add((Id=8845, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.space_aa12.Space_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Pickup_MIC"))
|
||||
|
||||
@ -4009,7 +4045,7 @@ defaultproperties
|
||||
Skins.Add((Id=9351, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("wep_skinset58_mat.chameleon_deagle.Chameleon_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleon_deagle.Chameleon_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleon_deagle.Chameleon_Deagle_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic Katana
|
||||
Skins.Add((Id=9352, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Katana', MIC_1P=("wep_skinset58_mat.chameleon_katana.Chameleon_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleon_katana.Chameleon_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleon_katana.Chameleon_Katana_3P_Pickup_MIC"))
|
||||
Skins.Add((Id=9352, Weapondef=class'KFWeapDef_Katana', MIC_1P=("wep_skinset58_mat.chameleon_katana.Chameleon_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleon_katana.Chameleon_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleon_katana.Chameleon_Katana_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic Kriss SMG
|
||||
Skins.Add((Id=9353, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("wep_skinset58_mat.chameleon_kriss.Chameleon_Kriss_1P_Mint_MIC", "wep_skinset58_mat.chameleon_kriss.Chameleon_Kriss_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleon_kriss.Chameleon_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleon_kriss.Chameleon_Kriss_3P_Pickup_MIC"))
|
||||
@ -4021,7 +4057,7 @@ defaultproperties
|
||||
Skins.Add((Id=9355, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("wep_skinset58_mat.chameleonrgb_deagle.ChameleonRGB_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleonrgb_deagle.ChameleonRGB_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleonrgb_deagle.ChameleonRGB_Deagle_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB Katana
|
||||
Skins.Add((Id=9356, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Katana', MIC_1P=("wep_skinset58_mat.chameleonrgb_katana.ChameleonRGB_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleonrgb_katana.ChameleonRGB_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleonrgb_katana.ChameleonRGB_Katana_3P_Pickup_MIC"))
|
||||
Skins.Add((Id=9356, Weapondef=class'KFWeapDef_Katana', MIC_1P=("wep_skinset58_mat.chameleonrgb_katana.ChameleonRGB_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleonrgb_katana.ChameleonRGB_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleonrgb_katana.ChameleonRGB_Katana_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB Kriss SMG
|
||||
Skins.Add((Id=9357, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("wep_skinset58_mat.chameleonrgb_kriss.ChameleonRGB_Kriss_1P_Mint_MIC", "wep_skinset58_mat.chameleonrgb_kriss.ChameleonRGB_Kriss_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet58_MAT.chameleonrgb_kriss.ChameleonRGB_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet58_MAT.chameleonrgb_kriss.ChameleonRGB_Kriss_3P_Pickup_MIC"))
|
||||
@ -4316,4 +4352,184 @@ defaultproperties
|
||||
|
||||
//Xeno Dynamic RGB Hemoclobber
|
||||
Skins.Add((Id=9432, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet63_MAT.xenorgb_medicbat.XenoRGB_MedicBat_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic Heckler & Koch UMP
|
||||
Skins.Add((Id=9485, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("wep_skinset68_mat.chameleon_hk_ump.Chameleon_HK_UMP_1P_Mint_MIC", "wep_skinset68_mat.chameleon_hk_ump.Chameleon_HK_UMP_Sight_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleon_hk_ump.Chameleon_HK_UMP_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleon_hk_ump.Chameleon_HK_UMP_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic Helios Rifle
|
||||
Skins.Add((Id=9486, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("wep_skinset68_mat.chameleon_microwaveassault.Chameleon_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleon_microwaveassault.Chameleon_MicrowaveAssault_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleon_microwaveassault.Chameleon_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic HMTech-501 Grenade Rifle
|
||||
Skins.Add((Id=9487, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("wep_skinset68_mat.chameleon_medicgrenadelauncher.Chameleon_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleon_medicgrenadelauncher.Chameleon_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleon_medicgrenadelauncher.Chameleon_MedicGrenadeLauncher_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic M32
|
||||
Skins.Add((Id=9488, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("wep_skinset68_mat.chameleon_m32.Chameleon_M32_1P_Mint_MIC", "wep_skinset68_mat.chameleon_m32.Chameleon_M32_Sight_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleon_m32.Chameleon_M32_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleon_m32.Chameleon_M32_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB Heckler & Koch UMP
|
||||
Skins.Add((Id=9489, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HK_UMP', MIC_1P=("wep_skinset68_mat.chameleonrgb_hk_ump.ChameleonRGB_HK_UMP_1P_Mint_MIC", "wep_skinset68_mat.chameleonrgb_hk_ump.ChameleonRGB_HK_UMP_Sight_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleonrgb_hk_ump.ChameleonRGB_HK_UMP_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleonrgb_hk_ump.ChameleonRGB_HK_UMP_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB Helios Rifle
|
||||
Skins.Add((Id=9490, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("wep_skinset68_mat.chameleonrgb_microwaveassault.ChameleonRGB_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleonrgb_microwaveassault.ChameleonRGB_MicrowaveAssault_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleonrgb_microwaveassault.ChameleonRGB_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB HMTech-501 Grenade Rifle
|
||||
Skins.Add((Id=9491, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("wep_skinset68_mat.chameleonrgb_medicgrenadelauncher.ChameleonRGB_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleonrgb_medicgrenadelauncher.ChameleonRGB_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleonrgb_medicgrenadelauncher.ChameleonRGB_MedicGrenadeLauncher_3P_Pickup_MIC"))
|
||||
|
||||
//Chameleon Dynamic RGB M32
|
||||
Skins.Add((Id=9492, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("wep_skinset68_mat.chameleonrgb_m32.ChameleonRGB_M32_1P_Mint_MIC", "wep_skinset68_mat.chameleonrgb_m32.ChameleonRGB_M32_Sight_1P_Mint_MIC"), MIC_3P="wep_skinset68_mat.chameleonrgb_m32.ChameleonRGB_M32_3P_Mint_MIC", MIC_Pickup="wep_skinset68_mat.chameleonrgb_m32.ChameleonRGB_M32_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Mint BattleAxe
|
||||
Skins.Add((Id=9494, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AbominationAxe', MIC_1P=("WEP_SkinSet67_MAT.medieval_krampusaxe.Medieval_KrampusAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medieval_krampusaxe.Medieval_KrampusAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medieval_krampusaxe.Medieval_KrampusAxe_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Mint Boomstick
|
||||
Skins.Add((Id=9495, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet67_MAT.medieval_doublebarrel.Medieval_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medieval_doublebarrel.Medieval_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medieval_doublebarrel.Medieval_DoubleBarrel_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Mint Pulverizer
|
||||
Skins.Add((Id=9496, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet67_MAT.medieval_pulverizer.Medieval_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medieval_pulverizer.Medieval_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medieval_pulverizer.Medieval_Pulverizer_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Mint RPG-7
|
||||
Skins.Add((Id=9497, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet67_MAT.medieval_rpg7.Medieval_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medieval_rpg7.Medieval_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medieval_rpg7.Medieval_RPG7_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Precious BattleAxe
|
||||
Skins.Add((Id=9498, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AbominationAxe', MIC_1P=("WEP_SkinSet67_MAT.medievalgold_krampusaxe.MedievalGold_KrampusAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medievalgold_krampusaxe.MedievalGold_KrampusAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medievalgold_krampusaxe.MedievalGold_KrampusAxe_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Precious Boomstick
|
||||
Skins.Add((Id=9499, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_DoubleBarrel', MIC_1P=("WEP_SkinSet67_MAT.medievalgold_DoubleBarrel.MedievalGold_DoubleBarrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medievalgold_DoubleBarrel.MedievalGold_DoubleBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medievalgold_DoubleBarrel.MedievalGold_DoubleBarrel_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Precious Pulverizer
|
||||
Skins.Add((Id=9500, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet67_MAT.medievalgold_pulverizer.MedievalGold_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medievalgold_pulverizer.MedievalGold_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medievalgold_pulverizer.MedievalGold_Pulverizer_3P_Pickup_MIC"))
|
||||
|
||||
//Medieval Precious RPG-7
|
||||
Skins.Add((Id=9501, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet67_MAT.medievalgold_rpg7.MedievalGold_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet67_MAT.medievalgold_rpg7.MedievalGold_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet67_MAT.medievalgold_rpg7.MedievalGold_RPG7_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic AA12
|
||||
Skins.Add((Id=9544, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet66_MAT.tacticool_aa12.Tacticool_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_aa12.Tacticool_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_aa12.Tacticool_AA12_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic M99
|
||||
Skins.Add((Id=9545, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet66_MAT.tacticool_m99.Tacticool_M99_1P_Mint_MIC", "WEP_SkinSet66_MAT.tacticool_m99.Tacticool_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_m99.Tacticool_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_m99.Tacticool_M99_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic MP5RAS
|
||||
Skins.Add((Id=9546, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet66_MAT.tacticool_mp5ras.Tacticool_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_mp5ras.Tacticool_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_mp5ras.Tacticool_MP5RAS_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic SCAR
|
||||
Skins.Add((Id=9547, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet66_MAT.tacticool_scar.Tacticool_SCAR_1P_Mint_MIC", "WEP_SkinSet66_MAT.tacticool_scar.Tacticool_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_scar.Tacticool_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_scar.Tacticool_SCAR_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic Precious AA12
|
||||
Skins.Add((Id=9548, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet66_MAT.tacticool_aa12.TacticoolPrecious_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_aa12.TacticoolPrecious_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_aa12.TacticoolPrecious_AA12_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic Precious M99
|
||||
Skins.Add((Id=9549, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M99', MIC_1P=("WEP_SkinSet66_MAT.tacticool_m99.TacticoolPrecious_M99_1P_Mint_MIC", "WEP_SkinSet66_MAT.tacticool_m99.TacticoolPrecious_M99_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_m99.TacticoolPrecious_M99_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_m99.TacticoolPrecious_M99_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic Precious MP5RAS
|
||||
Skins.Add((Id=9550, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet66_MAT.tacticool_mp5ras.TacticoolPrecious_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_mp5ras.TacticoolPrecious_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_mp5ras.TacticoolPrecious_MP5RAS_3P_Pickup_MIC"))
|
||||
|
||||
//Tacticool Dynamic Precious SCAR
|
||||
Skins.Add((Id=9551, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SCAR', MIC_1P=("WEP_SkinSet66_MAT.tacticool_scar.TacticoolPrecious_SCAR_1P_Mint_MIC", "WEP_SkinSet66_MAT.tacticool_scar.TacticoolPrecious_SCAR_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet66_MAT.tacticool_scar.TacticoolPrecious_SCAR_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet66_MAT.tacticool_scar.TacticoolPrecious_SCAR_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade P90
|
||||
Skins.Add((Id=9504, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroConsole_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroConsole_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroConsole_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroConsole_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir P90
|
||||
Skins.Add((Id=9505, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroLightNoir_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroLightNoir_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroLightNoir_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroLightNoir_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir P90
|
||||
Skins.Add((Id=9506, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroDarkNoir_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroDarkNoir_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroDarkNoir_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroDarkNoir_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber P90
|
||||
Skins.Add((Id=9507, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroCyber_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroCyber_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroCyber_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroCyber_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth P90
|
||||
Skins.Add((Id=9508, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroSynth_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroSynth_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroSynth_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroSynth_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Precious P90
|
||||
Skins.Add((Id=9509, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet69_MAT.retro_p90.RetroPrecious_P90_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_p90.RetroPrecious_P90_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_p90.RetroPrecious_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_p90.RetroPrecious_P90_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade Static Strikers
|
||||
Skins.Add((Id=9510, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroConsole_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroConsole_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroConsole_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir Static Strikers
|
||||
Skins.Add((Id=9511, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroLightNoir_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroLightNoir_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroLightNoir_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir Static Strikers
|
||||
Skins.Add((Id=9512, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroDarkNoir_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroDarkNoir_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroDarkNoir_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber Static Strikers
|
||||
Skins.Add((Id=9513, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroCyber_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroCyber_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroCyber_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth Static Strikers
|
||||
Skins.Add((Id=9514, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroSynth_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroSynth_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroSynth_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Precious Static Strikers
|
||||
Skins.Add((Id=9515, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_PowerGloves', MIC_1P=("WEP_SkinSet69_MAT.retro_staticstrikers.RetroPrecious_StaticStrikers_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_staticstrikers.RetroPrecious_StaticStrikers_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_staticstrikers.RetroPrecious_StaticStrikers_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade HZ12
|
||||
Skins.Add((Id=9516, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroConsole_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroConsole_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroConsole_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir HZ12
|
||||
Skins.Add((Id=9517, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroLightNoir_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroLightNoir_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroLightNoir_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir HZ12
|
||||
Skins.Add((Id=9518, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroDarkNoir_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroDarkNoir_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroDarkNoir_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber HZ12
|
||||
Skins.Add((Id=9519, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroCyber_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroCyber_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroCyber_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth HZ12
|
||||
Skins.Add((Id=9520, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroSynth_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroSynth_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroSynth_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Precious HZ12
|
||||
Skins.Add((Id=9521, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_HZ12', MIC_1P=("WEP_SkinSet69_MAT.retro_hz12.RetroPrecious_HZ12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_hz12.RetroPrecious_HZ12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_hz12.RetroPrecious_HZ12_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade Microwave Gun
|
||||
Skins.Add((Id=9522, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroConsole_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroConsole_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroConsole_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir Microwave Gun
|
||||
Skins.Add((Id=9523, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroLightNoir_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroLightNoir_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroLightNoir_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir Microwave Gun
|
||||
Skins.Add((Id=9524, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroDarkNoir_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroDarkNoir_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroDarkNoir_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber Microwave Gun
|
||||
Skins.Add((Id=9525, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroCyber_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroCyber_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroCyber_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth Microwave Gun
|
||||
Skins.Add((Id=9526, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroSynth_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroSynth_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroSynth_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Precious Microwave Gun
|
||||
Skins.Add((Id=9527, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet69_MAT.retro_microwavegun.RetroPrecious_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwavegun.RetroPrecious_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwavegun.RetroPrecious_MicrowaveGun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade Helios Rifle
|
||||
Skins.Add((Id=9528, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroConsole_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroConsole_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroConsole_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir Helios Rifle
|
||||
Skins.Add((Id=9529, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroLightNoir_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroLightNoir_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroLightNoir_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir Helios Rifle
|
||||
Skins.Add((Id=9530, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroDarkNoir_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroDarkNoir_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroDarkNoir_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber Helios Rifle
|
||||
Skins.Add((Id=9531, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroCyber_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroCyber_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroCyber_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth Helios Rifle
|
||||
Skins.Add((Id=9532, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroSynth_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroSynth_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroSynth_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Precious Helios Rifle
|
||||
Skins.Add((Id=9533, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveRifle', MIC_1P=("WEP_SkinSet69_MAT.retro_microwaveassault.RetroPrecious_MicrowaveAssault_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_microwaveassault.RetroPrecious_MicrowaveAssault_3P_Mint_M", MIC_Pickup="WEP_SkinSet69_MAT.retro_microwaveassault.RetroPrecious_MicrowaveAssault_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Arcade Railgun
|
||||
Skins.Add((Id=9534, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroConsole_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroConsole_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroConsole_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroConsole_Railgun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Light Noir Railgun
|
||||
Skins.Add((Id=9535, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroLightNoir_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroLightNoir_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroLightNoir_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroLightNoir_Railgun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Dark Noir Railgun
|
||||
Skins.Add((Id=9536, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroDarkNoir_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroDarkNoir_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroDarkNoir_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroDarkNoir_Railgun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Cyber Railgun
|
||||
Skins.Add((Id=9537, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroCyber_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroCyber_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroCyber_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroCyber_Railgun_3P_Pickup_MIC"))
|
||||
|
||||
//Retro Synth Railgun
|
||||
Skins.Add((Id=9538, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Railgun', MIC_1P=("WEP_SkinSet69_MAT.retro_railgun.RetroSynth_Railgun_1P_Mint_MIC", "WEP_SkinSet69_MAT.retro_railgun.RetroSynth_Railgun_Scope_1P_Mint_MIC"), MIC_3P="WEP_SkinSet69_MAT.retro_railgun.RetroSynth_Railgun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet69_MAT.retro_railgun.RetroSynth_Railgun_3P_Pickup_MIC"))
|
||||
|
||||
//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"))
|
||||
}
|
@ -27,7 +27,7 @@ var localized array<string> ModifierDescriptions;
|
||||
cpptext
|
||||
{
|
||||
/** Num of Weekly events available */
|
||||
static const int NumWeeklyEvents = 18;
|
||||
static const int NumWeeklyEvents = 19;
|
||||
}
|
||||
DefaultProperties
|
||||
{
|
||||
|
@ -158,4 +158,5 @@ const STATID_ACHIEVE_NetherholdCollectibles = 4060;
|
||||
const STATID_ACHIEVE_CarillonHamletCollectibles = 4061;
|
||||
const STATID_ACHIEVE_RigCollectibles = 4062;
|
||||
const STATID_ACHIEVE_BarmwichCollectibles = 4063;
|
||||
const STATID_ACHIEVE_CrashCollectibles = 4064;
|
||||
/** `endif */
|
||||
|
@ -80,3 +80,4 @@ const KFID_MouseLookUpScale=181; // Halloweeen 2022 QoL: added mouse options to
|
||||
const KFID_MouseLookRightScale=182; // Halloweeen 2022 QoL: added mouse options to menu
|
||||
const KFID_ViewSmoothingEnabled=183; // Halloweeen 2022 QoL: added mouse options to menu
|
||||
const KFID_ViewAccelerationEnabled=184; // Halloweeen 2022 QoL: added mouse options to menu
|
||||
const KFID_SavedAllowSeasonalSkinsIndex=185;
|
24
KFGameContent/Classes/KFDT_Ballistic_HRG_MedicMissile.uc
Normal file
24
KFGameContent/Classes/KFDT_Ballistic_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,24 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Ballistic_HRG_MedicMissile extends KFDT_Ballistic_Shell
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3000
|
||||
KDeathUpKick=1000
|
||||
KDeathVel=500
|
||||
|
||||
StumblePower=10
|
||||
GunHitPower=45
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_FieldMedic'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_MedicMissile'
|
||||
}
|
25
KFGameContent/Classes/KFDT_Ballistic_ZedMKIII_Rocket.uc
Normal file
25
KFGameContent/Classes/KFDT_Ballistic_ZedMKIII_Rocket.uc
Normal file
@ -0,0 +1,25 @@
|
||||
//=============================================================================
|
||||
// KFDT_Ballistic_ZedMKIII_Rocket
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Ballistic_ZedMKIII_Rocket extends KFDT_Ballistic_Shell
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=3000
|
||||
KDeathUpKick=1000
|
||||
KDeathVel=500
|
||||
|
||||
KnockdownPower=50
|
||||
StumblePower=100
|
||||
GunHitPower=70
|
||||
|
||||
ModifierPerkList(0)=class'KFPerk_Demolitionist'
|
||||
|
||||
WeaponDef=class'KFWeapDef_ZedMKIII'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_BallisticBouncer.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HRG_BallisticBouncer extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_BallisticBouncer'
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_BallisticBouncer_Shot
|
||||
//=============================================================================
|
||||
// Balls hit hard
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HRG_BallisticBouncer_Shot extends KFDT_Bludgeon
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=900
|
||||
KDeathUpKick=-300
|
||||
KDeathVel=100
|
||||
|
||||
StumblePower=400
|
||||
GunHitPower=300
|
||||
MeleeHitPower=150
|
||||
KnockdownPower=100
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_BallisticBouncer'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_MedicMissile.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HRG_MedicMissile extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HRG_MedicMissile'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_HVStormCannon.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_HVStormCannon.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_HVStormCannon
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_HVStormCannon extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_HVStormCannon'
|
||||
}
|
16
KFGameContent/Classes/KFDT_Bludgeon_ZedMKIII.uc
Normal file
16
KFGameContent/Classes/KFDT_Bludgeon_ZedMKIII.uc
Normal file
@ -0,0 +1,16 @@
|
||||
//=============================================================================
|
||||
// KFDT_Bludgeon_ZedMKIII
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Bludgeon_ZedMKIII extends KFDT_Bludgeon_RifleButt
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
//defaults
|
||||
WeaponDef=class'KFWeapDef_ZedMKIII'
|
||||
}
|
54
KFGameContent/Classes/KFDT_EMP_HVStormCannon.uc
Normal file
54
KFGameContent/Classes/KFDT_EMP_HVStormCannon.uc
Normal file
@ -0,0 +1,54 @@
|
||||
//=============================================================================
|
||||
// KFDT_EMP_HVStormCannon
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_EMP_HVStormCannon extends KFDT_EMP
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
var ParticleSystem ForceImpactEffect;
|
||||
var AkEvent ForceImpactSound;
|
||||
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
local KFSkinTypeEffects SkinType;
|
||||
|
||||
if ( P.CharacterArch != None && default.EffectGroup < FXG_Max )
|
||||
{
|
||||
SkinType = P.GetHitZoneSkinTypeEffects( HitZoneIndex );
|
||||
|
||||
if (SkinType != none)
|
||||
{
|
||||
SkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup, default.ForceImpactEffect);
|
||||
SkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup, default.ForceImpactSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=2000
|
||||
KDeathUpKick=400
|
||||
KDeathVel=250
|
||||
|
||||
KnockdownPower=20
|
||||
StunPower=50
|
||||
StumblePower=200
|
||||
GunHitPower=150
|
||||
MeleeHitPower=100
|
||||
EMPPower=0 // Don't use the affliction here, we manage this on KFWeap_HVStormCannon to completely synchronize it with the logic of the weapon
|
||||
|
||||
GoreDamageGroup=DGT_EMP
|
||||
EffectGroup=FXG_Electricity
|
||||
|
||||
ForceImpactEffect=ParticleSystem'WEP_HVStormCannon_EMIT.FX_HVStormCannon_Impact'
|
||||
ForceImpactSound=AkEvent'WW_WEP_HVStormCannon.Play_WEP_HVStormCannon_Impact'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HVStormCannon'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
|
||||
}
|
32
KFGameContent/Classes/KFDT_Explosive_HRG_MedicMissile.uc
Normal file
32
KFGameContent/Classes/KFDT_Explosive_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,32 @@
|
||||
//=============================================================================
|
||||
// KFDT_Explosive_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Explosive_HRG_MedicMissile extends KFDT_Explosive
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bShouldSpawnPersistentBlood=false
|
||||
|
||||
RadialDamageImpulse=2500
|
||||
GibImpulseScale=0.15
|
||||
KDeathUpKick=1500
|
||||
KDeathVel=500
|
||||
|
||||
KnockdownPower=50
|
||||
StumblePower=200
|
||||
|
||||
bExtraMomentumZ=false
|
||||
|
||||
bCanObliterate=false
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_FieldMedic'
|
||||
|
||||
WeaponDef=class'KFWeapDef_HRG_MedicMissile'
|
||||
}
|
30
KFGameContent/Classes/KFDT_Explosive_ZedMKIII.uc
Normal file
30
KFGameContent/Classes/KFDT_Explosive_ZedMKIII.uc
Normal file
@ -0,0 +1,30 @@
|
||||
//=============================================================================
|
||||
// KFDT_Explosive_ZedMKIII
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFDT_Explosive_ZedMKIII extends KFDT_Explosive
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bShouldSpawnPersistentBlood=true
|
||||
|
||||
// physics impact
|
||||
RadialDamageImpulse=10000
|
||||
KDeathUpKick=2000
|
||||
KDeathVel=500
|
||||
|
||||
KnockdownPower=150
|
||||
StumblePower=350
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Demolitionist'
|
||||
|
||||
ObliterationHealthThreshold=-500
|
||||
ObliterationDamageThreshold=500
|
||||
WeaponDef=class'KFWeapDef_ZedMKIII'
|
||||
}
|
69
KFGameContent/Classes/KFDT_Microwave_ZedMKIII.uc
Normal file
69
KFGameContent/Classes/KFDT_Microwave_ZedMKIII.uc
Normal file
@ -0,0 +1,69 @@
|
||||
//=============================================================================
|
||||
// KFDT_Microwave_ZedMKIII
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFDT_Microwave_ZedMKIII extends KFDT_Microwave
|
||||
abstract
|
||||
hidedropdown;
|
||||
|
||||
var ParticleSystem ForceImpactEffect;
|
||||
var AkEvent ForceImpactSound;
|
||||
|
||||
/** 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':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static function PlayImpactHitEffects( KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator )
|
||||
{
|
||||
local KFSkinTypeEffects SkinType;
|
||||
|
||||
if ( P.CharacterArch != None && default.EffectGroup < FXG_Max )
|
||||
{
|
||||
SkinType = P.GetHitZoneSkinTypeEffects( HitZoneIndex );
|
||||
|
||||
if (SkinType != none)
|
||||
{
|
||||
SkinType.PlayImpactParticleEffect(P, HitLocation, HitDirection, HitZoneIndex, default.EffectGroup, default.ForceImpactEffect);
|
||||
SkinType.PlayTakeHitSound(P, HitLocation, HitInstigator, default.EffectGroup, default.ForceImpactSound);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
KDamageImpulse=550
|
||||
GibImpulseScale=0.85
|
||||
KDeathUpKick=-200
|
||||
KDeathVel=200
|
||||
|
||||
StumblePower=18
|
||||
StunPower=15
|
||||
GunHitPower=15
|
||||
|
||||
WeaponDef=class'KFWeapDef_ZedMKIII'
|
||||
|
||||
//Perk
|
||||
ModifierPerkList(0)=class'KFPerk_Demolitionist'
|
||||
|
||||
EffectGroup=FXG_MicrowaveProj
|
||||
|
||||
ForceImpactEffect=ParticleSystem'WEP_ZEDMKIII_EMIT.FX_ZEDMKIII_Bullet_Impact'
|
||||
ForceImpactSound=AkEvent'WW_WEP_ZEDMKIII.Play_WEP_ZEDMKIII_Shoot_Impact'
|
||||
}
|
283
KFGameContent/Classes/KFExplosion_HRG_BallisticBouncer.uc
Normal file
283
KFGameContent/Classes/KFExplosion_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,283 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_BallisticBouncer extends KFExplosionActorLingering;
|
||||
|
||||
var() class<KFDamageType> HealingDamageType;
|
||||
var() float HealingAmount;
|
||||
|
||||
var AkEvent SmokeLoopStartEvent;
|
||||
var AkEvent SmokeLoopStopEvent;
|
||||
|
||||
var KFPerk CachedInstigatorPerk;
|
||||
|
||||
var float fChargePercentage;
|
||||
|
||||
var float fMinAmmoutHealing;
|
||||
var float fMaxAmmoutHealing;
|
||||
|
||||
var float fAltMinAmmoutHealing;
|
||||
var float fAltMaxAmmoutHealing;
|
||||
|
||||
var bool bHealsInstigator;
|
||||
var bool bHealsDifferentAmmoutToInstigator;
|
||||
|
||||
/* Only used if bOnlyDamagePawns is active to create fractures in walls */
|
||||
var bool bAllowFractureDamage;
|
||||
|
||||
simulated function SpawnExplosionParticleSystem(ParticleSystem Template)
|
||||
{
|
||||
local ParticleSystemComponent PSC;
|
||||
local vector vec;
|
||||
|
||||
// If the template is none, grab the default
|
||||
if( !ExplosionTemplate.bAllowPerMaterialFX && Template == none )
|
||||
{
|
||||
Template = KFGameExplosion(ExplosionTemplate).ExplosionEffects.DefaultImpactEffect.ParticleTemplate;
|
||||
}
|
||||
|
||||
// Use custom pool
|
||||
PSC = WorldInfo.MyEmitterPool.SpawnEmitter(Template, Location, rotator(ExplosionTemplate.HitNormal), None);
|
||||
//fChargePercentage
|
||||
vec.X = fChargePercentage;
|
||||
vec.Y = fChargePercentage;
|
||||
vec.Z = fChargePercentage;
|
||||
PSC.SetVectorParameter( name("BlobCharge"), vec);
|
||||
PSC.SetFloatParameter( name("MineFxControlParam"), fChargePercentage);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @param Direction For bDirectionalExplosion=true explosions, this is the forward direction of the blast.
|
||||
* Overridden to add the ability to spawn fragments from the explosion
|
||||
**/
|
||||
simulated function Explode(GameExplosion NewExplosionTemplate, optional vector Direction)
|
||||
{
|
||||
local KFPawn KFP;
|
||||
super.Explode(NewExplosionTemplate, Direction);
|
||||
|
||||
if( Instigator != none )
|
||||
{
|
||||
|
||||
KFP = KFPawn(Instigator);
|
||||
if( KFP != none )
|
||||
{
|
||||
CachedInstigatorPerk = KFP.GetPerk();
|
||||
}
|
||||
}
|
||||
|
||||
if (Role == Role_Authority)
|
||||
{
|
||||
//DelayedExplosionDamage();
|
||||
SetTimer(Interval, false, nameof(DelayedExplosionDamage), self);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deal damage or heal players
|
||||
*/
|
||||
protected simulated function AffectsPawn(Pawn Victim, float DamageScale)
|
||||
{
|
||||
local KFPawn_Human HumanVictim;
|
||||
local KFPawn_Monster MonsterVictim;
|
||||
local KFProj_MedicGrenade OwnerProjectile;
|
||||
local bool bCanRepairArmor;
|
||||
local Box BBox;
|
||||
local vector BBoxCenter;
|
||||
local Actor HitActor;
|
||||
local bool bDamageBlocked;
|
||||
|
||||
|
||||
if( Victim != none && Victim.IsAliveAndWell() )
|
||||
{
|
||||
MonsterVictim = KFPawn_Monster(Victim);
|
||||
if( MonsterVictim != none )
|
||||
{
|
||||
if( bWasFadedOut|| bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Victim.GetComponentsBoundingBox(BBox);
|
||||
BBoxCenter = (BBox.Min + BBox.Max) * 0.5f;
|
||||
HitActor = TraceExplosive(BBoxCenter, Location + vect(0, 0, 20));
|
||||
bDamageBlocked = (HitActor != None && HitActor != Victim);
|
||||
if(bDamageBlocked && HitActor.IsA('KFDoorActor'))
|
||||
{
|
||||
bDamageBlocked = false;
|
||||
}
|
||||
if( !bDamageBlocked )
|
||||
{
|
||||
Victim.TakeRadiusDamage(InstigatorController, ExplosionTemplate.Damage * DamageScale, ExplosionTemplate.DamageRadius,
|
||||
ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, bDoFullDamage,
|
||||
(Owner != None) ? Owner : self, ExplosionTemplate.DamageFalloffExponent);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Victim.GetComponentsBoundingBox(BBox);
|
||||
BBoxCenter = (BBox.Min + BBox.Max) * 0.5f;
|
||||
HitActor = TraceExplosive(BBoxCenter, Location + vect(0, 0, 20));
|
||||
bDamageBlocked = (HitActor != None && HitActor != Victim);
|
||||
if(bDamageBlocked && HitActor.IsA('KFDoorActor'))
|
||||
{
|
||||
bDamageBlocked = false;
|
||||
}
|
||||
if(!bDamageBlocked)
|
||||
{
|
||||
if(!bHealsInstigator && Victim == Instigator)
|
||||
{
|
||||
return;
|
||||
}
|
||||
HumanVictim = KFPawn_Human(Victim);
|
||||
if( HumanVictim != none && HumanVictim.GetExposureTo(Location) > 0 )
|
||||
{
|
||||
OwnerProjectile = KFProj_MedicGrenade(Owner);
|
||||
if( OwnerProjectile != none )
|
||||
{
|
||||
bCanRepairArmor = OwnerProjectile.HealedPawns.Find( HumanVictim ) == INDEX_NONE;
|
||||
}
|
||||
|
||||
if(bHealsDifferentAmmoutToInstigator && bHealsInstigator && Victim == Instigator)
|
||||
{
|
||||
HumanVictim.HealDamage( Lerp(fAltMinAmmoutHealing, fAltMaxAmmoutHealing, fChargePercentage), InstigatorController, HealingDamageType, bCanRepairArmor);
|
||||
}
|
||||
else
|
||||
{
|
||||
HumanVictim.HealDamage( Lerp(fMinAmmoutHealing, fMaxAmmoutHealing, fChargePercentage), InstigatorController, HealingDamageType, bCanRepairArmor);
|
||||
}
|
||||
|
||||
if( bCanRepairArmor )
|
||||
{
|
||||
OwnerProjectile.HealedPawns.AddItem( HumanVictim );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected simulated function bool DoExplosionDamage(bool bCauseDamage, bool bCauseEffects)
|
||||
{
|
||||
if( bWasFadedOut || bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( bOnlyDamagePawns && bAllowFractureDamage )
|
||||
{
|
||||
ExplodeFractures();
|
||||
}
|
||||
|
||||
if( bOnlyDamagePawns )
|
||||
{
|
||||
return ExplodePawns(bCauseDamage);
|
||||
}
|
||||
|
||||
return super(KFExplosionActor).DoExplosionDamage(bCauseDamage, bCauseEffects);
|
||||
}
|
||||
|
||||
/** Check fractures only if */
|
||||
protected simulated function ExplodeFractures()
|
||||
{
|
||||
local Actor Victim;
|
||||
local bool bCauseFractureEffects;
|
||||
local float CheckRadius, VictimDist;
|
||||
local Box BBox;
|
||||
local FracturedStaticMeshActor FracActor;
|
||||
local byte WantPhysChunksAndParticles;
|
||||
local TraceHitInfo HitInfo;
|
||||
|
||||
if( bWasFadedOut || bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bCauseFractureEffects = WorldInfo.NetMode != NM_DedicatedServer && ExplosionTemplate.bCausesFracture;
|
||||
|
||||
if( !bCauseFractureEffects )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// determine radius to check
|
||||
CheckRadius = GetEffectCheckRadius(true, bCauseFractureEffects, WorldInfo.NetMode != NM_Client);
|
||||
if ( CheckRadius > 0.0 )
|
||||
{
|
||||
foreach CollidingActors(class'Actor', Victim, CheckRadius, Location, ExplosionTemplate.bUseOverlapCheck,,HitInfo )
|
||||
{
|
||||
if ( Victim != Self
|
||||
&& (!Victim.bWorldGeometry || Victim.bCanBeDamaged)
|
||||
&& (NavigationPoint(Victim) == None)
|
||||
&& Victim != ExplosionTemplate.ActorToIgnoreForDamage
|
||||
&& (!ExplosionTemplate.bIgnoreInstigator || Victim != Instigator)
|
||||
&& !ClassIsChildOf(Victim.Class, ExplosionTemplate.ActorClassToIgnoreForDamage)
|
||||
&& !IsBehindExplosion(Victim) )
|
||||
{
|
||||
|
||||
// return if this is a pawn
|
||||
if(GamePawn(Victim) != none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check if visible, unless physics object
|
||||
// note: using bbox center instead of location, because that's what visiblecollidingactors does
|
||||
Victim.GetComponentsBoundingBox(BBox);
|
||||
|
||||
// adjust distance if using overlap check
|
||||
VictimDist = ExplosionTemplate.bUseOverlapCheck ? BoxDistanceToPoint(Location, BBox) : VSize(Location - Victim.Location);
|
||||
|
||||
FracActor = FracturedStaticMeshActor(Victim);
|
||||
if ( (FracActor != None)
|
||||
&& (VictimDist < ExplosionTemplate.FractureMeshRadius)
|
||||
&& (FracActor.Physics == PHYS_None)
|
||||
&& FracActor.IsFracturedByDamageType(ExplosionTemplate.MyDamageType)
|
||||
&& FracActor.FractureEffectIsRelevant( false, Instigator, WantPhysChunksAndParticles) )
|
||||
{
|
||||
// Let kismet know that we were hit by an explosion
|
||||
FracActor.NotifyHitByExplosion(InstigatorController, ExplosionTemplate.Damage, ExplosionTemplate.MyDamageType);
|
||||
|
||||
FracActor.BreakOffPartsInRadius(Location, ExplosionTemplate.FractureMeshRadius, ExplosionTemplate.FracturePartVel, WantPhysChunksAndParticles == 1 ? true : false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
HealingDamageType=class'KFDT_Healing'
|
||||
HealingAmount=0;
|
||||
|
||||
fMinAmmoutHealing=5; //4;
|
||||
fMaxAmmoutHealing=50; //40
|
||||
|
||||
Interval=0
|
||||
MaxTime=0.0
|
||||
FadeOutTime=0.0
|
||||
|
||||
bExplodeMoreThanOnce=false
|
||||
bDoFullDamage=false
|
||||
|
||||
bOnlyDamagePawns=true
|
||||
bAllowFractureDamage=true
|
||||
|
||||
bSkipLineCheckForPawns=true
|
||||
|
||||
LoopStartEvent=none
|
||||
LoopStopEvent=none
|
||||
|
||||
//EXPERIMENTAL FEATURES FOR DESIGN
|
||||
bHealsInstigator = false;
|
||||
bHealsDifferentAmmoutToInstigator = false;
|
||||
fAltMinAmmoutHealing=1;
|
||||
fAltMaxAmmoutHealing=5;
|
||||
}
|
73
KFGameContent/Classes/KFExplosion_HRG_MedicMissile.uc
Normal file
73
KFGameContent/Classes/KFExplosion_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,73 @@
|
||||
//=============================================================================
|
||||
// KFExplosion_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFExplosion_HRG_MedicMissile extends KFExplosionActorLingering;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected simulated function AffectsPawn(Pawn Victim, float DamageScale)
|
||||
{
|
||||
local KFPawn KFP;
|
||||
|
||||
if( bWasFadedOut|| bDeleteMe || bPendingDelete )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KFP = KFPawn(Victim);
|
||||
|
||||
if (KFP == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (KFP.GetTeamNum() == Instigator.GetTeamNum())
|
||||
{
|
||||
KFP.HealDamage(HealingValue, Instigator.Controller, class'KFDT_Healing');
|
||||
}
|
||||
else
|
||||
{
|
||||
super.AffectsPawn(VIctim, DamageScale);
|
||||
|
||||
KFP.ApplyDamageOverTime(class'KFDT_Toxic_HRG_MedicMissile'.default.PoisonPower, Instigator.Controller, class'KFDT_Toxic_HRG_MedicMissile');
|
||||
}
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
Interval=0f
|
||||
MaxTime=0f
|
||||
|
||||
bOnlyDamagePawns=true
|
||||
bDoFullDamage=false
|
||||
|
||||
bExplodeMoreThanOnce=false
|
||||
|
||||
HealingValue=50
|
||||
}
|
@ -386,6 +386,8 @@ function UpdateGameSettings()
|
||||
local int NumHumanPlayers, i;
|
||||
local KFGameEngine KFEngine;
|
||||
|
||||
super.UpdateGameSettings();
|
||||
|
||||
if (WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.NetMode == NM_ListenServer)
|
||||
{
|
||||
//`REMOVEMESOON_ServerTakeoverLog("KFGameInfo_Survival.UpdateGameSettings 1 - GameInterface: "$GameInterface);
|
||||
|
@ -550,14 +550,16 @@ function byte PickTeam(byte Current, Controller C, const out UniqueNetId PlayerI
|
||||
/** Return whether a team change is allowed. */
|
||||
function bool ChangeTeam(Controller Other, int N, bool bNewTeam)
|
||||
{
|
||||
if( Other.PlayerReplicationInfo == none
|
||||
|| Other.PlayerReplicationInfo.bBot
|
||||
|| (!Other.PlayerReplicationInfo.bOnlySpectator
|
||||
&& ArrayCount(Teams) > N
|
||||
&& Other.PlayerReplicationInfo.Team != Teams[N]) )
|
||||
if (ArrayCount(Teams) > N)
|
||||
{
|
||||
SetTeam( Other, Teams[N] );
|
||||
return true;
|
||||
if( Other.PlayerReplicationInfo == none
|
||||
|| Other.PlayerReplicationInfo.bBot
|
||||
|| ( !Other.PlayerReplicationInfo.bOnlySpectator
|
||||
&& Other.PlayerReplicationInfo.Team != Teams[N] ) )
|
||||
{
|
||||
SetTeam( Other, Teams[N] );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -445,6 +445,7 @@ event PostLogin( PlayerController NewPlayer )
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC_WS;
|
||||
local KFPawn_Customization KFCustomizePawn;
|
||||
|
||||
super.PostLogin(NewPlayer);
|
||||
|
||||
KFPC_WS = KFPlayerController_WeeklySurvival(NewPlayer);
|
||||
@ -544,6 +545,12 @@ function WaveEnded(EWaveEndCondition WinCondition)
|
||||
// This function is called multiple times in a row. Only apply it once.
|
||||
bWasFirstTime = bWaveStarted;
|
||||
|
||||
// Choose new perk before the end of wave message triggers in supper.
|
||||
if (MyKFGRI.IsRandomPerkMode() && WinCondition == WEC_WaveWon)
|
||||
{
|
||||
ChooseRandomPerks();
|
||||
}
|
||||
|
||||
super.WaveEnded(WinCondition);
|
||||
|
||||
if (OutbreakEvent.ActiveEvent.bPermanentZedTime && ZedTimeRemaining > ZedTimeBlendOutTime)
|
||||
@ -1315,6 +1322,10 @@ function WaveStarted()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Weekly 17: VIP MODE
|
||||
*/
|
||||
|
||||
function OnVIPDiesEndMatch()
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
@ -1500,6 +1511,182 @@ function OnOutbreakWaveWon()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Weekly 18: Random Perks
|
||||
*/
|
||||
|
||||
simulated function NotifyPlayerStatsInitialized(KFPlayerController_WeeklySurvival KFPC)
|
||||
{
|
||||
if (KFPC != none && MyKFGRI.IsRandomPerkMode())
|
||||
{
|
||||
ChooseInitialRandomPerk(KFPC);
|
||||
}
|
||||
}
|
||||
|
||||
function ChooseInitialRandomPerk(KFPlayerController_WeeklySurvival KFPC_WS)
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival OtherKFPC;
|
||||
local array<class<KFPerk> > AvailablePerks;
|
||||
local int i;
|
||||
local byte NewPerkIndex;
|
||||
local bool bPerkFound;
|
||||
|
||||
`Log("CHOOSING INITIAL PERKS");
|
||||
|
||||
for (i = 0; i < KFPC_WS.PerkList.Length; ++i)
|
||||
{
|
||||
bPerkFound = false;
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', OtherKFPC)
|
||||
{
|
||||
if (OtherKFPC == KFPC_WS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (KFPC_WS.Perklist[i].PerkClass == OtherKFPC.CurrentPerk.Class)
|
||||
{
|
||||
bPerkFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bPerkFound)
|
||||
{
|
||||
AvailablePerks.AddItem(KFPC_WS.PerkList[i].PerkClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (AvailablePerks.Length == 0)
|
||||
{
|
||||
for (i = 0; i < KFPC_WS.Perklist.Length; ++i)
|
||||
{
|
||||
AvailablePerks.AddItem(KFPC_WS.Perklist[i].PerkClass);
|
||||
}
|
||||
KFPC_WS.LockedPerks.Length = 0;
|
||||
}
|
||||
|
||||
NewPerkIndex = Rand(AvailablePerks.Length);
|
||||
|
||||
KFPC_WS.LockedPerks.AddItem(AvailablePerks[NewPerkIndex]);
|
||||
KFPC_WS.ForceNewPerk(AvailablePerks[NewPerkIndex]);
|
||||
}
|
||||
|
||||
function ChooseRandomPerks()
|
||||
{
|
||||
local KFPlayerController_WeeklySurvival KFPC;
|
||||
local array<class<KFPerk> > AvailablePerks;
|
||||
local array<class<KFPerk> > PickedPerks;
|
||||
local int i, j;
|
||||
local byte NewPerkIndex;
|
||||
local bool bPerkFound;
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController_WeeklySurvival', KFPC)
|
||||
{
|
||||
AvailablePerks.Length = 0;
|
||||
|
||||
for (i = 0; i < KFPC.Perklist.Length; ++i)
|
||||
{
|
||||
bPerkFound = false;
|
||||
for (j = 0; j < PickedPerks.Length; ++j)
|
||||
{
|
||||
if (KFPC.Perklist[i].PerkClass == PickedPerks[j])
|
||||
{
|
||||
bPerkFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bPerkFound)
|
||||
{
|
||||
for (j = 0; j < KFPC.LockedPerks.Length; ++j)
|
||||
{
|
||||
if (KFPC.Perklist[i].PerkClass == KFPC.LockedPerks[j])
|
||||
{
|
||||
bPerkFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bPerkFound)
|
||||
{
|
||||
AvailablePerks.AddItem(KFPC.Perklist[i].PerkClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (AvailablePerks.Length == 0)
|
||||
{
|
||||
for (i = 0; i < KFPC.Perklist.Length; ++i)
|
||||
{
|
||||
bPerkFound = false;
|
||||
for (j = 0; j < PickedPerks.Length; ++j)
|
||||
{
|
||||
if (KFPC.Perklist[i].PerkClass == PickedPerks[j])
|
||||
{
|
||||
bPerkFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bPerkFound && KFPC.Perklist[i].PerkClass != KFPC.CurrentPerk.Class)
|
||||
{
|
||||
AvailablePerks.AddItem(KFPC.Perklist[i].PerkClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (AvailablePerks.Length == 0)
|
||||
{
|
||||
for (i = 0; i < KFPC.Perklist.Length; ++i)
|
||||
{
|
||||
AvailablePerks.AddItem(KFPC.Perklist[i].PerkClass);
|
||||
PickedPerks.Length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
KFPC.LockedPerks.Length = 0;
|
||||
}
|
||||
|
||||
NewPerkIndex = Rand(AvailablePerks.Length);
|
||||
PickedPerks.AddItem(AvailablePerks[NewPerkIndex]);
|
||||
KFPC.LockedPerks.AddItem(AvailablePerks[NewPerkIndex]);
|
||||
|
||||
KFPC.ForceNewPerk(AvailablePerks[NewPerkIndex]);
|
||||
|
||||
KFPC.PlayRandomPerkChosenSound();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Overide BroadcastLocalizedMessage for the RandomPerk weekly (18)
|
||||
// Perk is replicated while the message is sent through a RPC, so the message arrives before
|
||||
// the perk is updated on clients.
|
||||
// Override the BroadcastLocalizedMessage function to RPC each player the message with their own
|
||||
// new perk class as the optional object so the client knows the information before it gets the perk updated.
|
||||
//
|
||||
event BroadcastLocalizedMessage( class<LocalMessage> InMessageClass, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
if (!MyKFGRI.IsRandomPerkMode() || Switch != GMT_WaveEnd)
|
||||
{
|
||||
Super.BroadcastLocalizedMessage(InMessageClass, Switch, RelatedPRI_1, RelatedPRI_2, OptionalObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
BroadcastCustomWaveEndMessage(self, InMessageClass, Switch);
|
||||
}
|
||||
}
|
||||
|
||||
function BroadcastCustomWaveEndMessage( actor Sender, class<LocalMessage> InMessageClass, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
foreach WorldInfo.AllControllers(class'KFPlayerController', KFPC)
|
||||
{
|
||||
KFPC.ReceiveLocalizedMessage( InMessageClass, Switch, RelatedPRI_1, RelatedPRI_2, KFPC.GetPerk().Class);
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
//Overrides
|
||||
|
@ -1220,6 +1220,21 @@ defaultproperties
|
||||
, class'KFGameContent.KFPawn_ZedHans'),
|
||||
)}
|
||||
|
||||
// Random Perks
|
||||
SetEvents[18]={(
|
||||
EventDifficulty=2,
|
||||
GameLength=GL_Normal,
|
||||
DoshOnKillGlobalModifier=1.3,
|
||||
SpawnReplacementList={(
|
||||
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.3),
|
||||
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedCrawler'),PercentChance=0.3),
|
||||
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedStalker'),PercentChance=0.3),
|
||||
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedSiren'),PercentChance=0.3),
|
||||
(SpawnEntry=AT_Scrake,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.3)
|
||||
|
||||
)}
|
||||
)}
|
||||
|
||||
//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
|
||||
|
22
KFGameContent/Classes/KFProj_Bullet_HVStormCannon.uc
Normal file
22
KFGameContent/Classes/KFProj_Bullet_HVStormCannon.uc
Normal file
@ -0,0 +1,22 @@
|
||||
//=============================================================================
|
||||
// KFProj_Bullet_HVStormCannon
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Bullet_HVStormCannon extends KFProj_Bullet
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MaxSpeed=22500.0
|
||||
Speed=22500.0
|
||||
|
||||
DamageRadius=0
|
||||
|
||||
ProjFlightTemplate = ParticleSystem'WEP_HVStormCannon_EMIT.FX_HVStormCannon_Projectile'
|
||||
ImpactEffects = KFImpactEffectInfo'WEP_HVStormCannon_ARCH.Wep_HVStormCannon_Impact'
|
||||
}
|
||||
|
22
KFGameContent/Classes/KFProj_Bullet_ZedMKIII.uc
Normal file
22
KFGameContent/Classes/KFProj_Bullet_ZedMKIII.uc
Normal file
@ -0,0 +1,22 @@
|
||||
//=============================================================================
|
||||
// KFProj_Bullet_ZedMKIII
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Bullet_ZedMKIII extends KFProj_Bullet
|
||||
hidedropdown;
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MaxSpeed=22500.0
|
||||
Speed=22500.0
|
||||
|
||||
DamageRadius=0
|
||||
|
||||
ProjFlightTemplate = ParticleSystem'WEP_ZEDMKIII_EMIT.FX_ZEDMKIII_Bullet_Projectile'
|
||||
ImpactEffects = KFImpactEffectInfo'WEP_ZEDMKIII_ARCH.FX_ZEDMKIII_Bullet_Impact'
|
||||
}
|
||||
|
@ -69,7 +69,9 @@ simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
class'KFPerk_Demolitionist'.static.PrepareExplosive( Instigator, self );
|
||||
|
||||
super.PrepareExplosionTemplate();
|
||||
GetRadialDamageValues(ExplosionTemplate.Damage, ExplosionTemplate.DamageRadius, ExplosionTemplate.DamageFalloffExponent);
|
||||
|
||||
// super.PrepareExplosionTemplate();
|
||||
}
|
||||
|
||||
simulated protected function SetExplosionActorClass()
|
||||
|
@ -133,7 +133,9 @@ simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
class'KFPerk_Berserker'.static.PrepareExplosive( Instigator, self );
|
||||
|
||||
super.PrepareExplosionTemplate();
|
||||
GetRadialDamageValues(ExplosionTemplate.Damage, ExplosionTemplate.DamageRadius, ExplosionTemplate.DamageFalloffExponent);
|
||||
|
||||
//super.PrepareExplosionTemplate();
|
||||
}
|
||||
|
||||
|
||||
|
556
KFGameContent/Classes/KFProj_HRG_BallisticBouncer.uc
Normal file
556
KFGameContent/Classes/KFProj_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,556 @@
|
||||
//=============================================================================
|
||||
// KFProj_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
// Projectile class for HRG Ballistic Bouncer
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFProj_HRG_BallisticBouncer extends KFProjectile;
|
||||
|
||||
/** Dampen amount for every bounce */
|
||||
var float DampenFactor;
|
||||
|
||||
/** Dampen amount for parallel angle to velocity */
|
||||
var float DampenFactorParallel;
|
||||
|
||||
/** Sound mine makes when it hits something and bounces off */
|
||||
var AkEvent BounceAkEvent;
|
||||
|
||||
/** Sound mine makes when it hits something and comes to rest */
|
||||
var AkEvent ImpactAkEvent;
|
||||
|
||||
/** Sound mine makes when it hits something and bounces off */
|
||||
var AkEvent BounceAkEventHeavy;
|
||||
|
||||
/** Sound mine makes when it hits something and comes to rest */
|
||||
var AkEvent ImpactAkEventHeavy;
|
||||
|
||||
/** Particle System spawned when it hits something */
|
||||
var ParticleSystem HitFXTemplate;
|
||||
var transient ParticleSystemComponent HitPSC;
|
||||
|
||||
/** Particle System for the fade out burst **/
|
||||
var ParticleSystem BurstFXTemplate;
|
||||
var transient ParticleSystemComponent BurstPSC;
|
||||
|
||||
/** Sound for the fade out burst **/
|
||||
var AkEvent BurstAkEvent;
|
||||
|
||||
/** Decal settings */
|
||||
var MaterialInterface ImpactDecalMaterial;
|
||||
var float ImpactDecalWidth;
|
||||
var float ImpactDecalHeight;
|
||||
var float ImpactDecalThickness;
|
||||
|
||||
var int MaxBounces;
|
||||
var int NumBounces;
|
||||
|
||||
var float MaxInitialSpeedByCharge;
|
||||
var float MinInitialSpeedByCharge;
|
||||
|
||||
var float MaxCollisionRadius;
|
||||
var float MinCollisionRadius;
|
||||
var float MaxCollisionHeight;
|
||||
var float MinCollisionHeight;
|
||||
|
||||
var float MaxScalePerPercentage;
|
||||
var float MinScalePerPercentage;
|
||||
|
||||
var int MaxBouncesPerPercentage;
|
||||
var int MinBouncesPerPercentage;
|
||||
|
||||
var float MaxLifeSpanPerPercentage;
|
||||
var float MinLifeSpanPerPercentage;
|
||||
|
||||
var float InheritedScale;
|
||||
|
||||
var repnotify float fChargePercentage;
|
||||
|
||||
var float fCachedCylinderWidth, fCachedCylinderHeight;
|
||||
|
||||
var float ArmDistSquared;
|
||||
|
||||
var bool bFadingOut;
|
||||
var float FadeOutTime;
|
||||
|
||||
var transient byte RequiredImpactsForSeasonal;
|
||||
var transient array<Pawn> ImpactVictims;
|
||||
|
||||
replication
|
||||
{
|
||||
if( bNetDirty )
|
||||
InheritedScale, fChargePercentage, MaxBounces;
|
||||
}
|
||||
|
||||
simulated event ReplicatedEvent( name VarName )
|
||||
{
|
||||
if( VarName == nameOf(fChargePercentage))
|
||||
{
|
||||
fCachedCylinderWidth = Lerp(MinCollisionRadius, MaxCollisionRadius, fChargePercentage);
|
||||
fCachedCylinderHeight = Lerp(MinCollisionHeight, MaxCollisionHeight, fChargePercentage);
|
||||
// CylinderComponent(CollisionComponent).SetCylinderSize(fCachedCylinderWidth, fCachedCylinderHeight);
|
||||
SetCollisionSize(fCachedCylinderWidth, fCachedCylinderHeight);
|
||||
ApplyVFXParams(fChargePercentage);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.ReplicatedEvent( VarName );
|
||||
}
|
||||
}
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
RequiredImpactsForSeasonal = class'KFSeasonalEventStats_Xmas2022'.static.GetMaxBallisticBouncerImpacts();
|
||||
}
|
||||
|
||||
simulated function SetInheritedScale(float Scale, float ChargePercentage)
|
||||
{
|
||||
local float NewSpeed;
|
||||
|
||||
InheritedScale = Scale;
|
||||
|
||||
fChargePercentage = ChargePercentage;
|
||||
fChargePercentage = FMax(0.1, fChargePercentage);
|
||||
|
||||
if (WorldInfo.NetMode == NM_DedicatedServer)
|
||||
{
|
||||
SetCollisionSize(Lerp(MinCollisionRadius, MaxCollisionRadius, fChargePercentage), Lerp(MinCollisionHeight, MaxCollisionHeight, ChargePercentage));
|
||||
}
|
||||
|
||||
NewSpeed = Lerp(MinInitialSpeedByCharge, MaxInitialSpeedByCharge, fChargePercentage);
|
||||
Velocity = Normal(Velocity) * NewSpeed;
|
||||
Speed = NewSpeed;
|
||||
|
||||
MaxBounces = Lerp(MinBouncesPerPercentage, MaxBouncesPerPercentage, fChargePercentage);
|
||||
|
||||
LifeSpan = Lerp(MinLifeSpanPerPercentage, MaxLifeSpanPerPercentage, fChargePercentage);
|
||||
|
||||
if (ProjEffects != none)
|
||||
{
|
||||
ProjEffects.SetScale(Lerp(MinScalePerPercentage, MaxScalePerPercentage, fChargePercentage));
|
||||
}
|
||||
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer)
|
||||
{
|
||||
ApplyVFXParams(fChargePercentage);
|
||||
}
|
||||
|
||||
bNetDirty=true;
|
||||
}
|
||||
|
||||
function RestoreCylinder()
|
||||
{
|
||||
CylinderComponent(CollisionComponent).SetCylinderSize(fCachedCylinderWidth, fCachedCylinderHeight);
|
||||
}
|
||||
|
||||
simulated function BounceNoCheckRepeatingTouch(vector HitNormal, Actor BouncedOff)
|
||||
{
|
||||
local vector VNorm;
|
||||
|
||||
// Reflect off BouncedOff w/damping
|
||||
VNorm = (Velocity dot HitNormal) * HitNormal;
|
||||
|
||||
if (NumBounces < MaxBounces)
|
||||
{
|
||||
Velocity = -VNorm + (Velocity - VNorm);
|
||||
}
|
||||
else
|
||||
{
|
||||
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
|
||||
}
|
||||
|
||||
Speed = VSize(Velocity);
|
||||
|
||||
// Play a sound
|
||||
PlayImpactSound();
|
||||
|
||||
// Spawn impact particle system, server needs to send the message (it's the only one storing MaxBounces)
|
||||
if (WorldInfo.NetMode != NM_DedicatedServer)
|
||||
{
|
||||
if (NumBounces < MaxBounces)
|
||||
{
|
||||
PlayImpactVFX(HitNormal);
|
||||
}
|
||||
|
||||
`ImpactEffectManager.PlayImpactEffects(Location, Instigator, VNorm, ImpactEffects);
|
||||
}
|
||||
|
||||
++NumBounces;
|
||||
}
|
||||
|
||||
/** Adjusts movement/physics of projectile.
|
||||
* Returns true if projectile actually bounced / was allowed to bounce */
|
||||
simulated function bool Bounce( vector HitNormal, Actor BouncedOff )
|
||||
{
|
||||
// Avoid crazy bouncing
|
||||
if (CheckRepeatingTouch(BouncedOff))
|
||||
{
|
||||
CylinderComponent(CollisionComponent).SetCylinderSize(1,1);
|
||||
SetTimer(0.06f, false, nameof(RestoreCylinder));
|
||||
return false;
|
||||
}
|
||||
|
||||
BounceNoCheckRepeatingTouch(HitNormal, BouncedOff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Plays a sound on impact */
|
||||
simulated function PlayImpactSound( optional bool bIsAtRest )
|
||||
{
|
||||
if( WorldInfo.NetMode != NM_DedicatedServer )
|
||||
{
|
||||
if( bIsAtRest )
|
||||
{
|
||||
if(fChargePercentage < 0.75f)
|
||||
PostAkEvent( ImpactAkEvent, true, true, false );
|
||||
else
|
||||
PostAkEvent( ImpactAkEventHeavy, true, true, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fChargePercentage < 0.75f)
|
||||
PostAkEvent( BounceAkEvent, true, true, false );
|
||||
else
|
||||
PostAkEvent( BounceAkEventHeavy, true, true, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function PlayImpactVFX(vector HitNormal)
|
||||
{
|
||||
HitPSC = WorldInfo.MyEmitterPool.SpawnEmitter(HitFXTemplate, ProjEffects.GetPosition(), rotator(HitNormal));
|
||||
HitPSC.SetFloatParameter(name("Charge"), fChargePercentage);
|
||||
}
|
||||
|
||||
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
|
||||
{
|
||||
local float TraveledDistance;
|
||||
|
||||
TraveledDistance = (`TimeSince(CreationTime) * Speed);
|
||||
TraveledDistance *= TraveledDistance;
|
||||
|
||||
// If we collided with a Siren shield, let the shield code handle touches
|
||||
if( Other.IsA('KFTrigger_SirenProjectileShield') )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Other != Instigator && Other.GetTeamNum() != GetTeamNum())
|
||||
{
|
||||
// check/ignore repeat touch events
|
||||
if (!CheckRepeatingTouch(Other))
|
||||
{
|
||||
ProcessBulletTouch(Other, HitLocation, HitNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function ProcessBulletTouch(Actor Other, Vector HitLocation, Vector HitNormal)
|
||||
{
|
||||
local Pawn Victim;
|
||||
local array<ImpactInfo> HitZoneImpactList;
|
||||
//local ImpactInfo ImpactInfoFallBack;
|
||||
local vector StartTrace, EndTrace, Direction; //, DirectionFallBack;
|
||||
local TraceHitInfo HitInfo;
|
||||
local KFWeapon KFW;
|
||||
|
||||
Victim = Pawn( Other );
|
||||
if ( Victim == none )
|
||||
{
|
||||
if ( bDamageDestructiblesOnTouch && Other.bCanBeDamaged )
|
||||
{
|
||||
HitInfo.HitComponent = LastTouchComponent;
|
||||
HitInfo.Item = INDEX_None; // force TraceComponent on fractured meshes
|
||||
Other.TakeDamage(Damage, InstigatorController, Location, MomentumTransfer * Normal(Velocity), MyDamageType, HitInfo, self);
|
||||
}
|
||||
|
||||
// Reduce the penetration power to zero if we hit something other than a pawn or foliage actor
|
||||
if( InteractiveFoliageActor(Other) == None )
|
||||
{
|
||||
PenetrationPower = 0;
|
||||
|
||||
BounceNoCheckRepeatingTouch(HitNormal, Other);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bSpawnShrapnel)
|
||||
{
|
||||
//spawn straight forward through the zed
|
||||
SpawnShrapnel(Other, HitLocation, HitNormal, rotator(Velocity), ShrapnelSpreadWidthZed, ShrapnelSpreadHeightZed);
|
||||
}
|
||||
|
||||
StartTrace = HitLocation;
|
||||
Direction = Normal(Velocity);
|
||||
EndTrace = StartTrace + Direction * (Victim.CylinderComponent.CollisionRadius * 6.0);
|
||||
|
||||
TraceProjHitZones(Victim, EndTrace, StartTrace, HitZoneImpactList);
|
||||
|
||||
//`Log("HitZoneImpactList: " $HitZoneImpactList.Length);
|
||||
|
||||
if ( HitZoneImpactList.length > 0 )
|
||||
{
|
||||
HitZoneImpactList[0].RayDir = Direction;
|
||||
|
||||
if( Owner != none )
|
||||
{
|
||||
KFW = KFWeapon( Owner );
|
||||
if( KFW != none )
|
||||
{
|
||||
KFW.HandleProjectileImpact(WeaponFireMode, HitZoneImpactList[0], PenetrationPower);
|
||||
}
|
||||
}
|
||||
|
||||
IncrementNumImpacts(Victim);
|
||||
|
||||
BounceNoCheckRepeatingTouch(HitNormal, Other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function IncrementNumImpacts(Pawn Victim)
|
||||
{
|
||||
local int i;
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
if (WorldInfo.NetMode == NM_Client)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KFPC = KFPlayerController(InstigatorController);
|
||||
|
||||
if (KFPC == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ImpactVictims.Length; ++i)
|
||||
{
|
||||
if (Victim == ImpactVictims[i])
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImpactVictims.AddItem(Victim);
|
||||
|
||||
UpdateImpactsSeasonalObjective(KFPC);
|
||||
}
|
||||
|
||||
function UpdateImpactsSeasonalObjective(KFPlayerController KFPC)
|
||||
{
|
||||
local byte ObjectiveIndex;
|
||||
|
||||
ObjectiveIndex = 3;
|
||||
|
||||
if (ImpactVictims.Length >= RequiredImpactsForSeasonal)
|
||||
{
|
||||
// Check parent controller.
|
||||
KFPC.ClientOnTryCompleteObjective(ObjectiveIndex, SEI_Winter);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event HitWall( vector HitNormal, Actor Wall, PrimitiveComponent WallComp )
|
||||
{
|
||||
// Don't collide with other projectiles
|
||||
if( Wall.class == class )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Bounce( HitNormal, Wall );
|
||||
}
|
||||
|
||||
simulated function SpawnBurstFX()
|
||||
{
|
||||
local vector vec;
|
||||
|
||||
if( WorldInfo.NetMode == NM_DedicatedServer || WorldInfo.MyEmitterPool == none || ProjEffects == none )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BurstPSC = WorldInfo.MyEmitterPool.SpawnEmitter(BurstFXTemplate, ProjEffects.GetPosition(), rotator(vect(0,0,1)), self, , ,true);
|
||||
|
||||
vec.X = fChargePercentage;
|
||||
vec.Y = fChargePercentage;
|
||||
vec.Z = fChargePercentage;
|
||||
|
||||
BurstPSC.SetVectorParameter(name("BlobCharge"), vec);
|
||||
BurstPSC.SetFloatParameter(name("MineFxControlParam"), fChargePercentage);
|
||||
|
||||
PostAkEvent(BurstAkEvent, true, true, false);
|
||||
}
|
||||
|
||||
simulated function Tick(float Delta)
|
||||
{
|
||||
if (NumBounces < MaxBounces || bFadingOut)
|
||||
return;
|
||||
|
||||
if (Speed < 20.0f)
|
||||
{
|
||||
bFadingOut = true;
|
||||
StopSimulating();
|
||||
|
||||
SpawnBurstFX();
|
||||
|
||||
// Tell clients to tear off and fade out on their own
|
||||
if( WorldInfo.NetMode != NM_Client )
|
||||
{
|
||||
ClearTimer(nameof(Timer_Destroy));
|
||||
|
||||
SetTimer( 1.0f, false, nameOf(Timer_Destroy) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function Timer_Destroy()
|
||||
{
|
||||
if (BurstPSC != none)
|
||||
{
|
||||
BurstPSC.DeactivateSystem();
|
||||
}
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
||||
simulated function ApplyVFXParams(float ChargePercent)
|
||||
{
|
||||
if (ProjEffects != none)
|
||||
{
|
||||
ProjEffects.SetFloatParameter(name("InflateBlob"), ChargePercent);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function SyncOriginalLocation()
|
||||
{
|
||||
local Actor HitActor;
|
||||
local vector HitLocation, HitNormal;
|
||||
local TraceHitInfo HitInfo;
|
||||
|
||||
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
|
||||
{
|
||||
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
|
||||
if (HitActor != none)
|
||||
{
|
||||
ProcessBulletTouch(HitActor, HitLocation, HitNormal);
|
||||
}
|
||||
}
|
||||
|
||||
Super.SyncOriginalLocation();
|
||||
}
|
||||
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
TerminalVelocity=5000
|
||||
TossZ=150
|
||||
GravityScale=0.5
|
||||
MomentumTransfer=50000.0
|
||||
|
||||
LifeSpan=300
|
||||
PostExplosionLifetime=1
|
||||
Physics=PHYS_Falling
|
||||
bBounce=true
|
||||
|
||||
ProjFlightTemplate= ParticleSystem'WEP_HRG_BallisticBouncer_EMIT.FX_HRG_BallisticBouncer_Ball_Projectile'
|
||||
BurstFXTemplate= ParticleSystem'WEP_HRG_BallisticBouncer_EMIT.FX_HRG_BallisticBouncer_Ball_Explode'
|
||||
HitFXTemplate= ParticleSystem'WEP_HRG_BallisticBouncer_EMIT.FX_HRG_BallisticBouncer_Ball_Hit'
|
||||
|
||||
bSuppressSounds=false
|
||||
bAmbientSoundZedTimeOnly=false
|
||||
bAutoStartAmbientSound=false
|
||||
bStopAmbientSoundOnExplode=true
|
||||
|
||||
ImpactAkEvent=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Ball_Impact'
|
||||
BounceAkEvent=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Ball_Impact'
|
||||
ImpactAkEventHeavy=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Ball_Impact_Heavy'
|
||||
BounceAkEventHeavy=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Ball_Impact_Heavy'
|
||||
|
||||
BurstAkEvent=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Ball_Explosion'
|
||||
|
||||
Begin Object Class=AkComponent name=AmbientAkSoundComponent
|
||||
bStopWhenOwnerDestroyed=true
|
||||
bForceOcclusionUpdateInterval=true
|
||||
OcclusionUpdateInterval=0.25f
|
||||
End Object
|
||||
AmbientComponent=AmbientAkSoundComponent
|
||||
Components.Add(AmbientAkSoundComponent)
|
||||
|
||||
//ImpactDecalMaterial=DecalMaterial'FX_Mat_Lib.FX_Puke_Mine_Splatter_DM'
|
||||
ImpactDecalWidth=178.f
|
||||
ImpactDecalHeight=178.f
|
||||
ImpactDecalThickness=28.f
|
||||
|
||||
Begin Object Name=CollisionCylinder
|
||||
CollisionRadius=0.f
|
||||
CollisionHeight=0.f
|
||||
CollideActors=true
|
||||
BlockNonZeroExtent=false
|
||||
PhysMaterialOverride=PhysicalMaterial'WEP_HRG_BallisticBouncer_EMIT.BloatPukeMine_PM'
|
||||
End Object
|
||||
|
||||
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
|
||||
bUseClientSideHitDetection=true
|
||||
bNoReplicationToInstigator=false
|
||||
bUpdateSimulatedPosition=true
|
||||
|
||||
bProjTarget=true
|
||||
bCanBeDamaged=false
|
||||
bNoEncroachCheck=true
|
||||
bPushedByEncroachers=false
|
||||
DampenFactor=0.175f
|
||||
DampenFactorParallel=0.175f
|
||||
|
||||
ExtraLineCollisionOffsets.Add((Y=-20))
|
||||
ExtraLineCollisionOffsets.Add((Y=20))
|
||||
ExtraLineCollisionOffsets.Add((Z=-20))
|
||||
ExtraLineCollisionOffsets.Add((Z=20))
|
||||
// Since we're still using an extent cylinder, we need a line at 0
|
||||
ExtraLineCollisionOffsets.Add(())
|
||||
GlassShatterType=FMGS_ShatterAll
|
||||
InheritedScale=1
|
||||
|
||||
MaxInitialSpeedByCharge=5000
|
||||
MinInitialSpeedByCharge=1500
|
||||
|
||||
MaxCollisionRadius=20
|
||||
MinCollisionRadius=10
|
||||
MaxCollisionHeight=20
|
||||
MinCollisionHeight=10
|
||||
|
||||
MaxScalePerPercentage=1.5f
|
||||
MinScalePerPercentage=0.5f
|
||||
|
||||
MaxBouncesPerPercentage=5
|
||||
MinBouncesPerPercentage=1
|
||||
|
||||
MaxLifespanPerPercentage=500
|
||||
MinLifeSpanPerPercentage=300
|
||||
|
||||
bBlockedByInstigator=true
|
||||
bNetTemporary=false
|
||||
|
||||
bSyncToOriginalLocation=true
|
||||
bSyncToThirdPersonMuzzleLocation=true
|
||||
|
||||
bReplicateLocationOnExplosion=true
|
||||
|
||||
TouchTimeThreshhold=0.05
|
||||
|
||||
MaxBounces=0
|
||||
NumBounces=0
|
||||
|
||||
ArmDistSquared=0
|
||||
|
||||
// Fade out properties
|
||||
FadeOutTime=5.0f
|
||||
|
||||
// ImpactEffects= KFImpactEffectInfo'WEP_DragonsBreath_ARCH.DragonsBreath_bullet_impact'
|
||||
}
|
128
KFGameContent/Classes/KFProj_Rocket_HRG_MedicMissile.uc
Normal file
128
KFGameContent/Classes/KFProj_Rocket_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,128 @@
|
||||
//=============================================================================
|
||||
// KFProj_Rocket_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFProj_Rocket_HRG_MedicMissile extends KFProj_BallisticExplosive
|
||||
hidedropdown;
|
||||
|
||||
simulated function bool AllowNuke()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistConcussive()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool AllowDemolitionistExplosionChangeRadius()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated protected function PrepareExplosionTemplate()
|
||||
{
|
||||
local Weapon OwnerWeapon;
|
||||
local Pawn OwnerPawn;
|
||||
local KFPerk_Survivalist Perk;
|
||||
|
||||
super(KFProjectile).PrepareExplosionTemplate();
|
||||
|
||||
OwnerWeapon = Weapon(Owner);
|
||||
if (OwnerWeapon != none)
|
||||
{
|
||||
OwnerPawn = Pawn(OwnerWeapon.Owner);
|
||||
if (OwnerPawn != none)
|
||||
{
|
||||
Perk = KFPerk_Survivalist(KFPawn(OwnerPawn).GetPerk());
|
||||
if (Perk != none)
|
||||
{
|
||||
ExplosionTemplate.DamageRadius *= KFPawn(OwnerPawn).GetPerk().GetAoERadiusModifier();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function AdjustCanDisintigrate()
|
||||
{
|
||||
// This weapon is not from Demolitionist, so always enable Siren disintegrate
|
||||
bCanDisintegrate = true;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
Physics=PHYS_Projectile
|
||||
Speed=5000
|
||||
MaxSpeed=5000
|
||||
TossZ=0
|
||||
GravityScale=1.0
|
||||
MomentumTransfer=50000.0
|
||||
ArmDistSquared=150000 // 4 meters
|
||||
|
||||
bCollideWithTeammates=true
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
ProjFlightTemplate=ParticleSystem'WEP_HRG_MedicMissile_EMIT.FX_HRG_MedicMissile_Projectile'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_MedicMissile_EMIT.FX_HRG_MedicMissile_Projectile_ZED_TIME'
|
||||
ProjDudTemplate=ParticleSystem'WEP_HRG_MedicMissile_EMIT.FX_HRG_MedicMissile_Projectile_Dud'
|
||||
GrenadeBounceEffectInfo=KFImpactEffectInfo'WEP_HRG_MedicMissile_ARCH.HRG_MedicMissile_Projectile_Impacts'
|
||||
|
||||
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
|
||||
bCanDisintegrate=true
|
||||
|
||||
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'
|
||||
|
||||
ExplosionActorClass=class'KFExplosion_HRG_MedicMissile'
|
||||
|
||||
// Grenade explosion light
|
||||
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
||||
LightColor=(R=60,G=200,B=255,A=255)
|
||||
Brightness=2.f
|
||||
Radius=1500.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=400
|
||||
DamageRadius=300
|
||||
DamageFalloffExponent=2
|
||||
DamageDelay=0.f
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Explosive_HRG_MedicMissile'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=0.0
|
||||
FracturePartVel=0.0
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_MedicMissile_ARCH.HRG_MedicMissile_Explosion'
|
||||
ExplosionSound=AkEvent'WW_WEP_HRG_MedicMissile.Play_WEP_HRG_MedicMissile_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
|
||||
End Object
|
||||
ExplosionTemplate=ExploTemplate0
|
||||
|
||||
bCanApplyDemolitionistPerks=false
|
||||
}
|
123
KFGameContent/Classes/KFProj_Rocket_ZedMKIII.uc
Normal file
123
KFGameContent/Classes/KFProj_Rocket_ZedMKIII.uc
Normal file
@ -0,0 +1,123 @@
|
||||
//=============================================================================
|
||||
// KFProj_Rocket_ZedMKIII
|
||||
//=============================================================================
|
||||
// KFProj_Rocket_ZedMKIII rocket
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFProj_Rocket_ZedMKIII extends KFProj_BallisticExplosive
|
||||
hidedropdown;
|
||||
|
||||
/** Our intended target actor */
|
||||
var private KFPawn LockedTarget;
|
||||
|
||||
/** How much 'stickyness' when seeking toward our target. Determines how accurate rocket is */
|
||||
var const float SeekStrength;
|
||||
|
||||
replication
|
||||
{
|
||||
if( bNetInitial )
|
||||
LockedTarget;
|
||||
}
|
||||
|
||||
function SetLockedTarget( KFPawn NewTarget )
|
||||
{
|
||||
LockedTarget = NewTarget;
|
||||
}
|
||||
|
||||
simulated event Tick( float DeltaTime )
|
||||
{
|
||||
local vector TargetImpactPos, DirToTarget;
|
||||
|
||||
super.Tick( DeltaTime );
|
||||
|
||||
// Skip the first frame, then start seeking
|
||||
if( !bHasExploded
|
||||
&& LockedTarget != none
|
||||
&& Physics == PHYS_Projectile
|
||||
&& Velocity != vect(0,0,0)
|
||||
&& LockedTarget.IsAliveAndWell()
|
||||
&& `TimeSince(CreationTime) > 0.03f )
|
||||
{
|
||||
// Grab our desired relative impact location from the weapon class
|
||||
TargetImpactPos = class'KFWeap_ZedMKIII'.static.GetLockedTargetLoc( LockedTarget );
|
||||
|
||||
// Seek towards target
|
||||
Speed = VSize( Velocity );
|
||||
DirToTarget = Normal( TargetImpactPos - Location );
|
||||
Velocity = Normal( Velocity + (DirToTarget * (SeekStrength * DeltaTime)) ) * Speed;
|
||||
|
||||
// Aim rotation towards velocity every frame
|
||||
SetRotation( rotator(Velocity) );
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
Physics=PHYS_Projectile
|
||||
Speed=4000 //6000
|
||||
MaxSpeed=4000 //6000
|
||||
TossZ=0
|
||||
GravityScale=1.0
|
||||
MomentumTransfer=50000.0f
|
||||
ArmDistSquared=110000.0f //20000.0f // 110000.0f // 4 meters 150000.0
|
||||
|
||||
SeekStrength=928000.0f // 128000.0f
|
||||
|
||||
bWarnAIWhenFired=true
|
||||
|
||||
ProjFlightTemplate=ParticleSystem'WEP_ZEDMKIII_EMIT.FX_ZEDMKIII_Rocket'
|
||||
ProjFlightTemplateZedTime=ParticleSystem'WEP_ZEDMKIII_EMIT.FX_ZEDMKIII_Rocket_ZED_TIME'
|
||||
ProjDudTemplate=ParticleSystem'WEP_ZEDMKIII_EMIT.FX_ZEDMKIII_Rocket_Dud'
|
||||
GrenadeBounceEffectInfo=KFImpactEffectInfo'WEP_RPG7_ARCH.RPG7_Projectile_Impacts'
|
||||
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
|
||||
|
||||
AmbientSoundPlayEvent=AkEvent'WW_WEP_ZEDMKIII.Play_WEP_ZEDMKIII_Rocket_LP'
|
||||
AmbientSoundStopEvent=AkEvent'WW_WEP_ZEDMKIII.Stop_WEP_ZEDMKIII_Rocket_LP'
|
||||
|
||||
AltExploEffects=KFImpactEffectInfo'WEP_ZEDMKIII_ARCH.FX_ZEDMKIII_Explosion_Concussive_force'
|
||||
|
||||
// Grenade explosion light
|
||||
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
||||
LightColor=(R=252,G=218,B=171,A=255)
|
||||
Brightness=4.f
|
||||
Radius=2000.f
|
||||
FalloffExponent=10.f
|
||||
CastShadows=False
|
||||
CastStaticShadows=FALSE
|
||||
CastDynamicShadows=False
|
||||
bCastPerObjectShadows=false
|
||||
bEnabled=FALSE
|
||||
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
|
||||
End Object
|
||||
|
||||
// explosion
|
||||
Begin Object Class=KFGameExplosion Name=ExploTemplate0
|
||||
Damage=200
|
||||
DamageRadius=300
|
||||
DamageFalloffExponent=2
|
||||
DamageDelay=0.f
|
||||
|
||||
// Damage Effects
|
||||
MyDamageType=class'KFDT_Explosive_ZedMKIII'
|
||||
KnockDownStrength=0
|
||||
FractureMeshRadius=200.0
|
||||
FracturePartVel=500.0
|
||||
ExplosionEffects=KFImpactEffectInfo'WEP_ZEDMKIII_ARCH.FX_ZEDMKIII_Explosion'
|
||||
ExplosionSound=AkEvent'WW_WEP_ZEDMKIII.Play_WEP_ZEDMKIII_Explosion'
|
||||
|
||||
// Dynamic Light
|
||||
ExploLight=ExplosionPointLight
|
||||
ExploLightStartFadeOutTime=0.0
|
||||
ExploLightFadeOutTime=0.2
|
||||
|
||||
// Camera Shake
|
||||
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
|
||||
CamShakeInnerRadius=0
|
||||
CamShakeOuterRadius=500
|
||||
CamShakeFalloff=3.f
|
||||
bOrientCameraShakeTowardsEpicenter=true
|
||||
End Object
|
||||
ExplosionTemplate=ExploTemplate0
|
||||
}
|
183
KFGameContent/Classes/KFSeasonalEventStats_Xmas2022.uc
Normal file
183
KFGameContent/Classes/KFSeasonalEventStats_Xmas2022.uc
Normal file
@ -0,0 +1,183 @@
|
||||
//=============================================================================
|
||||
// KFSeasonalEventStats_Xmas2022
|
||||
//=============================================================================
|
||||
// Tracks event-specific challenges/accomplishments for Xmas 2022
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFSeasonalEventStats_Xmas2022 extends KFSeasonalEventStats;
|
||||
|
||||
/**
|
||||
Required impacts of the same projectile to count for the objective. I.e. 3 means
|
||||
that a ballistic bouncer projectile needs to make 3 impacts to count for the objective
|
||||
*/
|
||||
var private const byte HRGBBProjectilImpactsRequired;
|
||||
|
||||
var transient private const int FrozenZedsRequired, ShotgunJumpsRequired, BallisticBouncerImpactsRequired, EndlessWaveRequired, XmasEventIndex;
|
||||
|
||||
var transient int ShotgunJumpsIdx;
|
||||
|
||||
private event Initialize(string MapName)
|
||||
{
|
||||
local string CapsMapName;
|
||||
CapsMapName = Caps(MapName);
|
||||
|
||||
bObjectiveIsValidForMap[0] = 1; // Freeze 500 Zeds using ice arsenal
|
||||
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Crash
|
||||
bObjectiveIsValidForMap[2] = 0; // Use 4 Boomstick Jumps in a same match on Crash
|
||||
bObjectiveIsValidForMap[3] = 1; // Hit 3 Zeds with a shot of HRG Ballistic Bouncer (15 times)
|
||||
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Crash
|
||||
|
||||
if (CapsMapName == "KF-CRASH")
|
||||
{
|
||||
bObjectiveIsValidForMap[1] = 1;
|
||||
bObjectiveIsValidForMap[2] = 1;
|
||||
bObjectiveIsValidForMap[4] = 1;
|
||||
}
|
||||
|
||||
SetSeasonalEventStatsMax(FrozenZedsRequired, 0, ShotgunJumpsRequired, BallisticBouncerImpactsRequired, 0);
|
||||
}
|
||||
|
||||
simulated event OnStatsInitialized()
|
||||
{
|
||||
super.OnStatsInitialized();
|
||||
|
||||
CheckRestartObjective(ShotgunJumpsIdx, ShotgunJumpsRequired);
|
||||
}
|
||||
|
||||
private event GrantEventItems()
|
||||
{
|
||||
if (Outer.IsEventObjectiveComplete(0) &&
|
||||
Outer.IsEventObjectiveComplete(1) &&
|
||||
Outer.IsEventObjectiveComplete(2) &&
|
||||
Outer.IsEventObjectiveComplete(3) &&
|
||||
Outer.IsEventObjectiveComplete(4))
|
||||
{
|
||||
GrantEventItem(9568);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
|
||||
{
|
||||
local int ObjIdx;
|
||||
ObjIdx = 1;
|
||||
|
||||
// Crash weekly
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (GameClass == class'KFGameInfo_WeeklySurvival')
|
||||
{
|
||||
FinishedObjective(XmasEventIndex, ObjIdx);
|
||||
}
|
||||
}
|
||||
|
||||
CheckRestartObjective(ShotgunJumpsIdx, ShotgunJumpsRequired);
|
||||
}
|
||||
|
||||
simulated event OnGameEnd(class<GameInfo> GameClass)
|
||||
{
|
||||
CheckRestartObjective(ShotgunJumpsIdx, ShotgunJumpsRequired);
|
||||
}
|
||||
|
||||
simulated function CheckRestartObjective(int ObjectiveIndex, int ObjectiveLimit)
|
||||
{
|
||||
local int StatValue;
|
||||
|
||||
StatValue = Outer.GetSeasonalEventStatValue(ObjectiveIndex);
|
||||
|
||||
if (StatValue != 0 && StatValue < ObjectiveLimit)
|
||||
{
|
||||
ResetSeasonalEventStat(ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
|
||||
{
|
||||
local int FrozenZedsIdx, BallisticBouncerImpactsIdx, ObjectiveLimit;
|
||||
local bool bValidIdx;
|
||||
|
||||
FrozenZedsIdx = 0;
|
||||
BallisticBouncerImpactsIdx = 3;
|
||||
bValidIdx = false;
|
||||
|
||||
if(EventIndex == XmasEventIndex)
|
||||
{
|
||||
if (ObjectiveIndex == FrozenZedsIdx)
|
||||
{
|
||||
ObjectiveLimit = FrozenZedsRequired;
|
||||
bValidIdx = true;
|
||||
}
|
||||
else if (ObjectiveIndex == ShotgunJumpsIdx)
|
||||
{
|
||||
ObjectiveLimit = ShotgunJumpsRequired;
|
||||
bValidIdx = true;
|
||||
}
|
||||
else if (ObjectiveIndex == BallisticBouncerImpactsIdx)
|
||||
{
|
||||
ObjectiveLimit = BallisticBouncerImpactsRequired;
|
||||
bValidIdx = true;
|
||||
}
|
||||
|
||||
if (bValidIdx && bObjectiveIsValidForMap[ObjectiveIndex] != 0)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjectiveIndex, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjectiveIndex) >= ObjectiveLimit)
|
||||
{
|
||||
FinishedObjective(XmasEventIndex, ObjectiveIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
|
||||
{
|
||||
local int ObjIdx;
|
||||
|
||||
// Complete wave 15 on Endless Hard or higher difficulty on Crash
|
||||
ObjIdx = 4;
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
|
||||
{
|
||||
FinishedObjective(XmasEventIndex, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function OnAfflictionCaused(EAfflictionType Type)
|
||||
{
|
||||
local int ObjIdx;
|
||||
|
||||
ObjIdx = 0;
|
||||
|
||||
if (bObjectiveIsValidForMap[ObjIdx] != 0)
|
||||
{
|
||||
if (Type == AF_Freeze)
|
||||
{
|
||||
IncrementSeasonalEventStat(ObjIdx, 1);
|
||||
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= FrozenZedsRequired)
|
||||
{
|
||||
FinishedObjective(XmasEventIndex, ObjIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function byte GetMaxBallisticBouncerImpacts()
|
||||
{
|
||||
return default.HRGBBProjectilImpactsRequired;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ShotgunJumpsIdx=2
|
||||
|
||||
FrozenZedsRequired=500
|
||||
ShotgunJumpsRequired=4
|
||||
BallisticBouncerImpactsRequired=30
|
||||
EndlessWaveRequired=15
|
||||
XmasEventIndex=SEI_Winter
|
||||
|
||||
HRGBBProjectilImpactsRequired=2
|
||||
}
|
95
KFGameContent/Classes/KFShotgunJumpEndVolume.uc
Normal file
95
KFGameContent/Classes/KFShotgunJumpEndVolume.uc
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// KFShotgunJumpEndVolume
|
||||
//=============================================================================
|
||||
// Barmwich volume used tracking the start of shotgun jumps.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFShotgunJumpEndVolume extends PhysicsVolume
|
||||
placeable;
|
||||
|
||||
/** Objective index for the event this is tied to */
|
||||
var() int ObjectiveIndex;
|
||||
|
||||
/** Index of the event this is tied to */
|
||||
var() int EventIndex;
|
||||
|
||||
/** All volumes that track the begin of a shotgun jump in the area */
|
||||
var() array<KFShotgunJumpStartVolume> LinkedVolumes;
|
||||
|
||||
var transient bool bIsDataValid;
|
||||
|
||||
var array<KFPlayerController> SucceededControllers;
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
bIsDataValid = IsObjectiveDataValid();
|
||||
|
||||
if (LinkedVolumes.Length == 0)
|
||||
{
|
||||
`warn("Volume [" $self $"] has no linked volumes (KFShotgunJumpStartVolume).");
|
||||
}
|
||||
}
|
||||
|
||||
simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
|
||||
{
|
||||
local KFPawn_Human KFPH;
|
||||
local KFPlayerController KFPC;
|
||||
local KFShotgunJumpStartVolume StartVolume;
|
||||
|
||||
KFPH = KFPawn_Human(Other);
|
||||
if (KFPH == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KFPC = KFPlayerController(KFPH.Controller);
|
||||
|
||||
if (KFPC == none || IsCompletedByController(KFPC))
|
||||
return;
|
||||
|
||||
foreach LinkedVolumes(StartVolume)
|
||||
{
|
||||
if (StartVolume.IsPlayerTracked(KFPC))
|
||||
{
|
||||
StartVolume.RemoveTrackedPlayer(KFPC);
|
||||
if (KFPC.bShotgunJumping)
|
||||
{
|
||||
SucceededControllers.AddItem(KFPC);
|
||||
KFPC.ClientOnTryCompleteObjective(ObjectiveIndex, EventIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
simulated function bool IsCompletedByController(KFPlayerController Controller)
|
||||
{
|
||||
local KFPlayerController Current;
|
||||
|
||||
foreach SucceededControllers(Current)
|
||||
{
|
||||
if (Controller == Current)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
simulated function bool IsObjectiveDataValid()
|
||||
{
|
||||
return ObjectiveIndex >= 0 && ObjectiveIndex < 5 && EventIndex > SEI_None && EventIndex < SEI_MAX;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
bIsDataValid = false
|
||||
}
|
151
KFGameContent/Classes/KFShotgunJumpStartVolume.uc
Normal file
151
KFGameContent/Classes/KFShotgunJumpStartVolume.uc
Normal file
@ -0,0 +1,151 @@
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// KFShotgunJumpStartVolume
|
||||
//=============================================================================
|
||||
// Barmwich volume used tracking the start of shotgun jumps.
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFShotgunJumpStartVolume extends PhysicsVolume
|
||||
placeable;
|
||||
|
||||
/** Max time we keep track of players */
|
||||
var() float TrackedPlayerLifetime;
|
||||
|
||||
var Info ShotgunJumpVolumeTimer;
|
||||
|
||||
struct KFTrackedController
|
||||
{
|
||||
var KFPlayerController KFPC;
|
||||
var float ExitTimestamp;
|
||||
var bool bInVolume;
|
||||
|
||||
structdefaultproperties
|
||||
{
|
||||
KFPC=none
|
||||
ExitTimestamp=0
|
||||
bInVolume=false
|
||||
}
|
||||
};
|
||||
|
||||
var transient array<KFTrackedController> TrackedControllers;
|
||||
|
||||
simulated event PostBeginPlay()
|
||||
{
|
||||
Super.PostBeginPlay();
|
||||
|
||||
if ( Role < ROLE_Authority )
|
||||
return;
|
||||
|
||||
ShotgunJumpVolumeTimer = Spawn(class'VolumeTimer', self);
|
||||
}
|
||||
|
||||
simulated event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
|
||||
{
|
||||
local KFPawn_Human KFPH;
|
||||
local KFPlayerController KFPC;
|
||||
local KFTrackedController NewTrackedController;
|
||||
local int i;
|
||||
|
||||
KFPH = KFPawn_Human(Other);
|
||||
if (KFPH == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KFPC = KFPlayerController(KFPH.Controller);
|
||||
if (KFPC == none)
|
||||
return;
|
||||
|
||||
for (i = 0; i < TrackedControllers.Length; ++i)
|
||||
{
|
||||
if (TrackedControllers[i].KFPC == KFPC)
|
||||
{
|
||||
TrackedControllers[i].bInVolume = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Update current time
|
||||
NewTrackedController.KFPC = KFPC;
|
||||
NewTrackedController.bInVolume = true;
|
||||
|
||||
TrackedControllers.AddItem(NewTrackedController);
|
||||
}
|
||||
|
||||
simulated event Untouch(Actor Other)
|
||||
{
|
||||
local KFPawn_Human KFPH;
|
||||
local int i;
|
||||
local KFPlayerController KFPC;
|
||||
|
||||
KFPH = KFPawn_Human(Other);
|
||||
if (KFPH == none)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
KFPC = KFPlayerController(KFPH.Controller);
|
||||
if (KFPC == none)
|
||||
return;
|
||||
|
||||
for (i = 0; i < TrackedControllers.Length; ++i)
|
||||
{
|
||||
if (TrackedControllers[i].KFPC == KFPC)
|
||||
{
|
||||
TrackedControllers[i].ExitTimestamp = WorldInfo.TimeSeconds;
|
||||
TrackedControllers[i].bInVolume = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function TimerPop(VolumeTimer T)
|
||||
{
|
||||
local int i;
|
||||
|
||||
for (i = TrackedControllers.Length-1; i >= 0 ; --i)
|
||||
{
|
||||
if (!TrackedControllers[i].bInVolume && (`TimeSince(TrackedControllers[i].ExitTimestamp) >= TrackedPlayerLifetime) )
|
||||
{
|
||||
TrackedControllers.Remove(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function RemoveTrackedPlayer(KFPlayerController KFPC)
|
||||
{
|
||||
local int i;
|
||||
|
||||
for (i = TrackedControllers.Length-1; i >= 0 ; --i)
|
||||
{
|
||||
if (TrackedControllers[i].KFPC == KFPC)
|
||||
{
|
||||
TrackedControllers.Remove(i, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function bool IsPlayerTracked(KFPlayerController KFPC)
|
||||
{
|
||||
local KFTrackedController TrackedController;
|
||||
foreach TrackedControllers(TrackedController)
|
||||
{
|
||||
if (TrackedController.KFPC == KFPC)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DefaultProperties
|
||||
{
|
||||
TrackedPlayerLifetime = 1.0f;
|
||||
}
|
120
KFGameContent/Classes/KFWeapAttach_HRG_BallisticBouncer.uc
Normal file
120
KFGameContent/Classes/KFWeapAttach_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,120 @@
|
||||
//=============================================================================
|
||||
// KFWeapAttach_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
//
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeapAttach_HRG_BallisticBouncer extends KFWeaponAttachment;
|
||||
|
||||
var() StaticMesh ChargeStaticMesh;
|
||||
var transient StaticMeshComponent ChargeAttachment;
|
||||
var transient MaterialInstanceConstant ChargeMIC;
|
||||
|
||||
var float MinProjPlaceholderScale;
|
||||
var float MaxProjPlaceHolderScale;
|
||||
|
||||
var bool bIsCharging;
|
||||
var bool bIsFullyCharged;
|
||||
|
||||
var repnotify float StartFireTime;
|
||||
|
||||
var int ChargeLevel;
|
||||
|
||||
var float ChargeRTPC;
|
||||
|
||||
simulated function StartFire()
|
||||
{
|
||||
StartFireTime = WorldInfo.TimeSeconds;
|
||||
bIsCharging = true;
|
||||
|
||||
if (ChargeAttachment == none)
|
||||
{
|
||||
ChargeAttachment = new (self) class'StaticMeshComponent';
|
||||
ChargeAttachment.SetStaticMesh(ChargeStaticMesh);
|
||||
|
||||
if (WeapMesh != none)
|
||||
{
|
||||
WeapMesh.AttachComponentToSocket(ChargeAttachment, 'MuzzleFlash');
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachComponent(ChargeAttachment);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetScale(MinProjPlaceholderScale);
|
||||
ChargeAttachment.SetHidden(false);
|
||||
}
|
||||
}
|
||||
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
local float ChargeValue;
|
||||
|
||||
if(bIsCharging && !bIsFullyCharged)
|
||||
{
|
||||
ChargeValue = FMin(class'KFWeap_HRG_BallisticBouncer'.default.MaxChargeTime, WorldInfo.TimeSeconds - StartFireTime) / class'KFWeap_HRG_BallisticBouncer'.default.MaxChargeTime;
|
||||
|
||||
if (ChargeValue >= 1.0f)
|
||||
{
|
||||
bIsFullyCharged = true;
|
||||
ChargeValue = 1.0f;
|
||||
}
|
||||
|
||||
if( ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetScale(MinProjPlaceholderScale + (MaxProjPlaceHolderScale - MinProjPlaceholderScale) * ChargeValue);
|
||||
}
|
||||
}
|
||||
|
||||
Super.Tick(DeltaTime);
|
||||
}
|
||||
|
||||
simulated function FirstPersonFireEffects(Weapon W, vector HitLocation)
|
||||
{
|
||||
super.FirstPersonFireEffects(W, HitLocation);
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetHidden(true);
|
||||
}
|
||||
}
|
||||
|
||||
simulated function bool ThirdPersonFireEffects(vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte)
|
||||
{
|
||||
bIsCharging = false;
|
||||
bIsFullyCharged = false;
|
||||
ChargeRTPC=0;
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetHidden(true);
|
||||
}
|
||||
|
||||
return Super.ThirdPersonFireEffects(HitLocation, P, ThirdPersonAnimRateByte);
|
||||
}
|
||||
|
||||
simulated function CauseMuzzleFlash(byte FiringMode)
|
||||
{
|
||||
if (MuzzleFlash == None && MuzzleFlashTemplate != None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
Super.CauseMuzzleFlash(FiringMode);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ChargeRTPC=0
|
||||
MuzzleFlashTemplate=KFMuzzleFlash'WEP_Mine_Reconstructor_Arch.Wep_Mine_Reconstructor_MuzzleFlash_3P'
|
||||
|
||||
ChargeStaticMesh = StaticMesh'WEP_HRG_BallisticBouncer_EMIT.HRG_BallisticBouncer_ball_MESH'
|
||||
MinProjPlaceholderScale = 2.0f;
|
||||
MaxProjPlaceholderScale = 3.0f;
|
||||
}
|
@ -196,7 +196,7 @@ defaultproperties
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_Doshinegun_Shot'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.2
|
||||
Spread(DEFAULT_FIREMODE)=0.015
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=60.0 //55.0 //60.0
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=80 //60.0 //55.0 //60.0
|
||||
FireOffset=(X=30,Y=4.5,Z=-5)
|
||||
|
||||
// ALT_FIREMODE
|
||||
@ -206,7 +206,7 @@ defaultproperties
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Dosh'
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Bludgeon_Doshinegun_Shot'
|
||||
FireInterval(ALTFIRE_FIREMODE)=+0.2
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=60.0 //55.0 //60.0
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=80 //60.0 //55.0 //60.0
|
||||
Spread(ALTFIRE_FIREMODE)=0.015
|
||||
|
||||
// BASH_FIREMODE
|
||||
@ -239,7 +239,7 @@ defaultproperties
|
||||
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.47f), (Stat=EWUS_Damage1, Scale=1.47f), (Stat=EWUS_Weight, Add=2)))
|
||||
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.70f), (Stat=EWUS_Damage1, Scale=1.70f), (Stat=EWUS_Weight, Add=3)))
|
||||
|
||||
DoshCost = 20; //25;
|
||||
DoshCost = 10 //20; //25;
|
||||
bUsesSecondaryAmmoAltHUD=true
|
||||
bAllowClientAmmoTracking=false
|
||||
bIsBeingDropped=false
|
||||
|
@ -142,7 +142,7 @@ defaultproperties
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Grenade_GravityImploder'
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpact'
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=150
|
||||
FireInterval(DEFAULT_FIREMODE)=1.33 //45 RPM
|
||||
FireInterval(DEFAULT_FIREMODE)=1 // 60 RPM //1.33 //45 RPM
|
||||
Spread(DEFAULT_FIREMODE)=0.02 //0
|
||||
PenetrationPower(DEFAULT_FIREMODE)=0
|
||||
FireOffset=(X=25,Y=3.0,Z=-2.5)
|
||||
@ -152,7 +152,7 @@ defaultproperties
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Grenade_GravityImploderAlt'
|
||||
FireInterval(ALTFIRE_FIREMODE)=1.33 //45 RPM
|
||||
FireInterval(ALTFIRE_FIREMODE)=1 // 60 RPM //1.33 //45 RPM
|
||||
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpactAlt'
|
||||
InstantHitDamage(ALTFIRE_FIREMODE)=200
|
||||
Spread(ALTFIRE_FIREMODE)=0.02 //0.0085
|
||||
|
766
KFGameContent/Classes/KFWeap_HRG_BallisticBouncer.uc
Normal file
766
KFGameContent/Classes/KFWeap_HRG_BallisticBouncer.uc
Normal file
@ -0,0 +1,766 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_BallisticBouncer
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
class KFWeap_HRG_BallisticBouncer extends KFWeapon;
|
||||
|
||||
//Props related to charging the weapon
|
||||
var float MaxChargeTime;
|
||||
var float ValueIncreaseTime;
|
||||
var float DmgIncreasePerCharge;
|
||||
var float AOEIncreasePerCharge;
|
||||
var float IncapIncreasePerCharge;
|
||||
var int AmmoIncreasePerCharge;
|
||||
|
||||
var transient float ChargeTime;
|
||||
var transient float ConsumeAmmoTime;
|
||||
var transient float MaxChargeLevel;
|
||||
|
||||
var ParticleSystem ChargedEffect;
|
||||
|
||||
var transient ParticleSystemComponent FullyChargedPSC;
|
||||
var transient bool bIsFullyCharged;
|
||||
|
||||
var const WeaponFireSndInfo FullyChargedSound;
|
||||
|
||||
var float FullChargedTimerInterval;
|
||||
var float FXScalingFactorByCharge, ChargePercentage;
|
||||
var float MinScale, MaxScale;
|
||||
|
||||
var int MaxDamageByCharge;
|
||||
var int MinDamageByCharge;
|
||||
|
||||
const SecondaryFireAnim = 'Alt_Fire';
|
||||
const SecondaryFireIronAnim = 'Alt_Fire_Iron';
|
||||
const SecondaryFireAnimEmpty = 'Alt_Fire_Empty';
|
||||
const SecondaryFireIronAnimEmpty = 'Alt_Fire_Iron_Empty';
|
||||
var bool bHasToLaunchEmptyAnim;
|
||||
|
||||
var SkelControlSingleBone Control;
|
||||
|
||||
var bool bBlocked;
|
||||
|
||||
var() StaticMesh ChargeStaticMesh;
|
||||
var transient StaticMeshComponent ChargeAttachment;
|
||||
var transient MaterialInstanceConstant ChargeMIC;
|
||||
|
||||
var float MinProjPlaceholderScale;
|
||||
var float MaxProjPlaceHolderScale;
|
||||
|
||||
Replication
|
||||
{
|
||||
if(Role == Role_Authority && bNetDirty)
|
||||
ChargeTime;
|
||||
}
|
||||
|
||||
simulated event PostInitAnimTree( SkeletalMeshComponent SkelComp )
|
||||
{
|
||||
local vector vec;
|
||||
local float fPercentage;
|
||||
|
||||
super.PostInitAnimTree( SkelComp );
|
||||
|
||||
Control = SkelControlSingleBone( SkelComp.FindSkelControl('AmmoControl') );
|
||||
if( Control != none )
|
||||
{
|
||||
Control.SetSkelControlActive( true );
|
||||
}
|
||||
|
||||
//from 0 to -8
|
||||
// If AmmoCount is being replicated, don't allow the client to modify it here
|
||||
fPercentage = FMin((float(AmmoCount[0])/(MagazineCapacity[0])), 1);
|
||||
vec.X = Control.BoneTranslation.X;
|
||||
vec.Y = Control.BoneTranslation.Y;
|
||||
vec.Z = Lerp(-8, 0, fPercentage);
|
||||
Control.BoneTranslation = vec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Weapon::ConsumeAmmo
|
||||
*/
|
||||
simulated function ConsumeAmmo(byte FireModeNum)
|
||||
{
|
||||
local vector vec;
|
||||
local float fPercentage;
|
||||
|
||||
//from 0 to -8
|
||||
// If AmmoCount is being replicated, don't allow the client to modify it here
|
||||
if (Role == ROLE_Authority)
|
||||
{
|
||||
fPercentage = FMin(float(AmmoCount[0])/(MagazineCapacity[0]), 1);
|
||||
super.ConsumeAmmo(FireModeNum);
|
||||
|
||||
if(Control != none)
|
||||
{
|
||||
vec.X = Control.BoneTranslation.X;
|
||||
vec.Y = Control.BoneTranslation.Y;
|
||||
vec.Z = Lerp(-8, 0, fPercentage);
|
||||
Control.BoneTranslation = vec;
|
||||
}
|
||||
|
||||
//Notify the client about the new percentage as the client is not tracking the ammo
|
||||
ClientUpdateVisualAmmo(fPercentage);
|
||||
}
|
||||
}
|
||||
|
||||
reliable client function ClientUpdateVisualAmmo(float BoneControlTranslation)
|
||||
{
|
||||
local vector vec;
|
||||
|
||||
if ( Role < ROLE_Authority && Control != none )
|
||||
{
|
||||
vec.X = Control.BoneTranslation.X;
|
||||
vec.Y = Control.BoneTranslation.Y;
|
||||
vec.Z = Lerp(-8, 0, BoneControlTranslation);
|
||||
Control.BoneTranslation = vec;
|
||||
}
|
||||
}
|
||||
|
||||
simulated function StartFire(byte FiremodeNum)
|
||||
{
|
||||
if (IsTimerActive('RefireCheckTimer') || bBlocked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(Role != Role_Authority && FireModeNum == DEFAULT_FIREMODE && HasAmmo(DEFAULT_FIREMODE))
|
||||
{
|
||||
bBlocked = true;
|
||||
if(IsTimerActive(nameof(UnlockClientFire)))
|
||||
{
|
||||
ClearTimer(nameof(UnlockClientFire));
|
||||
}
|
||||
}
|
||||
|
||||
super.StartFire(FiremodeNum);
|
||||
|
||||
if ( PendingFire(RELOAD_FIREMODE) && Role != Role_Authority)
|
||||
{
|
||||
bBlocked = false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
simulated function RefireCheckTimer()
|
||||
{
|
||||
Super.RefireCheckTimer();
|
||||
if(bBlocked && Role != Role_Authority)
|
||||
{
|
||||
SetTimer(0.25f , false, nameof(UnlockClientFire));
|
||||
}
|
||||
}
|
||||
|
||||
reliable client function UnlockClientFire()
|
||||
{
|
||||
bBlocked = false;
|
||||
}
|
||||
|
||||
simulated function OnStartFire()
|
||||
{
|
||||
local KFPawn PawnInst;
|
||||
PawnInst = KFPawn(Instigator);
|
||||
|
||||
if (PawnInst != none)
|
||||
{
|
||||
PawnInst.OnStartFire();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
simulated function FireAmmunition()
|
||||
{
|
||||
// Let the accuracy tracking system know that we fired
|
||||
HandleWeaponShotTaken(CurrentFireMode);
|
||||
|
||||
// Handle the different fire types
|
||||
switch (WeaponFireTypes[CurrentFireMode])
|
||||
{
|
||||
case EWFT_InstantHit:
|
||||
// Launch a projectile if we are in zed time, and this weapon has a projectile to launch for this mode
|
||||
if (`IsInZedTime(self) && WeaponProjectiles[CurrentFireMode] != none )
|
||||
{
|
||||
ProjectileFire();
|
||||
}
|
||||
else
|
||||
{
|
||||
InstantFireClient();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EWFT_Projectile:
|
||||
ProjectileFire();
|
||||
break;
|
||||
|
||||
case EWFT_Custom:
|
||||
CustomFire();
|
||||
break;
|
||||
}
|
||||
|
||||
//// If we're firing without charging, still consume one ammo
|
||||
if (GetChargeLevel() < 1)
|
||||
{
|
||||
ConsumeAmmo(CurrentFireMode);
|
||||
}
|
||||
|
||||
NotifyWeaponFired(CurrentFireMode);
|
||||
|
||||
// Play fire effects now (don't wait for WeaponFired to replicate)
|
||||
PlayFireEffects(CurrentFireMode, vect(0, 0, 0));
|
||||
}
|
||||
|
||||
simulated function ANIMNOTIFY_FILLMAG()
|
||||
{
|
||||
local vector vec;
|
||||
|
||||
if (Control != none)
|
||||
{
|
||||
vec.X = Control.BoneTranslation.X;
|
||||
vec.Y = Control.BoneTranslation.Y;
|
||||
vec.Z = 0;
|
||||
Control.BoneTranslation = vec;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Weapon::HasAmmo
|
||||
*/
|
||||
simulated event bool HasAmmo( byte FireModeNum, optional int Amount )
|
||||
{
|
||||
local KFPerk InstigatorPerk;
|
||||
// we can always do a melee attack
|
||||
if( FireModeNum == BASH_FIREMODE )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if ( FireModeNum == RELOAD_FIREMODE )
|
||||
{
|
||||
return CanReload();
|
||||
}
|
||||
else if ( FireModeNum == GRENADE_FIREMODE )
|
||||
{
|
||||
if( KFInventoryManager(InvManager) != none )
|
||||
{
|
||||
return KFInventoryManager(InvManager).HasGrenadeAmmo(Amount);
|
||||
}
|
||||
}
|
||||
|
||||
InstigatorPerk = GetPerk();
|
||||
if( InstigatorPerk != none && InstigatorPerk.GetIsUberAmmoActive( self ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If passed in ammo isn't set, use default ammo cost.
|
||||
if( Amount == 0 )
|
||||
{
|
||||
Amount = AmmoCost[FireModeNum];
|
||||
}
|
||||
|
||||
return AmmoCount[GetAmmoType(FireModeNum)] >= Amount;
|
||||
}
|
||||
|
||||
simulated state MineReconstructorCharge extends WeaponFiring
|
||||
{
|
||||
//For minimal code purposes, I'll directly call global.FireAmmunition after charging is released
|
||||
simulated function FireAmmunition()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Store start fire time so we don't have to timer this
|
||||
simulated event BeginState(Name PreviousStateName)
|
||||
{
|
||||
local KFPerk InstigatorPerk;
|
||||
|
||||
super.BeginState(PreviousStateName);
|
||||
|
||||
InstigatorPerk = GetPerk();
|
||||
if( InstigatorPerk != none )
|
||||
{
|
||||
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
|
||||
}
|
||||
|
||||
ChargeTime = 0;
|
||||
ConsumeAmmoTime = 0;
|
||||
MaxChargeLevel = int(MaxChargeTime / ValueIncreaseTime);
|
||||
|
||||
if (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone)
|
||||
{
|
||||
if (ChargeAttachment == none)
|
||||
{
|
||||
ChargeAttachment = new (self) class'StaticMeshComponent';
|
||||
|
||||
// ChargeAttachment.SetActorCollision(false, false);
|
||||
ChargeAttachment.SetStaticMesh(ChargeStaticMesh);
|
||||
// ChargeAttachment.SetShadowParent(Mesh);
|
||||
|
||||
ChargeMIC = ChargeAttachment.CreateAndSetMaterialInstanceConstant(0);
|
||||
|
||||
MySkelMesh.AttachComponentToSocket(ChargeAttachment, 'MuzzleFlash');
|
||||
|
||||
ChargeAttachment.SetHidden(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
ChargeAttachment.SetStaticMesh(ChargeStaticMesh);
|
||||
}
|
||||
}
|
||||
|
||||
bIsFullyCharged = false;
|
||||
|
||||
global.OnStartFire();
|
||||
|
||||
ChargeTime = 0;
|
||||
FXScalingFactorByCharge = 0;
|
||||
}
|
||||
|
||||
simulated function bool ShouldRefire()
|
||||
{
|
||||
// ignore how much ammo is left (super/global counts ammo)
|
||||
return StillFiring(CurrentFireMode);
|
||||
}
|
||||
|
||||
simulated event Tick(float DeltaTime)
|
||||
{
|
||||
local float ChargeRTPC;
|
||||
local float InstantHitDamageValue;
|
||||
local float NewScale;
|
||||
|
||||
global.Tick(DeltaTime);
|
||||
|
||||
if (ChargeAttachment != none && ChargeAttachment.StaticMesh == none)
|
||||
{
|
||||
ChargeAttachment.SetStaticMesh(ChargeStaticMesh);
|
||||
}
|
||||
|
||||
if(bIsFullyCharged) return;
|
||||
|
||||
// Don't charge unless we're holding down the button
|
||||
if (PendingFire(CurrentFireMode))
|
||||
{
|
||||
ConsumeAmmoTime += DeltaTime;
|
||||
}
|
||||
|
||||
if (bIsFullyCharged)
|
||||
{
|
||||
if (ConsumeAmmoTime >= FullChargedTimerInterval)
|
||||
{
|
||||
ConsumeAmmo(DEFAULT_FIREMODE);
|
||||
ConsumeAmmoTime -= FullChargedTimerInterval;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't charge unless we're holding down the button
|
||||
if (PendingFire(CurrentFireMode))
|
||||
{
|
||||
if(Role == Role_Authority && !bIsFullyCharged)
|
||||
{
|
||||
ChargeTime += DeltaTime;
|
||||
bNetDirty = true;
|
||||
}
|
||||
|
||||
ChargePercentage = FMin(ChargeTime / MaxChargeTime, 1);
|
||||
|
||||
if (ChargeAttachment != none && !bIsFullyCharged)
|
||||
{
|
||||
FXScalingFactorByCharge = FMin(Lerp(MinScale, MaxScale, ChargeTime / MaxChargeTime), MaxScale);
|
||||
|
||||
if(ChargePercentage < 0.1f)
|
||||
{
|
||||
InstantHitDamageValue = Lerp(MinDamageByCharge, MaxDamageByCharge, 0.1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
InstantHitDamageValue = Lerp(MinDamageByCharge, MaxDamageByCharge, ChargePercentage);
|
||||
}
|
||||
InstantHitDamage[DEFAULT_FIREMODE] = InstantHitDamageValue;
|
||||
|
||||
NewScale = Lerp(MinProjPlaceholderScale, MaxProjPlaceholderScale, ChargePercentage);
|
||||
|
||||
ChargeAttachment.SetHidden(false);
|
||||
ChargeAttachment.SetScale( NewScale );
|
||||
|
||||
if (ChargeMIC != none)
|
||||
{
|
||||
// Change Color
|
||||
ChargeMIC.SetScalarParameterValue('Charge', ChargePercentage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChargeRTPC = FMin(ChargeTime / MaxChargeTime, 1.f);
|
||||
KFPawn(Instigator).SetWeaponComponentRTPCValue("Weapon_Charge", ChargeRTPC); //For looping component
|
||||
Instigator.SetRTPCValue('Weapon_Charge', ChargeRTPC); //For one-shot sounds
|
||||
|
||||
if (ConsumeAmmoTime >= ValueIncreaseTime && !bIsFullyCharged)
|
||||
{
|
||||
ConsumeAmmo(DEFAULT_FIREMODE);
|
||||
ConsumeAmmoTime -= ValueIncreaseTime;
|
||||
}
|
||||
|
||||
if (ChargeTime >= MaxChargeTime || !HasAmmo(DEFAULT_FIREMODE))
|
||||
{
|
||||
bIsFullyCharged = true;
|
||||
|
||||
if(( Instigator.Role != ROLE_Authority ) || WorldInfo.NetMode == NM_Standalone)
|
||||
{
|
||||
if (FullyChargedPSC == none)
|
||||
{
|
||||
FullyChargedPSC = new(self) class'ParticleSystemComponent';
|
||||
|
||||
if(MySkelMesh != none)
|
||||
{
|
||||
MySkelMesh.AttachComponentToSocket(FullyChargedPSC, 'MuzzleFlash');
|
||||
}
|
||||
else
|
||||
{
|
||||
AttachComponent(FullyChargedPSC);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FullyChargedPSC.ActivateSystem();
|
||||
}
|
||||
|
||||
FullyChargedPSC.SetTemplate(ChargedEffect);
|
||||
|
||||
|
||||
KFPawn(Instigator).SetWeaponAmbientSound(FullyChargedSound.DefaultCue, FullyChargedSound.FirstPersonCue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Now that we're done charging, directly call FireAmmunition. This will handle the actual projectile fire and scaling.
|
||||
simulated event EndState(Name NextStateName)
|
||||
{
|
||||
if(Role == Role_Authority)
|
||||
{
|
||||
UnlockClientFire();
|
||||
}
|
||||
|
||||
ClearZedTimeResist();
|
||||
ClearPendingFire(CurrentFireMode);
|
||||
ClearTimer(nameof(RefireCheckTimer));
|
||||
|
||||
KFPawn(Instigator).bHasStartedFire = false;
|
||||
KFPawn(Instigator).bNetDirty = true;
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetHidden(true);
|
||||
ChargeAttachment.SetScale(MinProjPlaceholderScale);
|
||||
}
|
||||
|
||||
if (FullyChargedPSC != none)
|
||||
{
|
||||
FullyChargedPSC.DeactivateSystem();
|
||||
}
|
||||
|
||||
KFPawn(Instigator).SetWeaponAmbientSound(none);
|
||||
}
|
||||
|
||||
simulated function HandleFinishedFiring()
|
||||
{
|
||||
global.FireAmmunition();
|
||||
|
||||
if (bPlayingLoopingFireAnim)
|
||||
{
|
||||
StopLoopingFireEffects(CurrentFireMode);
|
||||
}
|
||||
|
||||
SetTimer(0.1f, false, 'Timer_StopFireEffects');
|
||||
|
||||
NotifyWeaponFinishedFiring(CurrentFireMode);
|
||||
|
||||
super.HandleFinishedFiring();
|
||||
//`Log("ChargePercentage"@ChargePercentage);
|
||||
}
|
||||
|
||||
simulated function PutDownWeapon()
|
||||
{
|
||||
global.FireAmmunition();
|
||||
|
||||
if (bPlayingLoopingFireAnim)
|
||||
{
|
||||
StopLoopingFireEffects(CurrentFireMode);
|
||||
}
|
||||
|
||||
SetTimer(0.1f, false, 'Timer_StopFireEffects');
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetHidden(true);
|
||||
ChargeAttachment.SetScale(MinProjPlaceholderScale);
|
||||
}
|
||||
|
||||
NotifyWeaponFinishedFiring(CurrentFireMode);
|
||||
|
||||
if(Role == Role_Authority)
|
||||
{
|
||||
UnlockClientFire();
|
||||
}
|
||||
|
||||
super.PutDownWeapon();
|
||||
}
|
||||
}
|
||||
|
||||
simulated function StopFireEffects(byte FireModeNum)
|
||||
{
|
||||
Super.StopFireEffects(FireModeNum);
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetStaticMesh(none); // if we don't do this it doesn't work ?!, when starting fire it assigns again so no problem..
|
||||
|
||||
ChargeAttachment.SetHidden(true);
|
||||
ChargeAttachment.SetScale(MinProjPlaceholderScale);
|
||||
}
|
||||
}
|
||||
|
||||
// Placing the actual Weapon Firing end state here since we need it to happen at the end of the actual firing loop.
|
||||
simulated function Timer_StopFireEffects()
|
||||
{
|
||||
// Simulate weapon firing effects on the local client
|
||||
if (WorldInfo.NetMode == NM_Client)
|
||||
{
|
||||
Instigator.WeaponStoppedFiring(self, false);
|
||||
|
||||
if (ChargeAttachment != none)
|
||||
{
|
||||
ChargeAttachment.SetHidden(true);
|
||||
}
|
||||
|
||||
if (FullyChargedPSC != none)
|
||||
{
|
||||
FullyChargedPSC.DeactivateSystem();
|
||||
}
|
||||
}
|
||||
|
||||
ClearFlashCount();
|
||||
ClearFlashLocation();
|
||||
}
|
||||
|
||||
simulated state Active
|
||||
{
|
||||
simulated function BeginState(name PreviousStateName)
|
||||
{
|
||||
Super.BeginState(PreviousStateName);
|
||||
if(Role == Role_Authority)
|
||||
{
|
||||
UnlockClientFire();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
simulated function KFProjectile SpawnProjectile(class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir)
|
||||
{
|
||||
local KFProj_HRG_BallisticBouncer BouncingProj;
|
||||
|
||||
BouncingProj = KFProj_HRG_BallisticBouncer(super.SpawnProjectile(KFProjClass, RealStartLoc, AimDir));
|
||||
//Calc and set scaling values
|
||||
if (BouncingProj != none)
|
||||
{
|
||||
ChargePercentage = FMax(0.1, ChargePercentage);
|
||||
FXScalingFactorByCharge = FMax(0.1, FXScalingFactorByCharge);
|
||||
BouncingProj.SetInheritedScale(FXScalingFactorByCharge, ChargePercentage);
|
||||
return BouncingProj;
|
||||
}
|
||||
return none;
|
||||
}
|
||||
|
||||
simulated function CauseMuzzleFlash(byte FireModeNum)
|
||||
{
|
||||
local vector vec;
|
||||
|
||||
if (MuzzleFlash == None)
|
||||
{
|
||||
AttachMuzzleFlash();
|
||||
}
|
||||
|
||||
if (MuzzleFlash != none)
|
||||
{
|
||||
vec.X = ChargePercentage;
|
||||
vec.Y = ChargePercentage;
|
||||
vec.Z = ChargePercentage;
|
||||
|
||||
MuzzleFlash.MuzzleFlash.PSC.SetVectorParameter(name("Charge"), vec);
|
||||
MuzzleFlash.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
|
||||
super.CauseMuzzleFlash(FireModeNum);
|
||||
}
|
||||
|
||||
simulated function int GetChargeLevel()
|
||||
{
|
||||
return Min(ChargeTime / ValueIncreaseTime, MaxChargeLevel);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
||||
PAWN ADJUST DAMAGE
|
||||
|
||||
****************************************************************/
|
||||
|
||||
// increase the instant hit damage based on the charge level
|
||||
simulated function int GetModifiedDamage(byte FireModeNum, optional vector RayDir)
|
||||
{
|
||||
local int ModifiedDamage;
|
||||
ModifiedDamage = super.GetModifiedDamage(FireModeNum, RayDir);
|
||||
return ModifiedDamage;
|
||||
}
|
||||
|
||||
state WeaponSingleFiring
|
||||
{
|
||||
/** Get whether we should play the reload anim as well or not */
|
||||
simulated function name GetWeaponFireAnim(byte FireModeNum)
|
||||
{
|
||||
if(bUsingSights)
|
||||
{
|
||||
return (bHasToLaunchEmptyAnim == false) ? SecondaryFireIronAnim : SecondaryFireIronAnimEmpty;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bHasToLaunchEmptyAnim == false) ? SecondaryFireIronAnim : SecondaryFireIronAnimEmpty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
//Gameplay Props
|
||||
MaxChargeTime=0.6
|
||||
AmmoIncreasePerCharge=1
|
||||
ValueIncreaseTime=0.1
|
||||
|
||||
//FOR LERPING DAMANGE
|
||||
MaxDamageByCharge=600
|
||||
MinDamageByCharge=60
|
||||
// FOV
|
||||
Meshfov=80
|
||||
MeshIronSightFOV=65 //52
|
||||
PlayerIronSightFOV=50 //80
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=150
|
||||
DOF_FG_MaxNearBlurSize=1
|
||||
|
||||
// Content
|
||||
PackageKey="HRG_BallisticBouncer"
|
||||
FirstPersonMeshName="wep_1p_hrg_ballisticbouncer_mesh.Wep_1stP_HRG_BallisticBouncer_Rig"
|
||||
FirstPersonAnimSetNames(0)="wep_1p_hrg_ballisticbouncer_anim.Wep_1stP_BallisticBouncer_Anim"
|
||||
PickupMeshName="wep_3p_hrg_ballisticbouncer_mesh.Wep_3rdP_HRG_BallisticBouncer_Pickup"
|
||||
AttachmentArchetypeName="wep_hrg_ballisticbouncer_arch.Wep_HRG_BallisticBouncer_3P"
|
||||
MuzzleFlashTemplateName="WEP_HRG_BallisticBouncer_ARCH.Wep_HRG_BallisticBouncer_MuzzleFlash"
|
||||
|
||||
Begin Object Name=FirstPersonMesh
|
||||
// new anim tree with skelcontrol to rotate cylinders
|
||||
AnimTreeTemplate=AnimTree'WEP_HRG_BallisticBouncer_ARCH.WEP_1stP_Animtree_HRG_BallisticBouncer'
|
||||
End Object
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=0.0,Y=12,Z=-1)
|
||||
IronSightPosition=(X=0,Y=0,Z=0)
|
||||
|
||||
// Controls the rotation when Hans(the bastard) grabs you
|
||||
QuickWeaponDownRotation=(Pitch=-19192,Yaw=-11500,Roll=16384) // (Pitch=-19192,Yaw=-11000,Roll=16384)
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=18
|
||||
SpareAmmoCapacity[0]=162
|
||||
InitialSpareMags[0]=3 //2
|
||||
AmmoPickupScale[0]=1.5 //1 //0.75
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=180
|
||||
minRecoilPitch=140
|
||||
maxRecoilYaw=150
|
||||
minRecoilYaw=-150
|
||||
RecoilRate=0.085
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=900
|
||||
RecoilMinPitchLimit=65035
|
||||
RecoilISMaxYawLimit=75
|
||||
RecoilISMinYawLimit=65460
|
||||
RecoilISMaxPitchLimit=375
|
||||
RecoilISMinPitchLimit=65460
|
||||
RecoilViewRotationScale=0.25
|
||||
IronSightMeshFOVCompensationScale=1.5
|
||||
HippedRecoilModifier=1.5
|
||||
|
||||
// Inventory
|
||||
InventorySize=5
|
||||
GroupPriority=80 //75
|
||||
WeaponSelectTexture=Texture2D'wep_ui_hrg_ballisticbouncer_tex.UI_WeaponSelect_HRG_BallisticBouncer'
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
//FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Grenade' //@TODO: Replace me
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_ShotgunSingle'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=MineReconstructorCharge
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_HRG_BallisticBouncer'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.223 //+0.33
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=100
|
||||
PenetrationPower(DEFAULT_FIREMODE)=0.0;
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Bludgeon_HRG_BallisticBouncer_Shot'
|
||||
FireOffset=(X=39,Y=4.5,Z=-10)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_None
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_BallisticBouncer'
|
||||
InstantHitDamage(BASH_FIREMODE)=27
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_3P_Start', FirstPersonCue=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_1P_Start')
|
||||
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_3P_Shoot', FirstPersonCue=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_1P_Shoot')
|
||||
FullyChargedSound=(DefaultCue = AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Charged_3P', FirstPersonCue=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_Charged')
|
||||
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_BallisticBouncer.Play_WEP_HRG_BallisticBouncer_DryFire'
|
||||
|
||||
// Advanced (High RPM) Fire Effects
|
||||
bLoopingFireAnim(DEFAULT_FIREMODE)=true
|
||||
bLoopingFireSnd(DEFAULT_FIREMODE)=true
|
||||
SingleFireSoundIndex=FIREMODE_NONE
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
AssociatedPerkClasses(0)= class'KFPerk_Support'
|
||||
|
||||
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Weak_Recoil'
|
||||
|
||||
ChargedEffect=ParticleSystem'WEP_HRG_BallisticBouncer_EMIT.FX_Mine_HRG_BallisticBouncer_FullCharge'
|
||||
|
||||
FullChargedTimerInterval=2.0f
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
//WeaponUpgrades[1]=(IncrementDamage=1.1f,IncrementWeight=1)
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
|
||||
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
|
||||
|
||||
FXScalingFactorByCharge = 0;
|
||||
MinScale=0.5
|
||||
MaxScale=1.5
|
||||
|
||||
bBlocked = false;
|
||||
|
||||
bAllowClientAmmoTracking = false;
|
||||
|
||||
ChargeStaticMesh = StaticMesh'WEP_HRG_BallisticBouncer_EMIT.HRG_BallisticBouncer_ball_MESH'
|
||||
MinProjPlaceholderScale = 2.0f;
|
||||
MaxProjPlaceholderScale = 3.0f;
|
||||
}
|
210
KFGameContent/Classes/KFWeap_HRG_MedicMissile.uc
Normal file
210
KFGameContent/Classes/KFWeap_HRG_MedicMissile.uc
Normal file
@ -0,0 +1,210 @@
|
||||
//=============================================================================
|
||||
// KFWeap_HRG_MedicMissile
|
||||
//=============================================================================
|
||||
// Killing Floor 2
|
||||
// Copyright (C) 2022 Tripwire Interactive LLC
|
||||
//=============================================================================
|
||||
|
||||
class KFWeap_HRG_MedicMissile extends KFWeap_GrenadeLauncher_Base;
|
||||
|
||||
/** Back blash explosion template. */
|
||||
var() GameExplosion ExplosionTemplate;
|
||||
|
||||
/** Holds an offest for spawning back blast effects. */
|
||||
var() vector BackBlastOffset;
|
||||
|
||||
/** Fires a projectile, but also does the back blast */
|
||||
simulated function CustomFire()
|
||||
{
|
||||
local KFExplosionActorReplicated ExploActor;
|
||||
local vector SpawnLoc;
|
||||
local rotator SpawnRot;
|
||||
|
||||
ProjectileFire();
|
||||
|
||||
if ( Instigator.Role < ROLE_Authority )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GetBackBlastLocationAndRotation(SpawnLoc, SpawnRot);
|
||||
|
||||
// explode using the given template
|
||||
ExploActor = Spawn(class'KFExplosionActorReplicated', self,, SpawnLoc, SpawnRot,, true);
|
||||
if (ExploActor != None)
|
||||
{
|
||||
ExploActor.InstigatorController = Instigator.Controller;
|
||||
ExploActor.Instigator = Instigator;
|
||||
|
||||
// So we get backblash decal from this explosion
|
||||
ExploActor.bTraceForHitActorWhenDirectionalExplosion = true;
|
||||
|
||||
ExploActor.Explode(ExplosionTemplate, vector(SpawnRot));
|
||||
}
|
||||
|
||||
if ( bDebug )
|
||||
{
|
||||
DrawDebugCone(SpawnLoc, vector(SpawnRot), ExplosionTemplate.DamageRadius, ExplosionTemplate.DirectionalExplosionAngleDeg * DegToRad,
|
||||
ExplosionTemplate.DirectionalExplosionAngleDeg * DegToRad, 16, MakeColor(64,64,255,0), TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the world location for spawning back blast and the direction to send the back blast in
|
||||
*/
|
||||
simulated function GetBackBlastLocationAndRotation(out vector BlastLocation, out rotator BlastRotation)
|
||||
{
|
||||
local vector X, Y, Z;
|
||||
local Rotator ViewRotation;
|
||||
|
||||
if( Instigator != none )
|
||||
{
|
||||
if( bUsingSights )
|
||||
{
|
||||
ViewRotation = Instigator.GetViewRotation();
|
||||
|
||||
// Add in the free-aim rotation
|
||||
if ( KFPlayerController(Instigator.Controller) != None )
|
||||
{
|
||||
ViewRotation += KFPlayerController(Instigator.Controller).WeaponBufferRotation;
|
||||
}
|
||||
|
||||
GetAxes(ViewRotation, X, Y, Z);
|
||||
|
||||
BlastRotation = Rotator(Vector(ViewRotation) * -1);
|
||||
BlastLocation = Instigator.GetWeaponStartTraceLocation() + X * BackBlastOffset.X;
|
||||
}
|
||||
else
|
||||
{
|
||||
ViewRotation = Instigator.GetViewRotation();
|
||||
|
||||
// Add in the free-aim rotation
|
||||
if ( KFPlayerController(Instigator.Controller) != None )
|
||||
{
|
||||
ViewRotation += KFPlayerController(Instigator.Controller).WeaponBufferRotation;
|
||||
}
|
||||
|
||||
BlastRotation = Rotator(Vector(ViewRotation) * -1);
|
||||
BlastLocation = Instigator.GetPawnViewLocation() + (BackBlastOffset >> ViewRotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Locks the bolt bone in place to the open position (Called by animnotify) */
|
||||
simulated function ANIMNOTIFY_LockBolt()
|
||||
{
|
||||
// Consider us empty after every shot so the rocket gets hidden
|
||||
EmptyMagBlendNode.SetBlendTarget(1, 0);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ForceReloadTime=0.4f
|
||||
|
||||
// Inventory
|
||||
InventoryGroup=IG_Primary
|
||||
GroupPriority=100
|
||||
InventorySize=7
|
||||
WeaponSelectTexture=Texture2D'WEP_UI_HRG_MedicMissile_TEX.UI_WeaponSelect_HRG_MedicMissile'
|
||||
|
||||
// FOV
|
||||
MeshFOV=75
|
||||
MeshIronSightFOV=65
|
||||
PlayerIronSightFOV=70
|
||||
PlayerSprintFOV=95
|
||||
|
||||
// Depth of field
|
||||
DOF_FG_FocalRadius=50
|
||||
DOF_FG_MaxNearBlurSize=2.5
|
||||
|
||||
// Zooming/Position
|
||||
PlayerViewOffset=(X=10.0,Y=10,Z=-2)
|
||||
FastZoomOutTime=0.2
|
||||
|
||||
// Content
|
||||
PackageKey="HRG_MedicMissile"
|
||||
FirstPersonMeshName="WEP_1P_HRG_MedicMissile_MESH.Wep_1stP_HRG_MedicMissile_Rig"
|
||||
FirstPersonAnimSetNames(0)="WEP_1P_HRG_MedicMissile_ANIM.Wep_1stP_HRG_MedicMissile_Anim"
|
||||
PickupMeshName="WEP_3P_HRG_MedicMissile_MESH.Wep_HRG_MedicMissile_Pickup"
|
||||
AttachmentArchetypeName="WEP_HRG_MedicMissile_ARCH.Wep_HRG_MedicMissile_3P"
|
||||
MuzzleFlashTemplateName="WEP_HRG_MedicMissile_ARCH.Wep_HRG_MedicMissile_MuzzleFlash"
|
||||
|
||||
// Zooming/Position
|
||||
IronSightPosition=(X=0,Y=0,Z=0)
|
||||
|
||||
// Ammo
|
||||
MagazineCapacity[0]=1
|
||||
SpareAmmoCapacity[0]=22
|
||||
InitialSpareMags[0]=6
|
||||
AmmoPickupScale[0]=4.0
|
||||
bCanBeReloaded=true
|
||||
bReloadFromMagazine=true
|
||||
|
||||
// Recoil
|
||||
maxRecoilPitch=800
|
||||
minRecoilPitch=675
|
||||
maxRecoilYaw=400
|
||||
minRecoilYaw=-400
|
||||
RecoilRate=0.085
|
||||
RecoilBlendOutRatio=0.35
|
||||
RecoilMaxYawLimit=500
|
||||
RecoilMinYawLimit=65035
|
||||
RecoilMaxPitchLimit=1500
|
||||
RecoilMinPitchLimit=64785
|
||||
RecoilISMaxYawLimit=50
|
||||
RecoilISMinYawLimit=65485
|
||||
RecoilISMaxPitchLimit=500
|
||||
RecoilISMinPitchLimit=65485
|
||||
RecoilViewRotationScale=0.8
|
||||
FallingRecoilModifier=1.5
|
||||
HippedRecoilModifier=1.25
|
||||
|
||||
// DEFAULT_FIREMODE
|
||||
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'UI_FireModes_TEX.UI_FireModeSelect_Rocket'
|
||||
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFireAndReload
|
||||
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Custom
|
||||
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Rocket_HRG_MedicMissile'
|
||||
FireInterval(DEFAULT_FIREMODE)=+0.25
|
||||
InstantHitDamage(DEFAULT_FIREMODE)=100.0
|
||||
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_MedicMissile'
|
||||
Spread(DEFAULT_FIREMODE)=0.025
|
||||
FireOffset=(X=20,Y=4.0,Z=-3)
|
||||
BackBlastOffset=(X=-20,Y=4.0,Z=-3)
|
||||
|
||||
// ALT_FIREMODE
|
||||
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
|
||||
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_None
|
||||
|
||||
// Back blash explosion settings. Using archetype so that clients can serialize the content
|
||||
// without loading the 1st person weapon content (avoid 'Begin Object')!
|
||||
ExplosionTemplate=KFGameExplosion'WEP_HRG_MedicMissile_ARCH.Wep_HRG_MedicMissile_BackBlastExplosion'
|
||||
|
||||
// BASH_FIREMODE
|
||||
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_MedicMissile'
|
||||
InstantHitDamage(BASH_FIREMODE)=27
|
||||
|
||||
// Fire Effects
|
||||
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_MedicMissile.Play_WEP_HRG_MedicMissile_3P_Shoot', FirstPersonCue=AkEvent'WW_WEP_HRG_MedicMissile.Play_WEP_HRG_MedicMissile_1P_Shoot')
|
||||
|
||||
//@todo: add akevent when we have it
|
||||
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_MedicMissile.Play_WEP_HRG_MedicMissile_DryFire'
|
||||
|
||||
// Animation
|
||||
bHasFireLastAnims=true
|
||||
IdleFidgetAnims=(Guncheck_v1, Guncheck_v2)
|
||||
|
||||
BonesToLockOnEmpty=(RW_Grenade1)
|
||||
|
||||
// Attachments
|
||||
bHasIronSights=true
|
||||
bHasFlashlight=false
|
||||
|
||||
AssociatedPerkClasses(0)=class'KFPerk_FieldMedic'
|
||||
|
||||
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Heavy_Recoil_SingleShot'
|
||||
|
||||
// Weapon Upgrade stat boosts
|
||||
//WeaponUpgrades[1]=(IncrementDamage=1.1f,IncrementWeight=1)
|
||||
|
||||
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.1f), (Stat=EWUS_Weight, Add=1)))
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user