1
0

Merge branch 'preview'

This commit is contained in:
GenZmeY 2021-10-05 20:46:47 +03:00
commit 248ed28e6d
92 changed files with 5114 additions and 155 deletions

View File

@ -30,6 +30,8 @@ var int PrevArmor;
var int CostPerAutofillCycle; var int CostPerAutofillCycle;
var int DoshBuffer; var int DoshBuffer;
var int ArmorMagSize; // Percentage of armor bought individually
function Initialize(optional bool bInitOwnedItems = true) function Initialize(optional bool bInitOwnedItems = true)
{ {
if( Pawn != none && PlayerReplicationInfo != none ) if( Pawn != none && PlayerReplicationInfo != none )
@ -431,13 +433,18 @@ function bool UpgradeWeapon(int OwnedItemIndex)
*******************/ *******************/
function int GetFillArmorCost() function int GetFillArmorCost()
{ {
local float ArmorPercentage, FillCost, ArmorPricePerPercent; // local float ArmorPercentage, FillCost, ArmorPricePerPercent;
ArmorPercentage = (float(ArmorItem.MaxSpareAmmo - ArmorItem.SpareAmmoCount) / float(ArmorItem.MaxSpareAmmo)) * 100.f; // ArmorPercentage = (float() / float(ArmorItem.MaxSpareAmmo)) * 100.f;
ArmorPricePerPercent = ArmorItem.AmmoPricePerMagazine; // ArmorPricePerPercent = ArmorItem.AmmoPricePerMagazine;
FillCost = FCeil( ArmorPercentage * ArmorPricePerPercent ); // FillCost = FCeil( (ArmorItem.SpareAmmoCount - ArmorItem.MaxSpareAmmo) * ArmorItem.AmmoPricePerMagazine );
return FillCost; return FCeil( (ArmorItem.MaxSpareAmmo - ArmorItem.SpareAmmoCount) * ArmorItem.AmmoPricePerMagazine );
}
function int GetChunkArmorCost()
{
return FCeil ( FMin(ArmorItem.MaxSpareAmmo - ArmorItem.SpareAmmoCount, ArmorMagSize) * ArmorItem.AmmoPricePerMagazine );
} }
function int FillArmor( ) function int FillArmor( )
@ -470,29 +477,72 @@ function int FillArmor( )
return FillCost; return FillCost;
} }
function int BuyArmorMag( )
{
local float ArmorPricePerPercent;
local float ChunkCost;
local float ArmorAvailable;
local float PercentArmorBought;
local float ArmorAmmountBought;
ArmorAvailable = (1 - float(ArmorItem.SpareAmmoCount) / ArmorItem.MaxSpareAmmo) * 100;
ArmorAmmountBought = ArmorMagSize;
PercentArmorBought = ArmorMagSize * 100.0f / ArmorItem.MaxSpareAmmo;
if (ArmorAvailable < PercentArmorBought)
return FillArmor();
ChunkCost = ArmorAmmountBought * ArmorItem.AmmoPricePerMagazine;
// Buy as much armor as we possibly can
if (ChunkCost > TotalDosh)
{
ArmorPricePerPercent = ArmorItem.AmmoPricePerMagazine;
// Because we are using ints this will round down and we can get how much we actually spent
PercentArmorBought = TotalDosh / ArmorPricePerPercent;
ChunkCost = ArmorPricePerPercent * PercentArmorBought;
ArmorAmmountBought = ArmorItem.MaxSpareAmmo * PercentArmorBought / 100;
}
PercentArmorBought = (PercentArmorBought > 0.f && PercentArmorBought < 1.f) ? 1.f : PercentArmorBought;
ArmorItem.SpareAmmoCount = FMin(ArmorItem.SpareAmmoCount + ArmorAmmountBought, ArmorItem.MaxSpareAmmo);
BoughtAmmo(PercentArmorBought, ChunkCost, EIT_Armor);
return ChunkCost;
}
function bool AttemptBuyArmorChunk( out int InAutoFillDosh ) function bool AttemptBuyArmorChunk( out int InAutoFillDosh )
{ {
local float ArmorPricePerPercent, ChunkCost; local float PercentArmorBought;
local int PercentArmorBought; local int ArmorPricePerPercent;
local int ChunkCost;
local int ActualArmorPointsAvailable;
ActualArmorPointsAvailable = ArmorItem.MaxSpareAmmo - ArmorItem.SpareAmmoCount;
ArmorPricePerPercent = ArmorItem.AmmoPricePerMagazine; ArmorPricePerPercent = ArmorItem.AmmoPricePerMagazine;
PercentArmorBought = 0; PercentArmorBought = 0;
if( ArmorItem.SpareAmmoCount < ArmorItem.MaxSpareAmmo ) if( ArmorItem.SpareAmmoCount < ArmorItem.MaxSpareAmmo )
{ {
// Because we are using int's this will round down and we can get how much we actually spent // Because we are using int's this will round down and we can get how much we actually spent
PercentArmorBought = CostPerAutofillCycle / ArmorPricePerPercent; PercentArmorBought = FMin(CostPerAutofillCycle / ArmorPricePerPercent, float(ActualArmorPointsAvailable));
ChunkCost = ArmorPricePerPercent * PercentArmorBought; ChunkCost = ArmorPricePerPercent * PercentArmorBought;
if( InAutoFillDosh < ChunkCost ) if( InAutoFillDosh < ChunkCost )
{ {
PercentArmorBought = InAutoFillDosh / ArmorPricePerPercent; PercentArmorBought = FMin(InAutoFillDosh / ArmorPricePerPercent, float(ActualArmorPointsAvailable));
ChunkCost = ArmorPricePerPercent * PercentArmorBought; ChunkCost = ArmorPricePerPercent * PercentArmorBought;
} }
InAutoFillDosh -= ChunkCost; InAutoFillDosh -= ChunkCost;
ArmorItem.SpareAmmoCount = FMin(ArmorItem.SpareAmmoCount + PercentArmorBought, ArmorItem.MaxSpareAmmo); PercentArmorBought = (PercentArmorBought > 0.f && PercentArmorBought < 1.f) ? 1.f : PercentArmorBought;
ArmorItem.SpareAmmoCount = FMin(ArmorItem.SpareAmmoCount + (PercentArmorBought / 100.f * ArmorItem.MaxSpareAmmo), ArmorItem.MaxSpareAmmo);
BoughtAmmo(PercentArmorBought, ChunkCost, EIT_Armor); BoughtAmmo(PercentArmorBought, ChunkCost, EIT_Armor);
} }
return (PercentArmorBought > 0); return (PercentArmorBought > 0);
} }
@ -1429,4 +1479,5 @@ DefaultProperties
//defaults //defaults
CostPerAutofillCycle=10 CostPerAutofillCycle=10
DoshBuffer=150 DoshBuffer=150
ArmorMagSize=25.0f;
} }

View File

@ -192,6 +192,11 @@ var(FaveWeapons) editoronly class<KFWeaponDefinition> FavoriteWeaponClassDefs[NU
/************************************************************************/ /************************************************************************/
var Animset EmoteAnimset; var Animset EmoteAnimset;
/************************************************************************/
/* Wild West London Weekly */
/************************************************************************/
var transient LinearColor WWLHatMonoChromeValue;
var transient LinearColor WWLHatColorValue;
/************************************************************************/ /************************************************************************/
/* Native Functions */ /* Native Functions */
@ -771,6 +776,44 @@ protected simulated function SetAttachmentSkinMaterial(
} }
} }
protected simulated function SetWeeklyCowboyAttachmentSkinMaterial(
int PawnAttachmentIndex,
const out AttachmentVariants CurrentVariant,
byte NewSkinIndex,
KFPawn KFP,
optional bool bIsFirstPerson)
{
local MaterialInstanceConstant MIC;
if (KFP.WorldInfo.NetMode != NM_DedicatedServer)
{
if (bIsFirstPerson)
{
if (KFP.FirstPersonAttachments[PawnAttachmentIndex] != none)
{
KFP.FirstPersonAttachments[PawnAttachmentIndex].SetMaterial(
CurrentVariant.AttachmentItem.SkinMaterialID,
CurrentVariant.AttachmentItem.SkinVariations[0].Skin1p);
MIC = MaterialInstanceConstant(KFP.FirstPersonAttachments[PawnAttachmentIndex].GetMaterial(0));
}
}
else
{
KFP.ThirdPersonAttachments[PawnAttachmentIndex].SetMaterial(
CurrentVariant.AttachmentItem.SkinMaterialID,
CurrentVariant.AttachmentItem.SkinVariations[0].Skin);
MIC = MaterialInstanceConstant(KFP.ThirdPersonAttachments[PawnAttachmentIndex].GetMaterial(0));
}
if (MIC != none)
{
MIC.SetVectorParameterValue('color_monochrome', WWLHatMonoChromeValue);
MIC.SetVectorParameterValue('Black_White_switcher', WWLHatColorValue);
}
}
}
/** Called on owning client to change a cosmetic attachment or on other clients via replication */ /** Called on owning client to change a cosmetic attachment or on other clients via replication */
private function SetAttachmentMeshAndSkin( private function SetAttachmentMeshAndSkin(
int CurrentAttachmentMeshIndex, int CurrentAttachmentMeshIndex,
@ -781,6 +824,8 @@ private function SetAttachmentMeshAndSkin(
local string CharAttachmentMeshName; local string CharAttachmentMeshName;
local name CharAttachmentSocketName; local name CharAttachmentSocketName;
local int AttachmentSlotIndex; local int AttachmentSlotIndex;
local KFGameReplicationInfo KFGRI;
if (KFP.WorldInfo.NetMode == NM_DedicatedServer) if (KFP.WorldInfo.NetMode == NM_DedicatedServer)
{ {
return; return;
@ -825,12 +870,25 @@ private function SetAttachmentMeshAndSkin(
SetAttachmentMesh(CurrentAttachmentMeshIndex, AttachmentSlotIndex, CharAttachmentMeshName, SetAttachmentMesh(CurrentAttachmentMeshIndex, AttachmentSlotIndex, CharAttachmentMeshName,
CharAttachmentSocketName, KFP.ArmsMesh, KFP, true); CharAttachmentSocketName, KFP.ArmsMesh, KFP, true);
SetAttachmentSkinMaterial( KFGRI = KFGameReplicationInfo(KFP.WorldInfo.GRI);
AttachmentSlotIndex, if (AttachmentSlotIndex == 2 && KFP != none && KFGRI.bIsWeeklyMode && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
CosmeticVariants[CurrentAttachmentMeshIndex], {
CurrentAttachmentSkinIndex, SetWeeklyCowboyAttachmentSkinMaterial(
KFP, AttachmentSlotIndex,
true); CosmeticVariants[CurrentAttachmentMeshIndex],
CurrentAttachmentSkinIndex,
KFP,
true);
}
else
{
SetAttachmentSkinMaterial(
AttachmentSlotIndex,
CosmeticVariants[CurrentAttachmentMeshIndex],
CurrentAttachmentSkinIndex,
KFP,
true);
}
} }
else else
{ {
@ -858,12 +916,25 @@ private function SetAttachmentMeshAndSkin(
SetAttachmentMesh(CurrentAttachmentMeshIndex, AttachmentSlotIndex, CharAttachmentMeshName, SetAttachmentMesh(CurrentAttachmentMeshIndex, AttachmentSlotIndex, CharAttachmentMeshName,
CharAttachmentSocketName, KFP.Mesh, KFP, false); CharAttachmentSocketName, KFP.Mesh, KFP, false);
SetAttachmentSkinMaterial( KFGRI = KFGameReplicationInfo(KFP.WorldInfo.GRI);
AttachmentSlotIndex, if (AttachmentSlotIndex == 2 && KFP != none && KFGRI.bIsWeeklyMode && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
CosmeticVariants[CurrentAttachmentMeshIndex], {
CurrentAttachmentSkinIndex, SetWeeklyCowboyAttachmentSkinMaterial(
KFP, AttachmentSlotIndex,
false); CosmeticVariants[CurrentAttachmentMeshIndex],
CurrentAttachmentSkinIndex,
KFP,
false);
}
else
{
SetAttachmentSkinMaterial(
AttachmentSlotIndex,
CosmeticVariants[CurrentAttachmentMeshIndex],
CurrentAttachmentSkinIndex,
KFP,
false);
}
} }
} }
@ -1165,4 +1236,6 @@ defaultproperties
{ {
SoundGroupArch=KFPawnSoundGroup'FX_Pawn_Sounds_ARCH.HumanPawnSounds' SoundGroupArch=KFPawnSoundGroup'FX_Pawn_Sounds_ARCH.HumanPawnSounds'
EmoteAnimset=AnimSet'ECON_emote.ECON_Emotes' EmoteAnimset=AnimSet'ECON_emote.ECON_Emotes'
WWLHatMonoChromeValue=(R=1.0f,G=0.0f,B=0.0f)
WWLHatColorValue=(R=0.0f,G=0.0f,B=0.0f)
} }

View File

@ -131,6 +131,14 @@ var(Gore) float ExplosionGibScale<DisplayName=Num Gibs Scale|UIMin=0|ClampMin=0|
grenade based explosions and explosions triggered by Explosion Joints */ grenade based explosions and explosions triggered by Explosion Joints */
var(Gore) float ExplosionImpulseScale<DisplayName=Gib Impulse Scale|UIMin=0|ClampMin=0|UIMax=20.0|ClampMax=20.0> ; var(Gore) float ExplosionImpulseScale<DisplayName=Gib Impulse Scale|UIMin=0|ClampMin=0|UIMax=20.0|ClampMax=20.0> ;
/************************************************************************/
/* Wild West London Weekly */
/************************************************************************/
var string ZEDCowboyHatMeshPath;
var transient LinearColor WWLHatMonoChromeValue;
var transient LinearColor WWLHatColorValue;
/************************************************************************/ /************************************************************************/
/* Script Functions */ /* Script Functions */
/************************************************************************/ /************************************************************************/
@ -145,6 +153,9 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
local LinearColor AppliedColor; local LinearColor AppliedColor;
local array<MaterialInstanceConstant> ExtraMICs; local array<MaterialInstanceConstant> ExtraMICs;
local MaterialInstanceConstant ExtraMIC; local MaterialInstanceConstant ExtraMIC;
local StaticAttachments NewAttachment;
local KFGameReplicationInfo KFGRI;
local MaterialInstanceConstant NewMIC;
super.SetCharacterMeshFromArch( KFP, KFPRI ); super.SetCharacterMeshFromArch( KFP, KFPRI );
@ -244,6 +255,29 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
} }
} }
} }
KFGRI = KFGameReplicationInfo(KFP.WorldInfo.GRI);
if (KFP != none && KFGRI.bIsWeeklyMode && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
{
NewAttachment.StaticAttachment = StaticMesh(DynamicLoadObject(ZEDCowboyHatMeshPath, class'StaticMesh'));
NewAttachment.AttachSocketName = KFPawn_Monster(KFP).ZEDCowboyHatAttachName;
StaticAttachment = new (KFP) class'StaticMeshComponent';
if (StaticAttachment != none)
{
KFPawn_Monster(KFP).StaticAttachList.AddItem(StaticAttachment);
StaticAttachment.SetActorCollision(false, false);
StaticAttachment.SetStaticMesh(NewAttachment.StaticAttachment);
StaticAttachment.SetShadowParent(KFP.Mesh);
StaticAttachment.SetLightingChannels(KFP.PawnLightingChannel);
NewMIC = StaticAttachment.CreateAndSetMaterialInstanceConstant(0);
NewMIC.SetVectorParameterValue('color_monochrome', WWLHatMonoChromeValue);
NewMIC.SetVectorParameterValue('Black_White_switcher', WWLHatColorValue);
ExtraMICs.AddItem(NewMIC);
KFP.AttachComponent(StaticAttachment);
KFP.Mesh.AttachComponentToSocket(StaticAttachment, NewAttachment.AttachSocketName);
}
}
} }
// Initialize MICs // Initialize MICs
@ -286,4 +320,9 @@ defaultproperties
//GoreMeshLOD=-1 //GoreMeshLOD=-1
ExplosionGibScale=1.f ExplosionGibScale=1.f
ExplosionImpulseScale=1.f ExplosionImpulseScale=1.f
WWLHatMonoChromeValue=(R=1.0f,G=0.0f,B=0.0f)
WWLHatColorValue=(R=1.0f,G=0.0f,B=0.0f)
ZEDCowboyHatMeshPath = "CHR_CosmeticSet01_MESH.cowboyhat.CHR_CowboyHat_Alberts_Cosmetic"
} }

View File

@ -0,0 +1,27 @@
class KFGFXSpecialEventObjectivesContainer_Fall2021 extends KFGFxSpecialEventObjectivesContainer;
function Initialize(KFGFxObject_Menu NewParentMenu)
{
super.Initialize(NewParentMenu);
}
DefaultProperties
{
ObjectiveIconURLs[0] = "Xmas_UI.UI_Objectives_Xmas_BossKill02" // Kill 15 Bosses on any map or mode
ObjectiveIconURLs[1] = "Spring_UI.UI_Objectives_Spring_Weekly" // Complete the Weekly on Netherhold
ObjectiveIconURLs[2] = "halloween2021_ui.UI_Objective_Halloween_2021_Im_hearing_heartbeats" // Find the nether heart
ObjectiveIconURLs[3] = "halloween2021_ui.UI_Objective_Halloween_2021_Purple_Miasma" // Unlock the chapel and the dining hall doors
ObjectiveIconURLs[4] = "halloween2021_ui.UI_Objective_Halloween_2021_Eternal_Punishment" // Complete wave 15 on Endless Hard or higher difficulty on Netherhold
//defaults
AllCompleteRewardIconURL="CHR_CosmeticSet_Halloween_05_Item_TEX.muertos_companion.diadelosmuertoscompanion_precious"
ChanceDropIconURLs[0]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket"
ChanceDropIconURLs[1]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket_golden"
IconURL="Halloween2021_UI.KF2_Halloween_DayOfTheZED_SmallLogo"
UsesProgressList[0] = true
UsesProgressList[1] = false
UsesProgressList[2] = false
UsesProgressList[3] = false
UsesProgressList[4] = false
}

View File

