1
0
This commit is contained in:
GenZmeY 2022-11-28 00:49:25 +03:00
parent 2893490576
commit ea1d43f08f
106 changed files with 5944 additions and 303 deletions

View File

@ -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
}

View File

@ -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);
}
/**

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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)
{

View File

@ -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();

View File

@ -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);
}

View File

@ -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))
{

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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()

View 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'
}

View 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'
}

View File

@ -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 );
}

View File

@ -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
}

View File

@ -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;

View File

@ -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 )

View File

@ -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'))

View File

@ -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;
@ -491,4 +517,4 @@ cpptext
{
UBOOL CheckPingRange(INT index, INT ping) const;
}
}

View File

@ -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)) );
@ -153,4 +158,4 @@ function string GetMapSource(string MapName)
return "img://" $MapData.ScreenshotPathName;
}
}
}
}

View File

@ -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");

View File

@ -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);

View File

@ -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
}

View File

@ -182,7 +182,7 @@ function FillWhatsNew()
local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_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");

View File

@ -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())
{
@ -292,9 +307,7 @@ function FilterWeeklyMaps(out array<string> List)
if (WeeklyIndex == 14)
{
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;

View File

@ -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
}

View File

@ -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);
}
}

View 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
}

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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 )
{
@ -92,14 +98,25 @@ static function ClientReceive(
TeamIndex = TeamInfo.TeamIndex;
}
}
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:

View File

@ -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"))
}

View File

@ -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,7 +2322,10 @@ 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
/*DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_VersusDamage,ObjectiveClasses=(KFPawn_ZedClot_Alpha, KFPawn_ZedClot_Alpha_Versus),CompletionAmount=1))

View File

@ -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)))
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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 )
{

View File

@ -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;
}

View File

@ -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
*

View File

@ -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
}

View File

@ -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
}

View File

@ -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))))

View File

@ -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
}

View File

@ -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);

View File

@ -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)}
}

View File

@ -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

View 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
}

View 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
}

View 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
}

View 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
}

View File

@ -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
*********************************************************************************************/

View File

@ -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) );
}
}
/**

View File

@ -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"))
}

View File

@ -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
{

View File

@ -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 */

View File

@ -79,4 +79,5 @@ const KFID_SurvivalStartingGrenIdx=180; // Summer 2022 QoL: added option to choo
const KFID_MouseLookUpScale=181; // Halloweeen 2022 QoL: added mouse options to menu
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_ViewAccelerationEnabled=184; // Halloweeen 2022 QoL: added mouse options to menu
const KFID_SavedAllowSeasonalSkinsIndex=185;

View 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'
}

View 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'
}

View 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'
}

View File

@ -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'
}

View 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'
}

View 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'
}

View 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'
}

View 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'
}

View 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'
}

View 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'
}

View 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'
}

View 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;
}

View 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
}

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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

View 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'
}

View 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'
}

View File

@ -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()

View File

@ -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();
}

View 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'
}

View 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
}

View 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
}

View 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
}

View 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
}

View 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;
}

View 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;
}

View File

@ -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

View File

@ -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

View 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;
}

View 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