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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -45,6 +45,8 @@ function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
if (class'GameEngine'.Static.IsGameFullyInstalled())
{
//@SABER_EGS IsEosBuild() case added
if( class'WorldInfo'.static.IsConsoleBuild() || class'WorldInfo'.static.IsEosBuild() )
{
@ -60,6 +62,7 @@ function InitializeMenu( KFGFxMoviePlayer_Manager InManager )
}
OnlineSub.AddOnInventoryReadCompleteDelegate(SearchInventoryForNewItem);
}
}
LocalizeText();
//SetPlayerInfo(); //no more name plate

View File

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

View File

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

View File

@ -12,7 +12,7 @@ class KFGFxPostGameContainer_PlayerStats extends KFGFxObject_Container
dependson(EphemeralMatchStats);
var localized string AchievementsString, ZedKillsString, TopWeaponsString;
var localized string TotalDamageDealtString, HeadShotsString, LargeZedKillsString, TotalDoshEarnedString, TotalKillsString, AssistsString, DamageDealtString;
var localized string TotalDamageDealtString, HeadShotsString, LargeZedKillsString, TotalDoshEarnedString, TotalKillsString, AssistsString, DamageDealtString, TotalStompsString;
var localized string KnifeString;
var string PlayerStatsString;
var int ItemCount;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -440,7 +440,7 @@ function AdjustDamage(out int InDamage, out vector Momentum, Controller Instigat
}
}
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<KFDamageType> DamageType, Actor DamageCauser)
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser)
{
if (ShieldHealthPctByte == 0)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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