@ -63,6 +63,11 @@ var string ClearImagePath;
var array<Emote> EmoteList; var array<Emote> EmoteList;
cpptext
{
static INT GetCowboyHatIndex(const UKFCharacterInfo_Human* CharInfo);
}
function InitializeMenu( KFGFxMoviePlayer_Manager InManager ) function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
{ {
super.InitializeMenu(InManager); super.InitializeMenu(InManager);
@ -78,6 +83,8 @@ function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
UpdateCharacterList(); UpdateCharacterList();
UpdateGear(); UpdateGear();
TraderItems = KFGameReplicationInfo( KFPlayerController(GetPC()).WorldInfo.GRI ).TraderItems; TraderItems = KFGameReplicationInfo( KFPlayerController(GetPC()).WorldInfo.GRI ).TraderItems;
ForceWeeklyCowboyHat();
} }
function OnOpen() function OnOpen()
@ -236,6 +243,8 @@ function UpdateGear()
UpdateEmoteList(); UpdateEmoteList();
SetCurrentCharacterButtons(); SetCurrentCharacterButtons();
ForceWeeklyCowboyHat();
} }
else else
{ {
@ -295,6 +304,10 @@ function UpdateAttachmentsList(array<AttachmentVariants> Attachments)
local Pawn MyPawn; local Pawn MyPawn;
local SkinVariant FirstSkin; local SkinVariant FirstSkin;
local string AttachmentName; local string AttachmentName;
local PlayerController PC;
local bool bIsWildWest;
bIsWildWest = false;
ItemIndex = 0; ItemIndex = 0;
DataProvider = CreateArray(); DataProvider = CreateArray();
MyPawn = GetPC().Pawn; MyPawn = GetPC().Pawn;
@ -308,11 +321,19 @@ function UpdateAttachmentsList(array<AttachmentVariants> Attachments)
DataProvider.SetElementObject(ItemIndex, SlotObject); DataProvider.SetElementObject(ItemIndex, SlotObject);
ItemIndex++; ItemIndex++;
PC = GetPC();
bIsWildWest = (PC != none && Pc.WorldInfo.GRI.IsA('KFGameReplicationInfo_WeeklySurvival') && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12));
for (i = 0; i < Attachments.length; i++) for (i = 0; i < Attachments.length; i++)
{ {
Variant = Attachments[i]; Variant = Attachments[i];
if ( CurrentCharInfo.IsAttachmentAvailable(Variant, MyPawn) ) if ( CurrentCharInfo.IsAttachmentAvailable(Variant, MyPawn) )
{ {
if (bIsWildWest && Variant.SocketName == 'HAT_Attach')
{
continue;
}
SlotObject = CreateObject( "Object" ); SlotObject = CreateObject( "Object" );
SlotObject.SetInt("ItemIndex", i); SlotObject.SetInt("ItemIndex", i);
FirstSkin = UpdateCosmeticVariants( AttachmentKey, AttachmentSkinKey, Variant.AttachmentItem, i, SlotObject ); FirstSkin = UpdateCosmeticVariants( AttachmentKey, AttachmentSkinKey, Variant.AttachmentItem, i, SlotObject );
@ -698,6 +719,7 @@ private function Callback_AttachmentNumbered(int MeshIndex, int SkinIndex, int S
local Pawn P; local Pawn P;
local KFPawn KFP; local KFPawn KFP;
local array<int> RemovedAttachments; local array<int> RemovedAttachments;
P = GetPC().Pawn; P = GetPC().Pawn;
if( P != none ) if( P != none )
{ {
@ -747,9 +769,29 @@ function RelayFromCheatManager(Pawn P, ECustomizationOption CustomizationOption,
Manager.CachedProfile.SetCharacterGear(MyKFPRI.RepCustomizationInfo); Manager.CachedProfile.SetCharacterGear(MyKFPRI.RepCustomizationInfo);
} }
function ForceWeeklyCowboyHat()
{
local PlayerController PC;
local int CowboyHatIndex;
PC = GetPC();
if (PC != none && Pc.WorldInfo.GRI.IsA('KFGameReplicationInfo_WeeklySurvival') && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
{
CowboyHatIndex = FindCowboyHatAttachmentIndex(CurrentCharInfo);
if (CowboyHatIndex >= 0)
{
Callback_AttachmentNumbered(CowboyHatIndex,0,2);
}
SetBool("ThirdAttachmentBlocked", true);
}
}
/** Update our character parts when the UI is being used */ /** Update our character parts when the UI is being used */
native private function SelectCharacter(Pawn P, byte CharacterIndex); native private function SelectCharacter(Pawn P, byte CharacterIndex);
native private function SelectCustomizationOption(Pawn P, ECustomizationOption CustomizationOption, int MeshIndex, int SkinIndex, optional int AttachmentIndex); native private function SelectCustomizationOption(Pawn P, ECustomizationOption CustomizationOption, int MeshIndex, int SkinIndex, optional int AttachmentIndex);
// native static function INT GetCowboyHatIndex(KFCharacterInfo_Human CharInfo);
native static function int FindCowboyHatAttachmentIndex(KFCharacterInfo_Human CharInfo);
defaultproperties defaultproperties
{ {

View File

@ -112,6 +112,8 @@ event bool WidgetInitialized(name WidgetName, name WidgetPath, GFxObject Widget)
function OnOpen() function OnOpen()
{ {
local KFGameReplicationInfo KFGRI;
LastPerkIndex = KFPC.SavedPerkIndex; LastPerkIndex = KFPC.SavedPerkIndex;
MyKFPRI = KFPlayerReplicationInfo( GetPC().PlayerReplicationInfo ); MyKFPRI = KFPlayerReplicationInfo( GetPC().PlayerReplicationInfo );
@ -120,6 +122,25 @@ function OnOpen()
`log("NO KFPC!!"); `log("NO KFPC!!");
KFPC = KFPlayerController(GetPC()); KFPC = KFPlayerController(GetPC());
} }
// Current Perk not allowed, search for the first one
KFGRI = KFGameReplicationInfo( KFPC.WorldInfo.GRI );
if( KFGRI != none && !KFGRI.IsPerkAllowed(KFPC.PerkList[LastPerkIndex].PerkClass) )
{
if (KFGRI.PerksAvailableData.bBerserkerAvailable) LastPerkIndex=0;
else if (KFGRI.PerksAvailableData.bCommandoAvailable) LastPerkIndex=1;
else if (KFGRI.PerksAvailableData.bSupportAvailable) LastPerkIndex=2;
else if (KFGRI.PerksAvailableData.bFieldMedicAvailable) LastPerkIndex=3;
else if (KFGRI.PerksAvailableData.bDemolitionistAvailable) LastPerkIndex=4;
else if (KFGRI.PerksAvailableData.bFirebugAvailable) LastPerkIndex=5;
else if (KFGRI.PerksAvailableData.bGunslingerAvailable) LastPerkIndex=6;
else if (KFGRI.PerksAvailableData.bSharpshooterAvailable) LastPerkIndex=7;
else if (KFGRI.PerksAvailableData.bSwatAvailable) LastPerkIndex=8;
else if (KFGRI.PerksAvailableData.bSurvivalistAvailable) LastPerkIndex=9;
else LastPerkIndex=0;
KFPC.SavedPerkIndex = LastPerkIndex;
}
UpdateSkillsHolder(KFPC.PerkList[KFPC.SavedPerkIndex].PerkClass); UpdateSkillsHolder(KFPC.PerkList[KFPC.SavedPerkIndex].PerkClass);
UpdateContainers(KFPC.PerkList[KFPC.SavedPerkIndex].PerkClass); UpdateContainers(KFPC.PerkList[KFPC.SavedPerkIndex].PerkClass);

View File

@ -271,6 +271,17 @@ function GFxObject CreateStoreItem(ItemProperties DesiredStoreItem)
DataObject.SetString("imageURLLarge", "img://"$DesiredStoreItem.IconURLLarge); DataObject.SetString("imageURLLarge", "img://"$DesiredStoreItem.IconURLLarge);
DataObject.SetInt("SKU", DesiredStoreItem.Definition); DataObject.SetInt("SKU", DesiredStoreItem.Definition);
if( DesiredStoreItem.ItemOnSale && DesiredStoreItem.BasePrice != DesiredStoreItem.Price)
{
DataObject.SetString("itemOnSale", DesiredStoreItem.ItemOnSale ? "1" : "0");
DataObject.SetString("itemPriceBase", DesiredStoreItem.BasePrice);
if(DesiredStoreItem.DiscountRate != "" && DesiredStoreItem.DiscountRate != "0")
{
DataObject.SetString("discountRate", DesiredStoreItem.DiscountRate);
}
}
return DataObject; return DataObject;
} }

View File

@ -42,6 +42,8 @@ var localized string HideRemodeHeadshotEffectsString;
var localized string ToggleToRunString; var localized string ToggleToRunString;
var localized string ClassicPlayerInfoString; var localized string ClassicPlayerInfoString;
var localized string AllowSwap9mmString;
var float FOVMinValue, FOVMaxValue, FOVCurrentValue; var float FOVMinValue, FOVMaxValue, FOVCurrentValue;
var float FriendlyHudScaleMinValue, FriendlyHudScaleMaxValue; var float FriendlyHudScaleMinValue, FriendlyHudScaleMaxValue;
@ -99,6 +101,8 @@ function LocalizeText()
//LocalizedObject.SetString("reduceHighPitchNoise", ReduceHighPitchNoiseString); //LocalizedObject.SetString("reduceHighPitchNoise", ReduceHighPitchNoiseString);
//LocalizedObject.SetString("antiMotionSickness", AntiMotionSicknessString); //LocalizedObject.SetString("antiMotionSickness", AntiMotionSicknessString);
LocalizedObject.SetString("allowSwap9mmLabel", AllowSwap9mmString);
SetObject("localizedText", LocalizedObject); SetObject("localizedText", LocalizedObject);
} }
@ -143,6 +147,8 @@ function InitValues()
DataObject.SetBool("enableToggleToRun", Manager.CachedProfile.GetProfileBool(KFID_ToggletoRun)); DataObject.SetBool("enableToggleToRun", Manager.CachedProfile.GetProfileBool(KFID_ToggletoRun));
DataObject.SetBool("enableClassicPlayerInfo", Manager.CachedProfile.GetProfileBool(KFID_ClassicPlayerInfo)); DataObject.SetBool("enableClassicPlayerInfo", Manager.CachedProfile.GetProfileBool(KFID_ClassicPlayerInfo));
DataObject.SetBool("allowSwapTo9mm", Manager.CachedProfile.GetProfileBool(KFID_AllowSwapTo9mm));
if(class'WorldInfo'.static.IsConsoleBuild(CONSOLE_Durango)) if(class'WorldInfo'.static.IsConsoleBuild(CONSOLE_Durango))
{ {
DataObject.SetBool("bDingo", true); DataObject.SetBool("bDingo", true);
@ -542,6 +548,25 @@ function Callback_ClassicPlayerInfoChanged(bool bActive)
} }
} }
function Callback_AllowSwapTo9mm(bool bActive)
{
local OnlineProfileSettings Settings;
local KFPlayerInput KFPI;
Settings = class'GameEngine'.static.GetOnlineSubsystem().PlayerInterface.GetProfileSettings(GetLP().ControllerId);
KFPI = KFPlayerInput(GetPC().PlayerInput);
if (Settings != none)
{
Settings.SetProfileSettingValueInt(KFID_AllowSwapTo9mm, bActive ? 1 : 0);
}
if (KFPI != none)
{
KFPI.bAllowSwapTo9mm = bActive;
}
}
function ResetGameOptions() function ResetGameOptions()
{ {
//local KFPlayerController KFPC; //local KFPlayerController KFPC;
@ -599,6 +624,8 @@ function ResetGameOptions()
Callback_ClassicPlayerInfoChanged(Manager.CachedProfile.GetDefaultInt(KFID_ClassicPlayerInfo) != 0); Callback_ClassicPlayerInfoChanged(Manager.CachedProfile.GetDefaultInt(KFID_ClassicPlayerInfo) != 0);
Callback_AllowSwapTo9mm(Manager.CachedProfile.GetDefaultInt(KFID_AllowSwapTo9mm) != 0);
InitValues(); InitValues();
} }

View File

@ -182,31 +182,31 @@ function FillWhatsNew()
local SWhatsNew item; local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length); WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update // Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_InterstellarInsanity_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_DayOfTheZED_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// KF2 Armory Season Pass 2021 // KF2 Armory Season Pass 2021
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Armory_Season_Pass", "ArmorySeasonPass", "https://store.steampowered.com/app/1524820/Killing_Floor_2__Armory_Season_Pass");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Time Limited Item // Featured Time Limited Item
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_SS_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/4928"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/9119");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle // Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Astronaut", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8953"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_DoZ", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9120");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle // Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Foundry","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/8956"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_Vietnam","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/9122");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle // Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_BeyondHorizon", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8955"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_Hellmark", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9121");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Bundle // Featured Weapon Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_FamasMasterkey", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8957"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_PiranhaPistol", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9123");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Bundle // Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_ThermiteBore", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8958"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Halloween_CorrupterCarbine", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9124");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Bundle // Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Summer_Weaponsbundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8959"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_halloween_Weaponsbundle", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/9125");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Misc Community Links // Misc Community Links
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");

View File

@ -341,11 +341,12 @@ function GFxObject CreateStoreItem(ItemProperties StoreItem)
DataObject.SetString("description", StoreItem.Description); DataObject.SetString("description", StoreItem.Description);
//`log("Price"@StoreItem.Price@"- BasePrice"@StoreItem.BasePrice@"- DiscountRate"@StoreItem.DiscountRate@"- ItemOnSale"@StoreItem.ItemOnSale); //`log("Price"@StoreItem.Price@"- BasePrice"@StoreItem.BasePrice@"- DiscountRate"@StoreItem.DiscountRate@"- ItemOnSale"@StoreItem.ItemOnSale);
if( StoreItem.ItemOnSale ) if( StoreItem.ItemOnSale && StoreItem.BasePrice != StoreItem.Price)
{ {
DataObject.SetString("itemOnSale", StoreItem.ItemOnSale ? "1" : "0"); DataObject.SetString("itemOnSale", StoreItem.ItemOnSale ? "1" : "0");
DataObject.SetString("itemPriceBase", StoreItem.BasePrice); DataObject.SetString("itemPriceBase", StoreItem.BasePrice);
if(StoreItem.DiscountRate != "")
if(StoreItem.DiscountRate != "" && StoreItem.DiscountRate != "0")
{ {
DataObject.SetString("discountRate", StoreItem.DiscountRate); DataObject.SetString("discountRate", StoreItem.DiscountRate);
} }
@ -446,21 +447,21 @@ DefaultProperties
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
FeaturedItemIDs[0]=8178 FeaturedItemIDs[0]=7619 //Whatsnew Gold Ticket
FeaturedItemIDs[1]=8953 FeaturedItemIDs[1]=9119
FeaturedItemIDs[2]=8959 FeaturedItemIDs[2]=9120
FeaturedItemIDs[3]=8956 FeaturedItemIDs[3]=9121
FeaturedItemIDs[4]=8955 FeaturedItemIDs[4]=9122
FeaturedItemIDs[5]=8957 FeaturedItemIDs[5]=9123
FeaturedItemIDs[6]=8958 FeaturedItemIDs[6]=9124
ConsoleFeaturedItemIDs[0]=8181 ConsoleFeaturedItemIDs[0]=7783 //Whatsnew Gold Ticket PSN
ConsoleFeaturedItemIDs[1]=8953 ConsoleFeaturedItemIDs[1]=9119
ConsoleFeaturedItemIDs[2]=8959 ConsoleFeaturedItemIDs[2]=9120
ConsoleFeaturedItemIDs[3]=8956 ConsoleFeaturedItemIDs[3]=9121
ConsoleFeaturedItemIDs[4]=8955 ConsoleFeaturedItemIDs[4]=9122
ConsoleFeaturedItemIDs[5]=8957 ConsoleFeaturedItemIDs[5]=9123
ConsoleFeaturedItemIDs[6]=8958 ConsoleFeaturedItemIDs[6]=9124
MaxFeaturedItems=5 MaxFeaturedItems=5
} }

View File

@ -54,6 +54,8 @@ function LocalizeContainer()
LocalizedObject.SetString("changePerk", ChangePerkString); LocalizedObject.SetString("changePerk", ChangePerkString);
LocalizedObject.SetString("grenadeLabel", BuyGrenadeString); LocalizedObject.SetString("grenadeLabel", BuyGrenadeString);
LocalizedObject.SetString("armorBuyLabel", class'KFAutoPurchaseHelper'.default.ArmorMagSize$"X");
//Prompt strings //Prompt strings
LocalizedObject.SetString("sellPrompt", Localize("KFGFxTraderContainer_ItemDetails", "SellString", "KFGame")); LocalizedObject.SetString("sellPrompt", Localize("KFGFxTraderContainer_ItemDetails", "SellString", "KFGame"));
LocalizedObject.SetString("perkPrompt", Localize("KFGFxTraderContainer_PlayerInventory", "PerkPrompt", "KFGameConsole")); LocalizedObject.SetString("perkPrompt", Localize("KFGFxTraderContainer_PlayerInventory", "PerkPrompt", "KFGameConsole"));
@ -155,19 +157,26 @@ function RefreshPlayerInventory()
function SetArmorInfo(out SItemInformation ArmorInfo, out int AutoFillCost) function SetArmorInfo(out SItemInformation ArmorInfo, out int AutoFillCost)
{ {
local GFxObject SlotObject; local GFxObject SlotObject;
local int FillCost; local int FillCost, ChunkCost;
local int ButtonState;
FillCost = KFPC.GetPurchaseHelper().GetFillArmorCost(); FillCost = KFPC.GetPurchaseHelper().GetFillArmorCost();
ChunkCost = KFPC.GetPurchaseHelper().GetChunkArmorCost();
SlotObject = CreateObject( "Object" ); SlotObject = CreateObject( "Object" );
SlotObject.SetInt("magCost", ChunkCost);
SlotObject.SetInt("cost", FillCost); SlotObject.SetInt("cost", FillCost);
SlotObject.SetString("itemName", ArmorString); SlotObject.SetString("itemName", ArmorString);
SlotObject.SetString("itemSource", "img://"$ArmorInfo.DefaultItem.WeaponDef.static.GetImagePath()); SlotObject.SetString("itemSource", "img://"$ArmorInfo.DefaultItem.WeaponDef.static.GetImagePath());
SlotObject.SetString("itemAmmo", ArmorInfo.SpareAmmoCount$"/"$ArmorInfo.MaxSpareAmmo); SlotObject.SetString("itemAmmo", ArmorInfo.SpareAmmoCount$"/"$ArmorInfo.MaxSpareAmmo);
SlotObject.Setint("buttonState", GetButtonState( ArmorInfo.AmmoPricePerMagazine, ArmorInfo.SpareAmmoCount, ArmorInfo.MaxSpareAmmo ));
SlotObject.SetBool("lowAmmo", (ArmorInfo.MaxSpareAmmo > 0) ? (float(ArmorInfo.SpareAmmoCount) / float(ArmorInfo.MaxSpareAmmo)) <= LowAmmoPercentThreshold : false); SlotObject.SetBool("lowAmmo", (ArmorInfo.MaxSpareAmmo > 0) ? (float(ArmorInfo.SpareAmmoCount) / float(ArmorInfo.MaxSpareAmmo)) <= LowAmmoPercentThreshold : false);
ButtonState = GetButtonState( ArmorInfo.AmmoPricePerMagazine, ArmorInfo.SpareAmmoCount, ArmorInfo.MaxSpareAmmo );
SlotObject.Setint("buttonState", ButtonState );
SlotObject.Setint("magButtonState", ButtonState );
SetObject("armorInfo", SlotObject); SetObject("armorInfo", SlotObject);
AutoFillCost += FillCost; AutoFillCost += FillCost;
} }

View File

@ -319,7 +319,8 @@ enum EForcedMusicType
EFM_Boss2, EFM_Boss2,
EFM_Boss3, EFM_Boss3,
EFM_Boss4, EFM_Boss4,
EFM_Boss5 EFM_Boss5,
EFM_WWL
}; };
/** Tracks that are not selected randomly but rather "forced" by the server (or standalone client) at specific times */ /** Tracks that are not selected randomly but rather "forced" by the server (or standalone client) at specific times */
@ -945,6 +946,10 @@ event PostLogin( PlayerController NewPlayer )
KFPC = KFPlayerController(NewPlayer); KFPC = KFPlayerController(NewPlayer);
if( KFPC != None ) if( KFPC != None )
{ {
KFPC.UpdatePerkOnInit();
KFPC.InitGameplayPostProcessFX();
if( KFPC.PlayerReplicationInfo.bOnlySpectator ) if( KFPC.PlayerReplicationInfo.bOnlySpectator )
{ {
// if we're initially spectating, initialize front-end but skip lobby menu // if we're initially spectating, initialize front-end but skip lobby menu
@ -2862,6 +2867,11 @@ simulated function ForceAbominationMusicTrack()
MyKFGRI.ForceNewMusicTrack( default.ForcedMusicTracks[EFM_Boss5] ); MyKFGRI.ForceNewMusicTrack( default.ForcedMusicTracks[EFM_Boss5] );
} }
simulated function ForceWWLMusicTrack()
{
MyKFGRI.ForceNewMusicTrack( default.ForcedMusicTracks[EFM_WWL] );
}
/********************************************************************************************* /*********************************************************************************************
* @name Map rotation * @name Map rotation
*********************************************************************************************/ *********************************************************************************************/
@ -3866,6 +3876,7 @@ defaultproperties
ForcedMusicTracks(4)=KFMusicTrackInfo'WW_MACT_Default.TI_Boss_Matriarch' // matriarch ForcedMusicTracks(4)=KFMusicTrackInfo'WW_MACT_Default.TI_Boss_Matriarch' // matriarch
ForcedMusicTracks(5)=KFMusicTrackInfo'WW_MACT_Default.TI_RG_KingFP' // king fp ForcedMusicTracks(5)=KFMusicTrackInfo'WW_MACT_Default.TI_RG_KingFP' // king fp
ForcedMusicTracks(6)=KFMusicTrackInfo'WW_MACT_Default.TI_RG_Abomination' // abomination ForcedMusicTracks(6)=KFMusicTrackInfo'WW_MACT_Default.TI_RG_Abomination' // abomination
ForcedMusicTracks(7)=KFMusicTrackInfo'WW_MACT_Default.TI_WWL' // WWL Weekly
ReservationTimeout=32 ReservationTimeout=32
bLogReservations=true bLogReservations=true

View File

@ -106,7 +106,7 @@ var int AIRemaining;
var int WaveTotalAICount; var int WaveTotalAICount;
var bool bEndlessMode; var bool bEndlessMode;
var bool bObjectiveMode; var bool bObjectiveMode;
var bool bIsWeeklyMode;
//@HSL_BEGIN - JRO - 3/21/2016 - PS4 Sessions //@HSL_BEGIN - JRO - 3/21/2016 - PS4 Sessions
/************************************ /************************************
* Console Sessions * Console Sessions
@ -381,7 +381,7 @@ replication
if ( bNetDirty ) if ( bNetDirty )
TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage, TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage,
CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount, CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount,
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader; //@HSL - JRO - 3/21/2016 - PS4 Sessions bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective, bIsBrokenTrader, bIsWeeklyMode; //@HSL - JRO - 3/21/2016 - PS4 Sessions
if ( bNetInitial ) if ( bNetInitial )
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled; GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled;
if ( bNetInitial || bNetDirty ) if ( bNetInitial || bNetDirty )
@ -1091,6 +1091,7 @@ simulated function int GetNextMapTimeRemaining()
/** Called from the GameInfo when the trader pod should be activated */ /** Called from the GameInfo when the trader pod should be activated */
function SetWaveActive(bool bWaveActive, optional byte NewMusicIntensity) function SetWaveActive(bool bWaveActive, optional byte NewMusicIntensity)
{ {
// set up music intensity for this wave // set up music intensity for this wave
MusicIntensity = NewMusicIntensity; MusicIntensity = NewMusicIntensity;
bTraderIsOpen = !bWaveActive && bMatchHasBegun && bTradersEnabled; bTraderIsOpen = !bWaveActive && bMatchHasBegun && bTradersEnabled;
@ -1106,6 +1107,21 @@ function SetWaveActive(bool bWaveActive, optional byte NewMusicIntensity)
} }
} }
simulated function bool CanOverrideWeeklyMusic()
{
local KFGameInfo KFGI;
if (WorldInfo.NetMode == NM_Client)
{
return !bIsWeeklyMode || class'KFGameEngine'.static.GetWeeklyEventIndexMod() != 12;
}
else
{
KFGI = KFGameInfo(WorldInfo.Game);
return (KFGI == none || KFGI.OutbreakEvent == none || !KFGI.OutbreakEvent.ActiveEvent.bForceWWLMusic);
}
}
simulated function bool IsFinalWave() simulated function bool IsFinalWave()
{ {
return (WaveNum == WaveMax - 1); return (WaveNum == WaveMax - 1);
@ -1717,6 +1733,9 @@ simulated function PlayNewMusicTrack( optional bool bGameStateChanged, optional
return; return;
} }
if ( !CanOverrideWeeklyMusic() )
return;
// @todo: consider using music intensity (255?) for ambient music to simplify this logic // @todo: consider using music intensity (255?) for ambient music to simplify this logic
bPlayActionTrack = (!bForceAmbient && KFGameClass.static.ShouldPlayActionMusicTrack(self)); bPlayActionTrack = (!bForceAmbient && KFGameClass.static.ShouldPlayActionMusicTrack(self));
@ -2202,4 +2221,5 @@ defaultproperties
PreviousObjectiveVoshResult=-1 PreviousObjectiveVoshResult=-1
PreviousObjectiveXPResult=-1 PreviousObjectiveXPResult=-1
bIsBrokenTrader=false bIsBrokenTrader=false
bIsWeeklyMode=false
} }

View File

@ -206,7 +206,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
case SEI_Summer: case SEI_Summer:
return class'KFGFxSpecialEventObjectivesContainer_Summer2021'; return class'KFGFxSpecialEventObjectivesContainer_Summer2021';
case SEI_Fall: case SEI_Fall:
return class'KFGFxSpecialEventObjectivesContainer_Fall2020'; return class'KFGFxSpecialEventObjectivesContainer_Fall2021';
case SEI_Winter: case SEI_Winter:
return class'KFGFXSpecialEventObjectivesContainer_Xmas2020'; return class'KFGFXSpecialEventObjectivesContainer_Xmas2020';
} }

View File

@ -702,6 +702,15 @@ function Callback_FillGrenades()
} }
} }
function Callback_BuyArmor()
{
if (PlayerInventoryContainer != none)
{
MyKFPC.GetPurchaseHelper().BuyArmorMag();
RefreshItemComponents();
}
}
function Callback_FillArmor() function Callback_FillArmor()
{ {
if (PlayerInventoryContainer != none) if (PlayerInventoryContainer != none)

View File

@ -65,6 +65,7 @@ simulated function PlayImpactEffects(const vector HitLocation, const Pawn Effect
local KFImpactEffectInfo ImpactEffectInfo; local KFImpactEffectInfo ImpactEffectInfo;
local KFFracturedMeshActor FracturedMeshActor; local KFFracturedMeshActor FracturedMeshActor;
local int i; local int i;
local bool bIsWeaponHandlingEffects;
// allow optional parameter to override impact effects // allow optional parameter to override impact effects
ImpactEffectInfo = (CustomImpactEffects != None) ? CustomImpactEffects : DefaultImpactEffects; ImpactEffectInfo = (CustomImpactEffects != None) ? CustomImpactEffects : DefaultImpactEffects;
@ -91,9 +92,11 @@ simulated function PlayImpactEffects(const vector HitLocation, const Pawn Effect
} }
} }
bIsWeaponHandlingEffects = KFPawn(EffectInstigator).MyKFWeapon.bForceHandleImpacts;
// Trace using the Instigator as the TraceOwner so that melee weapons don't collide with Instigator // Trace using the Instigator as the TraceOwner so that melee weapons don't collide with Instigator
HitActor = EffectInstigator.Trace(NewHitLoc, HitNormal, (HitLocation - (HitNormal * 32)), HitLocation + (HitNormal * 32), !bWorldImpactsOnly,, HitInfo, TRACEFLAG_Bullet); HitActor = EffectInstigator.Trace(NewHitLoc, HitNormal, (HitLocation - (HitNormal * 32)), HitLocation + (HitNormal * 32), !bWorldImpactsOnly,, HitInfo, TRACEFLAG_Bullet);
if( HitActor != none && HitActor.bCanBeDamaged && HitActor.IsA('Pawn') ) if( HitActor != none && HitActor.bCanBeDamaged && HitActor.IsA('Pawn') && !bIsWeaponHandlingEffects )
{ {
return; // pawns impacts are handled by the pawn (see PlayTakeHitEffects) return; // pawns impacts are handled by the pawn (see PlayTakeHitEffects)
} }
@ -130,7 +133,7 @@ simulated function PlayImpactEffects(const vector HitLocation, const Pawn Effect
// Pawns handle their own hit effects // Pawns handle their own hit effects
if ( HitActor != None && if ( HitActor != None &&
(Pawn(HitActor) == None || Vehicle(HitActor) != None) && ((Pawn(HitActor) == None || bIsWeaponHandlingEffects ) || Vehicle(HitActor) != None) &&
AllowImpactEffects(HitActor, HitLocation, HitNormal) ) AllowImpactEffects(HitActor, HitLocation, HitNormal) )
{ {
if (ImpactEffect.ParticleTemplate != None) if (ImpactEffect.ParticleTemplate != None)

View File

@ -803,8 +803,25 @@ simulated function InternalNextWeapon(bool bGamepad)
simulated function bool ShouldSkipCycleWeapon(Weapon CandidateWeapon, bool bGamepad) simulated function bool ShouldSkipCycleWeapon(Weapon CandidateWeapon, bool bGamepad)
{ {
local KFWeapon KFW; local KFWeapon KFW;
local PlayerController PC;
local KFPlayerInput KFPI;
local bool bCanSwapTo9mm;
// Default behaviour is you can't swap to 9mm
bCanSwapTo9mm = false;
PC = PlayerController(Instigator.Controller);
if ( PC != None )
{
KFPI = KFPlayerInput(PC.PlayerInput);
if (KFPI != None)
{
bCanSwapTo9mm = KFPI.bAllowSwapTo9mm;
}
}
KFW = KFWeapon(CandidateWeapon); KFW = KFWeapon(CandidateWeapon);
if(KFW != none) if(KFW != none)
{ {
if(KFW.InventoryGroup == IG_None) if(KFW.InventoryGroup == IG_None)
@ -819,7 +836,7 @@ simulated function bool ShouldSkipCycleWeapon(Weapon CandidateWeapon, bool bGame
return true; return true;
} }
if (KFW.bIsBackupWeapon) if (KFW.bIsBackupWeapon && (!bCanSwapTo9mm || KFW.IsMeleeWeapon()))
{ {
return true; return true;
} }

View File

@ -68,6 +68,7 @@ defaultproperties
ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen) ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen)
ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles) ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles)
ColumnIds.Add(STATID_ACHIEVE_MoonbaseCollectibles) ColumnIds.Add(STATID_ACHIEVE_MoonbaseCollectibles)
ColumnIds.Add(STATID_ACHIEVE_NetherholdCollectibles)
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
@ -124,4 +125,5 @@ defaultproperties
ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium")) ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium"))
ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029")) ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MoonbaseCollectibles,NAme="AchievementCollectMoonbase")) ColumnMappings.Add((Id=STATID_ACHIEVE_MoonbaseCollectibles,NAme="AchievementCollectMoonbase"))
ColumnMappings.Add((Id=STATID_ACHIEVE_NetherholdCollectibles,NAme="AchievementCollectNetherhold"))
} }

View File

@ -433,6 +433,10 @@ const KFACHID_MoonbaseHard = 283;
const KFACHID_MoonbaseHellOnEarth = 284; const KFACHID_MoonbaseHellOnEarth = 284;
const KFACHID_MoonbaseCollectibles = 285; const KFACHID_MoonbaseCollectibles = 285;
const KFACHID_NetherholdHard = 286;
const KFACHID_NetherholdHellOnEarth = 287;
const KFACHID_NetherholdCollectibles = 288;
/* __TW_ANALYTICS_ */ /* __TW_ANALYTICS_ */
var int PerRoundWeldXP; var int PerRoundWeldXP;
var int PerRoundHealXP; var int PerRoundHealXP;
@ -2055,6 +2059,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_HX25, KFDT_ExplosiveSubmunition_HX25,KFDT_Ballistic_HX25Impact,KFDT_Ballistic_HX25SubmunitionImpact,KFDT_Bludgeon_HX25),CompletionAmount=5000)) //3000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_HX25, KFDT_ExplosiveSubmunition_HX25,KFDT_Ballistic_HX25Impact,KFDT_Ballistic_HX25SubmunitionImpact,KFDT_Bludgeon_HX25),CompletionAmount=5000)) //3000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Thrown_C4, KFDT_Explosive_C4,KFDT_Bludgeon_C4),CompletionAmount=2500)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Thrown_C4, KFDT_Explosive_C4,KFDT_Bludgeon_C4),CompletionAmount=2500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_M79, KFDT_Ballistic_M79Impact,KFDT_Explosive_M79,KFDT_Bludgeon_M79),CompletionAmount=7000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_GrenadeLauncher_M79, KFDT_Ballistic_M79Impact,KFDT_Explosive_M79,KFDT_Bludgeon_M79),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Boomy, KFDT_Ballistic_HRG_Boomy,KFDT_Explosive_HRG_Boomy,KFDT_Bludgeon_HRG_Boomy),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_HRG_Kaboomstick, KFDT_Ballistic_HRG_Kaboomstick,KFDT_Explosive_HRG_Kaboomstick,KFDT_Bludgeon_HRG_Kaboomstick),CompletionAmount=9000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Shotgun_HRG_Kaboomstick, KFDT_Ballistic_HRG_Kaboomstick,KFDT_Explosive_HRG_Kaboomstick,KFDT_Bludgeon_HRG_Kaboomstick),CompletionAmount=9000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_RPG7, KFDT_Ballistic_RPG7Impact,KFDT_Explosive_RPG7,KFDT_Explosive_RPG7BackBlast,KFDT_Bludgeon_RPG7),CompletionAmount=7500)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_RocketLauncher_RPG7, KFDT_Ballistic_RPG7Impact,KFDT_Explosive_RPG7,KFDT_Explosive_RPG7BackBlast,KFDT_Bludgeon_RPG7),CompletionAmount=7500))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_M16M203, KFDT_Ballistic_M16M203,KFDT_Bludgeon_M16M203,KFDT_Ballistic_M203Impact,KFDT_Explosive_M16M203),CompletionAmount=9000)) //7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_AssaultRifle_M16M203, KFDT_Ballistic_M16M203,KFDT_Bludgeon_M16M203,KFDT_Ballistic_M203Impact,KFDT_Explosive_M16M203),CompletionAmount=9000)) //7000
@ -2094,6 +2099,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Deagle, KFDT_Bludgeon_Deagle,KFDT_Ballistic_Deagle),CompletionAmount=10000)) // 7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_Deagle, KFDT_Bludgeon_Deagle,KFDT_Ballistic_Deagle),CompletionAmount=10000)) // 7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Revolver_SW500, KFDT_Bludgeon_SW500,KFDT_Ballistic_SW500,KFDT_Ballistic_SW500_Dual),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Revolver_SW500, KFDT_Bludgeon_SW500,KFDT_Ballistic_SW500,KFDT_Ballistic_SW500_Dual),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_AF2011, KFDT_Bludgeon_AF2011,KFDT_Ballistic_AF2011),CompletionAmount=10000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Pistol_AF2011, KFDT_Bludgeon_AF2011,KFDT_Ballistic_AF2011),CompletionAmount=10000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_Energy, KFDT_Ballistic_HRG_Energy_Primary,KFDT_Ballistic_HRG_Energy_Secondary, KFDT_Bludgeon_HRG_Energy),CompletionAmount=10000))
//Sharpshooter Weapons //Sharpshooter Weapons
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Winchester1894, KFDT_Bludgeon_Winchester,KFDT_Ballistic_Winchester),CompletionAmount=5000)) //2000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Winchester1894, KFDT_Bludgeon_Winchester,KFDT_Ballistic_Winchester),CompletionAmount=5000)) //2000
@ -2247,6 +2253,9 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=1)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=2)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=3)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-MOONBASE),CompletionAmount=3))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-NETHERHOLD),CompletionAmount=3))
//Versus Damage //Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount // Per design doc that I have right now, these are x class damage y players, not damage y amount

View File

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

View File

@ -165,6 +165,10 @@ struct WeeklyOverrides
* 1) Disables Berserker lvl25 skills 2) Enables lvl25 battery ram skill of the swat * 1) Disables Berserker lvl25 skills 2) Enables lvl25 battery ram skill of the swat
*/ */
var() bool bColliseumSkillConditionsActive; var() bool bColliseumSkillConditionsActive;
/** Activates the special conditions for the Wild West Weekly Mode
* 1) Disables Berserker lvl25 skills 2) Enables lvl25 battery ram skill of the swat
*/
var () bool bWildWestSkillConditionsActive;
/** If this array is not empty, replaces AIClassList entries with a new spawn class */ /** If this array is not empty, replaces AIClassList entries with a new spawn class */
var() array<SpawnReplacement> SpawnReplacementList; var() array<SpawnReplacement> SpawnReplacementList;
@ -323,6 +327,9 @@ struct WeeklyOverrides
/** Heal after kill */ /** Heal after kill */
var() bool bHealAfterKill; var() bool bHealAfterKill;
/** Only heal with headshots */
var() bool bHealWithHeadshot;
/** Cannot be Healed*/ /** Cannot be Healed*/
var() bool bCannotBeHealed; var() bool bCannotBeHealed;
@ -371,6 +378,9 @@ struct WeeklyOverrides
/** If another outbreak mode shares the same events, this will link the two to quicker UI lookup */ /** If another outbreak mode shares the same events, this will link the two to quicker UI lookup */
var() int WeeklyOutbreakId; var() int WeeklyOutbreakId;
/** If WWL music should be forced */
var() bool bForceWWLMusic;
structdefaultproperties structdefaultproperties
{ {
GameLength = GL_Short GameLength = GL_Short
@ -403,6 +413,7 @@ struct WeeklyOverrides
MaxPerkLevel = 4 MaxPerkLevel = 4
bAllowSpawnReplacementDuringBossWave = true bAllowSpawnReplacementDuringBossWave = true
bHealAfterKill = false bHealAfterKill = false
bHealWithHeadshot = false
bCannotBeHealed = false bCannotBeHealed = false
bGlobalDamageAffectsShield = true bGlobalDamageAffectsShield = true
bApplyGlobalDamageBossWave = true bApplyGlobalDamageBossWave = true
@ -419,11 +430,13 @@ struct WeeklyOverrides
bAddSpawnListToLoadout = false bAddSpawnListToLoadout = false
bSpawnWeaponListAffectsSecondaryWeapons = false bSpawnWeaponListAffectsSecondaryWeapons = false
bColliseumSkillConditionsActive = false bColliseumSkillConditionsActive = false
bWildWestSkillConditionsActive = false
bModifyZedTimeOnANearZedKill = false bModifyZedTimeOnANearZedKill = false
ZedTimeOnANearZedKill = 0.05 ZedTimeOnANearZedKill = 0.05
DoshOnKillGlobalModifier = 1.0f DoshOnKillGlobalModifier = 1.0f
JumpZ = -1.f JumpZ = -1.f
DroppedItemLifespan=-1.0f DroppedItemLifespan=-1.0f
bForceWWLMusic = false;
} }
}; };

View File

@ -313,7 +313,7 @@ function PossessedBy(Controller C, bool bVehicleTransition)
} }
KFGameInfo(WorldInfo.Game).OverrideHumanDefaults( self ); KFGameInfo(WorldInfo.Game).OverrideHumanDefaults( self );
SetTimer(0.5f, false, nameof(ClientOverrideHumanDefaults), self);
} }
simulated function NotifyTeamChanged() simulated function NotifyTeamChanged()
@ -2114,6 +2114,36 @@ event Landed(vector HitNormal, actor FloorActor)
} }
} }
// Used for override aesthetics
client reliable function ClientOverrideHumanDefaults()
{
local KFPlayerController_WeeklySurvival KFPC_WS;
local KFPlayerReplicationInfo KFPRI;
local KFCharacterInfo_Human KFCIH;
local int CowboyHatIndex;
KFPC_WS = KFPlayerController_WeeklySurvival(Controller);
if (KFPC_WS == none)
{
return;
}
if (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12)
{
KFPRI = KFPlayerReplicationInfo(KFPC_WS.PlayerReplicationInfo);
if (KFPRI != none)
{
KFCIH = KFPRI.CharacterArchetypes[KFPRI.RepCustomizationInfo.CharacterIndex];
CowboyHatIndex = class'KFGFxMenu_Gear'.static.FindCowboyHatAttachmentIndex(KFCIH);
if (CowboyHatIndex >= 0)
{
KFCIH.DetachConflictingAttachments(CowboyHatIndex, self, KFPRI);
KFPRI.SetWeeklyCharacterAttachment(CowboyHatIndex, 0);
}
}
}
}
defaultproperties defaultproperties
{ {
Begin Object Class=KFFlashlightAttachment name=Flashlight_0 Begin Object Class=KFFlashlightAttachment name=Flashlight_0

View File

@ -92,6 +92,10 @@ var() array<name> WeakSpotSocketNames;
var int HealByKill; var int HealByKill;
var int HealByAssistance; var int HealByAssistance;
/** WWL Hat attach name*/
var name ZEDCowboyHatAttachName;
/** /**
* Information on resistant or vulnerable damage types * Information on resistant or vulnerable damage types
* @todo: This is all static data so we should consider moving to the archetype * @todo: This is all static data so we should consider moving to the archetype
@ -540,6 +544,14 @@ var byte PreviousArmorZoneStatus;
//Hit FX overrides for hitting armor //Hit FX overrides for hitting armor
var const int OverrideArmorFXIndex; var const int OverrideArmorFXIndex;
/*********************************************************************************************
* @name Parasite Weapon
********************************************************************************************* */
var array<KFProjectile> ParasiteSeeds;
// Max num of seeds in this character
var byte MaxNumSeeds;
/********************************************************************************************* /*********************************************************************************************
* @name Delegates * @name Delegates
********************************************************************************************* */ ********************************************************************************************* */
@ -2573,6 +2585,7 @@ function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLo
{ {
local KFPlayerController KFPC; local KFPlayerController KFPC;
local KFPerk InstigatorPerk; local KFPerk InstigatorPerk;
local int i;
if ( super.Died(Killer, damageType, HitLocation) ) if ( super.Died(Killer, damageType, HitLocation) )
{ {
@ -2613,6 +2626,16 @@ function bool Died(Controller Killer, class<DamageType> DamageType, vector HitLo
} }
} }
if (ParasiteSeeds.Length > 0)
{
for (i = 0; i < ParasiteSeeds.Length; ++i)
{
ParasiteSeeds[i].Explode(Location - (vect(0,0,1) * GetCollisionHeight()), vect(0,0,1) >> ParasiteSeeds[i].Rotation);
}
ParasiteSeeds.Remove(0, ParasiteSeeds.Length);
}
OnZedDied(Killer); OnZedDied(Killer);
return true; return true;
@ -4732,6 +4755,30 @@ function ZedExplodeArmor(int ArmorZoneIdx, name ArmorZoneName)
} }
} }
/*********************************************************************************************
* @name Armor
********************************************************************************************* */
server reliable function AddParasiteSeed(KFProjectile Proj)
{
local int i;
if (Role < ROLE_AUTHORITY)
return;
if (ParasiteSeeds.Length >= MaxNumSeeds)
{
for (i = 0; i < ParasiteSeeds.Length - (MaxNumSeeds-1); ++i)
{
ParasiteSeeds[i].Detonate();
}
ParasiteSeeds.Remove(0, ParasiteSeeds.Length - (MaxNumSeeds-1));
}
ParasiteSeeds.AddItem(Proj);
}
/********************************************************************************************* /*********************************************************************************************
* @name Achievements * @name Achievements
********************************************************************************************* */ ********************************************************************************************* */
@ -4927,4 +4974,7 @@ DefaultProperties
bSprintOverride=false bSprintOverride=false
VortexAttracionModifier=1.0f VortexAttracionModifier=1.0f
MaxNumSeeds=1
ZEDCowboyHatAttachName=HEAD_Attach
} }

View File

@ -348,7 +348,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
*/ */
simulated function bool GetIsUberAmmoActive( KFWeapon KFW ) simulated function bool GetIsUberAmmoActive( KFWeapon KFW )
{ {
return IsWeaponOnPerk( KFW,, self.class ) && IsUberAmmoActive() && WorldInfo.TimeDilation < 1.f; return IsWeaponOnPerk( KFW,, self.class ) && IsUberAmmoActive() && WorldInfo.TimeDilation < 1.f && !ShouldDisableZedTimeSkillsForWildWest();
} }
/** /**
@ -664,7 +664,7 @@ simulated function bool IsFanfareActive()
*/ */
simulated function bool GetFanfareActive() simulated function bool GetFanfareActive()
{ {
return IsFanfareActive(); return IsFanfareActive() || IsFanfareActiveForWildWest();
} }
/** /**
@ -798,6 +798,28 @@ simulated function LogPerkSkills()
} }
} }
/*********************************************************************************************
* @name Special Weekly Modes
********************************************************************************************* */
simulated function bool ShouldDisableZedTimeSkillsForWildWest()
{
if (WorldInfo.NetMode == NM_Client)
{
return MyKFGRI.bIsWeeklyMode && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12;
}
else
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bWildWestSkillConditionsActive;
}
}
function bool IsFanfareActiveForWildWest()
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bWildWestSkillConditionsActive;
}
DefaultProperties DefaultProperties
{ {
PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Gunslinger' PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Gunslinger'

View File

@ -52,6 +52,8 @@ var float SkillZedTimeChance;
var private transient bool bWasHeadshot; var private transient bool bWasHeadshot;
var private float FanFareModifier;
/********************************************************************************************* /*********************************************************************************************
* @name Stats/XP * @name Stats/XP
********************************************************************************************* */ ********************************************************************************************* */
@ -446,7 +448,7 @@ simulated function bool IsAmmoPouchActive()
*/ */
simulated function bool IsZTKnockdownActive() simulated function bool IsZTKnockdownActive()
{ {
return PerkSkills[ESharpshooterZTKnockdown].bActive && IsPerkLevelAllowed(ESharpshooterZTKnockdown); return PerkSkills[ESharpshooterZTKnockdown].bActive && IsPerkLevelAllowed(ESharpshooterZTKnockdown) && !ShouldDisableZedTimeSkillsForWildWest();
} }
/** /**
@ -466,7 +468,7 @@ simulated function bool GetZTKnockdownActive()
*/ */
simulated function bool IsZTStunActive() simulated function bool IsZTStunActive()
{ {
return PerkSkills[ESharpshooterZTStun].bActive && IsPerkLevelAllowed(ESharpshooterZTStun); return PerkSkills[ESharpshooterZTStun].bActive && IsPerkLevelAllowed(ESharpshooterZTStun) && !ShouldDisableZedTimeSkillsForWildWest();
} }
/** /**
@ -658,6 +660,62 @@ static simulated function bool IsWeaponOnPerk( KFWeapon W, optional array < clas
return super.IsWeaponOnPerk( W, WeaponPerkClass, InstigatorPerkClass, WeaponClassName ); return super.IsWeaponOnPerk( W, WeaponPerkClass, InstigatorPerkClass, WeaponClassName );
} }
/*********************************************************************************************
* @name Special Weekly Modes
********************************************************************************************* */
/**
* @brief Skills can modify the zed time time delation (Forced during wild west weekly)
*
* @param W used weapon
* @return time dilation modifier
*/
simulated function float GetZedTimeModifier( KFWeapon W )
{
local name StateName;
if( IsFanfareActiveForWildWest() && IsWeaponOnPerk( W,, self.class ) )
{
StateName = W.GetStateName();
if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
{
return FanFareModifier;
}
if( StateName == 'Reloading' )
{
return 1.f;
}
}
return 0.f;
}
function bool ShouldDisableZedTimeSkillsForWildWest()
{
if (WorldInfo.NetMode == NM_Client)
{
return MyKFGRI.bIsWeeklyMode && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12;
}
else
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bWildWestSkillConditionsActive;
}
}
simulated function bool IsFanfareActiveForWildWest()
{
if (WorldInfo.NetMode == NM_Client)
{
return MyKFGRI.bIsWeeklyMode && class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12;
}
else
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bWildWestSkillConditionsActive;
}
}
DefaultProperties DefaultProperties
{ {
PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Sharpshooter' PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Sharpshooter'
@ -732,4 +790,5 @@ DefaultProperties
AssistDoshModifier=1.1f AssistDoshModifier=1.1f
bWasHeadshot = false; bWasHeadshot = false;
FanFareModifier = 1.0f;
} }

View File

@ -23,6 +23,7 @@ var private const float RapidAssaultFiringRate; // Faster firing rate
var private const float SnarePower; var private const float SnarePower;
var private const float TacticalMovementBobDamp; var private const float TacticalMovementBobDamp;
var private const class<KFWeaponDefinition> BackupSecondaryWeaponDef; var private const class<KFWeaponDefinition> BackupSecondaryWeaponDef;
var private const float TacticalMovementModifier; // QoL: Tactical movement - Added modifier to move and sprint speed.
/** Percentage of how much armor should be damaged when the heavy armor skill is active */ /** Percentage of how much armor should be damaged when the heavy armor skill is active */
var private const float HeavyArmorAbsorptionPct; var private const float HeavyArmorAbsorptionPct;
@ -277,7 +278,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
if( KFW != none ) if( KFW != none )
{ {
if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW )) ) if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW ) || ClassIsChildOf(DamageType, class'KFDT_Bludgeon')) )
{ {
`QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk ); `QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk );
TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] ); TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] );
@ -467,6 +468,68 @@ simulated function int GetArmorDamageAmount( int AbsorbedAmt )
return AbsorbedAmt; return AbsorbedAmt;
} }
/**
* @brief Weapons and perk skills can affect the jog/sprint speed
*
* @param Speed jog speed
*/
simulated function ModifySpeed( out float Speed )
{
local KFWeapon MyKFWeapon;
local KFInventoryManager KFIM;
if( !IsTacticalMovementActive() )
{
return;
}
MyKFWeapon = GetOwnerWeapon();
if( MyKFWeapon == none && CheckOwnerPawn() )
{
KFIM = KFInventoryManager(OwnerPawn.InvManager);
if( KFIM != none && KFIM.PendingWeapon != none )
{
MyKFWeapon = KFWeapon(KFIM.PendingWeapon);
}
}
if (MyKFWeapon != none && (Is9mm(MyKFWeapon) || IsDual9mm( MyKFWeapon ) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{
Speed += Speed * TacticalMovementModifier;
}
}
/**
* @brief Weapons and perk skills can affect the jog/sprint speed
*
* @param Speed sprint speed
*/
simulated function ModifySprintSpeed( out float Speed )
{
local KFWeapon MyKFWeapon;
local KFInventoryManager KFIM;
if( !IsTacticalMovementActive() )
{
return;
}
MyKFWeapon = GetOwnerWeapon();
if( MyKFWeapon == none && CheckOwnerPawn() )
{
KFIM = KFInventoryManager(OwnerPawn.InvManager);
if( KFIM != none && KFIM.PendingWeapon != none )
{
MyKFWeapon = KFWeapon(KFIM.PendingWeapon);
}
}
if (MyKFWeapon != none && (Is9mm(MyKFWeapon) || IsDual9mm( MyKFWeapon ) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{
Speed += Speed * TacticalMovementModifier;
}
}
/********************************************************************************************* /*********************************************************************************************
* @name Getters etc * @name Getters etc
********************************************************************************************* */ ********************************************************************************************* */
@ -649,7 +712,7 @@ DefaultProperties
PerkSkills(ESWAT_HeavyArmor)=(Name="HeavyArmor",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_HeavyArmor", Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f) //0.1 PerkSkills(ESWAT_HeavyArmor)=(Name="HeavyArmor",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_HeavyArmor", Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f) //0.1
PerkSkills(ESWAT_TacticalMovement)=(Name="TacticalMovement",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_TacticalMovement", Increment=0.f,Rank=0,StartingValue=2.5f,MaxValue=2.5f) PerkSkills(ESWAT_TacticalMovement)=(Name="TacticalMovement",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_TacticalMovement", Increment=0.f,Rank=0,StartingValue=2.5f,MaxValue=2.5f)
PerkSkills(ESWAT_Backup)=(Name="Backup",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_Backup", Increment=0.f,Rank=0,StartingValue=0.85f,MaxValue=0.85f) //1.1 PerkSkills(ESWAT_Backup)=(Name="Backup",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_Backup", Increment=0.f,Rank=0,StartingValue=1.0f,MaxValue=1.0f) //0.85f
PerkSkills(ESWAT_TacticalReload)=(Name="TacticalReload",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_TacticalReload", Increment=0.f,Rank=0,StartingValue=2.0,MaxValue=2.0) PerkSkills(ESWAT_TacticalReload)=(Name="TacticalReload",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_TacticalReload", Increment=0.f,Rank=0,StartingValue=2.0,MaxValue=2.0)
PerkSkills(ESWAT_SpecialAmmunition)=(Name="SpecialAmmunition",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_SpecialAmmunition", Increment=0.f,Rank=0,StartingValue=2.0f,MaxValue=2.0f) PerkSkills(ESWAT_SpecialAmmunition)=(Name="SpecialAmmunition",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_SpecialAmmunition", Increment=0.f,Rank=0,StartingValue=2.0f,MaxValue=2.0f)
PerkSkills(ESWAT_AmmoVest)=(Name="AmmoVest",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_AmmoVest", Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f) PerkSkills(ESWAT_AmmoVest)=(Name="AmmoVest",IconPath="UI_PerkTalent_TEX.SWAT.UI_Talents_SWAT_AmmoVest", Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f)
@ -675,4 +738,6 @@ DefaultProperties
SWATEnforcerZedTimeSpeedScale=1.25f SWATEnforcerZedTimeSpeedScale=1.25f
BumpCooldown = 0.1f BumpCooldown = 0.1f
TacticalMovementModifier = 0.2;
} }

View File

@ -287,6 +287,8 @@ var name EffectPainParamName;
var name EffectLowHealthParamName; var name EffectLowHealthParamName;
/** Name of the MIC parameter used to display zed time */ /** Name of the MIC parameter used to display zed time */
var name EffectZedTimeParamName; var name EffectZedTimeParamName;
/** Name of the MIC parameter used to display zed time sepia*/
var name EffectZedTimeSepiaParamName;
/** Name of the MIC parameter used to display night vision time */ /** Name of the MIC parameter used to display night vision time */
var name EffectNightVisionParamName; var name EffectNightVisionParamName;
/** Name of the MIC parameter used to display Siren's scream attack effect */ /** Name of the MIC parameter used to display Siren's scream attack effect */
@ -1546,7 +1548,6 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful)
local KFProfileSettings Profile; local KFProfileSettings Profile;
local KFPlayerInput KFInput; local KFPlayerInput KFInput;
local KFGameInfo KFGI; local KFGameInfo KFGI;
local KFGameReplicationInfo KFGRI;
local KFGameEngine KFEngine; local KFGameEngine KFEngine;
local KFPlayerReplicationInfo KFPRI; local KFPlayerReplicationInfo KFPRI;
local string MatchmakingRegion; local string MatchmakingRegion;
@ -1590,7 +1591,7 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful)
KFInput.GamepadAccelerationJumpScale = Profile.GetProfileFloat(KFID_GamepadAccelerationJumpScale); KFInput.GamepadAccelerationJumpScale = Profile.GetProfileFloat(KFID_GamepadAccelerationJumpScale);
KFInput.SetGamepadLayout(Profile.GetProfileInt(KFID_CurrentLayoutIndex)); KFInput.SetGamepadLayout(Profile.GetProfileInt(KFID_CurrentLayoutIndex));
KFInput.bToggleToRun = Profile.GetProfileBool(KFID_ToggleToRun); KFInput.bToggleToRun = Profile.GetProfileBool(KFID_ToggleToRun);
KFInput.bAllowSwapTo9mm = Profile.GetProfileBool(KFID_AllowSwapTo9mm);
KFInput.ReInitializeControlsUI(); KFInput.ReInitializeControlsUI();
} }
@ -1686,37 +1687,21 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful)
OnlineSub.GetLobbyInterface().LobbyInvite(LobbyId, Zero, true); OnlineSub.GetLobbyInterface().LobbyInvite(LobbyId, Zero, true);
} }
// If the perk is not allowed for this game mode, search for one that is available starting from the index 0 SavedPerkIndex = CheckCurrentPerkAllowed();
KFGRI = KFGameReplicationInfo(WorldInfo.GRI); // Save the new perk selected in the the profile settings
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex );
if( KFGRI != none && !KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
SavedPerkIndex = 0;
for(SavedPerkIndex=0 ; SavedPerkIndex<PerkList.length ; SavedPerkIndex++)
{
if( KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
continue;
}
}
// Save the new perk selected in the the profile settings
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex );
}
// Update our cached Emote Id // Update our cached Emote Id
class'KFEmoteList'.static.RefreshCachedEmoteId(); class'KFEmoteList'.static.RefreshCachedEmoteId();
class'KFHeadShotEffectList'.static.RefreshCachedHeadShotEffectId(); class'KFHeadShotEffectList'.static.RefreshCachedHeadShotEffectId();
} }
function UpdatePerkOnInit() simulated function byte CheckCurrentPerkAllowed()
{ {
local KFGameReplicationInfo KFGRI; local KFGameReplicationInfo KFGRI;
local KFProfileSettings Profile;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
// If the perk is not allowed for this game mode, search for one that is available starting from the index 0 // If the perk is not allowed for this game mode, search for one that is available starting from the index 0
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if( KFGRI != none && !KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) ) if( KFGRI != none && !KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{ {
SavedPerkIndex = 0; SavedPerkIndex = 0;
@ -1724,16 +1709,25 @@ function UpdatePerkOnInit()
{ {
if( KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) ) if( KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{ {
continue; break;
} }
} }
}
// Save the new perk selected in the the profile settings
Profile = KFProfileSettings(OnlineSub.PlayerInterface.GetProfileSettings(StoredLocalUserNum)); return SavedPerkIndex;
if( Profile != None ) }
{
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex ); function UpdatePerkOnInit()
} {
local KFProfileSettings Profile;
SavedPerkIndex = CheckCurrentPerkAllowed();
// Save the new perk selected in the the profile settings
Profile = KFProfileSettings(OnlineSub.PlayerInterface.GetProfileSettings(StoredLocalUserNum));
if( Profile != None )
{
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex );
} }
} }
@ -5236,6 +5230,7 @@ function ResetGameplayPostProcessFX()
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectPainParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectPainParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectLowHealthParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectLowHealthParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectZedTimeParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectZedTimeParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectZedTimeSepiaParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectNightVisionParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectNightVisionParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectSirenScreamParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectSirenScreamParamName, 0.f);
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectBloatsPukeParamName, 0.f); GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectBloatsPukeParamName, 0.f);
@ -5267,6 +5262,8 @@ function bool ShouldDisplayGameplayPostProcessFX()
HealEffectTimeRemaining > 0.f || HealEffectTimeRemaining > 0.f ||
/* ZED time effect is active */ /* ZED time effect is active */
CurrentZEDTimeEffectIntensity > 0.f || CurrentZEDTimeEffectIntensity > 0.f ||
/* sepia effect */
(class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12) ||
/* Night vision active */ /* Night vision active */
bNightVisionActive || bNightVisionActive ||
SirenScreamEffectTimeRemaining > 0.f || SirenScreamEffectTimeRemaining > 0.f ||
@ -11726,6 +11723,7 @@ defaultproperties
PainEffectDuration=0.5f PainEffectDuration=0.5f
EffectLowHealthParamName=Effect_LowHealth EffectLowHealthParamName=Effect_LowHealth
EffectZedTimeParamName=Effect_ZEDTIME EffectZedTimeParamName=Effect_ZEDTIME
EffectZedTimeSepiaParamName=Effect_ZEDSEPIA
EffectNightVisionParamName=Effect_NightVision EffectNightVisionParamName=Effect_NightVision
EffectSirenScreamParamName=Effect_Siren EffectSirenScreamParamName=Effect_Siren
SonicScreamEffectDuration=6.f SonicScreamEffectDuration=6.f

View File

@ -195,6 +195,17 @@ reliable client function GoompaStompMessage( byte StompNum)
} }
} }
/** Resets all gameplay FX to initial state.
Append to this list if additional effects are added. */
function ResetGameplayPostProcessFX()
{
super.ResetGameplayPostProcessFX();
if( GameplayPostProcessEffectMIC != none && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
{
GameplayPostProcessEffectMIC.SetScalarParameterValue(EffectZedTimeSepiaParamName, 1.f);
}
}
// //
defaultProperties defaultProperties

View File

@ -227,6 +227,11 @@ var const float DoubleTapDelay;
********************************************************************************************* */ ********************************************************************************************* */
var bool bToggleToRun; var bool bToggleToRun;
/*********************************************************************************************
* @name Run/Sprint
********************************************************************************************* */
var bool bAllowSwapTo9mm;
/********************************************************************************************* /*********************************************************************************************
* @name Game class * @name Game class
********************************************************************************************* */ ********************************************************************************************* */

View File

@ -198,6 +198,7 @@ cpptext
native function bool StartLoadCosmeticContent(KFCharacterInfo_Human CharArch, INT CosmeticType, INT CosmeticIdx); native function bool StartLoadCosmeticContent(KFCharacterInfo_Human CharArch, INT CosmeticType, INT CosmeticIdx);
native function StartLoadHeadshotFxContent(); native function StartLoadHeadshotFxContent();
native function SetWeeklyCharacterAttachment(INT AttachmentIndex, int AttachmentSkin);
replication replication
{ {

View File

@ -254,7 +254,6 @@ defaultproperties
ProfileMappings.Add((Id=KFID_GamepadDeadzoneScale, Name="Gamepad Deadzone", MappingType=PVMT_RawValue)) ProfileMappings.Add((Id=KFID_GamepadDeadzoneScale, Name="Gamepad Deadzone", MappingType=PVMT_RawValue))
ProfileMappings.Add((Id=KFID_GamepadAccelerationJumpScale, Name="Gamepad Acceleration Jump", MappingType=PVMT_RawValue)) ProfileMappings.Add((Id=KFID_GamepadAccelerationJumpScale, Name="Gamepad Acceleration Jump", MappingType=PVMT_RawValue))
//Added 7/11/2016 //Added 7/11/2016
ProfileMappings.Add((Id=KFID_UseAltAimOnDuals, Name="Use alt Dual Aim", MappingType=PVMT_RawValue)) ProfileMappings.Add((Id=KFID_UseAltAimOnDuals, Name="Use alt Dual Aim", MappingType=PVMT_RawValue))
ProfileMappings.Add((Id=KFID_HideBossHealthBar, Name="Hide Boss Health Bar", MappingType=PVMT_RawValue)) ProfileMappings.Add((Id=KFID_HideBossHealthBar, Name="Hide Boss Health Bar", MappingType=PVMT_RawValue))
@ -377,4 +376,8 @@ defaultproperties
//Saber Added 10/15/2020 - Has Enter to Store Tab during sales //Saber Added 10/15/2020 - Has Enter to Store Tab during sales
ProfileMappings.Add((Id = KFID_HasTabbedToStore, Name = "Has Tabbed To Store", MappingType = PVMT_RawValue)) ProfileMappings.Add((Id = KFID_HasTabbedToStore, Name = "Has Tabbed To Store", MappingType = PVMT_RawValue))
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_HasTabbedToStore,Data=(Type=SDT_Int32,Value1=0)))) DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_HasTabbedToStore,Data=(Type=SDT_Int32,Value1=0))))
// Added 16/07/2021 - QoL: Quick Swap button allowing 9mm as an option.
ProfileMappings.Add((Id=KFID_AllowSwapTo9mm, Name="AllowSwitchTo9mm", MappingType=PVMT_RawValue))
DefaultSettings.Add((Owner=OPPO_Game,ProfileSetting=(PropertyId=KFID_AllowSwapTo9mm,Data=(Type=SDT_Int32,Value1=0))))
} }

View File

@ -90,7 +90,8 @@ event PreBeginPlay()
WeaponClass = Instigator.Weapon.Class; WeaponClass = Instigator.Weapon.Class;
// These better be the same or someone messed up // These better be the same or someone messed up
if ( WeaponClass.Name != WeaponClassName ) if ( WeaponClass.Name != WeaponClassName &&
(class<KFWeap_DualBase>(WeaponClass) == none || class<KFWeap_DualBase>(WeaponClass).default.SingleClass.Name != WeaponClassName))
{ {
`warn("Projectile pickup mismatch class:"$WeaponClass@"name:"$WeaponClassName); `warn("Projectile pickup mismatch class:"$WeaponClass@"name:"$WeaponClassName);
} }
@ -222,11 +223,17 @@ state Pickup
function GiveTo( Pawn P ) function GiveTo( Pawn P )
{ {
local KFWeapon W; local KFWeapon W;
local class<KFWeapon> KFWeaponClass;
local class<KFWeap_DualBase> DualWeaponClass;
KFWeaponClass = class<KFWeapon>(WeaponClass);
DualWeaponClass = class<KFWeap_DualBase>(WeaponClass);
foreach P.InvManager.InventoryActors( class'KFWeapon', W ) foreach P.InvManager.InventoryActors( class'KFWeapon', W )
{ {
// Give the player 1 shot back // Give the player 1 shot back
if( W.Class == WeaponClass ) if( W.Class == WeaponClass || (DualWeaponClass != none ? DualWeaponClass.default.SingleClass == W.Class
: KFWeaponClass.default.DualClass == W.Class))
{ {
W.AddAmmo(1); W.AddAmmo(1);

View File

@ -181,7 +181,7 @@ function SetFrozenParameter(float FreezeAmount)
{ {
local MaterialInstanceConstant MIC; local MaterialInstanceConstant MIC;
local int i; local int i;
local bool bIsWWLMode;
if ( PawnOwner.WorldInfo.NetMode != NM_DedicatedServer ) if ( PawnOwner.WorldInfo.NetMode != NM_DedicatedServer )
{ {
FreezeMatParamValue = FreezeAmount; FreezeMatParamValue = FreezeAmount;
@ -201,9 +201,11 @@ function SetFrozenParameter(float FreezeAmount)
if (KFPawn_Monster(KFPOwner) != none) if (KFPawn_Monster(KFPOwner) != none)
{ {
bIsWWLMode = class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12 && KFGameReplicationInfo(PawnOwner.WorldInfo.GRI) != none && KFGameReplicationInfo(PawnOwner.WorldInfo.GRI).bIsWeeklyMode;
for (i = 0; i < KFPawn_Monster(KFPOwner).StaticAttachList.length; i++) for (i = 0; i < KFPawn_Monster(KFPOwner).StaticAttachList.length; i++)
{ {
if (KFPawn_Monster(KFPOwner).StaticAttachList[i] != none) if (KFPawn_Monster(KFPOwner).StaticAttachList[i] != none && (!bIsWWLMode || KFPawn_Monster(KFPOwner).StaticAttachList[i].StaticMesh.Name != 'CHR_CowboyHat_Alberts_Cosmetic' ))
{ {
ApplyFreeze(KFPawn_Monster(KFPOwner).StaticAttachList[i]); ApplyFreeze(KFPawn_Monster(KFPOwner).StaticAttachList[i]);
} }

View File

@ -38,9 +38,11 @@ enum EEffectDamageGroup
FXG_Bludgeon_Chains, FXG_Bludgeon_Chains,
FXG_MicrowaveProj, FXG_MicrowaveProj,
FXG_Electricity, FXG_Electricity,
FXG_Slashing_Ion FXG_Slashing_Ion,
FXG_Energy_Yellow,
FXG_Energy_Magenta
}; };
const FXG_MAX = 20; //!! Update me when the enum gets modified !! const FXG_MAX = 22; //!! Update me when the enum gets modified !!
struct native SkinEffectInfo struct native SkinEffectInfo
{ {

View File

@ -246,6 +246,11 @@ static private event bool CheckCustomizationOwnership(KFPlayerReplicationInfo PR
// accessory // accessory
for( i=0; i < `MAX_COSMETIC_ATTACHMENTS; i++ ) for( i=0; i < `MAX_COSMETIC_ATTACHMENTS; i++ )
{ {
if (i == 2 && PRI.WorldInfo.GRI.IsA('KFGameReplicationInfo_WeeklySurvival') && (class'KFGameEngine'.static.GetWeeklyEventIndexMod() == 12))
{
continue;
}
if (PRI.RepCustomizationInfo.AttachmentSkinIndices[i] == INDEX_NONE) if (PRI.RepCustomizationInfo.AttachmentSkinIndices[i] == INDEX_NONE)
{ {
continue; continue;

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFWeapDef_BladedPistol
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_BladedPistol extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_Pistol_Bladed"
BuyPrice=600
AmmoPricePerMag=32
ImagePath="WEP_UI_BladedPistol_TEX.UI_WeaponSelect_BladedPistol"
EffectiveRange=25
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradeSellPrice[0]=550
UpgradeSellPrice[1]=1650
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFWeapDef_DualBladed
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_DualBladed extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_Pistol_DualBladed"
BuyPrice=1200
AmmoPricePerMag=64
ImagePath="WEP_UI_Dual_BladedPistol_TEX.UI_WeaponSelect_Dual_BladedPistol"
EffectiveRange=50
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradeSellPrice[0]=525
UpgradeSellPrice[1]=1650
}

View File

@ -0,0 +1,30 @@
//=============================================================================
// KFWeapDef_HRG_Boomy
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_Boomy extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_Boomy"
BuyPrice=650
AmmoPricePerMag=30 //50
ImagePath="WEP_UI_HRG_Boomy_TEX.UI_WeaponSelect_HRG_Boomy"
EffectiveRange=50
UpgradePrice[0]=600
UpgradePrice[1]=700
UpgradePrice[2]=1500
UpgradeSellPrice[0]=450
UpgradeSellPrice[1]=975
UpgradeSellPrice[2]=2100
}

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFWeapDef_HRG_Energy
//=============================================================================
// A lightweight container for basic weapon properties that can be safely
// accessed without a weapon actor (UI, remote clients).
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_Energy extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_Energy"
BuyPrice=1500 //1100
AmmoPricePerMag=65
ImagePath="WEP_UI_HRG_Energy_TEX.UI_WeaponSelect_HRG_Energy"
EffectiveRange=50
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
}

View File

@ -15,7 +15,7 @@ DefaultProperties
WeaponClassPath="KFGameContent.KFWeap_Blunt_MedicBat" WeaponClassPath="KFGameContent.KFWeap_Blunt_MedicBat"
BuyPrice=1200 BuyPrice=1200
AmmoPricePerMag=85 AmmoPricePerMag=75 //85
ImagePath="WEP_UI_Medic_Bat_TEX.UI_WeaponSelect_MedicBat" ImagePath="WEP_UI_Medic_Bat_TEX.UI_WeaponSelect_MedicBat"
EffectiveRange=3 EffectiveRange=3

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFWeapDef_ParasiteImplanter
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_ParasiteImplanter extends KFWeaponDefinition
abstract;
defaultproperties
{
WeaponClassPath="KFGameContent.KFWeap_Rifle_ParasiteImplanter"
ImagePath="wep_ui_parasiteimplanter_tex.UI_WeaponSelect_ParasiteImplanter"
BuyPrice=1500
AmmoPricePerMag=42
EffectiveRange=90
UpgradePrice[0]=1500
UpgradeSellPrice[0]=1125
// SharedUnlockId=SCU_ParasiteImplanter
}

View File

@ -545,6 +545,9 @@ var transient bool bCheckBoltLockPostReload;
/** array of bones to lock when out of ammo */ /** array of bones to lock when out of ammo */
var array<name> BonesToLockOnEmpty; var array<name> BonesToLockOnEmpty;
/** Handle impact effects on impact manager */
var bool bForceHandleImpacts;
/********************************************************************************************* /*********************************************************************************************
* @name Sounds * @name Sounds
********************************************************************************************* */ ********************************************************************************************* */
@ -8000,6 +8003,7 @@ defaultproperties
bKeepIronSightsOnJump=false bKeepIronSightsOnJump=false
bUsesSecondaryAmmoAltHUD = false bUsesSecondaryAmmoAltHUD=false
bForceHandleImpacts=false
} }

View File

@ -3559,66 +3559,165 @@ defaultproperties
//Thermite Thunder Jaws //Thermite Thunder Jaws
Skins.Add((Id=8945, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_ThunderJaws_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_ThunderJaws_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_ThunderJaws_MIC")); Skins.Add((Id=8945, Weapondef=class'KFWeapDef_ThermiteBore', MIC_1P=("WEP_SkinSet46_MAT.Wep_1stP_Thermite_ThunderJaws_MIC"), MIC_3P="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_ThunderJaws_MIC", MIC_Pickup="WEP_SkinSet46_MAT.Wep_3rdP_Thermite_Pickup_ThunderJaws_MIC"));
//BeyondHorizon AA12 //Corrupter Carbine Standard
Skins.Add((Id=8845, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.space_aa12.Space_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_aa12.Space_AA12_3P_Pickup_MIC")) Skins.Add((Id=9132, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("WEP_1P_ParasiteImplanter_MAT.Wep_1stP_ParasiteImplanter_PM", "WEP_1P_ParasiteImplanter_MAT.Wep_1stP_ParasiteImplanter_scope_PM"), MIC_3P="WEP_3P_ParasiteImplanter_MAT.Wep_3P_ParasiteImplanter_PM", MIC_Pickup="WEP_3P_ParasiteImplanter_MAT.WEP_3rdP_ParasiteImplanter_MIC"));
//BeyondHorizon AK12 //Corrupter Carbine Radioactive
Skins.Add((Id=8846, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.space_ak12.Space_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_ak12.Space_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Pickup_MIC")) Skins.Add((Id=9133, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("wep_skinset49_mat.Wep_ParasiteBody_Radioactive_PM", "wep_skinset49_mat.Wep_ParasiteScope_Radioactive_PM"), MIC_3P="wep_skinset49_mat.Wep_3rd_Parasite_Radioactive_PM", MIC_Pickup="wep_skinset49_mat.Wep_3rd_Parasite_Pickup_Radioactive_PM"));
//BeyondHorizon Desert Eagle //Corrupter Carbine Icy
Skins.Add((Id=8847, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.space_deagle.Space_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Pickup_MIC")) Skins.Add((Id=9134, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("wep_skinset49_mat.Wep_ParasiteBody_Icy_PM", "wep_skinset49_mat.Wep_ParasiteScope_Icy_PM"), MIC_3P="wep_skinset49_mat.Wep_3rd_Parasite_Icy_PM", MIC_Pickup="wep_skinset49_mat.Wep_3rd_Parasite_Pickup_Icy_PM"));
//BeyondHorizon Doomstick //Corrupter Carbine Danger
Skins.Add((Id=8848, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Pickup_MIC")) Skins.Add((Id=9135, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("wep_skinset49_mat.Wep_ParasiteBody_Deathranger_PM", "wep_skinset49_mat.Wep_ParasiteScope_Deathranger_PM"), MIC_3P="wep_skinset49_mat.Wep_3rd_Parasite_Deathranger_PM", MIC_Pickup="wep_skinset49_mat.Wep_3rd_Parasite_Pickup_Deathranger_PM"));
//BeyondHorizon Hemoclobber //Corrupter Carbine Lush
Skins.Add((Id=8849, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Pickup_MIC")) Skins.Add((Id=9136, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("wep_skinset49_mat.Wep_ParasiteBody_Lush_PM", "wep_skinset49_mat.Wep_ParasiteScope_Lush_PM"), MIC_3P="wep_skinset49_mat.Wep_3rd_Parasite_Lush_PM", MIC_Pickup="wep_skinset49_mat.Wep_3rd_Parasite_Pickup_Lush_PM"));
//BeyondHorizon HMTech-501 Grenade Rifle //Corrupter Carbine Lightning
Skins.Add((Id=8850, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Pickup_MIC")) Skins.Add((Id=9137, Weapondef=class'KFWeapDef_ParasiteImplanter', MIC_1P=("wep_skinset49_mat.Wep_ParasiteBody_Bluelightning_PM", "wep_skinset49_mat.Wep_ParasiteScope_Bluelightning_PM"), MIC_3P="wep_skinset49_mat.Wep_3rd_Parasite_Bluelightning_PM", MIC_Pickup="wep_skinset49_mat.Wep_3rd_Parasite_Pickup_Bluelightning_PM"));
//BeyondHorizon M32 //Piranha Standard
Skins.Add((Id=8851, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.space_m32.Space_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_m32.Space_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Pickup_MIC")) Skins.Add((Id=9126, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_1p_bladedpistol_mat.Wep_1stP_BladedPistol_MIC"), MIC_3P="wep_3p_bladedpistol_mat.WEP_3P_BladedPistol_MIC", MIC_Pickup="wep_3p_bladedpistol_mat.3P_Pickup_BladedPistol_MIC"));
//BeyondHorizon MAC 10 //Piranha Reptilian
Skins.Add((Id=8852, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.space_mac10.Space_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Pickup_MIC")) Skins.Add((Id=9127, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Reptilian_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Reptilian_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Reptilian_PM"));
//BeyondHorizon Microwave Gun //Piranha Phoenix
Skins.Add((Id=8853, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Pickup_MIC")) Skins.Add((Id=9128, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Phoenix_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Phoenix_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Phoenix_PM"));
//BeyondHorizon P90 //Piranha Copper
Skins.Add((Id=8854, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.space_p90.Space_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_p90.Space_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Pickup_MIC")) Skins.Add((Id=9129, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Angrycopper_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Angrycopper_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Angrycopper_PM"));
//Piranha Blade
Skins.Add((Id=9130, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Killerblade_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Killerblade_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Killerblade_PM"));
//Piranha Rusty
Skins.Add((Id=9131, Weapondef=class'KFWeapDef_BladedPistol', MIC_1P=("wep_skinset50_mat.Wep_Bladed_Rustynightmare_PM"), MIC_3P="wep_skinset50_mat.3rd_Wep_Bladed_Rustynightmare_PM", MIC_Pickup="wep_skinset50_mat.3rd_Wep_Bladed_Pickup_Rustynightmare_PM"));
//BeyondHorizon AA12 //BeyondHorizon AA12
Skins.Add((Id=8855, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Pickup_MIC")) 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"))
//BeyondHorizon AK12 //BeyondHorizon AK12
Skins.Add((Id=8856, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Pickup_MIC")) Skins.Add((Id=8846, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.space_ak12.Space_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_ak12.Space_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_ak12.Space_AK12_3P_Pickup_MIC"))
//BeyondHorizon Desert Eagle //BeyondHorizon Desert Eagle
Skins.Add((Id=8857, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Pickup_MIC")) Skins.Add((Id=8847, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.space_deagle.Space_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_deagle.Space_Deagle_3P_Pickup_MIC"))
//BeyondHorizon Doomstick //BeyondHorizon Doomstick
Skins.Add((Id=8858, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Pickup_MIC")) Skins.Add((Id=8848, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_quadbarrel.Space_QuadBarrel_3P_Pickup_MIC"))
//BeyondHorizon Hemoclobber //BeyondHorizon Hemoclobber
Skins.Add((Id=8859, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Pickup_MIC")) Skins.Add((Id=8849, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicbat.Space_MedicBat_3P_Pickup_MIC"))
//BeyondHorizon HMTech-501 Grenade Rifle //BeyondHorizon HMTech-501 Grenade Rifle
Skins.Add((Id=8860, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Pickup_MIC")) Skins.Add((Id=8850, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_medicgrenadelauncher.Space_MedicGrenadeLauncher_3P_Pickup_MIC"))
//BeyondHorizon M32 //BeyondHorizon M32
Skins.Add((Id=8861, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Pickup_MIC")) Skins.Add((Id=8851, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.space_m32.Space_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_m32.Space_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_m32.Space_M32_3P_Pickup_MIC"))
//BeyondHorizon MAC 10 //BeyondHorizon MAC 10
Skins.Add((Id=8862, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Pickup_MIC")) Skins.Add((Id=8852, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.space_mac10.Space_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_mac10.Space_MAC10_3P_Pickup_MIC"))
//BeyondHorizon Microwave Gun //BeyondHorizon Microwave Gun
Skins.Add((Id=8863, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Pickup_MIC")) Skins.Add((Id=8853, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_microwavegun.Space_MicrowaveGun_3P_Pickup_MIC"))
//BeyondHorizon P90 //BeyondHorizon P90
Skins.Add((Id=8864, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Pickup_MIC")) Skins.Add((Id=8854, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.space_p90.Space_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.space_p90.Space_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.space_p90.Space_P90_3P_Pickup_MIC"))
//BeyondHorizon AA12
Skins.Add((Id=8855, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_AA12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_aa12.SpaceElite_AA12_3P_Pickup_MIC"))
//BeyondHorizon AK12
Skins.Add((Id=8856, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_ak12.SpaceElite_AK12_3P_Pickup_MIC"))
//BeyondHorizon Desert Eagle
Skins.Add((Id=8857, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Deagle', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_deagle.SpaceElite_Deagle_3P_Pickup_MIC"))
//BeyondHorizon Doomstick
Skins.Add((Id=8858, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_quadbarrel.SpaceElite_QuadBarrel_3P_Pickup_MIC"))
//BeyondHorizon Hemoclobber
Skins.Add((Id=8859, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicbat.SpaceElite_MedicBat_3P_Pickup_MIC"))
//BeyondHorizon HMTech-501 Grenade Rifle
Skins.Add((Id=8860, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicRifleGrenadeLauncher', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_medicgrenadelauncher.SpaceElite_MedicGrenadeLauncher_3P_Pickup_MIC"))
//BeyondHorizon M32
Skins.Add((Id=8861, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_M32', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_m32.SpaceElite_M32_3P_Pickup_MIC"))
//BeyondHorizon MAC 10
Skins.Add((Id=8862, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Mac10', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_mac10.SpaceElite_MAC10_3P_Pickup_MIC"))
//BeyondHorizon Microwave Gun
Skins.Add((Id=8863, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MicrowaveGun', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_microwavegun.SpaceElite_MicrowaveGun_3P_Pickup_MIC"))
//BeyondHorizon P90
Skins.Add((Id=8864, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_P90', MIC_1P=("WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_1P_Mint_MIC", "WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet43_MAT.spaceelite_p90.SpaceElite_P90_3P_Pickup_MIC"))
//Scavenger AK12 //Scavenger AK12
Skins.Add((Id=8921, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_1P_Mint_MIC", "wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_Scope_1P_Mint_MIC"), MIC_3P="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Mint_MIC", MIC_Pickup="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Pickup_MIC")) Skins.Add((Id=8921, Weapondef=class'KFWeapDef_Ak12', MIC_1P=("wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_1P_Mint_MIC", "wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_Scope_1P_Mint_MIC"), MIC_3P="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Mint_MIC", MIC_Pickup="wep_skinset44_mat.scavenger_ak12.Scavenger_AK12_3P_Pickup_MIC"))
//Infernal Elite Kriss
Skins.Add((Id=9081, Weapondef=class'KFWeapDef_Kriss', MIC_1P=("wep_skinset47_mat.elite_kriss.Elite_Kriss_1P_Mint_MIC", "wep_skinset47_mat.elite_kriss.Elite_Kriss_Sight_1P_Mint_MIC"), MIC_3P="WEP_SkinSet47_MAT.elite_kriss.Elite_Kriss_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet47_MAT.elite_kriss.Elite_Kriss_3P_Pickup_MIC"))
//Hellmark Magma Katana
Skins.Add((Id=8991, Weapondef=class'KFWeapDef_Katana', MIC_1P=("WEP_SkinSet48_MAT.hellblade_katana.Hellblade_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_katana.Hellblade_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_katana.Hellblade_Katana_3P_Pickup_MIC"))
//Hellmark Magma BattleAxe
Skins.Add((Id=8992, Weapondef=class'KFWeapDef_AbominationAxe', MIC_1P=("WEP_SkinSet48_MAT.hellblade_krampusaxe.Hellblade_KrampusAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_krampusaxe.Hellblade_KrampusAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_krampusaxe.Hellblade_KrampusAxe_3P_Pickup_MIC"))
//Hellmark Magma Fire Axe
Skins.Add((Id=8993, Weapondef=class'KFWeapDef_FireAxe', MIC_1P=("WEP_SkinSet48_MAT.hellblade_fireaxe.Hellblade_FireAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_fireaxe.Hellblade_FireAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_fireaxe.Hellblade_FireAxe_3P_Pickup_MIC"))
//Hellmark Magma Bone Crusher
Skins.Add((Id=8994, Weapondef=class'KFWeapDef_MaceAndShield', MIC_1P=("WEP_SkinSet48_MAT.hellblade_maceshield.Hellblade_Mace_1P_Mint_MIC", "WEP_SkinSet48_MAT.hellblade_maceshield.Hellblade_Shield_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_maceshield.Hellblade_MaceAndShield_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_maceshield.Hellblade_MaceAndShield_3P_Pickup_MIC"))
//Hellmark Magma Pulverizer
Skins.Add((Id=8995, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet48_MAT.hellblade_pulverizer.Hellblade_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_pulverizer.Hellblade_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_pulverizer.Hellblade_Pulverizer_3P_Pickup_MIC"))
//Hellmark Magma Dragonsbreath
Skins.Add((Id=8996, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet48_MAT.hellblade_dragonsbreath.Hellblade_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_dragonsbreath.Hellblade_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_dragonsbreath.Hellblade_Dragonsbreath_3P_Pickup_MIC"))
//Hellmark Magma 500 Magnum Revolver
Skins.Add((Id=8997, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SW500', MIC_1P=("WEP_SkinSet48_MAT.hellblade_sw500.Hellblade_SW500_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_sw500.Hellblade_SW500_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_sw500.Hellblade_SW500_3P_Pickup_MIC"))
//Hellmark Magma RPG-7
Skins.Add((Id=8998, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet48_MAT.hellblade_rpg7.Hellblade_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_rpg7.Hellblade_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_rpg7.Hellblade_RPG7_3P_Pickup_MIC"))
//Hellmark Magma Doomstick
Skins.Add((Id=8999, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet48_MAT.hellblade_quadbarrel.Hellblade_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet48_MAT.hellblade_quadbarrel.Hellblade_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_quadbarrel.Hellblade_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_quadbarrel.Hellblade_QuadBarrel_3P_Pickup_MIC"))
//Hellmark Magma Hemoclobber
Skins.Add((Id=9000, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet48_MAT.hellblade_medicbat.Hellblade_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.hellblade_medicbat.Hellblade_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.hellblade_medicbat.Hellblade_MedicBat_3P_Pickup_MIC"))
//Hellmark Thunder Katana
Skins.Add((Id=9001, Weapondef=class'KFWeapDef_Katana', MIC_1P=("WEP_SkinSet48_MAT.thunder_katana.Thunder_Katana_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_katana.Thunder_Katana_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_katana.Thunder_Katana_3P_Pickup_MIC"))
//Hellmark Thunder BattleAxe
Skins.Add((Id=9002, Weapondef=class'KFWeapDef_AbominationAxe', MIC_1P=("WEP_SkinSet48_MAT.thunder_krampusaxe.Thunder_KrampusAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_krampusaxe.Thunder_KrampusAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_krampusaxe.Thunder_KrampusAxe_3P_Pickup_MIC"))
//Hellmark Thunder Fire Axe
Skins.Add((Id=9003, Weapondef=class'KFWeapDef_FireAxe', MIC_1P=("WEP_SkinSet48_MAT.thunder_fireaxe.Thunder_FireAxe_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_fireaxe.Thunder_FireAxe_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_fireaxe.Thunder_FireAxe_3P_Pickup_MIC"))
//Hellmark Thunder Bone Crusher
Skins.Add((Id=9004, Weapondef=class'KFWeapDef_MaceAndShield', MIC_1P=("WEP_SkinSet48_MAT.thunder_maceshield.Thunder_Mace_1P_Mint_MIC", "WEP_SkinSet48_MAT.thunder_maceshield.Thunder_Shield_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_maceshield.Thunder_MaceAndShield_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_maceshield.Thunder_MaceAndShield_3P_Pickup_MIC"))
//Hellmark Thunder Pulverizer
Skins.Add((Id=9005, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Pulverizer', MIC_1P=("WEP_SkinSet48_MAT.thunder_pulverizer.Thunder_Pulverizer_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_pulverizer.Thunder_Pulverizer_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_pulverizer.Thunder_Pulverizer_3P_Pickup_MIC"))
//Hellmark Thunder Dragonsbreath
Skins.Add((Id=9006, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_Dragonsbreath', MIC_1P=("WEP_SkinSet48_MAT.thunder_dragonsbreath.Thunder_Dragonsbreath_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_dragonsbreath.Thunder_Dragonsbreath_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_dragonsbreath.Thunder_Dragonsbreath_3P_Pickup_MIC"))
//Hellmark Thunder 500 Magnum Revolver
Skins.Add((Id=9007, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_SW500', MIC_1P=("WEP_SkinSet48_MAT.thunder_sw500.Thunder_SW500_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_sw500.Thunder_SW500_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_sw500.Thunder_SW500_3P_Pickup_MIC"))
//Hellmark Thunder RPG-7
Skins.Add((Id=9008, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_RPG7', MIC_1P=("WEP_SkinSet48_MAT.thunder_rpg7.Thunder_RPG7_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_rpg7.Thunder_RPG7_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_rpg7.Thunder_RPG7_3P_Pickup_MIC"))
//Hellmark Thunder Doomstick
Skins.Add((Id=9009, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_ElephantGun', MIC_1P=("WEP_SkinSet48_MAT.thunder_quadbarrel.Thunder_QuadBarrel_Main_1P_Mint_MIC", "WEP_SkinSet48_MAT.thunder_quadbarrel.Thunder_QuadBarrel_Barrel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_quadbarrel.Thunder_QuadBarrel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_quadbarrel.Thunder_QuadBarrel_3P_Pickup_MIC"))
//Hellmark Thunder Hemoclobber
Skins.Add((Id=9010, bNeedsCodeUpdates = true, Weapondef=class'KFWeapDef_MedicBat', MIC_1P=("WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_1P_Mint_MIC"), MIC_3P="WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet48_MAT.thunder_medicbat.Thunder_MedicBat_3P_Pickup_MIC"))
} }

View File

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

View File

@ -154,4 +154,5 @@ const STATID_ACHIEVE_HellmarkStationCollectibles = 4056;
const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057; const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057;
const STATID_ACHIEVE_Dystopia2029Collectibles = 4058; const STATID_ACHIEVE_Dystopia2029Collectibles = 4058;
const STATID_ACHIEVE_MoonbaseCollectibles = 4059; const STATID_ACHIEVE_MoonbaseCollectibles = 4059;
const STATID_ACHIEVE_NetherholdCollectibles = 4060;
/** `endif */ /** `endif */

View File

@ -73,3 +73,4 @@ const KFID_VOIPMicVolumeMultiplier = 174;
const KFID_GamepadDeadzoneScale = 175; const KFID_GamepadDeadzoneScale = 175;
const KFID_GamepadAccelerationJumpScale = 176; const KFID_GamepadAccelerationJumpScale = 176;
const KFID_HasTabbedToStore = 177; const KFID_HasTabbedToStore = 177;
const KFID_AllowSwapTo9mm = 178; // Halloween 2021 QoL: added option to quick switch weapons to 9mm

View File

@ -0,0 +1,27 @@
//=============================================================================
// KFDT_Ballistic_HRG_Boomy
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Boomy extends KFDT_Ballistic_Submachinegun
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=35
GunHitPower=25
WeaponDef=class'KFWeapDef_HRG_Boomy'
//Perk
ModifierPerkList(0)=class'KFPerk_Demolitionist'
}

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFDT_Ballistic_HRG_Energy_Primary
//=============================================================================
// HRG Energy Gun Damage Type
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Energy_Primary extends KFDT_Ballistic_Handgun
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=900
KDeathUpKick=-300
KDeathVel=100
StumblePower=15
GunHitPower=175
WeaponDef=class'KFWeapDef_HRG_Energy'
//Perk
ModifierPerkList(0)=class'KFPerk_Gunslinger'
EffectGroup=FXG_Energy_Yellow
}

View File

@ -0,0 +1,28 @@
//=============================================================================
// KFDT_Ballistic_HRG_Energy_Secondary
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_Energy_Secondary extends KFDT_Ballistic_Handgun
abstract
hidedropdown;
defaultproperties
{
StumblePower=100
KnockdownPower=20
GunHitPower=250
EMPPower=60
WeaponDef=class'KFWeapDef_HRG_Energy'
//Perk
ModifierPerkList(2)=class'KFPerk_Gunslinger'
EffectGroup=FXG_Energy_Magenta
}

View File

@ -0,0 +1,59 @@
//=============================================================================
// KFDT_Ballistic_ParasiteImplanter
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_ParasiteImplanter extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
if( super.CanDismemberHitZone( InHitZoneName ) )
{
return true;
}
switch ( InHitZoneName )
{
case 'lupperarm':
case 'rupperarm':
return true;
}
return false;
}
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=400
KDeathVel=250
KnockdownPower=25
//StunPower=20 //25
StumblePower=80
GunHitPower=160
//MeleeHitPower=0
WeaponDef=class'KFWeapDef_ParasiteImplanter'
ModifierPerkList(0)=class'KFPerk_FieldMedic'
ModifierPerkList(1)=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,36 @@
//=============================================================================
// KFDT_Ballistic_ParasiteImplanterAlt
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_ParasiteImplanterAlt extends KFDT_Toxic
abstract
hidedropdown;
/** Called when damage is dealt to apply additional damage type (e.g. Damage Over Time) */
static function ApplySecondaryDamage( KFPawn Victim, int DamageTaken, optional Controller InstigatedBy )
{
local class<KFDamageType> ToxicDT;
ToxicDT = class'KFDT_Ballistic_Assault_Medic'.static.GetMedicToxicDmgType( DamageTaken, InstigatedBy );
if ( ToxicDT != None )
{
Victim.ApplyDamageOverTime(DamageTaken, InstigatedBy, ToxicDT);
}
}
defaultproperties
{
KnockdownPower=30
StumblePower=200
GunHitPower=100
PoisonPower=0 //80
WeaponDef=class'KFWeapDef_ParasiteImplanter'
ModifierPerkList(0)=class'KFPerk_FieldMedic'
ModifierPerkList(1)=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,136 @@
//=============================================================================
// KFDT_Bludgeon_BladedPistol
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_BladedPistol extends KFDT_Slashing
abstract
hidedropdown;
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
return true;
}
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
{
local EPawnOctant SlashDir;
local KFCharacterInfo_Monster MonsterInfo;
MonsterInfo = InPawn.GetCharacterMonsterInfo();
if ( MonsterInfo == none )
{
return;
}
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
{
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Randomly pick the left or right shoulder bone and split the guy in half vertically
OutBoneName = Rand(2) == 0
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
}
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
{
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
{
// Split the guy in half horizontally
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
}
}
}
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
{
if( InHitZoneName == 'chest' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
else if( InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Use a random chance to decide whether to dismember the head or the shoulder constraints
if( Rand(2) == 0 )
{
// ... and choose one of the shoulder constraints at random
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
}
}
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
{
if( InHitZoneName == 'chest' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
}
}
else if( InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Use a random chance to decide whether to dismember the head or the shoulder constraints
if( Rand(2) == 0 )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
}
}
}
}
}
/** Allows the damage type to modify the impulse when a specified hit zone is dismembered */
static simulated function ModifyDismembermentHitImpulse(KFPawn_Monster InPawn, name InHitZoneName, vector HitDirection,
out vector OutImpulseDir, out vector OutParentImpulseDir,
out float OutImpulseScale, out float OutParentImpulseScale)
{
local EPawnOctant SlashDir;
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
// Apply upward impulse on decapitation from a clean horizontal slash
if( InHitZoneName == 'head' &&
( SlashDir == DIR_Left || SlashDir == DIR_Right ) )
{
OutImpulseDir += 10*vect(0,0,1);
OutImpulseDir = Normal(OutImpulseDir);
OutParentImpulseScale = 0.f;
}
// Do not apply any impulse on split in half from a vertical slash
else if( (InHitZoneName == 'head' || InHitZoneName == 'chest' ) &&
( SlashDir == DIR_Forward || SlashDir == DIR_Backward) )
{
OutImpulseScale = 0.f;
OutParentImpulseScale = 0.f;
}
}
DefaultProperties
{
StumblePower=200
MeleeHitPower=100
WeaponDef=class'KFWeapDef_BladedPistol'
ModifierPerkList(0)=class'KFPerk_Berserker'
ModifierPerkList(1)=class'KFPerk_Gunslinger'
}

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Healing_ParasiteSeed
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Healing_ParasiteSeed extends KFDT_Healing
abstract
hidedropdown;
defaultproperties
{
bNoPain=true
}

View File

@ -0,0 +1,190 @@
//=============================================================================
// KFDT_Slashing_EvisceratorProj
//=============================================================================
// Damage type for projectiles fired from the Eviscerator
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// John "Ramm-Jaeger" Gibson
//=============================================================================
class KFDT_Slashing_BladedPistol extends KFDT_Slashing
abstract
hidedropdown;
`define COSINE_0_DEGREES 1
`define COSINE_20_DEGREES 0.94
`define COSINE_70_DEGREES 0.34
`define COSINE_90_DEGREES 0
/** Allows the damage type to customize exactly which hit zones it can dismember */
static simulated function bool CanDismemberHitZone( name InHitZoneName )
{
return true;
}
/** @return The slast type from the HitFxInfo. This returns a 8-way slash info. */
static simulated function EPawnOctant GetLastSlashDirection(KFPawn_Monster InPawn, vector HitDirection)
{
local vector SlashPlaneNormal;
local rotator InstigatorRotation;
local vector InstigatorFaceDir, InstigatorRightDir;
local float UpDotSlash, RightDotSlash, UpThresholdValue;
if( InPawn != none )
{
HitDirection = Normal(HitDirection);
InstigatorRotation = InPawn.GetBaseAimRotation();
InstigatorFaceDir = GetRotatorAxis(InstigatorRotation, 0);
InstigatorRightDir = GetRotatorAxis(InstigatorRotation, 1);
// Cross the face direction of the instigator with the hit direction to find
// the normal to the "slashing" plane
SlashPlaneNormal = Normal(InstigatorFaceDir Cross HitDirection);
// Dot the slash plane normal with the world up direction to figure out
// the quadrant for the normal of the slash plane
UpDotSlash = vect(0,0,1) Dot SlashPlaneNormal;
UpThresholdValue = Abs(UpDotSlash);
// Dot the slash plane normal with the instigator right to figure out
// the direction of the slash
RightDotSlash = InstigatorRightDir Dot SlashPlaneNormal;
// Threshhold against the preset values to find out the type of slash. The sign (+ or -) of the
// dot products are used to further classify the direction of the slash
if( UpThresholdValue <= `COSINE_0_DEGREES && UpThresholdValue >= `COSINE_20_DEGREES )
{
if( UpDotSlash > 0 )
return DIR_Right;
else
return DIR_Left;
}
else if( UpThresholdValue <= `COSINE_20_DEGREES && UpThresholdValue >= `COSINE_70_DEGREES )
{
if( UpDotSlash < 0 && RightDotSlash > 0 )
return DIR_ForwardLeft;
else if( UpDotSlash > 0 && RightDotSlash > 0 )
return DIR_ForwardRight;
else if( UpDotSlash > 0 && RightDotSlash < 0 )
return DIR_BackwardRight;
else if( UpDotSlash < 0 && RightDotSlash < 0 )
return DIR_BackwardLeft;
}
else if( UpThresholdValue <= `COSINE_70_DEGREES && UpThresholdValue >= `COSINE_90_DEGREES )
{
if( RightDotSlash > 0 )
return DIR_Forward;
else
return DIR_Backward;
}
}
return DIR_None;
}
/** Allows the damage type to map a hit zone to a different bone for dismemberment purposes */
static simulated function GetBoneToDismember(KFPawn_Monster InPawn, vector HitDirection, name InHitZoneName, out name OutBoneName)
{
local EPawnOctant SlashDir;
local KFCharacterInfo_Monster MonsterInfo;
MonsterInfo = InPawn.GetCharacterMonsterInfo();
if ( MonsterInfo == none )
{
return;
}
SlashDir = GetLastSlashDirection(InPawn, HitDirection);
if( SlashDir == DIR_Forward || SlashDir == DIR_Backward )
{
if( InHitZoneName == 'chest' || InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Randomly pick the left or right shoulder bone and split the guy in half vertically
OutBoneName = Rand(2) == 0
? MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName
: MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
}
else if( SlashDir == DIR_Left || SlashDir == DIR_Right )
{
if( InHitZoneName == 'chest' || InHitZoneName == 'abdomen' || InHitZoneName == 'stomach')
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowHorizontalSplit )
{
// Split the guy in half horizontally
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.SpineBoneName;
}
}
}
else if( SlashDir == DIR_ForwardLeft || SlashDir == DIR_BackwardRight )
{
if( InHitZoneName == 'chest' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
else if( InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Use a random chance to decide whether to dismember the head or the shoulder constraints
if( Rand(2) == 0 )
{
// ... and choose one of the shoulder constraints at random
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.RightShoulderBoneName;
}
}
}
}
else if( SlashDir == DIR_ForwardRight || SlashDir == DIR_BackwardLeft )
{
if( InHitZoneName == 'chest' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
}
}
else if( InHitZoneName == 'head' )
{
if( MonsterInfo.SpecialMeleeDismemberment.bAllowVerticalSplit )
{
// Use a random chance to decide whether to dismember the head or the shoulder constraints
if( Rand(2) == 0 )
{
OutBoneName = MonsterInfo.SpecialMeleeDismemberment.LeftShoulderBoneName;
}
}
}
}
}
defaultproperties
{
EffectGroup=FXG_Sawblade
KDamageImpulse=1000
KDeathUpKick=800
KDeathVel=135
// Instigator damage can happen on owning client when projectile hits before Instigator is replicated and
// (Other != Instigator) == FALSE. This problem is specific to the eviscerator projectile since it's a
// replicated CSHD weapon, but it might make sense to have bNoInstigatorDamage=true on more weapons.
bNoInstigatorDamage=true
//StunPower=0
StumblePower=100
GunHitPower=100
//MeleeHitPower=100
WeaponDef=class'KFWeapDef_BladedPistol'
ModifierPerkList(0)=class'KFPerk_Berserker'
ModifierPerkList(1)=class'KFPerk_Gunslinger'
}

View File

@ -0,0 +1,29 @@
//=============================================================================
// KFDT_Toxic_ParasiteSeedExplosion
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFDT_Toxic_ParasiteSeedExplosion extends KFDT_Toxic_MedicGrenade
abstract
hidedropdown;
defaultproperties
{
DoT_Type=DOT_Toxic
DoT_Duration=6.5 //3.0
DoT_Interval=0.5
DoT_DamageScale=0.1
KnockdownPower=30
StumblePower=200
GunHitPower=100
PoisonPower=80.f
ModifierPerkList(0)=class'KFPerk_FieldMedic'
ModifierPerkList(1)=class'KFPerk_SharpShooter'
WeaponDef=class'KFWeapDef_ParasiteImplanter'
}

View File

@ -0,0 +1,97 @@
//=============================================================================
// KFExplosion_ParasiteSeed
//=============================================================================
// Used by projectiles and kismet to spawn an explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_ParasiteSeed extends KFExplosion_MedicGrenade;
var transient bool FirstExplosion;
/**
* 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(!FirstExplosion || 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
{
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;
}
HumanVictim.HealDamage(HealingAmount, InstigatorController, HealingDamageType, bCanRepairArmor);
if( bCanRepairArmor )
{
OwnerProjectile.HealedPawns.AddItem( HumanVictim );
}
}
}
}
}
simulated function DelayedExplosionDamage()
{
FirstExplosion=false;
super.DelayedExplosionDamage();
}
DefaultProperties
{
FirstExplosion = true;
HealingDamageType=class'KFDT_Healing_ParasiteSeed'
HealingAmount=5 //10
Interval=0.5 //1
MaxTime=5.5 //6.5 //8
bExplodeMoreThanOnce=false
bDoFullDamage=false //true
bSkipLineCheckForPawns=true
LoopingParticleEffect=ParticleSystem'WEP_3P_Medic_Grenade_EMIT.FX_Medic_Grenade_Explosion'
LoopStartEvent=AkEvent'WW_WEP_Medic_GrenadeLauncher.Play_WEP_Medic_GrenadeLauncher_Grenade_Smoke_Loop'
LoopStopEvent=AkEvent'WW_WEP_Medic_GrenadeLauncher.Stop_WEP_Medic_GrenadeLauncher_Grenade_Smoke_Loop'
}

View File

@ -0,0 +1,26 @@
//=============================================================================
// KFExplosion_ParasiteSeedHuman
//=============================================================================
// Explosion created when hitting a human
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_ParasiteSeedHuman extends KFExplosion_MedicGrenade;
DefaultProperties
{
HealingDamageType=class'KFDT_Healing_ParasiteSeed'
HealingAmount=30 //10
Interval=1.0 //1
MaxTime=0.5 //6.5 //8
bExplodeMoreThanOnce=false
bDoFullDamage=false //true
bSkipLineCheckForPawns=true
LoopingParticleEffect=ParticleSystem'WEP_3P_Medic_Grenade_EMIT.FX_Medic_Grenade_Explosion'
LoopStartEvent=AkEvent'WW_WEP_Medic_GrenadeLauncher.Play_WEP_Medic_GrenadeLauncher_Grenade_Smoke_Loop'
LoopStopEvent=AkEvent'WW_WEP_Medic_GrenadeLauncher.Stop_WEP_Medic_GrenadeLauncher_Grenade_Smoke_Loop'
}

View File

@ -235,16 +235,26 @@ protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPa
if(OutbreakEvent.ActiveEvent.bHealAfterKill) if(OutbreakEvent.ActiveEvent.bHealAfterKill)
{ {
if( MonsterPawn != none && MonsterPawn.DamageHistory.Length > 0 ) if( MonsterPawn != none && MonsterPawn.DamageHistory.Length > 0 )
{ {
HealAfterKilling( MonsterPawn, Killer ); if(OutbreakEvent.ActiveEvent.bHealWithHeadshot)
{
if (MonsterPawn.LastHitZoneIndex == HZI_HEAD)
{
HealAfterKilling( MonsterPawn, Killer, false );
}
}
else
{
HealAfterKilling( MonsterPawn, Killer );
}
} }
} }
} }
/** Heal players after a Zed was killed, based in more heal to the player that was the killer and less heal to the players that damaged the Zed */ /** Heal players after a Zed was killed, based in more heal to the player that was the killer and less heal to the players that damaged the Zed */
function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer) function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer, optional bool bGivePowerUp = true)
{ {
local int i; local int i;
local int j; local int j;
@ -302,7 +312,7 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
{ {
PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false ); PawnHuman.HealDamageForce(MonsterPawn.HealByKill, KFPC, class'KFDT_Healing', false, false );
if( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none ) if( bGivePowerUp && ( KFPawn_ZedFleshpound(MonsterPawn) != none || KFPawn_ZedScrake(MonsterPawn) != none ))
{ {
KFPC.ReceivePowerUp(class'KFPowerUp_HellishRage_NoCostHeal'); KFPC.ReceivePowerUp(class'KFPowerUp_HellishRage_NoCostHeal');
} }
@ -322,6 +332,11 @@ function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
function StartMatch() function StartMatch()
{ {
super.StartMatch(); super.StartMatch();
if (OutbreakEvent.ActiveEvent.bForceWWLMusic)
{
ForceWWLMusicTrack();
}
} }
function CreateDifficultyInfo(string Options) function CreateDifficultyInfo(string Options)

View File

@ -64,6 +64,7 @@ simulated function NotifyWaveStart()
DefaultProperties DefaultProperties
{ {
bIsWeeklyMode=True
BrokenTraderItemPickups={( BrokenTraderItemPickups={(
(WeaponClasses={( (WeaponClasses={(
class'KFGame.KFWeapDef_9mmDual', class'KFGame.KFWeapDef_9mmDual',

View File

@ -518,6 +518,118 @@ defaultproperties
)} )}
//Wild West
SetEvents[12]={(
EventDifficulty=2,
GameLength=GL_Normal,
PerksAvailableList=(class'KFPerk_Gunslinger', class'KFPerk_Sharpshooter'),
TraderWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.WildWestWeeklyTraderList',
bWildWestSkillConditionsActive=true,
//bModifyZedTimeOnANearZedKill=true,
DoshOnKillGlobalModifier=1.4,
PickupResetTime=PRS_Wave,
OverrideItemPickupModifier=0,
OverrideAmmoPickupModifier=1,
WaveAmmoPickupModifiers={(
0.125, 0.175, 0.35, 0.525, 0.7, 0.875, 0.75, 0.99, 0.99
)},
SpawnRateMultiplier=0.75,
WaveAICountScale=(0.75, 0.7, 0.7, 0.65, 0.65, 0.6),
bHealAfterKill = true,
bHealWithHeadshot = true,
bForceWWLMusic = true,
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler', HealByKill=1, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst', HealByKill=1, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha', HealByKill=1, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing', HealByKill=10, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher', HealByKill=1, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren', HealByKill=10, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker', HealByKill=2, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat', HealByKill=10, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk', HealByKill=10, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket', HealByKill=5, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake', HealByKill=20, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound', HealByKill=20, HealByAssistance=0, HealthScale=0.8, DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini', HealByKill=15, HealByAssistance=0, HealthScale=0.8, DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn', HealByKill=2, HealByAssistance=0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=0.8,DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=0.8,DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=0.8,DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=0.8,DamageDealtScale=0.7),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=0.8,DamageDealtScale=0.7)
)},
SpawnReplacementList={(
(SpawnEntry=AT_FleshPound,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.5),
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.5)
)}
)}
//Infernal Eternal
SetEvents[13]={(
EventDifficulty=3,
GameLength=GL_Normal,
SpawnRateMultiplier=3,
WaveAICountScale=(1.3, 1.3, 1.3, 1.3, 1.3, 1.3),
OverrideAmmoPickupModifier=1, // 1.2
WaveAmmoPickupModifiers={(
0.125, 0.15, 0.3, 0.45, 0.6, 0.75, 0.9, 0.99, 0.99
)},
bUseOverrideAmmoRespawnTime=true,
OverrideAmmoRespawnTime={(
PlayersMod[0]=25.000000,
PlayersMod[1]=12.000000,
PlayersMod[2]=8.000000,
PlayersMod[3]=5.000000,
PlayersMod[4]=4.000000,
PlayersMod[5]=3.000000,
ModCap=1.000000
)},
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=2.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=2.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=2.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=2.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=2.0,DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKingSubspawn',bStartEnraged=true, DamageDealtScale=1.0, InitialGroundSpeedModifierScale=1.2)
)},
SpawnReplacementList={(
(SpawnEntry=AT_Clot,NewClass=(class'KFGameContent.KFPawn_ZedClot_Alpha'),PercentChance=0.15),
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedClot_AlphaKing'),PercentChance=0.15),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.15),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedCrawlerKing'),PercentChance=0.15),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=0.05),
(SpawnEntry=AT_FleshpoundMini,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.05)
)}
)}
//Test events from here down. These don't end up in the regular rotation. //Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above. // The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8 // Ex: Big head = 7, Horde = 8

View File

@ -98,4 +98,6 @@ DefaultProperties
`if(`notdefined(ShippingPC)) `if(`notdefined(ShippingPC))
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Clot'; DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Clot';
`endif `endif
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -88,4 +88,6 @@ DefaultProperties
`if(`notdefined(ShippingPC)) `if(`notdefined(ShippingPC))
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Slasher'; DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Slasher';
`endif `endif
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -464,4 +464,6 @@ defaultproperties
// --------------------------------------------- // ---------------------------------------------
// Spawning // Spawning
MinSpawnSquadSizeType=EST_Crawler MinSpawnSquadSizeType=EST_Crawler
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -431,4 +431,6 @@ defaultproperties
StartSprintingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_Start' StartSprintingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_Start'
SprintLoopingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_LP' SprintLoopingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_LP'
StopSprintingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_Stop' StopSprintingSound=AkEvent'WW_ZED_Evil_DAR.Play_ZED_EvilDAR_SFX_Thruster_Stop'
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -605,4 +605,6 @@ End Object
MinSpawnSquadSizeType=EST_Large MinSpawnSquadSizeType=EST_Large
OnDeathAchievementID=KFACHID_ItsOnlyAFleshWound OnDeathAchievementID=KFACHID_ItsOnlyAFleshWound
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -72,4 +72,6 @@ defaultproperties
IncapSettings(AF_Freeze)= (Vulnerability=(0.95), Cooldown=10.5, Duration=1.0) IncapSettings(AF_Freeze)= (Vulnerability=(0.95), Cooldown=10.5, Duration=1.0)
IncapSettings(AF_Snare)= (Vulnerability=(1.0, 2.0, 1.0, 1.0, 2.0), Cooldown=8.5, Duration=5.0) IncapSettings(AF_Snare)= (Vulnerability=(1.0, 2.0, 1.0, 1.0, 2.0), Cooldown=8.5, Duration=5.0)
IncapSettings(AF_Bleed)= (Vulnerability=(0.75)) IncapSettings(AF_Bleed)= (Vulnerability=(0.75))
ZEDCowboyHatAttachName=HEAD_Attach
} }

View File

@ -657,4 +657,6 @@ DefaultProperties
// --------------------------------------------- // ---------------------------------------------
// Spawning // Spawning
MinSpawnSquadSizeType=EST_Medium MinSpawnSquadSizeType=EST_Medium
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -2012,4 +2012,6 @@ defaultproperties
// Gun tracking // Gun tracking
bUseServerSideGunTracking=true bUseServerSideGunTracking=true
GunTargetBoneName=Spine2 GunTargetBoneName=Spine2
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -391,4 +391,6 @@ defaultproperties
MinSpawnSquadSizeType=EST_Large MinSpawnSquadSizeType=EST_Large
OnDeathAchievementID=KFACHID_HackAndSlash OnDeathAchievementID=KFACHID_HackAndSlash
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -250,4 +250,6 @@ defaultproperties
`endif `endif
OnDeathAchievementID=KFACHID_DeadSilence OnDeathAchievementID=KFACHID_DeadSilence
ZEDCowboyHatAttachName=Hat_Attach
} }

View File

@ -0,0 +1,79 @@
//=============================================================================
// KFProj_Blade_BladedPistol
//=============================================================================
// Blade class for the BladedPistol
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Blade_BladedPistol extends KFProj_RicochetStickBullet
hidedropdown;
// Make sure that last location always exists.
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
LastLocation = Location;
}
simulated function bool ShouldProcessBulletTouch()
{
return BouncesLeft > 0 && GravityScale == default.GravityScale;
}
defaultproperties
{
MaxSpeed=4000.0 //2500.0
Speed=4000.0 //2500.0
GravityScale=0.8 //0.75
DamageRadius=0
bWarnAIWhenFired=true
BouncesLeft=2
DampingFactor=0.8 //0.95
RicochetEffects=KFImpactEffectInfo'WEP_BladedPistol_ARCH.BladedImpacts'
LifeSpan=8
LifeSpanAfterStick=180
Begin Object Name=CollisionCylinder
CollisionRadius=6
CollisionHeight=2
End Object
// Additional zero-extent line traces
//ExtraLineCollisionOffsets.Add((Y=-8))
//ExtraLineCollisionOffsets.Add((Y=8))
ExtraLineCollisionOffsets.Add((Y=-16))
ExtraLineCollisionOffsets.Add((Y=16))
ExtraLineCollisionOffsets.Add((Z=-6))
ExtraLineCollisionOffsets.Add((Z=6))
// Since we're still using an extent cylinder, we need a line at 0
ExtraLineCollisionOffsets.Add(())
bAmbientSoundZedTimeOnly=false
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bRotationFollowsVelocity=false
bNetTemporary=False
ProjFlightTemplate=ParticleSystem'WEP_BladedPistol_EMIT.FX_bladed_projectile_01'
ProjFlightTemplateZedTime=ParticleSystem'WEP_BladedPistol_EMIT.FX_bladed_projectile_01'
ImpactEffects=KFImpactEffectInfo'WEP_BladedPistol_ARCH.BladedEmbedFX'
AmbientSoundPlayEvent=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Projectile_Loop'
AmbientSoundStopEvent=AkEvent'WW_WEP_BladedPistol.Stop_WEP_BladedPistol_Projectile_Loop'
PickupRadius=250 //200
WeaponClassName=KFWeap_Pistol_Bladed
ProjPickupTemplate=ParticleSystem'WEP_BladedPistol_EMIT.FX_bladed_pickup_01'
AmmoPickupSound=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Projectile_Pickup'
TouchTimeThreshhold=0.15
}

View File

@ -0,0 +1,79 @@
//=============================================================================
// KFProj_Bullet_HRG_Boomy
//=============================================================================
// Class Description
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_HRG_Boomy extends KFProj_BallisticExplosive
hidedropdown;
simulated protected function PrepareExplosionTemplate()
{
super.PrepareExplosionTemplate();
/** Since bIgnoreInstigator is transient, its value must be defined here */
ExplosionTemplate.bIgnoreInstigator = true;
}
defaultproperties
{
MaxSpeed=22500.0
Speed=22500.0
DamageRadius=0
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
// ProjFlightTemplate=ParticleSystem'WEP_HRG_Boomy_EMIT.FX_Boomy_Tracer_ZEDTime'
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Boomy_EMIT.FX_Boomy_Tracer_ZEDTime'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=252,G=218,B=171,A=255)
Brightness=0.5f
Radius=400.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=35 //30
DamageRadius=150 //120
DamageFalloffExponent=1.f
DamageDelay=0.f
MomentumTransferScale=10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_HRG_Boomy'
KnockDownStrength=150
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionSound=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_ProjExplosion'
ExplosionEffects=KFImpactEffectInfo'WEP_HRG_Boomy_ARCH.WEB_HRG_Boomy_Impacts'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.3
bIgnoreInstigator=true
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=0
CamShakeOuterRadius=300
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ExploTemplate0
}

View File

@ -0,0 +1,23 @@
//=============================================================================
// KFProj_Bullet_HRG_Energy
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_HRG_Energy extends KFProj_Bullet
hidedropdown;
defaultproperties
{
MaxSpeed=15000.0
Speed=15000.0
DamageRadius=0
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Energy_EMIT.FX_Energy_Tracer_Instant'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_Energy_ARCH.Wep_HRG_Energy_Impact'
}

View File

@ -0,0 +1,21 @@
//=============================================================================
// KFProj_Bullet_HRG_Energy_Secondary
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_HRG_Energy_Secondary extends KFProj_Bullet;
defaultproperties
{
MaxSpeed=7500.0
Speed=7500.0
DamageRadius=0
ProjFlightTemplateZedTime=ParticleSystem'WEP_HRG_Energy_EMIT.FX_Energy_Alt_Tracer_Instant'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_Energy_ARCH.Wep_HRG_Energy_Impact_Alt'
}

View File

@ -0,0 +1,22 @@
//=============================================================================
// KFProj_Bullet_ParasiteImplanter
//=============================================================================
// Bullet class for the Parasite Implanter
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_ParasiteImplanter extends KFProj_Bullet
hidedropdown;
defaultproperties
{
MaxSpeed=24000.0
Speed=24000.0
DamageRadius=0
ProjFlightTemplate=ParticleSystem'WEP_1P_L85A2_EMIT.FX_L85A2_Tracer_ZEDTime'
}

View File

@ -0,0 +1,382 @@
//=============================================================================
// KFProj_Bullet_ParasiteImplanterAlt
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProj_Bullet_ParasiteImplanterAlt extends KFProjectile;
var float FuseTime;
/** This is the effect indicator that is played for the current user **/
var(Projectile) ParticleSystem ProjIndicatorTemplate;
var ParticleSystemComponent ProjIndicatorEffects;
var bool IndicatorActive;
var transient bool bShouldEnableIndicator;
var Class<GameExplosionActor> HumanExplosionActorClass;
var KFGameExplosion HumanExplosionTemplate;
var private AKEvent SeedTimerOutEvent;
simulated function TryActivateIndicator()
{
if(!IndicatorActive && Instigator != None)
{
IndicatorActive = true;
if(WorldInfo.NetMode == NM_Standalone || Instigator.Role == Role_AutonomousProxy ||
(Instigator.Role == ROLE_Authority && WorldInfo.NetMode == NM_ListenServer && Instigator.IsLocallyControlled() ))
{
if( ProjIndicatorTemplate != None )
{
ProjIndicatorEffects = WorldInfo.MyEmitterPool.SpawnEmitterCustomLifetime(ProjIndicatorTemplate);
}
if(ProjIndicatorEffects != None)
{
ProjIndicatorEffects.SetAbsolute(false, false, false);
ProjIndicatorEffects.SetLODLevel(WorldInfo.bDropDetail ? 1 : 0);
ProjIndicatorEffects.bUpdateComponentInTick = true;
AttachComponent(ProjIndicatorEffects);
}
}
}
}
/**
* Set the initial velocity and cook time
*/
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
if (Role == ROLE_Authority)
{
SetTimer(FuseTime, false, 'Timer_Detonate');
}
AdjustCanDisintigrate();
}
/**
* Explode after a certain amount of time
*/
function Timer_Detonate()
{
Detonate();
}
/** Called when the owning instigator controller has left a game */
simulated function OnInstigatorControllerLeft()
{
if( WorldInfo.NetMode != NM_Client )
{
SetTimer( 1.f + Rand(5) + fRand(), false, nameOf(Timer_Detonate) );
}
}
/**
* Trace down and get the location to spawn the explosion effects and decal
*/
simulated function GetExplodeEffectLocation(out vector HitLocation, out vector HitRotation, out Actor HitActor)
{
local vector EffectStartTrace, EffectEndTrace;
local TraceHitInfo HitInfo;
EffectStartTrace = Location + vect(0,0,1) * 4.f;
EffectEndTrace = EffectStartTrace - vect(0,0,1) * 32.f;
// Find where to put the decal
HitActor = Trace(HitLocation, HitRotation, EffectEndTrace, EffectStartTrace, false,, HitInfo, TRACEFLAG_Bullet);
// If the locations are zero (probably because this exploded in the air) set defaults
if (IsZero(HitLocation))
{
HitLocation = Location;
}
if (IsZero(HitRotation))
{
HitRotation = vect(0,0,1);
}
}
/** Used to check current status of StuckTo actor (to figure out if we should fall) */
simulated event Tick(float DeltaTime)
{
super.Tick(DeltaTime);
StickHelper.Tick(DeltaTime);
if (!IsZero(Velocity))
{
SetRelativeRotation(rotator(Velocity));
}
if (bShouldEnableIndicator)
{
TryActivateIndicator();
}
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
StickHelper.UnPin();
super.Explode(HitLocation, HitNormal);
}
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
StickHelper.TryStick(HitNormal, HitLocation, HitActor);
}
}
}
simulated protected function StopSimulating()
{
super.StopSimulating();
if (ProjIndicatorEffects!=None)
{
ProjIndicatorEffects.DeactivateSystem();
}
}
/** Causes charge to explode */
function Detonate()
{
local KFPawn_Monster KFPM;
//@Todo: Some VFX?
if (StuckToActor != none)
{
KFPM = KFPawn_Monster(StuckToActor);
if (KFPM != none)
{
KFPM.ParasiteSeeds.RemoveItem(self);
}
}
StickHelper.UnPin();
ShutDown();
}
simulated function OnActorSticked(Actor TargetActor)
{
local KFPawn_Monster KFPM;
KFPM = KFPawn_Monster(TargetActor);
if (KFPM != none)
{
if (Role == ROLE_Authority)
{
KFPM.AddParasiteSeed(self);
PlaySoundBase(SeedTimerOutEvent, false, false);
}
if (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_StandAlone)
{
bShouldEnableIndicator = true;
}
}
}
simulated function ExplodeOnHuman(Vector HitLocation, Vector HitNormal, Actor HitActor)
{
local vector NudgedHitLocation, ExplosionDirection;
if (HumanExplosionTemplate != None)
{
StopSimulating();
// using a hit location slightly away from the impact point is nice for certain things
NudgedHitLocation = HitLocation + (HitNormal * 32.f);
ExplosionActor = Spawn(HumanExplosionActorClass, self,, NudgedHitLocation, rotator(HitNormal));
if (ExplosionActor != None)
{
ExplosionActor.Instigator = Instigator;
ExplosionActor.InstigatorController = InstigatorController;
PrepareExplosionTemplate();
// If the locations are zero (probably because this exploded in the air) set defaults
if( IsZero(HitLocation) )
{
HitLocation = Location;
}
if( IsZero(HitNormal) )
{
HitNormal = vect(0,0,1);
}
// these are needed for the decal tracing later in GameExplosionActor.Explode()
HumanExplosionTemplate.HitLocation = HitLocation;// NudgedHitLocation
HumanExplosionTemplate.HitNormal = HitNormal;
// If desired, attach to mover if we hit one
if(bAttachExplosionToHitMover && InterpActor(HitActor) != None)
{
ExplosionActor.Attachee = HitActor;
HumanExplosionTemplate.bAttachExplosionEmitterToAttachee = TRUE;
ExplosionActor.SetBase(HitActor);
}
// directional?
if (HumanExplosionTemplate.bDirectionalExplosion)
{
ExplosionDirection = GetExplosionDirection(HitNormal);
//DrawDebugLine(ExplosionActor.Location, ExplosionActor.Location+ExplosionDirection*64, 255, 255, 0, TRUE);
}
// @todo: make this function responsible for setting explosion instance parameters, and take instance parameters
// out of GearExplosion (e.g. Attachee)
PrepareExplosionActor(ExplosionActor);
ExplosionActor.Explode(HumanExplosionTemplate, ExplosionDirection); // go bewm
}
// done with it
if (!bPendingDelete && !bDeleteMe)
{
// defer destruction so any replication of explosion stuff can happen if necessary
DeferredDestroy(PostExplosionLifetime);
}
}
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
if (KFPawn_Human(Other) != none && Other != Instigator)
{
ExplodeOnHuman(HitLocation, HitNormal, Other);
}
else
{
super.ProcessTouch(Other, HitLocation, HitNormal);
}
}
defaultproperties
{
ProjFlightTemplate=ParticleSystem'WEP_ParasiteImplanter_EMIT.FX_Seed_Projectile'
ProjIndicatorTemplate=ParticleSystem'WEP_ParasiteImplanter_EMIT.FX_Seed_Projectile_Indicator'
bWarnAIWhenFired=true
MaxSpeed=15000.0 //10000.0 //4000.0
Speed=15000.0 //10000.0 //4000.0
TerminalVelocity=15000.0 //10000.0 //4000.0
Physics=PHYS_Falling
TossZ=0 //150
GravityScale=0 //0.01 //0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=true
bIgnoreFoliageTouch=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
FuseTime=6.0 //4.0
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=true
bCanDisintegrate=true
ExplosionActorClass=class'KFExplosion_ParasiteSeed'
HumanExplosionActorClass=class'KFExplosion_ParasiteSeedHuman'
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=400 //250
DamageRadius=450
DamageFalloffExponent=0.5f //1.f
DamageDelay=0.f
MyDamageType=class'KFDT_Toxic_ParasiteSeedExplosion'
// Damage Effects
KnockDownStrength=0
KnockDownRadius=0
FractureMeshRadius=0
FracturePartVel=0
// ExplosionEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Explosions.MedicGrenade_Explosion'
ExplosionSound=AkEvent'WW_WEP_Medic_GrenadeLauncher.Play_WEP_Medic_GrenadeLauncher_Grenade_Explosion'
MomentumTransferScale=0
// Camera Shake
CamShake=none
CamShakeInnerRadius=0
CamShakeOuterRadius=0
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
ExplosionTemplate=ExploTemplate0
Begin Object Class=KFGameExplosion Name=ExploTemplate1
Damage=1 //250
DamageRadius=100 //450
DamageFalloffExponent=0.5f //1.f
DamageDelay=0.f
// Damage Effects
KnockDownStrength=0
KnockDownRadius=0
FractureMeshRadius=0
FracturePartVel=0
// ExplosionEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Explosions.MedicGrenade_Explosion'
ExplosionSound=AkEvent'WW_WEP_Medic_GrenadeLauncher.Play_WEP_Medic_GrenadeLauncher_Grenade_Explosion'
MomentumTransferScale=0
// Camera Shake
CamShake=none
CamShakeInnerRadius=0
CamShakeOuterRadius=0
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
End Object
HumanExplosionTemplate=ExploTemplate1
bCanStick=true
bCanPin=true
Begin Object Class=KFProjectileStickHelper_ParasiteImplanter Name=StickHelper0
End Object
StickHelper=StickHelper0
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
bShouldEnableIndicator=false;
ImpactEffects = KFImpactEffectInfo'WEP_ParasiteImplanter_ARCH.Wep_Parasite_Impact_Alt'
SeedTimerOutEvent = AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_Seed_Timer_Out';
}

View File

@ -905,8 +905,8 @@ defaultproperties
MaxDamageRadiusPerPercentage=340 MaxDamageRadiusPerPercentage=340
MinDamageRadiusPerPercentage=160 MinDamageRadiusPerPercentage=160
MaxDamagePerPercentage=300 //270//180 MaxDamagePerPercentage=350 //300
MinDamagePerPercentage=30//90 MinDamagePerPercentage=35 //30
MaxCollisionRadius=20 MaxCollisionRadius=20
MinCollisionRadius=10 MinCollisionRadius=10

View File

@ -0,0 +1,205 @@
//=============================================================================
// KFProjectileStickHelper_ParasiteImplanter
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFProjectileStickHelper_ParasiteImplanter extends KFProjectileStickHelper;
simulated function TryStick(vector HitNormal, optional vector HitLocation, optional Actor HitActor)
{
if( WorldInfo.NetMode != NM_DedicatedServer )
{
`ImpactEffectManager.PlayImpactEffects(HitLocation, Instigator,, KFProj_Bullet_ParasiteImplanterAlt(Outer).ImpactEffects);
}
super.TryStick(HitNormal, HitLocation, HitActor);
}
/** Stops movement of projectile and calculates orientation to surface */
simulated function Stick(Actor HitActor, vector HitLocation, vector HitNormal, const out TraceHitInfo HitInfo)
{
local int BoneIdx;
local KFPawn_Monster HitMonster;
local array<ImpactInfo> HitZoneImpactList;
local vector StartTrace, EndTrace, Direction, ClosestBoneLocation;
local name BoneName;
BoneName = HitInfo.BoneName;
HitMonster = KFPawn_Monster(HitActor);
if (HitMonster != none)
{
// get injury hit zone
StartTrace = HitLocation;
Direction = Normal(Velocity);
EndTrace = StartTrace + Direction * (HitMonster.CylinderComponent.CollisionRadius * 6.0);
TraceProjHitZones(HitMonster, EndTrace, StartTrace, HitZoneImpactList);
if (BoneName == '')
{
// get the best bone to attach to
ClosestBoneLocation = HitMonster.Mesh.GetClosestCollidingBoneLocation(HitLocation, true, false);
BoneName = HitMonster.Mesh.FindClosestBone(ClosestBoneLocation, ClosestBoneLocation);
}
// Deleted damage to monster code, we don't want to do damage on sticking
// Bringed damage back
if (KFWeapon(Owner) != none)
{
HitZoneImpactList[0].RayDir = Normal(EndTrace - StartTrace); // add a raydir here since TraceProjHitZones doesn't fill this out (so certain afflictions apply)
KFWeapon(Owner).HandleProjectileImpact(WeaponFireMode, HitZoneImpactList[0], PenetrationPower);
}
}
else if (KFPawn_Human(HitActor) != none)
{
// When it hits a human, use explosion.
KFProj_Bullet_ParasiteImplanterAlt(Outer).ExplodeOnHuman(HitLocation, HitNormal, HitActor);
return;
}
if (!IsZero(HitLocation))
{
SetLocation(HitLocation);
}
SetStickOrientation(HitNormal);
BoneIdx = INDEX_NONE;
if (BoneName != '')
{
BoneIdx = GetBoneIndexFromActor(HitActor, BoneName);
}
StickToActor(HitActor, HitInfo.HitComponent, BoneIdx, true);
if (Role < ROLE_Authority)
{
Outer.ServerStick(HitActor, BoneIdx, StuckToLocation, StuckToRotation);
}
if (WorldInfo.NetMode != NM_DedicatedServer && StickAkEvent != none)
{
PlaySoundBase(StickAkEvent);
}
}
/** Changes the base of the charge to the stick actor and sets its relative loc/rot */
simulated function StickToActor(Actor StickTo, PrimitiveComponent HitComp, int BoneIdx, optional bool bCalculateRelativeLocRot)
{
local SkeletalMeshComponent SkelMeshComp;
local Name BoneName;
local vector RelStuckToLocation;
local rotator RelStuckToRotation;
local KFPawn StickToPawn;
local KFProj_Bullet_ParasiteImplanterAlt ParasiteProj;
StickToPawn = KFPawn(StickTo);
if (bCanPin && (StickToPawn == none || StickToPawn.bCanBePinned))
{
// if StickTo pawn is dead, pin it and keep flying
if (Role == ROLE_Authority)
{
if (StickToPawn != none && !StickToPawn.IsAliveAndWell())
{
if (PinPawn == none)
{
Pin(StickTo, BoneIdx);
}
return;
}
}
if (WorldInfo.NetMode != NM_DedicatedServer && PinPawn != none)
{
if (StickToPawn == none)
{
// Pin pinned pawn to StickTo actor
//PinPawn.Mesh.RetardRBLinearVelocity(vector(Rotation), 0.75);
PinPawn.Mesh.SetRBPosition(Location, PinBoneName);
PinConstraint = Spawn(class'RB_ConstraintActorSpawnable',,,Location);
PinConstraint.InitConstraint(PinPawn, none, PinBoneName, '');
}
PinPawn = none;
}
}
else if (StickToPawn != none && !StickToPawn.IsAliveAndWell())
{
return;
}
SetPhysics(PHYS_None);
PrevStuckToActor = StuckToActor;
StuckToActor = StickTo;
StuckToBoneIdx = BoneIdx;
// if we found a skel mesh, set our base to it and set relative loc/rot
if (BoneIdx != INDEX_NONE)
{
SkelMeshComp = SkeletalMeshComponent(HitComp);
BoneName = SkelMeshComp.GetBoneName(BoneIdx);
if (bCalculateRelativeLocRot)
{
StuckToLocation = Location;
StuckToRotation = Rotation;
}
SkelMeshComp.TransformToBoneSpace(BoneName, StuckToLocation, StuckToRotation, RelStuckToLocation, RelStuckToRotation);
SetBase(StickTo,, SkelMeshComp, BoneName);
SetRelativeLocation(RelStuckToLocation);
SetRelativeRotation(RelStuckToRotation);
}
// otherwise, just set our base
else
{
if (bCalculateRelativeLocRot)
{
// set replicated loc/rot
StuckToLocation = Location;
StuckToRotation = Rotation;
}
else
{
// set loc/rot to replicated loc/rot
SetLocation(StuckToLocation);
SetRotation(StuckToRotation);
}
SetBase(StickTo);
}
ParasiteProj = KFProj_Bullet_ParasiteImplanterAlt(Outer);
ParasiteProj.OnActorSticked(StickTo);
}
/** Resets physics/collision vars to defaults */
simulated function UnStick()
{
// local KFPawn_Monster KFPM;
GravityScale=0.5f;
/*
KFPM = KFPawn_Monster(StuckToActor);
if (KFPM != none && KFPM.Health > 0)
{
KFPM.ParasiteSeeds.Remove(0, KFPM.ParasiteSeeds.Length - (KFPM.MaxNumSeeds-1));
}
*/
super.UnStick();
}

View File

@ -0,0 +1,117 @@
//=============================================================================
// KFSeasonalEventStats_Fall2021
//=============================================================================
// Tracks event-specific challenges/accomplishments for Fall 2021
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Fall2021 extends KFSeasonalEventStats;
var transient private const int BossKillsRequired, EndlessWaveRequired;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
bObjectiveIsValidForMap[0] = 1; // Kill 15 Bosses on any map or mode
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Netherhold
bObjectiveIsValidForMap[2] = 0; // Find the nether heart
bObjectiveIsValidForMap[3] = 0; // Unlock the chapel and the dining hall doors
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Netherhold
if (CapsMapName == "KF-NETHERHOLD")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(BossKillsRequired, 0, 0, 0, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
// TODO: Uncomment me and set the proper item ID
GrantEventItem(8990);
}
}
// Kill 15 Bosses on any map or mode
simulated function OnBossDied()
{
local int ObjIdx;
ObjIdx = 0;
// Boss kills in any map
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= BossKillsRequired)
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
// Complete the Weekly on Netherhold
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
local int ObjIdx;
ObjIdx = 1;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
// Complete wave 15 on Endless Hard or higher difficulty on Netherhold
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Fall, ObjIdx);
}
}
}
simulated function OnTryCompleteObjective(int ObjectiveIndex, int EventIndex)
{
local int NetherHeartIdx, ChapelIdx;
NetherHeartIdx = 2;
ChapelIdx = 3;
if(EventIndex == SEI_Fall)
{
if (ObjectiveIndex == NetherHeartIdx || ObjectiveIndex == ChapelIdx)
{
if (bObjectiveIsValidForMap[ObjectiveIndex] != 0)
{
FinishedObjective(SEI_Fall, ObjectiveIndex);
}
}
}
}
defaultproperties
{
BossKillsRequired=15
EndlessWaveRequired=15
}

View File

@ -0,0 +1,106 @@
//=============================================================================
// KFWeapAttach_HRG_Energy
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_HRG_Energy extends KFWeaponAttachment;
`define HRG_ENERGY_MIC_LED_INDEX_1 0
`define HRG_ENERGY_MIC_SCREEN_INDEX 1
`define HRG_ENERGY_MIC_LED_INDEX_2 2
var MaterialInstanceConstant WeaponMIC_2;
var MaterialInstanceConstant WeaponMICScreen;
simulated function SetWeaponAltFireMode (bool bUsingAltFireMode)
{
super.SetWeaponAltFireMode(bUsingAltFireMode);
UpdateMaterial(bUsingAltFireMode ? 1 : 0);
}
simulated function UpdateMaterial(byte FireMode)
{
local LinearColor MatColor;
if (WeapMesh == none)
{
return;
}
MatColor = FireMode == 0 ? class'KFWeap_HRG_Energy'.default.DefaultFireMaterialColor : class'KFWeap_HRG_Energy'.default.AltFireMaterialColor;
if ( WeaponMIC == none )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`HRG_ENERGY_MIC_LED_INDEX_1);
}
if ( WeaponMIC_2 == none )
{
WeaponMIC_2 = WeapMesh.CreateAndSetMaterialInstanceConstant(`HRG_ENERGY_MIC_LED_INDEX_2);
}
if (WeaponMICScreen == none)
{
WeaponMICScreen = WeapMesh.CreateAndSetMaterialInstanceConstant(`HRG_ENERGY_MIC_SCREEN_INDEX);
}
WeaponMIC.SetVectorParameterValue('Vector_GlowColor', MatColor);
WeaponMIC_2.SetVectorParameterValue('Vector_GlowColor', MatColor);
WeaponMICScreen.SetVectorParameterValue('Color_override', MatColor);
}
/** Plays fire animation on weapon mesh */
simulated function PlayWeaponFireAnim()
{
local float Duration, AnimRateModifier;
local name Animation;
local KFPawn_Human KFPH;
KFPH = KFPawn_Human(Instigator);
AnimRateModifier = (KFPH != none && KFPH.bUsingAltFireMode) ? class'KFWeap_HRG_Energy'.default.SecondaryFireAnimRateModifier : 1.0f;
if ( Instigator.bIsWalking )
{
Duration = WeapMesh.GetAnimLength( WeaponIronFireAnim );
Animation = WeaponIronFireAnim;
}
else
{
Duration = WeapMesh.GetAnimLength( WeaponFireAnim );
Animation = WeaponFireAnim;
WeapMesh.PlayAnim( WeaponFireAnim, Duration / ThirdPersonAnimRate,, true );
}
WeapMesh.PlayAnim( Animation, Duration / ThirdPersonAnimRate * AnimRateModifier,, true );
}
/** Play a 3rd person reload animation */
simulated function PlayReloadMagazineAnim(EWeaponState NewWeaponState, KFPawn P)
{
local name AnimName;
switch (NewWeaponState)
{
case WEP_Reload:
case WEP_ReloadEmpty:
AnimName = (!P.bIsCrouched) ? ReloadHalfAnim : CH_ReloadHalfAnim;
break;
case WEP_Reload_Elite:
case WEP_ReloadEmpty_Elite:
AnimName = (!P.bIsCrouched) ? ReloadHalfEliteAnim : CH_ReloadHalfEliteAnim;
break;
}
PlayCharacterMeshAnim(P, AnimName, true);
}
defaultproperties
{
}

View File

@ -0,0 +1,108 @@
//=============================================================================
// KFWeapAttach_FAMAS
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_ParasiteImplanter extends KFWeaponAttachment;
`define PARASITEIMPLANTER_MIC_INDEX 0
const SecondaryFireAnim = 'Shoot_Secondary';
const SecondaryFireAnimCrouch = 'Shoot_Secondary_CH';
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
const SecondaryFireBodyAnim = 'ADD_Shoot_Secondary';
const SecondaryFireBodyAnimCH = 'ADD_Shoot_Secondary_CH';
const SecondaryFireBodyAnimIron = 'ADD_Shoot_Secondary_Iron';
/** Material colors applied to different fire modes */
var LinearColor NoAmmoMaterialColor;
var LinearColor AmmoReadyMaterialColor;
/** Plays fire animation on weapon mesh */
simulated function PlayWeaponFireAnim()
{
local float Duration;
local name Anim;
if ( Instigator.bIsWalking )
{
if (Instigator.FiringMode == 0) // DEFAULT FIRE MODE
{
Anim = WeaponIronFireAnim;
}
else if (Instigator.FiringMode == 1)
{
Anim = SecondaryFireIronAnim;
}
}
else
{
if (Instigator.FiringMode == 0) // ALT FIRE MODE
{
Anim = WeaponFireAnim;
}
else if (Instigator.FiringMode == 1)
{
Anim = Instigator.bIsCrouched ? SecondaryFireAnimCrouch : SecondaryFireAnim;
}
}
Duration = WeapMesh.GetAnimLength( Anim );
WeapMesh.PlayAnim( Anim, Duration / ThirdPersonAnimRate,, true );
}
/** Plays fire animation on pawn */
simulated function PlayPawnFireAnim( KFPawn P, EAnimSlotStance AnimType )
{
if (P.FiringMode == 0)
{
super.PlayPawnFireAnim(P, AnimType);
}
else if (P.FiringMode == 1)
{
if ( P.bIsCrouched )
{
P.PlayBodyAnim(SecondaryFireBodyAnimCH, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else if ( P.bIsWalking )
{
P.PlayBodyAnim(SecondaryFireBodyAnimIron, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
else
{
P.PlayBodyAnim(SecondaryFireBodyAnim, AnimType, ThirdPersonAnimRate, ShootBlendInTime, ShootBlendOutTime);
}
}
}
/** Special event added for weap attachments. Free for use */
function OnSpecialEvent(int Arg)
{
if (Arg <= 2)
{
UpdateMaterial(Arg == 2);
}
}
simulated function UpdateMaterial(bool HasEnoughAmmo)
{
local LinearColor Value;
Value = HasEnoughAmmo ? AmmoReadyMaterialColor : NoAmmoMaterialColor;
if ( WeaponMIC == None && WeapMesh != None )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`PARASITEIMPLANTER_MIC_INDEX);
}
WeaponMIC.SetVectorParameterValue('Vector_GlowColor', Value);
}
defaultproperties
{
NoAmmoMaterialColor=(R=0.0f,G=0.0f,B=0.0f)
AmmoReadyMaterialColor=(R=0.08f,G=1.0f,B=0.08f)
}

View File

@ -661,8 +661,8 @@ defaultproperties
HealFullRechargeSeconds=12 HealFullRechargeSeconds=12
// Heavy Attack Explosion Ammo // Heavy Attack Explosion Ammo
MagazineCapacity[0]=3 MagazineCapacity[0]=2 //3
SpareAmmoCapacity[0]=12 SpareAmmoCapacity[0]=10 //12
InitialSpareMags[0]=1 InitialSpareMags[0]=1
bCanBeReloaded=true bCanBeReloaded=true
bReloadFromMagazine=true bReloadFromMagazine=true
@ -687,7 +687,7 @@ defaultproperties
// Heavy Attack // Heavy Attack
FireModeIconPaths(HEAVY_ATK_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BluntMelee' FireModeIconPaths(HEAVY_ATK_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BluntMelee'
InstantHitDamage(HEAVY_ATK_FIREMODE)=130 InstantHitDamage(HEAVY_ATK_FIREMODE)=140 //130
InstantHitDamageTypes(HEAVY_ATK_FIREMODE) = class'KFDT_Bludgeon_MedicBatHeavy' InstantHitDamageTypes(HEAVY_ATK_FIREMODE) = class'KFDT_Bludgeon_MedicBatHeavy'
// Heavy Attack Explosion // Heavy Attack Explosion
@ -729,12 +729,12 @@ defaultproperties
// Explosion // Explosion
ExplosionActorClass = class'KFExplosionActorReplicated' ExplosionActorClass = class'KFExplosionActorReplicated'
Begin Object Class=KFGameExplosion Name=HeavyAttackHealingExplosion Begin Object Class=KFGameExplosion Name=HeavyAttackHealingExplosion
Damage=200 Damage=225 //200
DamageRadius=500 DamageRadius=500
DamageFalloffExponent=0.f DamageFalloffExponent=0.f
DamageDelay=0.f DamageDelay=0.f
MyDamageType=class'KFDT_Toxic_MedicBatGas' MyDamageType=class'KFDT_Toxic_MedicBatGas'
HealingAmount=30 HealingAmount=20 //30
// Damage Effects // Damage Effects
KnockDownStrength=0 KnockDownStrength=0

View File

@ -0,0 +1,192 @@
//=============================================================================
// KFWeap_HRG_Boomy
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_Boomy extends KFWeap_SMGBase;
/**
* Overriden to use instant hit vfx.
* Basically, calculate the hit location so vfx can play
*/
simulated function Projectile ProjectileFire()
{
local vector StartTrace, EndTrace, RealStartLoc, AimDir;
local ImpactInfo TestImpact;
local vector DirA, DirB;
local Quat Q;
local class<KFProjectile> MyProjectileClass;
MyProjectileClass = GetKFProjectileClass();
// This is where we would start an instant trace. (what CalcWeaponFire uses)
StartTrace = GetSafeStartTraceLocation();
AimDir = Vector(GetAdjustedAim( StartTrace ));
// this is the location where the projectile is spawned.
RealStartLoc = GetPhysicalFireStartLoc(AimDir);
// if projectile is spawned at different location of crosshair,
// then simulate an instant trace where crosshair is aiming at, Get hit info.
EndTrace = StartTrace + AimDir * GetTraceRange();
TestImpact = CalcWeaponFire( StartTrace, EndTrace );
// Set flash location to trigger client side effects. Bypass Weapon.SetFlashLocation since
// that function is not marked as simulated and we want instant client feedback.
// ProjectileFire/IncrementFlashCount has the right idea:
// 1) Call IncrementFlashCount on Server & Local
// 2) Replicate FlashCount if ( !bNetOwner )
// 3) Call WeaponFired() once on local player
if( Instigator != None )
{
Instigator.SetFlashLocation( Self, CurrentFireMode, TestImpact.HitLocation );
}
if( Role == ROLE_Authority || (MyProjectileClass.default.bUseClientSideHitDetection
&& MyProjectileClass.default.bNoReplicationToInstigator && Instigator != none
&& Instigator.IsLocallyControlled()) )
{
if( StartTrace != RealStartLoc )
{
// Store the original aim direction without correction
DirB = AimDir;
// Then we realign projectile aim direction to match where the crosshair did hit.
AimDir = Normal(TestImpact.HitLocation - RealStartLoc);
// Store the desired corrected aim direction
DirA = AimDir;
// Clamp the maximum aim adjustment for the AimDir so you don't get wierd
// cases where the projectiles velocity is going WAY off of where you
// are aiming. This can happen if you are really close to what you are
// shooting - Ramm
if ( (DirA dot DirB) < MaxAimAdjust_Cos )
{
Q = QuatFromAxisAndAngle(Normal(DirB cross DirA), MaxAimAdjust_Angle);
AimDir = QuatRotateVector(Q,DirB);
}
}
return SpawnAllProjectiles(MyProjectileClass, RealStartLoc, AimDir);
}
return None;
}
defaultproperties
{
bHasFireLastAnims=true
BonesToLockOnEmpty=(RW_Charging_Handle)
// Shooting Animations
FireSightedAnims[0]=Shoot_Iron
FireSightedAnims[1]=Shoot_Iron2
FireSightedAnims[2]=Shoot_Iron3
// FOV
MeshFOV=75
MeshIronSightFOV=52
PlayerIronSightFOV=70
// Depth of field
DOF_FG_FocalRadius=85
DOF_FG_MaxNearBlurSize=2.5
// Content
PackageKey="HRG_Boomy"
FirstPersonMeshName="WEP_1P_HRG_Boomy_MESH.Wep_1stP_HRG_Boomy_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_HRG_Boomy_ANIM.WEP_1stP_HRG_Boomy_Anim"
PickupMeshName="WEP_3P_HRG_Boomy_MESH.Wep_3rdP_HRG_Boomy_Pickup"
AttachmentArchetypeName="WEP_HRG_Boomy_ARCH.Wep_HRG_Boomy_3P"
MuzzleFlashTemplateName="WEP_HRG_Boomy_ARCH.Wep_HRG_Boomy_MuzzleFlash"
// Zooming/Position
PlayerViewOffset=(X=5.0,Y=9,Z=-5)
IronSightPosition=(X=5,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=24
SpareAmmoCapacity[0]=192
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=325 //325 //130 //165
minRecoilPitch=300 //275 //115 //130
maxRecoilYaw=140 //150 //115 //130
minRecoilYaw=-140 //-150 //-115 //130
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 / Grouping
InventorySize=7
GroupPriority=50
WeaponSelectTexture=Texture2D'WEP_UI_HRG_Boomy_TEX.UI_WeaponSelect_HRG_Boomy'
AssociatedPerkClasses(0)=class'KFPerk_Demolitionist'
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletAuto'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_HRG_Boomy'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_Boomy'
FireInterval(DEFAULT_FIREMODE)=+0.1667 // 360 RPM
Spread(DEFAULT_FIREMODE)=0.01 //0.025
InstantHitDamage(DEFAULT_FIREMODE)=25.0
FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_HRG_Boomy'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_Boomy'
FireInterval(ALTFIRE_FIREMODE)=+0.1667 // 360 RPM
InstantHitDamage(ALTFIRE_FIREMODE)=25.0
Spread(ALTFIRE_FIREMODE)=0.01 //0.025
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_Boomy'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_3P_ShootLoop', FirstPersonCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_1P_ShootLoop')
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_3P_Shoot', FirstPersonCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_1P_Shoot')
WeaponFireLoopEndSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_3P_ShootLoopEnd', FirstPersonCue=AkEvent'ww_wep_hrg_boomy.Play_WEP_HRG_Boomy_1P_ShootLoopEnd')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_L85A2.Play_WEP_SA_L85A2_Handling_DryFire'
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_L85A2.Play_WEP_SA_L85A2_Handling_DryFire'
// Advanced (High RPM) Fire Effects
bLoopingFireAnim(DEFAULT_FIREMODE)=true
bLoopingFireSnd(DEFAULT_FIREMODE)=true
SingleFireSoundIndex=ALTFIRE_FIREMODE
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Damage1, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
WeaponUpgrades[3]=(Stats=((Stat=EWUS_Damage0, Scale=1.45f), (Stat=EWUS_Damage1, Scale=1.45f), (Stat=EWUS_Weight, Add=3)))
}

View File

@ -0,0 +1,510 @@
//=============================================================================
// KFWeap_HRG_Energy
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_Energy extends KFWeap_PistolBase;
`define HRG_ENERGY_MIC_LED_INDEX_1 0
`define HRG_ENERGY_MIC_SCREEN_INDEX 1
`define HRG_ENERGY_MIC_LED_INDEX_2 2
/*********************************************************************************************
@name Optics UI
********************************************************************************************* */
var class<KFGFxWorld_MedicOptics> OpticsUIClass;
var KFGFxWorld_MedicOptics OpticsUI;
/** The last updated value for our ammo - Used to know when to update our optics ammo */
var byte StoredPrimaryAmmo;
var byte StoredSecondaryAmmo;
var transient float AltFireMaxShots;
/** Modifier applied to the alt fire animation */
var float SecondaryFireAnimRateModifier;
/** Material colors applied to different fire modes */
var LinearColor DefaultFireMaterialColor;
var LinearColor AltFireMaterialColor;
/** How much recoil the altfire should do */
var protected const float AltFireRecoilScale;
simulated event PreBeginPlay()
{
super.PreBeginPlay();
AltFireMaxShots = MagazineCapacity[DEFAULT_FIREMODE] / AmmoCost[ALTFIRE_FIREMODE];
}
simulated function Activate()
{
super.Activate();
UpdateMaterial(bUseAltFireMode ? ALTFIRE_FIREMODE : DEFAULT_FIREMODE);
}
simulated function UpdateMaterial(byte FireMode)
{
local LinearColor MatColor;
MatColor = FireMode == DEFAULT_FIREMODE ? DefaultFireMaterialColor : AltFireMaterialColor;
if( WeaponMICs.Length > `HRG_ENERGY_MIC_LED_INDEX_1 )
{
WeaponMICs[`HRG_ENERGY_MIC_LED_INDEX_1].SetVectorParameterValue('Vector_GlowColor', MatColor);
}
if (WeaponMICs.Length > `HRG_ENERGY_MIC_SCREEN_INDEX)
{
WeaponMICs[`HRG_ENERGY_MIC_SCREEN_INDEX].SetVectorParameterValue('Color_override', MatColor);
}
if( WeaponMICs.Length > `HRG_ENERGY_MIC_LED_INDEX_2 )
{
WeaponMICs[`HRG_ENERGY_MIC_LED_INDEX_2].SetVectorParameterValue('Vector_GlowColor', MatColor);
}
}
/**
* Check target locking - server-side only
* HealAmmo Regen client and server
*/
simulated event Tick( FLOAT DeltaTime )
{
if (Instigator != none && Instigator.weapon == self)
{
UpdateOpticsUI();
}
Super.Tick(DeltaTime);
}
/*********************************************************************************************
@name Optics UI
********************************************************************************************* */
/** Get our optics movie from the inventory once our InvManager is created */
reliable client function ClientWeaponSet(bool bOptionalSet, optional bool bDoNotActivate)
{
local KFInventoryManager KFIM;
super.ClientWeaponSet(bOptionalSet, bDoNotActivate);
if (OpticsUI == none)
{
KFIM = KFInventoryManager(InvManager);
if (KFIM != none)
{
//Create the screen's UI piece
OpticsUI = KFGFxWorld_MedicOptics(KFIM.GetOpticsUIMovie(OpticsUIClass));
}
}
}
function ItemRemovedFromInvManager()
{
local KFInventoryManager KFIM;
local KFWeap_MedicBase KFW;
Super.ItemRemovedFromInvManager();
if (OpticsUI != none)
{
KFIM = KFInventoryManager(InvManager);
if (KFIM != none)
{
// @todo future implementation will have optics in base weapon class
foreach KFIM.InventoryActors(class'KFWeap_MedicBase', KFW)
{
// This is not a MedicBase, no need to check against itself
if(KFW.OpticsUI.Class == OpticsUI.class)
{
// A different weapon is still using this optics class
return;
}
}
//Create the screen's UI piece
KFIM.RemoveOpticsUIMovie(OpticsUI.class);
OpticsUI.Close();
OpticsUI = none;
}
}
}
/** Unpause our optics movie and reinitialize our ammo when we equip the weapon */
simulated function AttachWeaponTo(SkeletalMeshComponent MeshCpnt, optional Name SocketName)
{
super.AttachWeaponTo(MeshCpnt, SocketName);
if (OpticsUI != none)
{
OpticsUI.SetPause(false);
OpticsUI.ClearLockOn();
UpdateOpticsUI(true);
OpticsUI.SetShotPercentCost( AmmoCost[ALTFIRE_FIREMODE]);
}
}
/** Pause the optics movie once we unequip the weapon so it's not playing in the background */
simulated function DetachWeapon()
{
local Pawn OwnerPawn;
super.DetachWeapon();
OwnerPawn = Pawn(Owner);
if( OwnerPawn != none && OwnerPawn.Weapon == self )
{
if (OpticsUI != none)
{
OpticsUI.SetPause();
}
}
}
/**
* Update our displayed ammo count if it's changed
*/
simulated function UpdateOpticsUI(optional bool bForceUpdate)
{
if (OpticsUI != none && OpticsUI.OpticsContainer != none)
{
if (AmmoCount[DEFAULT_FIREMODE] != StoredPrimaryAmmo || bForceUpdate)
{
StoredPrimaryAmmo = AmmoCount[DEFAULT_FIREMODE];
OpticsUI.SetPrimaryAmmo(StoredPrimaryAmmo);
if(AmmoCount[DEFAULT_FIREMODE] < AmmoCost[ALTFIRE_FIREMODE])
{
OpticsUI.SetHealerCharge(0);
}
else
{
OpticsUI.SetHealerCharge((AmmoCount[DEFAULT_FIREMODE] / AmmoCost[ALTFIRE_FIREMODE]) / AltFireMaxShots * 100);
}
}
if(OpticsUI.MinPercentPerShot != AmmoCost[ALTFIRE_FIREMODE])
{
OpticsUI.SetShotPercentCost( AmmoCost[ALTFIRE_FIREMODE] );
}
}
}
/** Healing charge doesn't count as ammo for purposes of inventory management (e.g. switching) */
simulated function bool HasAnyAmmo()
{
return HasSpareAmmo() || HasAmmo(DEFAULT_FIREMODE) || HasSpareAmmo(ALTFIRE_FIREMODE) || HasAmmo(ALTFIRE_FIREMODE);
}
simulated function StartFire(byte FireModeNum)
{
if (FireModeNum == DEFAULT_FIREMODE && bUseAltFireMode)
{
if (AmmoCount[FireModeNum] < AmmoCost[ALTFIRE_FIREMODE] && SpareAmmoCount[FireModeNum] > 0)
{
BeginFire(RELOAD_FIREMODE);
return;
}
}
super.StartFire(FireModeNum);
}
simulated function AltFireMode()
{
if ( !Instigator.IsLocallyControlled() )
{
return;
}
if ( !bUseAltFireMode && SpareAmmoCount[0] + AmmoCount[0] < AmmoCost[1] )
{
return;
}
super.AltFireMode();
UpdateMaterial(bUseAltFireMode ? ALTFIRE_FIREMODE : DEFAULT_FIREMODE);
NotifyAltFireUsage();
}
/** Overriden to use WeaponAnimSeqNode */
simulated function PlayWeaponAnimation(name Sequence, float fDesiredDuration, optional bool bLoop, optional SkeletalMeshComponent SkelMesh)
{
local float DesiredRate;
if ( Mesh != none && Instigator != none && WorldInfo.NetMode != NM_DedicatedServer )
{
if ( WeaponAnimSeqNode != None )
{
if (WeaponAnimSeqNode.AnimSeq == None || WeaponAnimSeqNode.AnimSeq.SequenceName != Sequence)
{
WeaponAnimSeqNode.SetAnim(Sequence);
}
if(fDesiredDuration > 0.0 && WeaponAnimSeqNode.AnimSeq.RateScale > 0.0)
{
DesiredRate = WeaponAnimSeqNode.AnimSeq.SequenceLength / (fDesiredDuration * WeaponAnimSeqNode.AnimSeq.RateScale);
WeaponAnimSeqNode.PlayAnim(bLoop, DesiredRate);
}
else
{
WeaponAnimSeqNode.PlayAnim(bLoop, DefaultAnimSpeed);
}
}
}
}
/**
* PlayFireEffects Is the root function that handles all of the effects associated with
* a weapon. This function creates the 1st person effects. It should only be called
* on a locally controlled player.
*/
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
local name WeaponFireAnimName;
local KFPerk CurrentPerk;
local float TempTweenTime, AdjustedAnimLength;
// If we have stopped the looping fire sound to play single fire sounds for zed time
// start the looping sound back up again when the time is back above zed time speed
if( FireModeNum < bLoopingFireSnd.Length && bLoopingFireSnd[FireModeNum] && !bPlayingLoopingFireSnd )
{
StartLoopingFireSound(FireModeNum);
}
PlayFiringSound(CurrentFireMode);
if( Instigator != none )
{
// Tell our pawn about any changes in animation speed
UpdateWeaponAttachmentAnimRate( GetThirdPersonAnimRate() );
if( Instigator.IsLocallyControlled() )
{
if( Instigator.IsFirstPerson() )
{
if ( !bPlayingLoopingFireAnim )
{
WeaponFireAnimName = GetWeaponFireAnim(FireModeNum);
if ( WeaponFireAnimName != '' )
{
AdjustedAnimLength = MySkelMesh.GetAnimLength(WeaponFireAnimName);
TempTweenTime = FireTweenTime;
if (FireModeNum == ALTFIRE_FIREMODE)
{
AdjustedAnimLength *= SecondaryFireAnimRateModifier;
}
CurrentPerk = GetPerk();
if( CurrentPerk != none )
{
CurrentPerk.ModifyRateOfFire( AdjustedAnimLength, self );
// We need to unlock the slide if we fire from zero ammo while uber ammo is active
if( EmptyMagBlendNode != none
&& BonesToLockOnEmpty.Length > 0
&& AmmoCount[GetAmmoType(FireModeNum)] == 0
&& CurrentPerk.GetIsUberAmmoActive(self) )
{
EmptyMagBlendNode.SetBlendTarget( 0, 0 );
TempTweenTime = 0.f;
}
}
PlayAnimation(WeaponFireAnimName, AdjustedAnimLength,, TempTweenTime);
}
}
// Start muzzle flash effect
CauseMuzzleFlash(FireModeNum);
}
HandleRecoil();
ShakeView();
if (AmmoCount[0] == 0 && ForceReloadTimeOnEmpty > 0)
{
SetTimer(ForceReloadTimeOnEmpty, false, nameof(ForceReload));
}
}
}
}
simulated function ModifyRecoil( out float CurrentRecoilModifier )
{
if( CurrentFireMode == ALTFIRE_FIREMODE )
{
CurrentRecoilModifier *= AltFireRecoilScale;
}
super.ModifyRecoil( CurrentRecoilModifier );
}
simulated function NotifyAltFireUsage()
{
local KFPawn_Human KFPH;
// Notify 3P to change material.
KFPH = KFPawn_Human(Instigator);
if (KFPH != none)
{
KFPH.SetUsingAltFireMode(bUseAltFireMode, true);
KFPH.bNetDirty = true;
}
}
simulated state WeaponEquipping
{
simulated function BeginState(Name PreviousStateName)
{
super.BeginState(PreviousStateName);
// NotifyAltFireUsage();
if (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone)
{
SetTimer(1.0f, false, nameof(NotifyAltFireUsage));
}
}
}
/** Returns animation to play based on reload type and status */
simulated function name GetReloadAnimName( bool bTacticalReload )
{
return bTacticalReload ? ReloadNonEmptyMagEliteAnim : ReloadNonEmptyMagAnim;
}
simulated function ConsumeAmmo( byte FireModeNum )
{
super.ConsumeAmmo(FireModeNum);
if( bUseAltFireMode && SpareAmmoCount[0] + AmmoCount[0] < AmmoCost[1] )
{
bUseAltFireMode = false;
UpdateMaterial(DEFAULT_FIREMODE);
NotifyAltFireUsage();
}
}
defaultproperties
{
// Inventory
InventoryGroup=IG_Secondary
InventorySize=4
GroupPriority=125
bCanThrow=true
bDropOnDeath=true
WeaponSelectTexture=Texture2D'WEP_UI_HRG_Energy_TEX.UI_WeaponSelect_HRG_Energy'
SecondaryAmmoTexture=Texture2D'UI_SecondaryAmmo_TEX.MedicDarts'
AssociatedPerkClasses(0)=class'KFPerk_Gunslinger'
// Shooting Animations
FireSightedAnims[0]=Shoot_Iron
FireSightedAnims[1]=Shoot_Iron2
FireSightedAnims[2]=Shoot_Iron3
// FOV
MeshFOV=86
MeshIronSightFOV=77
PlayerIronSightFOV=77
// Depth of field
DOF_FG_FocalRadius=40
DOF_FG_MaxNearBlurSize=3.5
// Zooming/Position
PlayerViewOffset=(X=29.0,Y=13,Z=-4)
//Content
PackageKey="HRG_Energy"
FirstPersonMeshName="WEP_1P_HRG_Energy_MESH.Wep_1stP_HRG_Energy_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_HRG_Energy_ANIM.WEP_1P_HRG_Energy_ANIM"
PickupMeshName="wep_3p_HRG_Energy_mesh.Wep_HRG_Energy_Pickup"
AttachmentArchetypeName="WEP_HRG_Energy_ARCH.Wep_HRG_Energy_3P"
MuzzleFlashTemplateName="WEP_HRG_Energy_ARCH.Wep_HRG_Energy_MuzzleFlash"
OpticsUIClass=class'KFGFxWorld_MedicOptics'
// Zooming/Position
IronSightPosition=(X=15,Y=0,Z=0)
// Ammo
MagazineCapacity[0]=15
SpareAmmoCapacity[0]=135
InitialSpareMags[0]=2
bCanBeReloaded=true
bReloadFromMagazine=true
MagazineCapacity[1]=0
bCanRefillSecondaryAmmo=false
// Recoil
maxRecoilPitch=475 //250
minRecoilPitch=425 //200
maxRecoilYaw=130 //100
minRecoilYaw=-130 //-100
RecoilRate=0.07
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=250
RecoilISMinPitchLimit=65485
AltFireRecoilScale=2.0f
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_HRG_Energy'
FireInterval(DEFAULT_FIREMODE)=+0.175 //342 RPM
PenetrationPower(DEFAULT_FIREMODE)=1.0
InstantHitDamage(DEFAULT_FIREMODE)=90.0 //125.0
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_Energy_Primary'
Spread(DEFAULT_FIREMODE)=0.015
FireOffset=(X=20,Y=4.0,Z=-3)
// ALTFIRE_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_InstantHit
FireInterval(ALTFIRE_FIREMODE)=+0.705 //85 RPM
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_HRG_Energy_Secondary'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_HRG_Energy_Secondary'
InstantHitMomentum(ALTFIRE_FIREMODE)=1.0
PenetrationPower(ALTFIRE_FIREMODE)=3.0
InstantHitDamage(ALTFIRE_FIREMODE)=300.0 //475.0
PenetrationDamageReductionCurve(ALTFIRE_FIREMODE)=(Points=((InVal=0.f,OutVal=0.f),(InVal=1.f, OutVal=1.f)))
AmmoCost(ALTFIRE_FIREMODE)=3
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_Energy'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'ww_wep_hrg_energy.Play_WEP_HRG_Energy_3P_Shoot', FirstPersonCue=AkEvent'ww_wep_hrg_energy.Play_WEP_HRG_Energy_1P_Shoot')
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'ww_wep_hrg_energy.Play_WEP_HRG_Energy_3P_ShootAlt', FirstPersonCue=AkEvent'ww_wep_hrg_energy.Play_WEP_HRG_Energy_1P_ShootAlt')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_SA_MedicPistol.Play_SA_MedicPistol_Handling_DryFire'
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_SA_MedicDart.Play_WEP_SA_Medic_Dart_DryFire'
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
SecondaryFireAnimRateModifier = 2.0f;
DefaultFireMaterialColor=(R=0.90f,G=0.26f,B=0.0f)
AltFireMaterialColor=(R=0.7f,G=0.04f,B=0.9f)
NumBloodMapMaterials=3
// bForceHandleImpacts=true;
}

View File

@ -842,8 +842,8 @@ defaultproperties
ValueIncreaseTime=0.2 ValueIncreaseTime=0.2
//FOR LERPING DAMANGE //FOR LERPING DAMANGE
MaxDamageByCharge=250 //200 //120 MaxDamageByCharge=300 //250 //200 //120
MinDamageByCharge=25 //30 MinDamageByCharge=30 //25 //30
// FOV // FOV
Meshfov=80 Meshfov=80
MeshIronSightFOV=65 //52 MeshIronSightFOV=65 //52
@ -870,8 +870,8 @@ defaultproperties
// Ammo // Ammo
MagazineCapacity[0]=12 //24 MagazineCapacity[0]=12 //24
SpareAmmoCapacity[0]=108 //96 //120 SpareAmmoCapacity[0]=132 //108
InitialSpareMags[0]=2 //1 InitialSpareMags[0]=3 //2
AmmoPickupScale[0]=1.5 //1 //0.75 AmmoPickupScale[0]=1.5 //1 //0.75
bCanBeReloaded=true bCanBeReloaded=true
bReloadFromMagazine=true bReloadFromMagazine=true
@ -905,7 +905,7 @@ defaultproperties
FiringStatesArray(DEFAULT_FIREMODE)=MineReconstructorCharge FiringStatesArray(DEFAULT_FIREMODE)=MineReconstructorCharge
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Mine_Reconstructor' WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Mine_Reconstructor'
FireInterval(DEFAULT_FIREMODE)=+0.33 //180 RPMs FireInterval(DEFAULT_FIREMODE)=+0.223 //+0.33
InstantHitDamage(DEFAULT_FIREMODE)=120 InstantHitDamage(DEFAULT_FIREMODE)=120
PenetrationPower(DEFAULT_FIREMODE)=0.0; PenetrationPower(DEFAULT_FIREMODE)=0.0;
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Toxic_MineReconstructorImpact' InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Toxic_MineReconstructorImpact'
@ -914,7 +914,7 @@ defaultproperties
// ALT_FIREMODE // ALT_FIREMODE
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
FireInterval(ALTFIRE_FIREMODE)=+0.25 FireInterval(ALTFIRE_FIREMODE)=+0.15 //+0.25
AmmoCost(ALTFIRE_FIREMODE)=0 AmmoCost(ALTFIRE_FIREMODE)=0
// BASH_FIREMODE // BASH_FIREMODE

View File

@ -0,0 +1,228 @@
//=============================================================================
// KFWeap_Pistol_Bladed
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_Pistol_Bladed extends KFWeap_MeleeBase;
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Pistol;
}
/** Override melee SetIronSights (which sends to heavy attack) so that this weapon ironsights normally*/
simulated function SetIronSights(bool bNewIronSights)
{
super(KFWeapon).SetIronSights(bNewIronSights);
}
/** Override melee ShouldOwnerWalk which doesn't account for walking when in ironsights */
simulated function bool ShouldOwnerWalk()
{
return super(KFWeapon).ShouldOwnerWalk();
}
/** Override to drop the player out of ironsights first */
simulated function AltFireMode()
{
if (!Instigator.IsLocallyControlled())
{
return;
}
// break out of ironsights when starting to block
if (bUsingSights)
{
SetIronSights(false);
}
StartFire(BLOCK_FIREMODE);
}
simulated state MeleeBlocking
{
simulated function bool AllowIronSights() { return false; }
}
/** Called during reload state */
simulated function bool CanOverrideMagReload(byte FireModeNum)
{
if (FireModeNum == BLOCK_FIREMODE)
{
return true;
}
return super.CanOverrideMagReload(FireModeNum);
}
simulated function StartFire(byte FireModeNum)
{
if( FireModeNum == DEFAULT_FIREMODE )
{
if ( ShouldAutoReload(FireModeNum) )
{
BeginFire(RELOAD_FIREMODE);
return;
}
}
super.StartFire(FireModeNum);
}
/*********************************************************************************************
* @name Firing / Projectile
********************************************************************************************* */
/**
* See Pawn.ProcessInstantHit
* @param DamageReduction: Custom KF parameter to handle penetration damage reduction
*/
simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum )
{
local KFPerk InstigatorPerk;
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
InstigatorPerk.UpdatePerkHeadShots( Impact, InstantHitDamageTypes[FiringMode], ImpactNum );
}
super.ProcessInstantHitEx( FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum );
}
defaultproperties
{
// MeleeBase
bMeleeWeapon=false
// FOV
MeshFOV=96
MeshIronSightFOV=77
PlayerIronSightFOV=77
// Depth of field
DOF_FG_FocalRadius=40
DOF_FG_MaxNearBlurSize=3.5
// Zooming/Position
PlayerViewOffset=(X=-15,Y=12,Z=-6)
IronSightPosition=(X=0,Y=0,Z=1.0) //(X=-3,Y=-0.38,Z=-0.2)
// Content
PackageKey="BladedPistol"
FirstPersonMeshName="WEP_1P_BladedPistol_MESH.WEP_1stP_BladedPistol_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_BladedPistol_ANIM.WEP_1stP_BladedPistol_Anim"
PickupMeshName="WEP_3P_BladedPistol_MESH.Wep_BladedPistol_Pickup"
AttachmentArchetypeName="WEP_BladedPistol_ARCH.Wep_BladedPistol_3P"
MuzzleFlashTemplateName="WEP_BladedPistol_ARCH.Wep_BladedPistol_MuzzleFlash"
// Ammo
MagazineCapacity[0]=6
SpareAmmoCapacity[0]=72 //96
InitialSpareMags[0]=2
AmmoPickupScale[0]=1.0 //2.0
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=330 //400 //250
minRecoilPitch=300 //350 //200
maxRecoilYaw=90 //120 //100
minRecoilYaw=-90 //-120 //-100
RecoilRate=0.07
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=250
RecoilISMinPitchLimit=65485
// DEFAULT_FIREMODE
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Blade_BladedPistol'
PenetrationPower(DEFAULT_FIREMODE)=3.0
FireInterval(DEFAULT_FIREMODE)=+0.25 //+0.3
InstantHitDamage(DEFAULT_FIREMODE)=115.0
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Slashing_BladedPistol'
Spread(DEFAULT_FIREMODE)=0.005 //0.015
AmmoCost(DEFAULT_FIREMODE)=1
FireOffset=(X=30,Y=5,Z=-4)
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Sawblade'
// ALT_FIREMODE
// FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
// WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_None
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_BladedPistol'
InstantHitDamage(BASH_FIREMODE)=75 //26
FiringStatesArray(BASH_FIREMODE)=MeleeAttackBasic
WeaponFireTypes(BASH_FIREMODE)=EWFT_Custom
InstantHitMomentum(BASH_FIREMODE)=10000.f
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Handling_DryFire'
// RELOAD_FIREMODE
FiringStatesArray(RELOAD_FIREMODE)="Reloading"
WeaponFireTypes(RELOAD_FIREMODE)=EWFT_InstantHit
// Attachments
bHasIronSights=true
bHasFlashlight=true
AssociatedPerkClasses(0)=class'KFPerk_Gunslinger'
AssociatedPerkClasses(1)=class'KFPerk_Berserker'
// Inventory
InventoryGroup=IG_Secondary
InventorySize=3
GroupPriority=25
bCanThrow=true
bDropOnDeath=true
WeaponSelectTexture=Texture2D'WEP_UI_BladedPistol_TEX.UI_WeaponSelect_BladedPistol'
bIsBackupWeapon=false
DualClass=class'KFWeap_Pistol_DualBladed'
// Custom animations
FireSightedAnims=(Shoot_Iron)
IdleFidgetAnims=(Guncheck_v1, Guncheck_v2, Guncheck_v3)
bHasFireLastAnims=true
BonesToLockOnEmpty=(RW_FrontPivot)
// default MIC param names
BlockEffectsSocketName=BlockEffect
// Defensive
BlockDamageMitigation=0.60f
ParryDamageMitigationPercent=0.5
ParryStrength=4
BlockHitAnimCooldownTime=0.5f
BlockTypes.Add((DmgType=class'KFDT_Bludgeon'))
BlockTypes.Add((DmgType=class'KFDT_Slashing'))
// Block Sounds
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Crovel'
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
BlockParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Block_melee_01'
ParryParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Parry_melee_01'
MeleeBlockHitAnims=(Block_Hit_V1, Block_Hit_V2, Block_Hit_V3);
//Upgrades
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Damage2, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Damage1, Scale=1.3f), (Stat=EWUS_Damage2, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
}

View File

@ -0,0 +1,679 @@
//=============================================================================
// KFWeap_Pistol_DualBladed
//=============================================================================
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_Pistol_DualBladed extends KFWeap_DualBase;
/*
*
* BROUGHT FROM MELEE WEAPON TO SUPPORT PARRYING
*
*/
/** These override the base firemodes of the same ID (for readability) */
const BLOCK_FIREMODE = 1; // ALTFIRE_FIREMODE
/*********************************************************************************************
* @name Defensive Abilities
*********************************************************************************************/
struct native BlockEffectInfo
{
var class<DamageType> DmgType;
/** If != None, overrides the class default FX */
var AkEvent BlockSound;
var AkEvent ParrySound;
var ParticleSystem BlockParticleSys;
var ParticleSystem ParryParticleSys;
};
var array<BlockEffectInfo> BlockTypes;
/** Damage while blocking will be mitigated by this percentage */
var() float BlockDamageMitigation;
/** Parry damage will be mitigated by this percentage */
var() float ParryDamageMitigationPercent;
/** Hit reaction strength to bypass pawn's ParryStumbleResist */
var() byte ParryStrength;
/** If true, owning pawn moves at a slower (iron sight) walking speed */
var bool bMoveAtWalkingSpeed;
/** Time between block hit reaction anims */
var() protected float BlockHitAnimCooldownTime;
/** The last time we played a block hit reaction anim */
var transient protected float LastBlockHitAnimTime;
/** Animations played on successful block */
var array<name> MeleeBlockHitAnims;
/*********************************************************************************************
* @name Effects
********************************************************************************************* */
/** Block / Parry */
var AkBaseSoundObject BlockSound;
var AKBaseSoundObject ParrySound;
var ParticleSystem BlockParticleSystem;
var ParticleSystem ParryParticleSystem;
var name BlockEffectsSocketName;
/** Defensive stance animation names */
const MeleeBlockStartAnim = 'Brace_in';
const MeleeBlockLoopAnim = 'Brace_loop';
const MeleeBlockEndAnim = 'Brace_out';
var array<name> BonesToLockOnEmpty_Override;
simulated function NotifyAttackParried();
simulated function NotifyAttackBlocked();
// Global declarations for blocking state
simulated function BlockLoopTimer();
simulated function ParryCheckTimer();
/** Called on the server when successfully block/parry an attack */
unreliable client function ClientPlayBlockEffects(optional byte BlockTypeIndex=255)
{
local AkBaseSoundObject Sound;
local ParticleSystem PSTemplate;
GetBlockEffects(BlockTypeIndex, Sound, PSTemplate);
PlayLocalBlockEffects(Sound, PSTemplate);
}
/** Called on the server when successfully block/parry an attack */
reliable client function ClientPlayParryEffects(optional byte BlockTypeIndex=255)
{
local AkBaseSoundObject Sound;
local ParticleSystem PSTemplate;
local KFPerk InstigatorPerk;
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
InstigatorPerk.SetSuccessfullParry();
}
GetParryEffects(BlockTypeIndex, Sound, PSTemplate);
PlayLocalBlockEffects(Sound, PSTemplate);
}
simulated state MeleeBlocking
{
ignores ForceReload, ShouldAutoReload;
simulated function bool AllowIronSights() { return false; }
simulated function byte GetWeaponStateId()
{
return WEP_MeleeBlock;
}
simulated function BeginState(name PreviousStateName)
{
local float ParryDuration;
ParryDuration = PlayBlockStart();
// Set the duration of the window to parry incoming attacks
if ( ParryDuration > 0.f )
{
SetTimer( ParryDuration, false, nameof(ParryCheckTimer) );
}
NotifyBeginState();
}
simulated function EndState(Name NextStateName)
{
if ( Instigator.IsLocallyControlled() )
{
PlayAnimation(MeleeBlockEndAnim);
}
//SetSlowMovement(false);
NotifyEndState();
}
/** Return to active state if we're done blocking */
simulated function EndFire(byte FireModeNum)
{
Global.EndFire(FireModeNum);
// Wait until parry is finished, then check PendingFire to stop blocking
if ( !StillFiring(CurrentFireMode) && !IsTimerActive(nameof(ParryCheckTimer)) )
{
GotoState('BlockingCooldown');
}
}
/** After the parry window is finished, check PendingFire to see if we're still blocking */
simulated function ParryCheckTimer()
{
// Check PendingFire to stop blocking
if ( !StillFiring(CurrentFireMode) )
{
GotoState('BlockingCooldown');
}
}
/** Grab/Grapple attacks can be parried */
function bool IsGrappleBlocked(Pawn InstigatedBy)
{
local float FacingDot;
local vector Dir2d;
// zero Z to give us a 2d dot product
Dir2d = Normal2d(InstigatedBy.Location - Instigator.Location);
FacingDot = vector(Instigator.Rotation) dot (Dir2d);
// Cos(85)
if ( FacingDot > 0.087f )
{
if ( IsTimerActive(nameof(ParryCheckTimer)) )
{
KFPawn(InstigatedBy).NotifyAttackParried(Instigator, 255);
ClientPlayParryEffects();
NotifyAttackParried();
}
else
{
ClientPlayBlockEffects();
NotifyAttackBlocked();
}
return TRUE;
}
return FALSE;
}
/** While holding a melee weapon reduce some incoming damage */
function AdjustDamage(out int InDamage, class<DamageType> DamageType, Actor DamageCauser)
{
local float FacingDot;
local vector Dir2d;
local KFPerk InstigatorPerk;
local byte BlockTypeIndex;
// don't apply block/parry effects for teammates
if (Instigator.IsSameTeam(DamageCauser.Instigator))
{
return;
}
// zero Z to give us a 2d dot product
Dir2d = Normal2d(DamageCauser.Location - Instigator.Location);
FacingDot = vector(Instigator.Rotation) dot (Dir2d);
// Cos(85)
if ( FacingDot > 0.087f && CanBlockDamageType(DamageType, BlockTypeIndex) )
{
InstigatorPerk = GetPerk();
if ( IsTimerActive(nameof(ParryCheckTimer)) )
{
InDamage *= GetUpgradedParryDamageMitigation(CurrentWeaponUpgradeIndex);
// Notify attacking pawn for effects / animations
if ( KFPawn(DamageCauser) != None )
{
KFPawn(DamageCauser).NotifyAttackParried(Instigator, ParryStrength);
}
// @NOTE: This is now always true per discussion with AndrewL on KFII-29686. Since we always
// do the damage mitigation, we should always play the effect regardless of whether the
// zed was stumbled or knocked down. -MattF
ClientPlayParryEffects(BlockTypeIndex);
NotifyAttackParried();
if( InstigatorPerk != none )
{
InstigatorPerk.SetSuccessfullParry();
}
}
else
{
InDamage *= GetUpgradedBlockDamageMitigation(CurrentWeaponUpgradeIndex);
ClientPlayBlockEffects(BlockTypeIndex);
NotifyAttackBlocked();
if( InstigatorPerk != none )
{
InstigatorPerk.SetSuccessfullBlock();
}
}
}
}
simulated function BlockLoopTimer()
{
if( Instigator.IsLocallyControlled() )
{
PlayAnimation(MeleeBlockLoopAnim, , true);
}
}
/** State override for Block_Hit animations */
unreliable client function ClientPlayBlockEffects(optional byte BlockTypeIndex=255)
{
local int AnimIdx;
local float Duration;
local KFPerk InstigatorPerk;
Global.ClientPlayBlockEffects(BlockTypeIndex);
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
InstigatorPerk.SetSuccessfullBlock();
}
if( MeleeBlockHitAnims.Length > 0 && `TimeSince(LastBlockHitAnimTime) > BlockHitAnimCooldownTime && !IsTimerActive(nameof(ParryCheckTimer)) )
{
AnimIdx = Rand(MeleeBlockHitAnims.Length);
Duration = MySkelMesh.GetAnimLength(MeleeBlockHitAnims[AnimIdx]);
if ( Duration > 0 )
{
LastBlockHitAnimTime = WorldInfo.TimeSeconds;
PlayAnimation(MeleeBlockHitAnims[AnimIdx]);
SetTimer(Duration, false, nameof(BlockLoopTimer));
}
}
}
}
simulated function float PlayBlockStart()
{
local float AnimDuration;
if( Instigator.IsLocallyControlled() )
{
PlayAnimation(MeleeBlockStartAnim);
}
// set when to start playing the looping anim
AnimDuration = MySkelMesh.GetAnimLength(MeleeBlockStartAnim);
if ( AnimDuration > 0.f )
{
SetTimer(AnimDuration, false, nameof(BlockLoopTimer));
}
else
{
BlockLoopTimer();
}
// set the parry duration to the same as the block start anim
return AnimDuration;
}
/** Called on the client when successfully block/parry an attack */
simulated function PlayLocalBlockEffects(AKBaseSoundObject Sound, ParticleSystem PSTemplate)
{
local vector Loc;
local rotator Rot;
local ParticleSystemComponent PSC;
if ( Sound != None )
{
PlaySoundBase(Sound, true);
}
if ( PSTemplate != None )
{
if ( MySkelMesh.GetSocketWorldLocationAndRotation(BlockEffectsSocketName, Loc, Rot) )
{
PSC = WorldInfo.MyEmitterPool.SpawnEmitter(PSTemplate, Loc, Rot);
PSC.SetDepthPriorityGroup(SDPG_Foreground);
}
else
{
`log(self@GetFuncName()@"missing BlockEffects Socket!");
}
}
}
/** If true, this damage type can be blocked by the MeleeBlocking state */
function bool CanBlockDamageType(class<DamageType> DamageType, optional out byte out_Idx)
{
local int Idx;
// Check if this damage should be ignored completely
for (Idx = 0; Idx < BlockTypes.length; ++Idx)
{
if ( ClassIsChildOf(DamageType, BlockTypes[Idx].DmgType) )
{
out_Idx = Idx;
return true;
}
}
out_Idx = INDEX_NONE;
return false;
}
/** Returns sound and particle system overrides using index into BlockTypes array */
simulated function GetBlockEffects(byte BlockIndex, out AKBaseSoundObject outSound, out ParticleSystem outParticleSys)
{
outSound = BlockSound;
outParticleSys = BlockParticleSystem;
if ( BlockIndex != 255 )
{
if ( BlockTypes[BlockIndex].BlockSound != None )
{
outSound = BlockTypes[BlockIndex].BlockSound;
}
if ( BlockTypes[BlockIndex].BlockParticleSys != None )
{
outParticleSys = BlockTypes[BlockIndex].BlockParticleSys;
}
}
}
/** Returns sound and particle system overrides using index into BlockTypes array */
simulated function GetParryEffects(byte BlockIndex, out AKBaseSoundObject outSound, out ParticleSystem outParticleSys)
{
outSound = ParrySound;
outParticleSys = ParryParticleSystem;
if ( BlockIndex != 255 )
{
if ( BlockTypes[BlockIndex].ParrySound != None )
{
outSound = BlockTypes[BlockIndex].ParrySound;
}
if ( BlockTypes[BlockIndex].ParryParticleSys != None )
{
outParticleSys = BlockTypes[BlockIndex].ParryParticleSys;
}
}
}
/*********************************************************************************************
* State BlockingCooldown
* A short cooldown state to prevent spamming block while still allowing pendingfire to be set
*********************************************************************************************/
// Global declarations for this state
simulated function BlockCooldownTimer();
simulated state BlockingCooldown extends Active
{
ignores AllowSprinting;
/** Set cooldown duration */
simulated function BeginState( Name PreviousStateName )
{
SetTimer(0.5, false, nameof(BlockCooldownTimer));
Super.BeginState(PreviousStateName);
}
// prevent going to block/parry state
simulated function bool HasAmmo( byte FireModeNum, optional int Amount )
{
if ( FireModeNum == BLOCK_FIREMODE )
{
return false;
}
return Global.HasAmmo(FireModeNum, Amount);
}
// prevent HasAmmo (above) from causing an auto reload
simulated function bool ShouldAutoReload(byte FireModeNum)
{
if ( FireModeNum == BLOCK_FIREMODE )
{
return false;
}
return Global.ShouldAutoReload(FireModeNum);
}
simulated function BlockCooldownTimer()
{
GotoState('Active');
}
}
/*
*
* END of parrying code.
*
*/
/**
* Toggle between DEFAULT and ALTFIRE
*/
simulated function AltFireMode()
{
if (!Instigator.IsLocallyControlled())
{
return;
}
// break out of ironsights when starting to block
if (bUsingSights)
{
SetIronSights(false);
}
Super(KFWeapon).StartFire(BLOCK_FIREMODE);
}
/** Called during reload state */
simulated function bool CanOverrideMagReload(byte FireModeNum)
{
if (FireModeNum == BLOCK_FIREMODE)
{
return true;
}
return super.CanOverrideMagReload(FireModeNum);
}
/*********************************************************************************************
* Upgrades
********************************************************************************************/
static simulated function float GetUpgradedBlockDamageMitigation(int UpgradeIndex)
{
return GetUpgradedStatValue(default.BlockDamageMitigation, EWUS_BlockDmgMitigation, UpgradeIndex);
}
static simulated function float GetUpgradedParryDamageMitigation(int UpgradeIndex)
{
return GetUpgradedStatValue(default.ParryDamageMitigationPercent, EWUS_ParryDmgMitigation, UpgradeIndex);
}
simulated function int GetModifiedDamage(byte FireModeNum, optional vector RayDir)
{
if (FireModeNum == BASH_FIREMODE)
{
return GetUpgradedStatValue(InstantHitDamage[FireModeNum], EWUS_Damage2, CurrentWeaponUpgradeIndex);
}
return super.GetModifiedDamage(FireModeNum, RayDir);
}
/** Check AmmoCount and update anim tree nodes if needed */
simulated function UpdateOutOfAmmoEffects(float BlendTime)
{
if ( WorldInfo.NetMode == NM_DedicatedServer )
return;
if( EmptyMagBlendNode != None )
{
// Differentiate Left/Right
if ( bAllowClientAmmoTracking && AmmoCount[0] <= 1 )
{
EmptyMagBlendNode.SetBlendTarget(1, 0);
if ( AmmoCount[0] == 0 )
{
EmptyMagBlendNode = AnimNodeBlendPerBone(SkeletalMeshComponent(Mesh).FindAnimNode('EmptyMagBlend'));
BuildEmptyMagNodeWeightList( EmptyMagBlendNode, BonesToLockOnEmpty_Override );
EmptyMagBlendNode.SetBlendTarget(1,0);
`Log("blending left");
EmptyMagBlendNode_L.SetBlendTarget(1,0);
}
}
}
}
/** Unlocks the bolt bone (Called by animnotify) */
simulated function ANIMNOTIFY_UnLockBolt()
{
super.ANIMNOTIFY_UnLockBolt();
EmptyMagBlendNode_L.SetBlendTarget(0, 0);
EmptyMagBlendNode = AnimNodeBlendPerBone(SkeletalMeshComponent(Mesh).FindAnimNode('EmptyMagBlend'));
BuildEmptyMagNodeWeightList( EmptyMagBlendNode, BonesToLockOnEmpty);
}
defaultproperties
{
// Content
PackageKey="Dual_BladedPistol"
FirstPersonMeshName="WEP_1P_Dual_BladedPistol_MESH.WEP_1stP_DualBladedPistol_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_Dual_BladedPistol_ANIM.Wep_1stP_Dual_BladedPistol_ANIM"
PickupMeshName="WEP_3P_Dual_BladedPistol_MESH.Wep_Dual_BladedPistol_Pickup"
AttachmentArchetypeName="WEP_Dual_BladedPistol_ARCH.Wep_Dual_BladedPistol_3P"
MuzzleFlashTemplateName="WEP_Dual_BladedPistol_ARCH.Wep_Dual_BladedPistol_MuzzleFlash"
Begin Object Name=FirstPersonMesh
AnimTreeTemplate=AnimTree'CHR_1P_Arms_ARCH.WEP_1stP_Dual_Animtree_Master'
End Object
FireOffset=(X=30,Y=7,Z=-5)
LeftFireOffset=(X=30,Y=-7,Z=-5)
// Zooming/Position
IronSightPosition=(X=-3,Y=0,Z=0)
PlayerViewOffset=(X=-15,Y=0,Z=0)
QuickWeaponDownRotation=(Pitch=-8192,Yaw=0,Roll=0)
SingleClass=class'KFWeap_Pistol_Bladed'
// FOV
MeshFOV=96
MeshIronSightFOV=77
PlayerIronSightFOV=77
// Depth of field
DOF_FG_FocalRadius=40
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=12
SpareAmmoCapacity[0]=72 //96
InitialSpareMags[0]=1
AmmoPickupScale[0]=0.5 //1.0
bCanBeReloaded=true
bReloadFromMagazine=true
// Recoil
maxRecoilPitch=330 //400 //250
minRecoilPitch=300 //350 //200
maxRecoilYaw=120 //100
minRecoilYaw=-120 //-100
RecoilRate=0.07
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=900
RecoilMinPitchLimit=65035
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=250
RecoilISMinPitchLimit=65485
// DEFAULT_FIREMODE
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Blade_BladedPistol'
PenetrationPower(DEFAULT_FIREMODE)=3.0
FireInterval(DEFAULT_FIREMODE)=+0.19 //+0.231
InstantHitDamage(DEFAULT_FIREMODE)=115.0
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Slashing_BladedPistol'
Spread(DEFAULT_FIREMODE)=0.005 //0.015
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Sawblade'
// MELEE_BLOCK_FIREMODE
FiringStatesArray(BLOCK_FIREMODE)=MeleeBlocking
WeaponFireTypes(BLOCK_FIREMODE)=EWFT_Custom
FireInterval(BLOCK_FIREMODE)=1.f
AmmoCost(BLOCK_FIREMODE)=0
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_BladedPistol'
InstantHitDamage(BASH_FIREMODE)=75 //26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Handling_DryFire'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_3P', FirstPersonCue=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Fire_1P')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_BladedPistol.Play_WEP_BladedPistol_Handling_DryFire'
// Attachments
bHasIronSights=true
bHasFlashlight=true
AssociatedPerkClasses(0)=class'KFPerk_Gunslinger'
AssociatedPerkClasses(1)=class'KFPerk_Berserker'
// Inventory
InventoryGroup= IG_Primary
InventorySize=6
GroupPriority=45
bCanThrow=true
bDropOnDeath=true
WeaponSelectTexture=Texture2D'WEP_UI_Dual_BladedPistol_TEX.UI_WeaponSelect_Dual_BladedPistol'
bIsBackupWeapon=false
BonesToLockOnEmpty=(RW_FrontPivot)
BonesToLockOnEmpty_L=(LW_FrontPivot)
BonesToLockOnEmpty_Override=(RW_FrontPivot, LW_FrontPivot)
bHasFireLastAnims=true
// default MIC param names
BlockEffectsSocketName=BlockEffect
// Defensive
BlockDamageMitigation=0.60f
ParryDamageMitigationPercent=0.5
ParryStrength=4
BlockHitAnimCooldownTime=0.5f
BlockTypes.Add((DmgType=class'KFDT_Bludgeon'))
BlockTypes.Add((DmgType=class'KFDT_Slashing'))
// Block Sounds
BlockSound=AkEvent'WW_WEP_Bullet_Impacts.Play_Block_MEL_Crovel'
ParrySound=AkEvent'WW_WEP_Bullet_Impacts.Play_Parry_Metal'
BlockParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Block_melee_01'
ParryParticleSystem=ParticleSystem'FX_Impacts_EMIT.FX_Parry_melee_01'
MeleeBlockHitAnims=(Block_Hit_V1, Block_Hit_V2, Block_Hit_V3);
// Upgrades
UpgradeFireModes(BLOCK_FIREMODE) = 0
//Upgrades
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Damage1, Scale=1.15f), (Stat=EWUS_Damage2, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Damage1, Scale=1.3f), (Stat=EWUS_Damage2, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
}

View File

@ -0,0 +1,428 @@
//=============================================================================
// KFWeap_Rifle_ParasiteImplanter
//=============================================================================
// Weapon code for parasite implanter.
//=============================================================================
// Killing Floor 2
// Copyright (C) 2021 Tripwire Interactive LLC
//=============================================================================
class KFWeap_Rifle_ParasiteImplanter extends KFWeap_ScopedBase;
`define PARASITE_MIC_LED_INDEX 0
var float LastFireInterval;
/** How many seed ammo to recharge per second */
var float SeedFullRechargeSeconds;
/** How many ammo to recharge per second. */
var transient float SeedRechargePerSecond;
var transient float SeedIncrement;
var repnotify byte SeedAmmo;
const SecondaryFireAnim = 'Shoot_Secondary';
const SecondaryFireIronAnim = 'Shoot_Secondary_Iron';
/** Material colors applied to different fire modes */
var LinearColor NoAmmoMaterialColor;
var LinearColor AmmoReadyMaterialColor;
/** How much recoil the altfire should do */
var protected const float AltFireRecoilScale;
replication
{
if (bNetDirty && Role == ROLE_Authority)
SeedAmmo;
}
simulated event ReplicatedEvent(name VarName)
{
if (VarName == nameof(SeedAmmo))
{
if (AmmoCount[ALTFIRE_FIREMODE] < AmmoCost[ALTFIRE_FIREMODE] && SeedAmmo >= AmmoCost[ALTFIRE_FIREMODE])
{
UpdateMaterial(true);
}
else if (AmmoCount[ALTFIRE_FIREMODE] >= AmmoCost[ALTFIRE_FIREMODE] && SeedAmmo < AmmoCost[ALTFIRE_FIREMODE])
{
UpdateMaterial(false);
}
AmmoCount[ALTFIRE_FIREMODE] = SeedAmmo;
}
else
{
Super.ReplicatedEvent(VarName);
}
}
/*********************************************************************************************
* @name Trader
*********************************************************************************************/
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
if( default.FiringStatesArray[DEFAULT_FIREMODE] == 'WeaponFiring' || default.FiringStatesArray[DEFAULT_FIREMODE] == 'WeaponBurstFiring' )
{
return FT_Assault;
}
else // if( FiringStatesArray[DEFAULT_FIREMODE] == 'WeaponSingleFiring')
{
return FT_Rifle;
}
}
simulated event PreBeginPlay()
{
super.PreBeginPlay();
StartSeedRecharge();
}
function StartSeedRecharge()
{
// local KFPerk InstigatorPerk;
local float UsedSeedRechargeTime;
// begin ammo recharge on server
if( Role == ROLE_Authority )
{
UsedSeedRechargeTime = SeedFullRechargeSeconds;
SeedRechargePerSecond = MagazineCapacity[ALTFIRE_FIREMODE] / UsedSeedRechargeTime;
SeedIncrement = 0;
}
}
function RechargeSeed(float DeltaTime)
{
if ( Role == ROLE_Authority )
{
SeedIncrement += SeedRechargePerSecond * DeltaTime;
if( SeedIncrement >= 1.0 && AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE] )
{
AmmoCount[ALTFIRE_FIREMODE]++;
SeedIncrement -= 1.0;
SeedAmmo = AmmoCount[ALTFIRE_FIREMODE];
}
}
}
/** Overridden to call StartHealRecharge on server */
function GivenTo( Pawn thisPawn, optional bool bDoNotActivate )
{
super.GivenTo( thisPawn, bDoNotActivate );
if( Role == ROLE_Authority && !thisPawn.IsLocallyControlled() )
{
StartSeedRecharge();
}
}
/*********************************************************************************************
@name Actor
********************************************************************************************* */
simulated event Tick( FLOAT DeltaTime )
{
local bool bWasLowAmmo;
bWasLowAmmo = AmmoCount[ALTFIRE_FIREMODE] < AmmoCost[ALTFIRE_FIREMODE];
if( AmmoCount[ALTFIRE_FIREMODE] < MagazineCapacity[ALTFIRE_FIREMODE] )
{
RechargeSeed(DeltaTime);
}
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if (bWasLowAmmo && AmmoCount[ALTFIRE_FIREMODE] >= AmmoCost[ALTFIRE_FIREMODE])
{
UpdateMaterial(true);
}
}
else
{
if (bWasLowAmmo && AmmoCount[ALTFIRE_FIREMODE] >= AmmoCost[ALTFIRE_FIREMODE])
{
NotifyAltAmmoReady(true);
}
}
Super.Tick(DeltaTime);
}
/*********************************************************************************************
* Trader
********************************************************************************************/
/** Allows weapon to set its own trader stats (can set number of stats, names and values of stats) */
static simulated event SetTraderWeaponStats( out array<STraderItemWeaponStats> WeaponStats )
{
super.SetTraderWeaponStats( WeaponStats );
WeaponStats.Length = WeaponStats.Length + 1;
WeaponStats[WeaponStats.Length-1].StatType = TWS_RechargeTime;
WeaponStats[WeaponStats.Length-1].StatValue = default.SeedFullRechargeSeconds;
}
/** Seeds doesn't count as ammo for purposes of inventory management (e.g. switching) */
simulated function bool HasAnyAmmo()
{
return HasSpareAmmo() || HasAmmo(DEFAULT_FIREMODE);
}
simulated function ConsumeAmmo( byte FireModeNum )
{
local bool bWasHighAmmo;
if( FireModeNum != ALTFIRE_FIREMODE )
{
Super.ConsumeAmmo(FireModeNum);
return;
}
`if(`notdefined(ShippingPC))
if( bInfiniteAmmo )
{
return;
}
`endif
bWasHighAmmo = AmmoCount[ALTFIRE_FIREMODE] >= AmmoCost[ALTFIRE_FIREMODE];
// If AmmoCount is being replicated, don't allow the client to modify it here
if (Role == ROLE_Authority)
{
// Don't consume ammo if magazine size is 0 (infinite ammo with no reload)
if (MagazineCapacity[1] > 0 && AmmoCount[1] > 0)
{
// Reduce ammo amount by heal ammo cost
AmmoCount[1] = Max(AmmoCount[1] - AmmoCost[1], 0);
}
}
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if (bWasHighAmmo && AmmoCount[ALTFIRE_FIREMODE] < AmmoCost[ALTFIRE_FIREMODE])
{
UpdateMaterial(false);
}
}
else if (bWasHighAmmo && AmmoCount[ALTFIRE_FIREMODE] < AmmoCost[ALTFIRE_FIREMODE])
{
NotifyAltAmmoReady(false);
}
}
/** Instead of switch fire mode use as immediate alt fire */
simulated function AltFireMode()
{
if ( !Instigator.IsLocallyControlled() )
{
return;
}
StartFire(ALTFIRE_FIREMODE);
}
simulated function float GetFireInterval(byte FireModeNum)
{
if (FireModeNum == DEFAULT_FIREMODE && AmmoCount[FireModeNum] == 0)
{
return LastFireInterval;
}
return super.GetFireInterval(FireModeNum);
}
simulated function name GetWeaponFireAnim(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE)
{
return bUsingSights ? SecondaryFireIronAnim : SecondaryFireAnim;
}
return super.GetWeaponFireAnim(FireModeNum);
}
simulated function UpdateMaterial(bool HasEnoughAmmo)
{
local LinearColor MatColor;
if (WorldInfo.NetMode != NM_DedicatedServer)
{
MatColor = HasEnoughAmmo ? AmmoReadyMaterialColor : NoAmmoMaterialColor;
if( WeaponMICs.Length >= `PARASITE_MIC_LED_INDEX )
{
WeaponMICs[`PARASITE_MIC_LED_INDEX].SetVectorParameterValue('Vector_GlowColor', MatColor);
}
}
}
/**
Should replicate to 3P to show the alt fire ready
*/
simulated function NotifyAltAmmoReady(bool bActive)
{
local KFPawn KFP;
if (WorldInfo.NetMode != NM_Client)
{
KFP = KFPawn(Instigator);
KFP.OnWeaponSpecialAction(bActive ? 2 : 1);
}
}
simulated function ModifyRecoil( out float CurrentRecoilModifier )
{
if( CurrentFireMode == ALTFIRE_FIREMODE )
{
CurrentRecoilModifier *= AltFireRecoilScale;
}
super.ModifyRecoil( CurrentRecoilModifier );
}
simulated function bool ShouldAutoReload(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE)
return false;
return super.ShouldAutoReload(FireModeNum);
}
defaultproperties
{
SeedFullRechargeSeconds=14 //10
// Inventory / Grouping
InventorySize=7
GroupPriority=100
WeaponSelectTexture=Texture2D'wep_ui_parasiteimplanter_tex.UI_WeaponSelect_ParasiteImplanter'
AssociatedPerkClasses(0)=class'KFPerk_FieldMedic'
AssociatedPerkClasses(1)=class'KFPerk_SharpShooter'
// FOV
MeshFOV=70 //65
MeshIronSightFOV=27 //25 //45
PlayerIronSightFOV=70 //65
// Depth of field
DOF_BlendInSpeed=3.0
DOF_FG_FocalRadius=0 //50
DOF_FG_MaxNearBlurSize=3.5
// Content
PackageKey="ParasiteImplanter"
FirstPersonMeshName="WEP_1P_ParasiteImplanter_MESH.Wep_1stP_ParasiteImplanter_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_ParasiteImplanter_ANIM.Wep_1stP_ParasiteImplanter_Anim"
PickupMeshName="WEP_3P_ParasiteImplanter_MESH.Wep_3rdP_ParasiteImplanter_Pickup"
AttachmentArchetypeName="WEP_ParasiteImplanter_ARCH.Wep_ParasiteImplanter_3P"
MuzzleFlashTemplateName="WEP_ParasiteImplanter_ARCH.Wep_ParasiteImplanter_MuzzleFlash"
// Ammo
MagazineCapacity[0]=6
SpareAmmoCapacity[0]=78
InitialSpareMags[0]=3
bCanBeReloaded=true
bReloadFromMagazine=true
MagazineCapacity[1]=100
SeedAmmo=100
bCanRefillSecondaryAmmo=false
// Zooming/Position
PlayerViewOffset=(X=3.0,Y=8,Z=-1.8)
//IronSightPosition=(X=0,Y=-0.07,Z=1.03)
IronSightPosition=(X=0,Y=-0.115,Z=1.0425)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=575 //700
minRecoilPitch=425 //600
maxRecoilYaw=135
minRecoilYaw=-135
RecoilRate=0.08
RecoilMaxYawLimit=500
RecoilMinYawLimit=65035
RecoilMaxPitchLimit=1250
RecoilMinPitchLimit=64785
RecoilISMaxYawLimit=50
RecoilISMinYawLimit=65485
RecoilISMaxPitchLimit=500
RecoilISMinPitchLimit=65485
RecoilViewRotationScale=0.6
IronSightMeshFOVCompensationScale=1.5
AltFireRecoilScale=0.2f
// Scope Render
// 2D scene capture
Begin Object Name=SceneCapture2DComponent0
//TextureTarget=TextureRenderTarget2D'Wep_Mat_Lib.WEP_ScopeLense_Target'
FieldOfView=12.5 //23.0 // "1.5X" = 35.0(our real world FOV determinant)/1.5
End Object
ScopedSensitivityMod=8.0 //16.0
ScopeLenseMICTemplate=MaterialInstanceConstant'WEP_1P_ParasiteImplanter_MAT.Wep_1stP_Parasite_Lens_MIC'
ScopeMICIndex = 2
// DEFAULT_FIREMODE
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_BulletSingle'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_InstantHit
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Bullet_ParasiteImplanter'
InstantHitDamage(DEFAULT_FIREMODE)=275 //250
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_ParasiteImplanter'
FireInterval(DEFAULT_FIREMODE)=+1.0 //60 RPM
Spread(DEFAULT_FIREMODE)=0.005
PenetrationPower(DEFAULT_FIREMODE)=3
FireOffset=(X=25,Y=3.0,Z=-2.5)
LastFireInterval=0.3
// ALT_FIREMODE
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
FireInterval(ALTFIRE_FIREMODE)=+0.5 //+1.0 //+0.175
InstantHitDamage(ALTFIRE_FIREMODE)=1.0
Spread(ALTFIRE_FIREMODE)=0.005
AmmoCost(ALTFIRE_FIREMODE)=50
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_ParasiteImplanterAlt'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_ParasiteImplanterAlt'
SecondaryAmmoTexture=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_ParasiteImplanter'
InstantHitDamage(BASH_FIREMODE)=26
// Custom animations
FireSightedAnims=(Shoot_Iron)
BonesToLockOnEmpty=(RW_Hammer)
bHasFireLastAnims=true
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_3P_Rifle', FirstPersonCue=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_1P_Rifle')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_Dry_Fire_Rifle'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_3P_Altfire', FirstPersonCue=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_1P_Altfire')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_ParasiteImplanter.Play_WEP_ParasiteImplanter_Dry_Fire_Altfire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
// From original KFWeap_RifleBase base class
AimCorrectionSize=40.f
NoAmmoMaterialColor=(R=0.0f,G=0.0f,B=0.0f)
AmmoReadyMaterialColor=(R=0.08f,G=1.0f,B=0.08f)
NumBloodMapMaterials=2
}