1
0
This commit is contained in:
GenZmeY 2021-03-02 14:56:51 +03:00
parent 1fd126afa1
commit 28f1e3c001
95 changed files with 3970 additions and 260 deletions

View File

@ -13,7 +13,8 @@ class DamageType extends object
native native
abstract; abstract;
var() bool bArmorStops; // does regular armor provide protection against this damage var() bool bArmorStops; // does regular armor provide protection against this damage (only affects KFPawn_Human)
var float ArmorDamageModifier; // modifier for armor damage (only affects KFPawn_Monster)
var bool bCausedByWorld; //this damage was caused by the world (falling off level, into lava, etc) var bool bCausedByWorld; //this damage was caused by the world (falling off level, into lava, etc)
var bool bExtraMomentumZ; // Add extra Z to momentum on walking pawns to throw them up into the air var bool bExtraMomentumZ; // Add extra Z to momentum on walking pawns to throw them up into the air
@ -54,6 +55,7 @@ static function float VehicleDamageScalingFor(Vehicle V)
defaultproperties defaultproperties
{ {
bArmorStops=true bArmorStops=true
ArmorDamageModifier=1
KDamageImpulse=800 KDamageImpulse=800
VehicleDamageScaling=+1.0 VehicleDamageScaling=+1.0
VehicleMomentumScaling=+1.0 VehicleMomentumScaling=+1.0

View File

@ -2173,6 +2173,22 @@ function Logout( Controller Exiting )
} }
} }
simulated function ExileServerUsingKickBan()
{
local OnlineGameSettings GameSettings;
if (GameInterface != None)
{
GameSettings = GameInterface.GetGameSettings(PlayerReplicationInfoClass.default.SessionName);
}
if (GameSettings != None)
{
GameSettings.bServerExiled = true;
}
}
/** /**
* Removes the player from the named session when they leave * Removes the player from the named session when they leave
* *

View File

@ -115,6 +115,10 @@ var databinding int BotPlayers;
var databinding string SteamServerUID; var databinding string SteamServerUID;
//@SABER_EGS_END //@SABER_EGS_END
//@SABER_BEGIN "Exiling" servers which kicks/bans
var databinding bool bServerExiled;
//@SABER_END
`if (`__TW_ONLINESUBSYSTEM_) `if (`__TW_ONLINESUBSYSTEM_)
//used to keep track of the gfx objects in the serverbrowser's list //used to keep track of the gfx objects in the serverbrowser's list
@ -176,4 +180,7 @@ defaultproperties
//@SABER_EGS_BEGIN Crossplay support //@SABER_EGS_BEGIN Crossplay support
BotPlayers=0 BotPlayers=0
//@SABER_EGS_END //@SABER_EGS_END
//@SABER_BEGIN "Exiling" servers which kicks/bans
bServerExiled=false
//@SABER_END
} }

View File

@ -2301,6 +2301,7 @@ static function DumpGameSettings(const OnlineGameSettings GameSettings)
`Log(" bIsLanMatch: "$GameSettings.bIsLanMatch); `Log(" bIsLanMatch: "$GameSettings.bIsLanMatch);
`Log(" bIsDedicated: "$GameSettings.bIsDedicated); `Log(" bIsDedicated: "$GameSettings.bIsDedicated);
`Log(" bUsesStats: "$GameSettings.bUsesStats); `Log(" bUsesStats: "$GameSettings.bUsesStats);
`Log(" bServerExiled: "$GameSettings.bServerExiled);
`Log(" bUsesArbitration: "$GameSettings.bUsesArbitration); `Log(" bUsesArbitration: "$GameSettings.bUsesArbitration);
`Log(" bAntiCheatProtected: "$GameSettings.bAntiCheatProtected); `Log(" bAntiCheatProtected: "$GameSettings.bAntiCheatProtected);
`Log(" bShouldAdvertise: "$GameSettings.bShouldAdvertise); `Log(" bShouldAdvertise: "$GameSettings.bShouldAdvertise);

View File

@ -2596,10 +2596,17 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
Killer = SetKillInstigator(InstigatedBy, DamageType); Killer = SetKillInstigator(InstigatedBy, DamageType);
TearOffMomentum = momentum; TearOffMomentum = momentum;
Died(Killer, damageType, HitLocation); 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 else
{ {
HandleMomentum( momentum, HitLocation, DamageType, HitInfo ); 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); NotifyTakeHit(InstigatedBy, HitLocation, ActualDamage, DamageType, Momentum, DamageCauser);
if (DrivenVehicle != None) if (DrivenVehicle != None)
{ {
@ -2619,6 +2626,8 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
`endif `endif
} }
function HandleAfflictionsOnHit(Controller DamageInstigator, vector HitDir, class<DamageType> DamageType, Actor DamageCauser);
/* /*
* Queries the PRI and returns our current team index. * Queries the PRI and returns our current team index.
*/ */

View File

@ -9,6 +9,8 @@
class KFAfflictionManager extends Object within KFPawn class KFAfflictionManager extends Object within KFPawn
native(Pawn); native(Pawn);
const STUN_GUARANTEED_POWER = 10000.f;
/** Abstracted body parts that can be associated with multiple zones */ /** Abstracted body parts that can be associated with multiple zones */
enum EHitZoneBodyPart enum EHitZoneBodyPart
{ {
@ -246,11 +248,12 @@ protected function ProcessSpecialMoveAfflictions(KFPerk InstigatorPerk, vector H
StumblePower *= StumbleModifier; StumblePower *= StumbleModifier;
StunPower *= StunModifier; StunPower *= StunModifier;
// [FFERRANDO @ SABER3D] INCAP MASTER NOW MODIFIES THE STUN POWER BY SETTING IT TO THE GIVEN VALUE // [RMORENO @ SABER3D] //Overriding stun power with a High number so we can assure the stun independently of weapon, Zed resistances, body part hit. This does NOT ignores other factors like cooldowns.
if (InstigatorPerk != None && InstigatorPerk.GetIncapMasterActive()) if (InstigatorPerk != None && InstigatorPerk.IsStunGuaranteed( DamageType, HitZoneIdx ))
{ {
StunPower += InstigatorPerk.GetStunPowerModifier( DamageType, HitZoneIdx ); StunPower = STUN_GUARANTEED_POWER;
} }
// increment affliction power // increment affliction power
if (KnockdownPower > 0 && CanDoSpecialmove(SM_Knockdown)) if (KnockdownPower > 0 && CanDoSpecialmove(SM_Knockdown))
{ {

View File

@ -310,7 +310,7 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
{ {
local int AttachmentIdx, CosmeticMeshIdx; local int AttachmentIdx, CosmeticMeshIdx;
local bool bMaskHeadMesh; local bool bMaskHeadMesh;
local int NumberOfCosmetics, NumberOfCosmeticsPostRemoval; //local int NumberOfCosmetics, NumberOfCosmeticsPostRemoval;
super.SetCharacterMeshFromArch( KFP, KFPRI ); super.SetCharacterMeshFromArch( KFP, KFPRI );
@ -356,7 +356,7 @@ simulated function SetCharacterMeshFromArch( KFPawn KFP, optional KFPlayerReplic
CosmeticMeshIdx = KFPRI.RepCustomizationInfo.AttachmentMeshIndices[AttachmentIdx]; CosmeticMeshIdx = KFPRI.RepCustomizationInfo.AttachmentMeshIndices[AttachmentIdx];
if ( CosmeticMeshIdx != `CLEARED_ATTACHMENT_INDEX && CosmeticMeshIdx != INDEX_NONE) if ( CosmeticMeshIdx != `CLEARED_ATTACHMENT_INDEX && CosmeticMeshIdx != INDEX_NONE)
{ {
NumberOfCosmetics++; //NumberOfCosmetics++;
bMaskHeadMesh = bMaskHeadMesh || CosmeticVariants[CosmeticMeshIdx].bMaskHeadMesh; bMaskHeadMesh = bMaskHeadMesh || CosmeticVariants[CosmeticMeshIdx].bMaskHeadMesh;
// Attach all saved attachments to the character // Attach all saved attachments to the character
@ -878,7 +878,7 @@ private function SetAttachmentMeshAndSkin(
* Removes any attachments that exist in the same socket or have overriding cases * Removes any attachments that exist in the same socket or have overriding cases
* Network: Local Player * Network: Local Player
*/ */
function array<int> DetachConflictingAttachments(int NewAttachmentMeshIndex, KFPawn KFP, optional KFPlayerReplicationInfo KFPRI, optional out array<int> out_RemovedAttachments ) function DetachConflictingAttachments(int NewAttachmentMeshIndex, KFPawn KFP, optional KFPlayerReplicationInfo KFPRI, optional out array<int> out_RemovedAttachments )
{ {
local name NewAttachmentSocketName; local name NewAttachmentSocketName;
local int i, CurrentAttachmentIdx; local int i, CurrentAttachmentIdx;

View File

@ -929,6 +929,15 @@ simulated exec function Vampire()
GiveWeapon( "KFGameContent.KFWeap_HRG_Vampire" ); GiveWeapon( "KFGameContent.KFWeap_HRG_Vampire" );
} }
/**
* Give the player the HRG SonicGun
*/
simulated exec function SonicGun()
{
GiveWeapon( "KFGameContent.KFWeap_HRG_SonicGun" );
}
/** /**
* Give the player all pistol weapons * Give the player all pistol weapons
*/ */
@ -1177,6 +1186,7 @@ exec function Surv()
GiveWeapon( "KFGameContent.KFWeap_HRG_EMP_ArcGenerator" ); GiveWeapon( "KFGameContent.KFWeap_HRG_EMP_ArcGenerator" );
GiveWeapon( "KFGameContent.KFWeap_Ice_FreezeThrower" ); GiveWeapon( "KFGameContent.KFWeap_Ice_FreezeThrower" );
GiveWeapon( "KFGameContent.KFWeap_AssaultRifle_LazerCutter" ); GiveWeapon( "KFGameContent.KFWeap_AssaultRifle_LazerCutter" );
GiveWeapon( "KFGameContent.KFWeap_HRG_SonicGun" );
} }
/** /**

View File

@ -0,0 +1,27 @@
class KFGFxSpecialEventObjectivesContainer_Spring2021 extends KFGFxSpecialEventObjectivesContainer;
function Initialize(KFGFxObject_Menu NewParentMenu)
{
super.Initialize(NewParentMenu);
}
DefaultProperties
{
ObjectiveIconURLs[0] = "Spring2021_UI.UI_Objectives_Spring2021_Cyber_Threat" // Kill 15 Bosses on any map or mode
ObjectiveIconURLs[1] = "Spring2021_UI.UI_Objectives_Spring2021_Weekly_Hack" // Complete the Weekly on Dystopia 2029
ObjectiveIconURLs[2] = "Spring2021_UI.UI_Objectives_Spring2021_AI_Out_of_Control" // Kill 100 E.D.A.R.s on Dystopia 2029
ObjectiveIconURLs[3] = "Spring2021_UI.UI_Objectives_Spring2021_Not_a_Simulation" // Complete a wave without taking any damage 10 times on Dystopia 2029
ObjectiveIconURLs[4] = "Spring2021_UI.UI_Objectives_Spring2021_Zed_World" // Complete wave 15 on Endless Hard or higher difficulty on Dystopia 2029
//defaults
AllCompleteRewardIconURL="CHR_CosmeticSet_Spring_01_Item_TEX.cyborg_companionbackpack.cyborgcompanionbackpack_precious"
ChanceDropIconURLs[0]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket"
ChanceDropIconURLs[1]="CHR_CosmeticSet14_Item_TEX.Tickets.CyberPunk_ticket_golden"
IconURL="Spring2021_UI.KF2_Spring_DystopianDevastation_SmallLogo"
UsesProgressList[0] = true
UsesProgressList[1] = false
UsesProgressList[2] = true
UsesProgressList[3] = true
UsesProgressList[4] = false
}

View File

@ -12,6 +12,7 @@ class KFGFxHUD_PlayerStatus extends GFxObject;
/** Cached KFPlayerController */ /** Cached KFPlayerController */
var KFPlayerController MyPC; var KFPlayerController MyPC;
var KFGameReplicationinfo KFGRI;
var KFPawn_Human MyHumanPawn; var KFPawn_Human MyHumanPawn;
var KFInventoryManager MyInventoryManager; var KFInventoryManager MyInventoryManager;
// Player's perk type as of the last tick. // Player's perk type as of the last tick.
@ -46,6 +47,7 @@ function TickHud(float DeltaTime)
UpdateHealth(); UpdateHealth();
UpdateArmor(); UpdateArmor();
UpdateHealer(); UpdateHealer();
UpdateGlobalDamage();
} }
function ShowActiveIndicators( array<string> IconPathStrings ) function ShowActiveIndicators( array<string> IconPathStrings )
@ -213,6 +215,18 @@ function ShowXPBark( int DeltaXP, string iconPath, bool bIsCurrentPerk )
ActionScriptVoid("showXPBark"); ActionScriptVoid("showXPBark");
} }
function UpdateGlobalDamage()
{
if(KFGRI == none)
{
KFGRI = KFGameReplicationInfo(GetPC().WorldInfo.GRI);
}
else
{
SetBool("waveApplyingDamage", KFGRI.IsGlobalDamage());
}
}
DefaultProperties DefaultProperties
{ {

View File

@ -12,6 +12,7 @@ class KFGFxHUD_WaveInfo extends GFxObject;
/** Cached KFPlayerController */ /** Cached KFPlayerController */
var KFGameReplicationinfo KFGRI; var KFGameReplicationinfo KFGRI;
// //
var int LastWaveMax; var int LastWaveMax;
// //
@ -50,10 +51,10 @@ function TickHud(float DeltaTime)
{ {
if (KFGRI.bWaveIsActive && !KFGRI.bWaveStarted) if (KFGRI.bWaveIsActive && !KFGRI.bWaveStarted)
{ {
SetString("waitingForWaveStart", "-----"); SetString("waitingForWaveStart", "-----");
} }
else if (!KFGRI.bWaveIsActive) else if (!KFGRI.bWaveIsActive)
{ {
UpdateTraderTimeRemaining(); UpdateTraderTimeRemaining();
} }
else else
@ -82,7 +83,6 @@ function UpdateWaveCount()
return; return;
} }
// Max # of waves. // Max # of waves.
CurrentWaveMax = KFGRI.GetFinalWaveNum(); CurrentWaveMax = KFGRI.GetFinalWaveNum();
if(LastWaveMax != CurrentWaveMax) if(LastWaveMax != CurrentWaveMax)
@ -156,7 +156,6 @@ function UpdateTraderTimeRemaining()
} }
} }
DefaultProperties DefaultProperties
{ {
LastTraderTimeRemaining=0 LastTraderTimeRemaining=0

View File

@ -697,7 +697,6 @@ private function Callback_AttachmentNumbered(int MeshIndex, int SkinIndex, int S
{ {
local Pawn P; local Pawn P;
local KFPawn KFP; local KFPawn KFP;
local int i;
local array<int> RemovedAttachments; local array<int> RemovedAttachments;
P = GetPC().Pawn; P = GetPC().Pawn;
if( P != none ) if( P != none )

View File

@ -224,8 +224,18 @@ function bool IsMatchStarted()
function PerkChanged( byte NewPerkIndex, bool bClickedIndex) function PerkChanged( byte NewPerkIndex, bool bClickedIndex)
{ {
local KFGameReplicationInfo KFGRI;
if( KFPC != none ) if( KFPC != none )
{ {
KFGRI = KFGameReplicationInfo( KFPC.WorldInfo.GRI );
// If the perk is not allowed stop the change process
if( KFGRI != none && !KFGRI.IsPerkAllowed(KFPC.PerkList[NewPerkIndex].PerkClass) )
{
return;
}
// We aren't actually changing our selected perk so don't save stuff. // We aren't actually changing our selected perk so don't save stuff.
UpdateSkillsHolder( KFPC.PerkList[NewPerkIndex].PerkClass ); UpdateSkillsHolder( KFPC.PerkList[NewPerkIndex].PerkClass );

View File

@ -86,7 +86,7 @@ function UpdatePerkSelection(byte SelectedPerkIndex)
TempObj.SetString( "Title", PerkClass.default.PerkName ); TempObj.SetString( "Title", PerkClass.default.PerkName );
TempObj.SetString( "iconSource", "img://"$PerkClass.static.GetPerkIconPath() ); TempObj.SetString( "iconSource", "img://"$PerkClass.static.GetPerkIconPath() );
TempObj.SetBool("bTierUnlocked", bool(bTierUnlocked) && KFPC.PerkList[i].PerkLevel >= UnlockedPerkLevel); TempObj.SetBool("bTierUnlocked", bool(bTierUnlocked) && KFPC.PerkList[i].PerkLevel >= UnlockedPerkLevel);
TempObj.SetBool("bPerkAllowed", true);
DataProvider.SetElementObject( i, TempObj ); DataProvider.SetElementObject( i, TempObj );
} }
SetObject( "perkData", DataProvider ); SetObject( "perkData", DataProvider );
@ -111,7 +111,7 @@ function UpdatePendingPerkInfo(byte SelectedPerkIndex)
local KFPlayerController KFPC; local KFPlayerController KFPC;
KFPC = KFPlayerController( GetPC() ); KFPC = KFPlayerController( GetPC() );
if( KFPC != none && KFGRI != none ) if( KFPC != none && KFGRI != none )
{ {
if(!class'WorldInfo'.static.IsMenuLevel()) if(!class'WorldInfo'.static.IsMenuLevel())

View File

@ -13,13 +13,13 @@ class KFGFxServerBrowser_Filters extends KFGFxObject_Container
config(UI); config(UI);
var KFGFxMenu_ServerBrowser ServerMenu; var KFGFxMenu_ServerBrowser ServerMenu;
var localized string NoPasswordString, NoMutatorsString, NotFullString, NotEmptyString, NoRankedStandardString, NoRankedCustomString, NoUnrankedString, DedicatedString, VACSecureString, InLobbyString, InProgressString, OnlyStockMapsString, OnlyCustomMapsString, LimitServerResultsString; var localized string NoPasswordString, NoMutatorsString, NotFullString, NotEmptyString, NoRankedStandardString, NoRankedCustomString, NoUnrankedString, DedicatedString, VACSecureString, InLobbyString, InProgressString, OnlyStockMapsString, OnlyCustomMapsString, LimitServerResultsString, NotServerExiledString;
var array<string> FilterStrings; var array<string> FilterStrings;
var config Bool bNoPassword, bNoMutators, bNotFull, bNotEmpty, bUsesStats, bCustom, bDedicated, bVAC_Secure, bInLobby, bInProgress, bOnlyStockMaps, bOnlyCustomMaps, bLimitServerResults; var config Bool bNoPassword, bNoMutators, bNotFull, bNotEmpty, bUsesStats, bCustom, bDedicated, bVAC_Secure, bInLobby, bInProgress, bOnlyStockMaps, bOnlyCustomMaps, bLimitServerResults, bNoLocalAdmin;
var config byte SavedGameModeIndex, SavedMapIndex, SavedDifficultyIndex, SavedLengthIndex, SavedPingIndex; var config byte SavedGameModeIndex, SavedMapIndex, SavedDifficultyIndex, SavedLengthIndex, SavedPingIndex;
var Bool bNoPasswordPending, bNoMutatorsPending, bNotFullPending, bNotEmptyPending, bUsesStatsPending, bCustomPending, bDedicatedPending, bVAC_SecurePending, bInLobbyPending, bInProgressPending, bOnlyStockMapsPending, bOnlyCustomMapsPending, bLimitServerResultsPending; var Bool bNoPasswordPending, bNoMutatorsPending, bNotFullPending, bNotEmptyPending, bUsesStatsPending, bCustomPending, bDedicatedPending, bVAC_SecurePending, bInLobbyPending, bInProgressPending, bOnlyStockMapsPending, bOnlyCustomMapsPending, bLimitServerResultsPending, bNoLocalAdminPending;
var byte SavedGameModeIndexPending, SavedMapIndexPending, SavedDifficultyIndexPending, SavedLengthIndexPending, SavedPingIndexPending; var byte SavedGameModeIndexPending, SavedMapIndexPending, SavedDifficultyIndexPending, SavedLengthIndexPending, SavedPingIndexPending;
var transient string CachedMapName, CachedModeName; var transient string CachedMapName, CachedModeName;
@ -45,6 +45,7 @@ enum EFilter_Key
LIMIT_SERVER_RESULTS, LIMIT_SERVER_RESULTS,
/*ONLY_STOCK_MAPS, //Not using for EA /*ONLY_STOCK_MAPS, //Not using for EA
ONLY_CUSTOM_MAPS,*/ //Not using for EA ONLY_CUSTOM_MAPS,*/ //Not using for EA
NO_LOCAL_ADMIN,
FILTERS_MAX, FILTERS_MAX,
}; };
@ -115,6 +116,7 @@ function InitFiltersArray()
FilterStrings[IN_LOBBY] = InLobbyString; FilterStrings[IN_LOBBY] = InLobbyString;
FilterStrings[IN_PROGRESS] = InProgressString; FilterStrings[IN_PROGRESS] = InProgressString;
FilterStrings[LIMIT_SERVER_RESULTS] = LimitServerResultsString @class'KFGFxServerBrowser_ServerList'.default.MaxSearchResults; FilterStrings[LIMIT_SERVER_RESULTS] = LimitServerResultsString @class'KFGFxServerBrowser_ServerList'.default.MaxSearchResults;
FilterStrings[NO_LOCAL_ADMIN] = NotServerExiledString;
/*FilterStrings[ONLY_STOCK_MAPS] = OnlyStockMapsString; /*FilterStrings[ONLY_STOCK_MAPS] = OnlyStockMapsString;
FilterStrings[ONLY_CUSTOM_MAPS] = OnlyCustomMapsString;*/ FilterStrings[ONLY_CUSTOM_MAPS] = OnlyCustomMapsString;*/
} }
@ -316,6 +318,7 @@ function ApplyFilters()
bOnlyStockMaps = bOnlyStockMapsPending; bOnlyStockMaps = bOnlyStockMapsPending;
bOnlyCustomMaps = bOnlyCustomMapsPending; bOnlyCustomMaps = bOnlyCustomMapsPending;
bLimitServerResults = bLimitServerResultsPending; bLimitServerResults = bLimitServerResultsPending;
bNoLocalAdmin = bNoLocalAdminPending;
SavedGameModeIndex = SavedGameModeIndexPending; SavedGameModeIndex = SavedGameModeIndexPending;
SavedMapIndex = SavedMapIndexPending; SavedMapIndex = SavedMapIndexPending;
@ -340,7 +343,8 @@ function ClearPendingValues()
bInProgressPending = bInProgress; bInProgressPending = bInProgress;
bOnlyStockMapsPending = bOnlyStockMaps; bOnlyStockMapsPending = bOnlyStockMaps;
bOnlyCustomMapsPending = bOnlyCustomMaps; bOnlyCustomMapsPending = bOnlyCustomMaps;
bLimitServerResultsPending = bLimitServerResults; bLimitServerResultsPending = bLimitServerResults;
bNoLocalAdminPending = bNoLocalAdmin;
SavedGameModeIndexPending = SavedGameModeIndex; SavedGameModeIndexPending = SavedGameModeIndex;
SavedMapIndexPending = SavedMapIndex; SavedMapIndexPending = SavedMapIndex;
SavedDifficultyIndexPending = SavedDifficultyIndex; SavedDifficultyIndexPending = SavedDifficultyIndex;
@ -364,6 +368,7 @@ function ResetFilters()
bOnlyStockMaps = false; bOnlyStockMaps = false;
bOnlyCustomMaps = false; bOnlyCustomMaps = false;
bLimitServerResults = true; bLimitServerResults = true;
bNoLocalAdmin = true;
SavedGameModeIndex = 255; SavedGameModeIndex = 255;
SavedMapIndex = 255; SavedMapIndex = 255;
@ -420,6 +425,9 @@ function SetBoolByEFilter_Key(EFilter_Key Filter, bool FilterValue)
case LIMIT_SERVER_RESULTS: case LIMIT_SERVER_RESULTS:
bLimitServerResultsPending = FilterValue; bLimitServerResultsPending = FilterValue;
break; break;
case NO_LOCAL_ADMIN:
bNoLocalAdminPending = FilterValue;
break;
/*case ONLY_STOCK_MAPS: /*case ONLY_STOCK_MAPS:
bOnlyStockMapsPending = FilterValue; bOnlyStockMapsPending = FilterValue;
break; break;
@ -467,6 +475,9 @@ function bool GetBoolByEFilter_Key(EFilter_Key Filter)
case LIMIT_SERVER_RESULTS: case LIMIT_SERVER_RESULTS:
return bLimitServerResults; return bLimitServerResults;
case NO_LOCAL_ADMIN:
return bNoLocalAdmin;
/*case ONLY_STOCK_MAPS: /*case ONLY_STOCK_MAPS:
return bOnlyStockMaps; return bOnlyStockMaps;

View File

@ -278,6 +278,7 @@ function BuildServerFilters(KFGFxServerBrowser_Filters Filters, OnlineGameSearch
Search.AddServerFilter("version_match", string(class'KFGameEngine'.static.GetKFGameVersion())); Search.AddServerFilter("version_match", string(class'KFGameEngine'.static.GetKFGameVersion()));
Search.TestAddServerFilter( Filters.bNotFull, "notfull"); Search.TestAddServerFilter( Filters.bNotFull, "notfull");
Search.TestAddServerFilter( Filters.bNotEmpty, "hasplayers"); Search.TestAddServerFilter( Filters.bNotEmpty, "hasplayers");
Search.TestAddBoolGametagFilter(GametagSearch, Filters.bNoLocalAdmin, 'bServerExiled', 0);
if( !class'WorldInfo'.static.IsConsoleBuild() ) if( !class'WorldInfo'.static.IsConsoleBuild() )
{ {
@ -972,6 +973,7 @@ function UpdateListDataProvider()
TempObj.SetString("mode", class'KFCommon_LocalizedStrings'.static.GetGameModeString(TempOnlineGamesSettings.Mode) ); TempObj.SetString("mode", class'KFCommon_LocalizedStrings'.static.GetGameModeString(TempOnlineGamesSettings.Mode) );
TempObj.SetString("map", TempOnlineGamesSettings.MapName); TempObj.SetString("map", TempOnlineGamesSettings.MapName);
TempObj.SetBool("locked", TempOnlineGamesSettings.bRequiresPassword); TempObj.SetBool("locked", TempOnlineGamesSettings.bRequiresPassword);
TempObj.SetBool("serverExiled", TempOnlineGamesSettings.bServerExiled);
//Get Game State from var const databinding EOnlineGameState GameState; //Get Game State from var const databinding EOnlineGameState GameState;
TempObj.SetString("gameStatus", String(TempOnlineGamesSettings.GameState)); TempObj.SetString("gameStatus", String(TempOnlineGamesSettings.GameState));

View File

@ -175,22 +175,28 @@ function FillWhatsNew()
local SWhatsNew item; local SWhatsNew item;
WhatsNewItems.Remove(0, WhatsNewItems.Length); WhatsNewItems.Remove(0, WhatsNewItems.Length);
// Latest Update // Latest Update
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_ChristmasBreakdown_Event", "LatestUpdate", "http://www.tripwireinteractive.com/redirect/KF2LatestUpdate/"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_DystopianDevastation_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); WhatsNewItems.AddItem(item);
// Featured Time Limited Item // Featured Time Limited Item
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5588"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_PremiumTicket", "FeaturedEventItem", "https://store.steampowered.com/buyitem/232090/5803");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle // Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Xmas_IceBreaker", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8616"); item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_Neon_MKVII", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8774");
WhatsNewItems.AddItem(item);
// Featured Weapon Skin Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_Spectre", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8618");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Cosmetic Bundle // Featured Cosmetic Bundle
item = SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Winter","FeaturedItemBundle","https://store.steampowered.com/buyitem/232090/8617"); 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");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Featured Weapon Bundle // Featured Weapon Bundle
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Christmas_FrostGun", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8619"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Spring_GravityImploder", "FeaturedItemBundle", "https://store.steampowered.com/buyitem/232090/8777");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
// Misc Community Links // Misc Community Links
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityHub", "Jaegorhorn", "https://steamcommunity.com/app/232090");
@ -199,7 +205,7 @@ function FillWhatsNew()
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Survey", "Survey", "http://www.tripwireinteractive.com/redirect/KF2Survey/"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Survey", "Survey", "http://www.tripwireinteractive.com/redirect/KF2Survey/");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityIssue", "CommunityTracker", "https://trello.com/b/ZOwMRlcW/killing-floor-2-community-issue-roadmap"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_CommunityIssue", "CommunityTracker", "http://www.killingfloor2.com/roadmap");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);
item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Merch", "Merch", "http://www.tripwireinteractive.com/redirect/shop/"); item=SetWhatsNewItem("img://UI_WhatsNew.UI_WhatsNew_Merch", "Merch", "http://www.tripwireinteractive.com/redirect/shop/");
WhatsNewItems.AddItem(item); WhatsNewItems.AddItem(item);

View File

@ -446,19 +446,19 @@ DefaultProperties
XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle XboxFilterExceptions[0]="Wasteland Bundle" // Wasteland Outfit Bundle
FeaturedItemIDs[0]=7944 FeaturedItemIDs[0]=8115
FeaturedItemIDs[1]=8615 FeaturedItemIDs[1]=8773
FeaturedItemIDs[2]=8616 FeaturedItemIDs[2]=8774
FeaturedItemIDs[3]=8617 FeaturedItemIDs[3]=8775
FeaturedItemIDs[4]=8618 FeaturedItemIDs[4]=8776
FeaturedItemIDs[5]=8619 FeaturedItemIDs[5]=8777
ConsoleFeaturedItemIDs[0]=7947 ConsoleFeaturedItemIDs[0]=8116
ConsoleFeaturedItemIDs[1]=8615 ConsoleFeaturedItemIDs[1]=8773
ConsoleFeaturedItemIDs[2]=8616 ConsoleFeaturedItemIDs[2]=8774
ConsoleFeaturedItemIDs[3]=8617 ConsoleFeaturedItemIDs[3]=8775
ConsoleFeaturedItemIDs[4]=8618 ConsoleFeaturedItemIDs[4]=8776
ConsoleFeaturedItemIDs[5]=8619 ConsoleFeaturedItemIDs[5]=8777
MaxFeaturedItems=5 MaxFeaturedItems=5
} }

View File

@ -1165,8 +1165,14 @@ function ResetAllPickups()
AllPickupFactories.AddItem( AmmoPickups[i] ); AllPickupFactories.AddItem( AmmoPickups[i] );
} }
ResetPickups( ItemPickups, NumWeaponPickups ); if(NumWeaponPickups > 0 )
ResetPickups( AmmoPickups, NumAmmoPickups ); {
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 */
@ -1632,12 +1638,24 @@ function bool AllowPrimaryWeapon(string ClassPath)
return true; return true;
} }
/** Whether or not a specific secondary weapon is allowed. Called at player spawn time while setting inventory. */
function bool AllowSecondaryWeapon(string ClassPath)
{
return true;
}
/** Allows gametype to adjust starting grenade count. Called at player spawn time from GiveInitialGrenadeCount in the inventory. */ /** Allows gametype to adjust starting grenade count. Called at player spawn time from GiveInitialGrenadeCount in the inventory. */
function int AdjustStartingGrenadeCount(int CurrentCount) function int AdjustStartingGrenadeCount(int CurrentCount)
{ {
return CurrentCount; return CurrentCount;
} }
/** Allows gametype to validate a perk for the current match */
function bool IsPerkAllowed(class<KFPerk> PerkClass)
{
return true;
}
/************************************************************************************ /************************************************************************************
* @name Difficulty Scaling * @name Difficulty Scaling
***********************************************************************************/ ***********************************************************************************/
@ -2719,7 +2737,14 @@ function CheckZedTimeOnKill(Controller Killer, Controller KilledPlayer, Pawn Kil
// Handle monster/zed kills - increased probability if closer to the player // Handle monster/zed kills - increased probability if closer to the player
if( Killer != none && Killer.Pawn != none && VSizeSq(Killer.Pawn.Location - KilledPawn.Location) < 90000 ) // 3 meters if( Killer != none && Killer.Pawn != none && VSizeSq(Killer.Pawn.Location - KilledPawn.Location) < 90000 ) // 3 meters
{ {
DramaticEvent(0.05); if(OutbreakEvent != none && Role == ROLE_Authority && OutbreakEvent.ActiveEvent.bModifyZedTimeOnANearZedKill)
{
DramaticEvent(OutbreakEvent.ActiveEvent.ZedTimeOnANearZedKill);
}
else
{
DramaticEvent(0.05);
}
} }
else else
{ {

View File

@ -77,6 +77,25 @@ var bool bMatchVictory;
//Whether or not traders are enabled //Whether or not traders are enabled
var bool bTradersEnabled; var bool bTradersEnabled;
struct native PerkAvailableData
{
var bool bPerksAvailableLimited;
var bool bBerserkerAvailable;
var bool bCommandoAvailable;
var bool bSupportAvailable;
var bool bFieldMedicAvailable;
var bool bDemolitionistAvailable;
var bool bFirebugAvailable;
var bool bGunslingerAvailable;
var bool bSharpshooterAvailable;
var bool bSwatAvailable;
var bool bSurvivalistAvailable;
};
//Wheter or not some perks are not allowed
var repnotify PerkAvailableData PerksAvailableData;
/************************************ /************************************
* Spawning * Spawning
************************************/ ************************************/
@ -275,6 +294,10 @@ var float VersusZedDamageMod;
/** The current game is a versus game */ /** The current game is a versus game */
var bool bVersusGame; var bool bVersusGame;
/** The current game has global damage*/
var bool bGlobalDamage;
/************************************ /************************************
* Team Management * Team Management
************************************/ ************************************/
@ -350,11 +373,13 @@ cpptext
replication replication
{ {
if ( bNetDirty ) if ( bNetDirty )
TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, TraderVolume, TraderVolumeCheckType, bTraderIsOpen, NextTrader, WaveNum, bWaveIsEndless, AIRemaining, WaveTotalAICount, bWaveIsActive, MaxHumanCount, bGlobalDamage,
CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount, CurrentObjective, PreviousObjective, PreviousObjectiveResult, PreviousObjectiveXPResult, PreviousObjectiveVoshResult, MusicIntensity, ReplicatedMusicTrackInfo, MusicTrackRepCount,
bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective; //@HSL - JRO - 3/21/2016 - PS4 Sessions bIsUnrankedGame, GameSharedUnlocks, bHidePawnIcons, ConsoleGameSessionGuid, GameDifficulty, GameDifficultyModifier, BossIndex, bWaveStarted, NextObjective; //@HSL - JRO - 3/21/2016 - PS4 Sessions
if ( bNetInitial ) if ( bNetInitial )
GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled; GameLength, WaveMax, bCustom, bVersusGame, TraderItems, GameAmmoCostScale, bAllowGrenadePurchase, MaxPerkLevel, bTradersEnabled;
if ( bNetInitial || bNetDirty )
PerksAvailableData;
if ( bNetInitial && Role == ROLE_Authority ) if ( bNetInitial && Role == ROLE_Authority )
ServerAdInfo; ServerAdInfo;
@ -492,6 +517,10 @@ simulated event ReplicatedEvent(name VarName)
{ {
ReceivedGameLength(); ReceivedGameLength();
} }
else if(VarName == nameof(PerksAvailableData))
{
UpdatePerksAvailable();
}
else else
{ {
super.ReplicatedEvent(VarName); super.ReplicatedEvent(VarName);
@ -2108,6 +2137,39 @@ simulated function bool IsObjectiveMode()
return false; return false;
} }
function SetGlobalDamage(bool bEnable)
{
bGlobalDamage = bEnable;
}
simulated function bool IsGlobalDamage()
{
return bGlobalDamage;
}
simulated function bool IsPerkAllowed(class<KFPerk> PerkClass)
{
if(PerksAvailableData.bPerksAvailableLimited)
{
if(PerkClass == class'KFPerk_Berserker') return PerksAvailableData.bBerserkerAvailable;
else if(PerkClass == class'KFPerk_Commando') return PerksAvailableData.bCommandoAvailable;
else if(PerkClass == class'KFPerk_Support') return PerksAvailableData.bSupportAvailable;
else if(PerkClass == class'KFPerk_FieldMedic') return PerksAvailableData.bFieldMedicAvailable;
else if(PerkClass == class'KFPerk_Demolitionist') return PerksAvailableData.bDemolitionistAvailable;
else if(PerkClass == class'KFPerk_Firebug') return PerksAvailableData.bFirebugAvailable;
else if(PerkClass == class'KFPerk_Gunslinger') return PerksAvailableData.bGunslingerAvailable;
else if(PerkClass == class'KFPerk_Sharpshooter') return PerksAvailableData.bSharpshooterAvailable;
else if(PerkClass == class'KFPerk_Swat') return PerksAvailableData.bSwatAvailable;
else if(PerkClass == class'KFPerk_Survivalist') return PerksAvailableData.bSurvivalistAvailable;
}
return true;
}
simulated function UpdatePerksAvailable()
{
KFPlayerController(GetALocalPlayerController()).UpdatePerkOnInit();
}
defaultproperties defaultproperties
{ {
TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems" TraderItemsPath="GP_Trader_ARCH.DefaultTraderItems"

View File

@ -202,7 +202,7 @@ static function class<KFGFxSpecialeventObjectivesContainer> GetSpecialEventClass
switch (SpecialEventID) switch (SpecialEventID)
{ {
case SEI_Spring: case SEI_Spring:
return class'KFGFxSpecialEventObjectivesContainer_Spring2020'; return class'KFGFxSpecialEventObjectivesContainer_Spring2021';
case SEI_Summer: case SEI_Summer:
return class'KFGFxSpecialEventObjectivesContainer_Summer2020'; return class'KFGFxSpecialEventObjectivesContainer_Summer2020';
case SEI_Fall: case SEI_Fall:
@ -1480,6 +1480,8 @@ function BuildServerFilters(OnlineGameInterface GameInterfaceSteam, KFGFxStartGa
else else
{ {
Search.AddServerFilter("version_match", string(class'KFGameEngine'.static.GetKFGameVersion())); Search.AddServerFilter("version_match", string(class'KFGameEngine'.static.GetKFGameVersion()));
Search.TestAddBoolGametagFilter(GameTagFilters, true, 'bServerExiled', 0);//Consoles does NOT have this property, so only in PC matchmaking search variables has to be added
//TestAddBoolGametagFilter Explanation: if set to true the second param, it will add the property to the search filters. But this property may interest us to search it as "false" or "true" so that is the purpose of the fourth param.
} }
if (OptionsComponent.GetMakeNewServer() || bAttemptingServerCreate ) if (OptionsComponent.GetMakeNewServer() || bAttemptingServerCreate )

View File

@ -1121,7 +1121,6 @@ simulated function AttemptQuickHeal()
{ {
local KFWeap_HealerBase W; local KFWeap_HealerBase W;
local KFPlayerController KFPC; local KFPlayerController KFPC;
local class<KFPowerUp> KFPowerUpClass;
// Do not heal if we have full health // Do not heal if we have full health
if ( Instigator.Health >= Instigator.HealthMax ) if ( Instigator.Health >= Instigator.HealthMax )
@ -1138,8 +1137,7 @@ simulated function AttemptQuickHeal()
KFPC = KFPlayerController(Instigator.Owner); KFPC = KFPlayerController(Instigator.Owner);
if( KFPC != none ) if( KFPC != none )
{ {
KFPowerUpClass = KFPC.GetPowerUpClass(); if(!KFPC.CanUseHealObject())
if( KFPowerUpClass != none && !KFPowerUpClass.default.CanBeHealedWhilePowerUpIsActive )
{ {
return; return;
} }

View File

@ -116,6 +116,8 @@ var() EBossAIType SurvivalBossOverride<EditCondition=bOverrideSurvivalBoss>;
var() SeasonalEventIndex ZedSeasonalThemeId; var() SeasonalEventIndex ZedSeasonalThemeId;
// Mutator code class that can override various map settings // Mutator code class that can override various map settings
var() class<KFMapMutator> MapMutatorClass; var() class<KFMapMutator> MapMutatorClass;
// Whether to allow shotgun jumps
var() bool bAllowShootgunJump;
// Objectives to use in Objective Mode // Objectives to use in Objective Mode
var(ObjectiveMode) array<WaveObjectivePair> ObjectiveModeObjectives; var(ObjectiveMode) array<WaveObjectivePair> ObjectiveModeObjectives;
@ -451,4 +453,6 @@ DefaultProperties
AmbientMusicTracks.Add(KFMusicTrackInfo'WW_MAMB_Default.TI_SJ_Menace') AmbientMusicTracks.Add(KFMusicTrackInfo'WW_MAMB_Default.TI_SJ_Menace')
TraderVoiceGroupClassPath="KFGameContent.KFTraderVoiceGroup_Default" TraderVoiceGroupClassPath="KFGameContent.KFTraderVoiceGroup_Default"
bAllowShootgunJump=true
} }

View File

@ -66,6 +66,7 @@ defaultproperties
ColumnIds.Add(STATID_ACHIEVE_DesolationCollectibles) ColumnIds.Add(STATID_ACHIEVE_DesolationCollectibles)
ColumnIds.Add(STATID_ACHIEVE_HellmarkStationCollectibles) ColumnIds.Add(STATID_ACHIEVE_HellmarkStationCollectibles)
ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen) ColumnIds.Add(STATID_ACHIEVE_ElysiumEndlessWaveFifteen)
ColumnIds.Add(STATID_ACHIEVE_Dystopia2029Collectibles)
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky5, Name="AchievementMrPerky5"))
ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10")) ColumnMappings.Add((Id=STATID_ACHIEVE_MrPerky10, Name = "AchievementMrPerky10"))
@ -120,4 +121,5 @@ defaultproperties
ColumnMappings.Add((Id=STATID_ACHIEVE_DesolationCollectibles,Name="AchievementCollectDesolation")) ColumnMappings.Add((Id=STATID_ACHIEVE_DesolationCollectibles,Name="AchievementCollectDesolation"))
ColumnMappings.Add((Id=STATID_ACHIEVE_HellmarkStationCollectibles,Name="AchievementCollectHellmarkStation")) ColumnMappings.Add((Id=STATID_ACHIEVE_HellmarkStationCollectibles,Name="AchievementCollectHellmarkStation"))
ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium")) ColumnMappings.Add((Id=STATID_ACHIEVE_ElysiumEndlessWaveFifteen,Name="AchievementEndlessElysium"))
ColumnMappings.Add((Id=STATID_ACHIEVE_Dystopia2029Collectibles,NAme="AchievementCollectDystopia2029"))
} }

View File

@ -425,6 +425,10 @@ const KFACHID_ElysiumHard = 277;
const KFACHID_ElysiumHellOnEarth = 278; const KFACHID_ElysiumHellOnEarth = 278;
const KFACHID_ElysiumEndlessWaveFifteen = 279; const KFACHID_ElysiumEndlessWaveFifteen = 279;
const KFACHID_Dystopia2029Hard = 280;
const KFACHID_Dystopia2029HellOnEarth = 281;
const KFACHID_Dystopia2029Collectibles = 282;
/* __TW_ANALYTICS_ */ /* __TW_ANALYTICS_ */
var int PerRoundWeldXP; var int PerRoundWeldXP;
var int PerRoundHealXP; var int PerRoundHealXP;
@ -1073,6 +1077,12 @@ function SavePersonalBest( EPersonalBests PersonalBestID, int Value )
/********************************************************************************************* /*********************************************************************************************
* @name Gameplay * @name Gameplay
********************************************************************************************* */ ********************************************************************************************* */
private event AddToHitsTaken()
{
SeasonalEventStats_OnHitTaken();
}
/** /**
* @brief Add a kill and give some EXP tp the player * @brief Add a kill and give some EXP tp the player
* @param MonsterClass The killed monster's class * @param MonsterClass The killed monster's class
@ -1792,6 +1802,14 @@ final native simulated event SeasonalEventStats_OnGameWon(class<GameInfo> GameCl
final native simulated event SeasonalEventStats_OnGameEnd(class<GameInfo> GameClass); final native simulated event SeasonalEventStats_OnGameEnd(class<GameInfo> GameClass);
final simulated function SeasonalEventStats_OnHitTaken()
{
if (SeasonalEventIsValid())
{
SeasonalEvent.OnHitTaken();
}
}
final simulated function SeasonalEventStats_OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT) final simulated function SeasonalEventStats_OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{ {
if (SeasonalEventIsValid()) if (SeasonalEventIsValid())
@ -2062,6 +2080,7 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Winchester1894, KFDT_Bludgeon_Winchester,KFDT_Ballistic_Winchester),CompletionAmount=5000)) //2000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_Winchester1894, KFDT_Bludgeon_Winchester,KFDT_Ballistic_Winchester),CompletionAmount=5000)) //2000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Bow_Crossbow, KFDT_Bludgeon_Crossbow,KFDT_Piercing_Crossbow),CompletionAmount=7000)) //5000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Bow_Crossbow, KFDT_Bludgeon_Crossbow,KFDT_Piercing_Crossbow),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M14EBR, KFDT_Bludgeon_M14EBR,KFDT_Ballistic_M14EBR),CompletionAmount=9000)) //7000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M14EBR, KFDT_Bludgeon_M14EBR,KFDT_Ballistic_M14EBR),CompletionAmount=9000)) //7000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_HRG_SonicGun, KFDT_Bludgeon_HRG_SonicGun, KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged, KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged, KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged),CompletionAmount=7000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_RailGun, KFDT_Bludgeon_RailGun,KFDT_Ballistic_RailGun),CompletionAmount=5000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_RailGun, KFDT_Bludgeon_RailGun,KFDT_Ballistic_RailGun),CompletionAmount=5000))
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_CenterfireMB464, KFDT_Bludgeon_CenterfireMB464,KFDT_Ballistic_CenterfireMB464),CompletionAmount=7000)) //5000 DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_CenterfireMB464, KFDT_Bludgeon_CenterfireMB464,KFDT_Ballistic_CenterfireMB464),CompletionAmount=7000)) //5000
DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M99, KFDT_Bludgeon_M99,KFDT_Ballistic_M99),CompletionAmount=5000)) DailyEvents.Add((ObjectiveType=DOT_WeaponDamage,ObjectiveClasses=(KFWeap_Rifle_M99, KFDT_Bludgeon_M99,KFDT_Ballistic_M99),CompletionAmount=5000))
@ -2203,6 +2222,9 @@ defaultproperties
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=1)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=1))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=2)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=2))
DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=3)) DailyEvents.Add((ObjectiveType=DOT_Maps,SecondaryType=DOST_MapCompletion,ObjectiveClasses=(KF-ELYSIUM),CompletionAmount=3))
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))
//Versus Damage //Versus Damage
// Per design doc that I have right now, these are x class damage y players, not damage y amount // Per design doc that I have right now, these are x class damage y players, not damage y amount

View File

@ -68,4 +68,5 @@ defaultproperties
Properties.Add((PropertyId = STATID_ACHIEVE_DesolationCollectibles,Data = (Type = SDT_Int32,Value1 = 0))) Properties.Add((PropertyId = STATID_ACHIEVE_DesolationCollectibles,Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_HellmarkStationCollectibles,Data = (Type = SDT_Int32,Value1 = 0))) 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_ElysiumEndlessWaveFifteen,Data = (Type = SDT_Int32,Value1 = 0)))
Properties.Add((PropertyId = STATID_ACHIEVE_Dystopia2029Collectibles, Data = (Type = SDT_Int32,Value1 = 0)))
} }

View File

@ -81,9 +81,19 @@ struct StatAdjustments
/** 1 to max player count range of how many AI should spawn during the sub wave */ /** 1 to max player count range of how many AI should spawn during the sub wave */
var() Vector2D AdditionalSubSpawnCount; var() Vector2D AdditionalSubSpawnCount;
/** Ammount of health recovered to the player on kill */
var() int HealByKill;
/** Ammount of health recovered to the player on kill assistance */
var() int HealByAssistance;
/** Killing the zed should give a different dosh amount than the standard. */ /** Killing the zed should give a different dosh amount than the standard. */
var() int DoshGiven; var() int DoshGiven;
/** Speed modifier */
var() float InitialGroundSpeedModifierScale;
structdefaultproperties structdefaultproperties
{ {
HealthScale = 1.f; HealthScale = 1.f;
@ -101,6 +111,8 @@ struct StatAdjustments
AdditionalSubSpawnCount = (X = 1,Y = 1) AdditionalSubSpawnCount = (X = 1,Y = 1)
DoshGiven=INDEX_NONE DoshGiven=INDEX_NONE
InitialGroundSpeedModifierScale = 1.0
} }
}; };
@ -135,12 +147,23 @@ struct WeeklyOverrides
*/ */
var() KFGFxObject_TraderItems SpawnWeaponList; var() KFGFxObject_TraderItems SpawnWeaponList;
/** If this flag is set to true, the secondary weapon will be checked for availability in the current game mode */
var() bool bSpawnWeaponListAffectsSecondaryWeapons;
/** If this array is not empty, modifies the trader's list of available weapons */ /** If this array is not empty, modifies the trader's list of available weapons */
var() KFGFxObject_TraderItems TraderWeaponList; var() KFGFxObject_TraderItems TraderWeaponList;
/** Whether or not grenades are disabled at spawn and for purchase */ /** Whether or not grenades are disabled at spawn and for purchase */
var() bool bDisableGrenades; var() bool bDisableGrenades;
/** If this array is not empty, modifies the list of perks available for this weekly mode */
var() const array<class<KFPerk> > PerksAvailableList;
/** Activates the special conditions for the Colliseum Weekly Mode
* 1) Disables Berserker lvl25 skills 2) Enables lvl25 battery ram skill of the swat
*/
var() bool bColliseumSkillConditionsActive;
/** If this array is not empty, replaces AIClassList entries with a new spawn class */ /** If this array is not empty, replaces AIClassList entries with a new spawn class */
var() array<SpawnReplacement> SpawnReplacementList; var() array<SpawnReplacement> SpawnReplacementList;
@ -202,6 +225,12 @@ struct WeeklyOverrides
/** Height to use for kicking players out of partial zed time */ /** Height to use for kicking players out of partial zed time */
var() float ZedTimeHeight; var() float ZedTimeHeight;
/** Use a new probability of getting a drama event when a Zed is killed on a 3m radius of the player */
var() bool bModifyZedTimeOnANearZedKill;
/** Percentage value (0...1) for the probability of getting a drama event when a Zed is killed on a 3m radius of the player */
var() float ZedTimeOnANearZedKill;
/** Whether or not to use size scale on damage */ /** Whether or not to use size scale on damage */
var() bool bScaleOnHealth; var() bool bScaleOnHealth;
@ -289,6 +318,27 @@ struct WeeklyOverrides
/** Boom performance optimization - Max booms in one frame (avoids big Demo spikes) */ /** Boom performance optimization - Max booms in one frame (avoids big Demo spikes) */
var() int MaxBoomsPerFrame; var() int MaxBoomsPerFrame;
/** Heal after kill */
var() bool bHealAfterKill;
/** Cannot be Healed*/
var() bool bCannotBeHealed;
/** Global Damage affects shield or ignores it */
var() bool bGlobalDamageAffectsShield;
/** Global Damage Should be applied during a boss wave*/
var() bool bApplyGlobalDamageBossWave;
/** Replenish player's health once a wave ends. */
var() bool bHealPlayerAfterWave;
/** 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 another outbreak mode shares the same events, this will link the two to quicker UI lookup */ /** If another outbreak mode shares the same events, this will link the two to quicker UI lookup */
var() int WeeklyOutbreakId; var() int WeeklyOutbreakId;
@ -323,7 +373,18 @@ struct WeeklyOverrides
InflationDeathGravity = -0.1 InflationDeathGravity = -0.1
MaxPerkLevel = 4 MaxPerkLevel = 4
bAllowSpawnReplacementDuringBossWave = true bAllowSpawnReplacementDuringBossWave = true
bHealAfterKill = false
bCannotBeHealed = false
bGlobalDamageAffectsShield = true
bApplyGlobalDamageBossWave = true
bHealPlayerAfterWave = false
DamageDelayAfterWaveStarted = 10.0f
WeeklyOutbreakId=INDEX_NONE WeeklyOutbreakId=INDEX_NONE
bSpawnWeaponListAffectsSecondaryWeapons = false
bColliseumSkillConditionsActive = false
bModifyZedTimeOnANearZedKill = false
ZedTimeOnANearZedKill = 0.05
DoshOnKillGlobalModifier = 1.0f
} }
}; };
@ -336,6 +397,7 @@ struct CachedOutbreakInfo
var byte MaxPerkLevel; var byte MaxPerkLevel;
var float CachedWorldGravityZ; var float CachedWorldGravityZ;
var float CachedGlobalGravityZ; var float CachedGlobalGravityZ;
var PerkAvailableData PerksAvailableData;
structdefaultproperties structdefaultproperties
{ {
@ -404,6 +466,11 @@ function ClearActiveEvent()
KFGameReplicationInfo(GameReplicationInfo).TraderItems = CachedItems.TraderItems; KFGameReplicationInfo(GameReplicationInfo).TraderItems = CachedItems.TraderItems;
} }
if(ActiveEvent.PerksAvailableList.length > 0)
{
KFGameReplicationInfo(GameReplicationInfo).PerksAvailableData = CachedItems.PerksAvailableData;
}
KFGameReplicationInfo(GameReplicationInfo).GameAmmoCostScale = CachedItems.GameAmmoCostScale; KFGameReplicationInfo(GameReplicationInfo).GameAmmoCostScale = CachedItems.GameAmmoCostScale;
KFGameReplicationInfo(GameReplicationInfo).bAllowGrenadePurchase = CachedItems.bAllowGrenadePurchase; KFGameReplicationInfo(GameReplicationInfo).bAllowGrenadePurchase = CachedItems.bAllowGrenadePurchase;
KFGameReplicationInfo(GameReplicationInfo).bTradersEnabled = CachedItems.bTradersEnabled; KFGameReplicationInfo(GameReplicationInfo).bTradersEnabled = CachedItems.bTradersEnabled;
@ -425,6 +492,11 @@ function CacheGRI()
CachedItems.TraderItems = KFGameReplicationInfo(GameReplicationInfo).TraderItems; CachedItems.TraderItems = KFGameReplicationInfo(GameReplicationInfo).TraderItems;
} }
if(ActiveEvent.PerksAvailableList.length > 0)
{
CachedItems.PerksAvailableData = KFGameReplicationInfo(GameReplicationInfo).PerksAvailableData;
}
CachedItems.GameAmmoCostScale = KFGameReplicationInfo(GameReplicationInfo).GameAmmoCostScale; CachedItems.GameAmmoCostScale = KFGameReplicationInfo(GameReplicationInfo).GameAmmoCostScale;
CachedItems.bAllowGrenadePurchase = KFGameReplicationInfo(GameReplicationInfo).bAllowGrenadePurchase; CachedItems.bAllowGrenadePurchase = KFGameReplicationInfo(GameReplicationInfo).bAllowGrenadePurchase;
CachedItems.bTradersEnabled = KFGameReplicationInfo(GameReplicationInfo).bTradersEnabled; CachedItems.bTradersEnabled = KFGameReplicationInfo(GameReplicationInfo).bTradersEnabled;
@ -434,20 +506,54 @@ function CacheGRI()
function UpdateGRI() function UpdateGRI()
{ {
local int i;
local KFGameReplicationInfo KFGRI;
CacheGRI(); CacheGRI();
//This should have just been spawned in the super //This should have just been spawned in the super
if (GameReplicationInfo != none && KFGameReplicationInfo(GameReplicationInfo) != none) if (GameReplicationInfo != none && KFGameReplicationInfo(GameReplicationInfo) != none)
{ {
KFGRI = KFGameReplicationInfo(GameReplicationInfo);
if (ActiveEvent.TraderWeaponList != none) if (ActiveEvent.TraderWeaponList != none)
{ {
KFGameReplicationInfo(GameReplicationInfo).TraderItems = ActiveEvent.TraderWeaponList; KFGRI.TraderItems = ActiveEvent.TraderWeaponList;
} }
KFGameReplicationInfo(GameReplicationInfo).GameAmmoCostScale = ActiveEvent.GlobalAmmoCostScale; if(ActiveEvent.PerksAvailableList.length > 0)
KFGameReplicationInfo(GameReplicationInfo).bAllowGrenadePurchase = !ActiveEvent.bDisableGrenades; {
KFGameReplicationInfo(GameReplicationInfo).bTradersEnabled = !ActiveEvent.bDisableTraders; KFGRI.PerksAvailableData.bPerksAvailableLimited = true;
KFGameReplicationInfo(GameReplicationInfo).MaxPerkLevel = ActiveEvent.MaxPerkLevel; KFGRI.PerksAvailableData.bBerserkerAvailable = false;
KFGRI.PerksAvailableData.bCommandoAvailable = false;
KFGRI.PerksAvailableData.bSupportAvailable = false;
KFGRI.PerksAvailableData.bFieldMedicAvailable = false;
KFGRI.PerksAvailableData.bDemolitionistAvailable = false;
KFGRI.PerksAvailableData.bFirebugAvailable = false;
KFGRI.PerksAvailableData.bGunslingerAvailable = false;
KFGRI.PerksAvailableData.bSharpshooterAvailable = false;
KFGRI.PerksAvailableData.bSwatAvailable = false;
KFGRI.PerksAvailableData.bSurvivalistAvailable = false;
for(i=0 ; i<ActiveEvent.PerksAvailableList.length ; i++)
{
if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Berserker') KFGRI.PerksAvailableData.bBerserkerAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Commando') KFGRI.PerksAvailableData.bCommandoAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Support') KFGRI.PerksAvailableData.bSupportAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_FieldMedic') KFGRI.PerksAvailableData.bFieldMedicAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Demolitionist') KFGRI.PerksAvailableData.bDemolitionistAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Firebug') KFGRI.PerksAvailableData.bFirebugAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Gunslinger') KFGRI.PerksAvailableData.bGunslingerAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Sharpshooter') KFGRI.PerksAvailableData.bSharpshooterAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Swat') KFGRI.PerksAvailableData.bSwatAvailable = true;
else if(ActiveEvent.PerksAvailableList[i] == class'KFPerk_Survivalist') KFGRI.PerksAvailableData.bSurvivalistAvailable = true;
}
}
KFGRI.GameAmmoCostScale = ActiveEvent.GlobalAmmoCostScale;
KFGRI.bAllowGrenadePurchase = !ActiveEvent.bDisableGrenades;
KFGRI.bTradersEnabled = !ActiveEvent.bDisableTraders;
KFGRI.MaxPerkLevel = ActiveEvent.MaxPerkLevel;
} }
} }
@ -648,6 +754,11 @@ function AdjustMonsterDefaults(out KFPawn_Monster P)
P.HitZones[HZI_HEAD].MaxGoreHealth = P.HitZones[HZI_HEAD].GoreHealth; P.HitZones[HZI_HEAD].MaxGoreHealth = P.HitZones[HZI_HEAD].GoreHealth;
P.SetShieldScale(ToAdjust.ShieldScale); P.SetShieldScale(ToAdjust.ShieldScale);
P.HealByKill = ToAdjust.HealByKill;
P.HealByAssistance = ToAdjust.HealByAssistance;
P.InitialGroundSpeedModifier *= ToAdjust.InitialGroundSpeedModifierScale;
if (ToAdjust.bStartEnraged) if (ToAdjust.bStartEnraged)
{ {
//If we aren't using the AI controller's spawn enrage, go into the pawn //If we aren't using the AI controller's spawn enrage, go into the pawn
@ -703,9 +814,12 @@ function OnScoreKill(Pawn KilledPawn)
function ApplyGlobalDamage() function ApplyGlobalDamage()
{ {
local KFPawn_Human Pawn; local KFPawn_Human Pawn;
local class<DamageType> DamageType;
DamageType = ActiveEvent.bGlobalDamageAffectsShield ? class'DmgType_Crushed' : class'KFDT_Falling';
foreach WorldInfo.AllPawns(class'KFPawn_Human', Pawn) foreach WorldInfo.AllPawns(class'KFPawn_Human', Pawn)
{ {
Pawn.TakeDamage(OutbreakEvent.ActiveEvent.GlobalDamageTickAmount, none, Pawn.Location, vect(0, 0, 0), class'DmgType_Crushed'); Pawn.TakeDamage(OutbreakEvent.ActiveEvent.GlobalDamageTickAmount, none, Pawn.Location, vect(0, 0, 0), DamageType);
} }
} }

View File

@ -2672,9 +2672,6 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
OldHealth = Health; OldHealth = Health;
Super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser); 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);
ActualDamage = OldHealth - Health; ActualDamage = OldHealth - Health;
if( ActualDamage > 0 ) if( ActualDamage > 0 )
{ {
@ -3999,12 +3996,12 @@ simulated function KFSkinTypeEffects GetHitZoneSkinTypeEffects( int HitZoneIdx )
*/ */
simulated function AdjustAffliction(out float AfflictionPower); 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 //Handle afflictions
if (AfflictionHandler != None) if (AfflictionHandler != None)
{ {
AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, DamageType, DamageCauser); AfflictionHandler.NotifyTakeHit(DamageInstigator, HitDir, class<KFDamageType>(DamageType), DamageCauser);
} }
} }

View File

@ -159,9 +159,9 @@ var float MinHealthPctToTriggerSurrounded;
********************************************************************************************* */ ********************************************************************************************* */
var array<string> ActiveSkillIconPaths; var array<string> ActiveSkillIconPaths;
var private byte HealingSpeedBoost; var repnotify private byte HealingSpeedBoost;
var private byte HealingDamageBoost; var repnotify private byte HealingDamageBoost;
var private byte HealingShield; var repnotify private byte HealingShield;
var transient KFExplosion_AirborneAgent AAExplosionActor; var transient KFExplosion_AirborneAgent AAExplosionActor;
@ -359,9 +359,17 @@ simulated event ReplicatedEvent(name VarName)
case nameof(PowerUpFxStopInfo): case nameof(PowerUpFxStopInfo):
StopPowerUpEffect(PowerUpFxStopInfo); StopPowerUpEffect(PowerUpFxStopInfo);
break; break;
case nameof(HealingSpeedBoost):
NotifyHealingSpeedBoostBuff(HealingSpeedBoost);
break;
case nameof(HealingDamageBoost):
NotifyHealingDamageBoostBuff(HealingDamageBoost);
break;
case nameof(HealingShield):
NotifyHealingShieldBoostBuff(HealingShield);
break;
} }
Super.ReplicatedEvent(VarName); Super.ReplicatedEvent(VarName);
} }
@ -436,6 +444,7 @@ simulated function OnCharacterMeshChanged()
function AddDefaultInventory() function AddDefaultInventory()
{ {
local KFPerk MyPerk; local KFPerk MyPerk;
local KFGameInfo GameInfo;
MyPerk = GetPerk(); MyPerk = GetPerk();
@ -447,7 +456,12 @@ function AddDefaultInventory()
/** DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Pistol_9mm", class'Class'))); /** DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Pistol_9mm", class'Class')));
Loading the secondary weapon in the perk again */ Loading the secondary weapon in the perk again */
DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Healer_Syringe", class'Class'))); GameInfo = KFGameInfo(WorldInfo.Game);
if(GameInfo.OutbreakEvent == none || !GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed)
{
DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Healer_Syringe", class'Class')));
}
DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Welder", class'Class'))); DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject("KFGameContent.KFWeap_Welder", class'Class')));
DefaultInventory.AddItem(class<Inventory>(DynamicLoadObject("KFGameContent.KFInventory_Money", class'Class'))); DefaultInventory.AddItem(class<Inventory>(DynamicLoadObject("KFGameContent.KFInventory_Money", class'Class')));
@ -675,18 +689,9 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageType) event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageType)
`endif `endif
{ {
local int DoshEarned; local KFPlayerController KFPC;
local float UsedHealAmount;
local KFPlayerReplicationInfo InstigatorPRI;
local KFPlayerController InstigatorPC, KFPC;
local KFPerk InstigatorPerk;
local KFPowerUp KFPowerUp; local KFPowerUp KFPowerUp;
local class<KFDamageType> KFDT; local KFGameInfo GameInfo;
local int i;
local bool bRepairedArmor;
local int OldHealth;
OldHealth = Health;
KFPC = KFPlayerController(Controller); KFPC = KFPlayerController(Controller);
if ( KFPC != none ) if ( KFPC != none )
@ -698,6 +703,30 @@ event bool HealDamage(int Amount, Controller Healer, class<DamageType> DamageTyp
} }
} }
GameInfo = KFGameInfo(WorldInfo.Game);
if (GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed)
{
return false;
}
return HealDamageForce(Amount, Healer, DamageType, bCanRepairArmor, bMessageHealer);
}
event bool HealDamageForce(int Amount, Controller Healer, class<DamageType> DamageType, optional bool bCanRepairArmor=true, optional bool bMessageHealer=true)
{
local int DoshEarned;
local float UsedHealAmount;
local KFPlayerReplicationInfo InstigatorPRI;
local KFPlayerController InstigatorPC, KFPC;
local KFPerk InstigatorPerk;
local class<KFDamageType> KFDT;
local int i;
local bool bRepairedArmor;
local int OldHealth;
OldHealth = Health;
InstigatorPC = KFPlayerController(Healer); InstigatorPC = KFPlayerController(Healer);
InstigatorPerk = InstigatorPC != None ? InstigatorPC.GetPerk() : None; InstigatorPerk = InstigatorPC != None ? InstigatorPC.GetPerk() : None;
if( InstigatorPerk != None ) if( InstigatorPerk != None )
@ -1260,6 +1289,7 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
{ {
local int ActualDamageTaken, OldHealth; local int ActualDamageTaken, OldHealth;
//local KFGameInfo KFGI; //local KFGameInfo KFGI;
local KFGameReplicationInfo KFGRI;
local KFPlayerReplicationInfo KFPRI; local KFPlayerReplicationInfo KFPRI;
local KFAIController_ZedBoss InstigatedByBoss; local KFAIController_ZedBoss InstigatedByBoss;
@ -1272,6 +1302,12 @@ event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector
`log(GetFuncName()@"Damage AFTER ="$ActualDamageTaken$" DamageType: "$DamageType$" DamageCauser: "$DamageCauser, bLogTakeDamage); `log(GetFuncName()@"Damage AFTER ="$ActualDamageTaken$" DamageType: "$DamageType$" DamageCauser: "$DamageCauser, bLogTakeDamage);
KFGRI = KFGameReplicationInfo(KFGameInfo(WorldInfo.Game).GameReplicationInfo);
if( Damage > 0 && IsAliveAndWell() && !KFGRI.bTraderIsOpen )
{
KFPlayerController(Controller).NotifyHitTaken();
}
if( ActualDamageTaken > 0 && IsAliveAndWell() ) if( ActualDamageTaken > 0 && IsAliveAndWell() )
{ {
CheckAndEndActiveEMoteSpecialMove(); CheckAndEndActiveEMoteSpecialMove();
@ -1396,6 +1432,11 @@ simulated function UpdateHealingSpeedBoost()
{ {
HealingSpeedBoost = Min( HealingSpeedBoost + class'KFPerk_FieldMedic'.static.GetHealingSpeedBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost() ); HealingSpeedBoost = Min( HealingSpeedBoost + class'KFPerk_FieldMedic'.static.GetHealingSpeedBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingSpeedBoost() );
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingSpeedBoostDuration(),, nameOf(ResetHealingSpeedBoost) ); SetTimer( class'KFPerk_FieldMedic'.static.GetHealingSpeedBoostDuration(),, nameOf(ResetHealingSpeedBoost) );
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingSpeedBoostBuff(HealingSpeedBoost);
}
} }
simulated function ResetHealingSpeedBoost() simulated function ResetHealingSpeedBoost()
@ -1406,6 +1447,11 @@ simulated function ResetHealingSpeedBoost()
{ {
ClearTimer( nameOf( ResetHealingSpeedBoost ) ); ClearTimer( nameOf( ResetHealingSpeedBoost ) );
} }
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingSpeedBoostBuff(HealingSpeedBoost);
}
} }
simulated function float GetHealingDamageBoostModifier() simulated function float GetHealingDamageBoostModifier()
@ -1417,6 +1463,11 @@ simulated function UpdateHealingDamageBoost()
{ {
HealingDamageBoost = Min( HealingDamageBoost + class'KFPerk_FieldMedic'.static.GetHealingDamageBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost() ); HealingDamageBoost = Min( HealingDamageBoost + class'KFPerk_FieldMedic'.static.GetHealingDamageBoost(), class'KFPerk_FieldMedic'.static.GetMaxHealingDamageBoost() );
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingDamageBoostDuration(),, nameOf(ResetHealingDamageBoost) ); SetTimer( class'KFPerk_FieldMedic'.static.GetHealingDamageBoostDuration(),, nameOf(ResetHealingDamageBoost) );
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingDamageBoostBuff(HealingDamageBoost);
}
} }
simulated function ResetHealingDamageBoost() simulated function ResetHealingDamageBoost()
@ -1427,6 +1478,11 @@ simulated function ResetHealingDamageBoost()
{ {
ClearTimer( nameOf( ResetHealingDamageBoost ) ); ClearTimer( nameOf( ResetHealingDamageBoost ) );
} }
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingDamageBoostBuff(HealingDamageBoost);
}
} }
simulated function float GetHealingShieldModifier() simulated function float GetHealingShieldModifier()
@ -1438,6 +1494,11 @@ simulated function UpdateHealingShield()
{ {
HealingShield = Min( HealingShield + class'KFPerk_FieldMedic'.static.GetHealingShield(), class'KFPerk_FieldMedic'.static.GetMaxHealingShield() ); HealingShield = Min( HealingShield + class'KFPerk_FieldMedic'.static.GetHealingShield(), class'KFPerk_FieldMedic'.static.GetMaxHealingShield() );
SetTimer( class'KFPerk_FieldMedic'.static.GetHealingShieldDuration(),, nameOf(ResetHealingShield) ); SetTimer( class'KFPerk_FieldMedic'.static.GetHealingShieldDuration(),, nameOf(ResetHealingShield) );
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingShieldBoostBuff(HealingShield);
}
} }
simulated function ResetHealingShield() simulated function ResetHealingShield()
@ -1448,6 +1509,11 @@ simulated function ResetHealingShield()
{ {
ClearTimer( nameOf( ResetHealingShield ) ); ClearTimer( nameOf( ResetHealingShield ) );
} }
if ( WorldInfo.NetMode == NM_STANDALONE)
{
NotifyHealingShieldBoostBuff(HealingShield);
}
} }
/** /**
@ -1964,6 +2030,68 @@ simulated function DisplayDebug(HUD HUD, out float out_YL, out float out_YPos)
} }
} }
simulated function NotifyHealingSpeedBoostBuff(byte Speed)
{
if( Role == ROLE_Authority )
{
HealingSpeedBoost = Speed;
bForceNetUpdate = true;
}
if( IsLocallyControlled() )
{
UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingSpeedBoost].IconPath, Speed > 0.0f);
}
}
simulated function NotifyHealingDamageBoostBuff(byte Damage)
{
if( Role == ROLE_Authority )
{
HealingSpeedBoost = Damage;
bForceNetUpdate = true;
}
if( IsLocallyControlled() )
{
UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingDamageBoost].IconPath, Damage > 0.0f);
}
}
simulated function NotifyHealingShieldBoostBuff(byte Shield)
{
if( Role == ROLE_Authority )
{
HealingSpeedBoost = Shield;
bForceNetUpdate = true;
}
if( IsLocallyControlled() )
{
UpdateActiveSkillsPath(class'KFPerk_FieldMedic'.default.PerkSkills[EMedicHealingShield].IconPath, Shield > 0.0f);
}
}
function UpdateActiveSkillsPath(string IconPath, bool Active)
{
local KFPlayerController KFPC;
if(Active)
{
if (ActiveSkillIconPaths.Find(IconPath) == INDEX_NONE)
{
ActiveSkillIconPaths.AddItem(IconPath);
}
}
else
{
ActiveSkillIconPaths.RemoveItem(IconPath);
}
KFPC = KFPlayerController(Controller);
KFPC.MyGFxHUD.PlayerStatusContainer.ShowActiveIndicators(ActiveSkillIconPaths);
}
defaultproperties defaultproperties
{ {
Begin Object Class=KFFlashlightAttachment name=Flashlight_0 Begin Object Class=KFFlashlightAttachment name=Flashlight_0

View File

@ -88,6 +88,10 @@ var private const float XPValues[4];
/** List of sockets representing weakpoint zone locations */ /** List of sockets representing weakpoint zone locations */
var() array<name> WeakSpotSocketNames; var() array<name> WeakSpotSocketNames;
/** Heal after die */
var int HealByKill;
var int HealByAssistance;
/** /**
* Information on resistant or vulnerable damage types * Information on resistant or vulnerable damage types
* @todo: This is all static data so we should consider moving to the archetype * @todo: This is all static data so we should consider moving to the archetype
@ -318,8 +322,11 @@ var protected const float BlockSprintSpeedModifier;
/** The last time a successful block ended */ /** The last time a successful block ended */
var transient float LastBlockTime; var transient float LastBlockTime;
/** Multiplier applied to the vortex attraction force */
var protected float VortexAttracionModifier;
var float KnockedDownBySonicWaveOdds; var float KnockedDownBySonicWaveOdds;
var bool bCloakOnMeleeEnd; var bool bCloakOnMeleeEnd;
var bool bIsCloakingSpottedByLP; var bool bIsCloakingSpottedByLP;
var repnotify bool bIsCloakingSpottedByTeam; var repnotify bool bIsCloakingSpottedByTeam;
var float LastSpottedStatusUpdate; var float LastSpottedStatusUpdate;
@ -2368,6 +2375,11 @@ function BleedOutTimer()
} }
} }
function float GetVortexAttractionModifier ()
{
return VortexAttracionModifier;
}
/** Applies the rally buff and spawns a rally effect */ /** Applies the rally buff and spawns a rally effect */
simulated function bool Rally( simulated function bool Rally(
KFPawn RallyInstigator, KFPawn RallyInstigator,
@ -4852,4 +4864,6 @@ DefaultProperties
Components.Add(HeadshotAkComponent0) Components.Add(HeadshotAkComponent0)
bSprintOverride=false bSprintOverride=false
VortexAttracionModifier=1.0f
} }

View File

@ -443,4 +443,6 @@ defaultproperties
SpeedLimitScalar=1.30 SpeedLimitScalar=1.30
bCanBePinned=false bCanBePinned=false
VortexAttracionModifier=0.3f
} }

View File

@ -189,6 +189,17 @@ var float HeadshotAccuracyHandicap;
var array<string> PrestigeRewardItemIconPaths; var array<string> PrestigeRewardItemIconPaths;
/*********************************************************************************************
* Transient vars
********************************************************************************************* */
/**
Indicates if the last hit was a headshot.
This is added for the crossbow to apply the stun on enemies only if hit in the head.
Afflictions are calculated after adjusting the damage, so the bone is not necessary
indicating a headshot anymore.
*/
var transient bool bWasLastHitAHeadshot;
/********************************************************************************************* /*********************************************************************************************
* Caching * Caching
********************************************************************************************* */ ********************************************************************************************* */
@ -461,6 +472,17 @@ static function bool IsBackupWeapon( KFWeapon KFW )
return KFW != none && KFW.default.bIsBackupWeapon; return KFW != none && KFW.default.bIsBackupWeapon;
} }
/**
* @brief Return if a weapon is Dual 9mm
*
* @param KFW Weapon to check
* @return true if backup weapon
*/
static function bool IsDual9mm( KFWeapon KFW )
{
return KFW != none && KFW.Class.Name == 'KFWeap_Pistol_Dual9mm';
}
/********************************************************************************************* /*********************************************************************************************
* @name Build / Level Management - Apply and save the updated build and level * @name Build / Level Management - Apply and save the updated build and level
********************************************************************************************* */ ********************************************************************************************* */
@ -934,13 +956,18 @@ function AddDefaultInventory( KFPawn P )
{ {
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class'))); P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class')));
} }
if(KFGameInfo(WorldInfo.Game).AllowSecondaryWeapon(GetSecondaryWeaponClassPath()))
{
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetSecondaryWeaponClassPath(), class'Class')));
}
} }
else else
{ {
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class'))); P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetPrimaryWeaponClassPath(), class'Class')));
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetSecondaryWeaponClassPath(), class'Class')));
} }
// Secondary weapon is spawned through the pawn unless we want an additional one not anymore
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetSecondaryWeaponClassPath(), class'Class')));
P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetKnifeWeaponClassPath(), class'Class'))); P.DefaultInventory.AddItem(class<Weapon>(DynamicLoadObject(GetKnifeWeaponClassPath(), class'Class')));
} }
} }
@ -1073,8 +1100,7 @@ simulated function ModifySprintSpeed( out float Speed ){ ModifySpeed( Speed ); }
function FinalizeSpeedVariables(); function FinalizeSpeedVariables();
/** Kickback - recaoil bonus */ /** Kickback - recaoil bonus */
simulated function ModifyRecoil( out float CurrentRecoilModifier, KFWeapon KFW ); simulated function ModifyRecoil( out float CurrentRecoilModifier, KFWeapon KFW );
/** Allow perk to adjust damage given */ /** Allows to modify the damage taken */
function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx );
function ModifyDamageTaken( out int InDamage, optional class<DamageType> DamageType, optional Controller InstigatedBy ); function ModifyDamageTaken( out int InDamage, optional class<DamageType> DamageType, optional Controller InstigatedBy );
/** Ammunition capacity and mag count increased */ /** Ammunition capacity and mag count increased */
simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacity, optional array< Class<KFPerk> > WeaponPerkClass, optional bool bSecondary=false, optional name WeaponClassname ); simulated function ModifyMagSizeAndNumber( KFWeapon KFW, out int MagazineCapacity, optional array< Class<KFPerk> > WeaponPerkClass, optional bool bSecondary=false, optional name WeaponClassname );
@ -1092,6 +1118,7 @@ static simulated function float GetZedTimeExtension( byte Level ){ return 1.0f;
function float GetKnockdownPowerModifier( optional class<DamageType> DamageType, optional byte BodyPart, optional bool bIsSprinting=false ){ return 0.f; } function float GetKnockdownPowerModifier( optional class<DamageType> DamageType, optional byte BodyPart, optional bool bIsSprinting=false ){ return 0.f; }
function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDamageType> DamageType, optional out float CooldownModifier, optional byte BodyPart ){ return 0.f; } function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDamageType> DamageType, optional out float CooldownModifier, optional byte BodyPart ){ return 0.f; }
function float GetStunPowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ){ return 0.f; } function float GetStunPowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ){ return 0.f; }
function bool IsStunGuaranteed( optional class<DamageType> DamageType, optional byte HitZoneIdx ){ return false; }
function float GetReactionModifier( optional class<KFDamageType> DamageType ){ return 1.f; } function float GetReactionModifier( optional class<KFDamageType> DamageType ){ return 1.f; }
simulated function float GetSnareSpeedModifier() { return 1.f; } simulated function float GetSnareSpeedModifier() { return 1.f; }
simulated function float GetSnarePowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ){ return 1.f; } simulated function float GetSnarePowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ){ return 1.f; }
@ -1199,9 +1226,6 @@ simulated function int GetArmorDamageAmount( int AbsorbedAmt ) { return Absorbed
simulated event float GetZedTimeSpeedScale() { return 1.f; } simulated event float GetZedTimeSpeedScale() { return 1.f; }
/** Survivalist dunctions */
simulated function bool GetIncapMasterActive(){ return false; }
static function ModifyAssistDosh( out int EarnedDosh ) static function ModifyAssistDosh( out int EarnedDosh )
{ {
local float TempDosh; local float TempDosh;
@ -1304,6 +1328,7 @@ function TickRegen( float DeltaTime )
local KFPlayerController KFPC; local KFPlayerController KFPC;
local KFPowerUp PowerUp; local KFPowerUp PowerUp;
local bool bCannotBeHealed; local bool bCannotBeHealed;
local KFGameInfo GameInfo;
TimeUntilNextRegen -= DeltaTime; TimeUntilNextRegen -= DeltaTime;
if( TimeUntilNextRegen <= 0.f ) if( TimeUntilNextRegen <= 0.f )
@ -1314,9 +1339,12 @@ function TickRegen( float DeltaTime )
if( KFPC != none ) if( KFPC != none )
{ {
PowerUp = KFPC.GetPowerUp(); PowerUp = KFPC.GetPowerUp();
bCannotBeHealed = PowerUp != none && !PowerUp.CanBeHealedWhilePowerUpIsActive; bCannotBeHealed = PowerUp != none && !PowerUp.CanBeHealed();
} }
GameInfo = KFGameInfo(WorldInfo.Game);
bCannotBeHealed = bCannotBeHealed || (GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed);
// If the Pawn cannot be healed return... // If the Pawn cannot be healed return...
if( bCannotBeHealed ) if( bCannotBeHealed )
{ {
@ -1372,6 +1400,12 @@ simulated function class<KFWeaponDefinition> GetGrenadeWeaponDef()
return default.GrenadeWeaponDef; return default.GrenadeWeaponDef;
} }
/** Allow perk to adjust damage given */
function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
bWasLastHitAHeadshot = MyKFPM != none && HitZoneIdx == HZI_HEAD;
}
/********************************************************************************************* /*********************************************************************************************
* @name Debug * @name Debug
********************************************************************************************* */ ********************************************************************************************* */
@ -1485,4 +1519,6 @@ DefaultProperties
AssistDoshModifier=1.f AssistDoshModifier=1.f
PrestigeRewardItemIconPaths[0]="Xmas_UI.UI_Objectives_Xmas_Krampus" PrestigeRewardItemIconPaths[0]="Xmas_UI.UI_Objectives_Xmas_Krampus"
bWasLastHitAHeadshot=false
} }

View File

@ -53,6 +53,11 @@ enum EBerserkPerkSkills
EBerserkerSpartan EBerserkerSpartan
}; };
/** The last time a zed was bumped using battering ram */
var float LastBumpTime;
/** The unique list of actors that have been bumped before the last cooldown reset */
var array<Actor> CurrentBumpedActors;
cpptext cpptext
{ {
// specific abilities // specific abilities
@ -71,7 +76,7 @@ function ApplySkillsToPawn()
if( OwnerPawn != none ) if( OwnerPawn != none )
{ {
OwnerPawn.bMovesFastInZedTime = IsFastInZedTime(); OwnerPawn.bMovesFastInZedTime = IsFastInZedTime() || IsSWATEnforcerActiveForWeekly();
} }
} }
@ -112,13 +117,17 @@ reliable client function ClientClearPerkEffects()
event Tick( float DeltaTime ) event Tick( float DeltaTime )
{ {
super.Tick( DeltaTime ); super.Tick( DeltaTime );
if( IsNinjaActive() ) if( IsNinjaActive() )
{ {
TickRegen( DeltaTime ); TickRegen( DeltaTime );
} }
} }
simulated event float GetZedTimeSpeedScale()
{
return GetZedTimeSpeedScaleForColliseum();
}
/********************************************************************************************* /*********************************************************************************************
* @name Passive skills functions * @name Passive skills functions
********************************************************************************************* */ ********************************************************************************************* */
@ -136,6 +145,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon MyKFWeapon; local KFWeapon MyKFWeapon;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )
@ -540,6 +551,7 @@ function NotifyZedTimeStarted()
local KFPlayerController KFPC; local KFPlayerController KFPC;
local KFPowerUp PowerUp; local KFPowerUp PowerUp;
local KFAIController KFAIC; local KFAIController KFAIC;
local KFGameInfo GameInfo;
local bool bScaredAI; local bool bScaredAI;
local bool bCannotBeHealed; local bool bCannotBeHealed;
@ -549,9 +561,15 @@ function NotifyZedTimeStarted()
if( KFPC != none ) if( KFPC != none )
{ {
PowerUp = KFPC.GetPowerUp(); PowerUp = KFPC.GetPowerUp();
bCannotBeHealed = PowerUp != none && !PowerUp.CanBeHealedWhilePowerUpIsActive; bCannotBeHealed = (PowerUp != none && !PowerUp.CanBeHealedWhilePowerUpIsActive);
GameInfo = KFGameInfo(WorldInfo.Game);
if(GameInfo != none)
{
bCannotBeHealed = bCannotBeHealed ||(GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed);
}
} }
if( bCannotBeHealed == false ) if( bCannotBeHealed == false )
{ {
OwnerPawn.Health += OwnerPawn.HealthMax * GetSkillValue( PerkSkills[EBerserkerRage] ); OwnerPawn.Health += OwnerPawn.HealthMax * GetSkillValue( PerkSkills[EBerserkerRage] );
@ -637,11 +655,11 @@ private static function float GetParryDamageModifier()
{ {
return default.ParryDamageReduction; return default.ParryDamageReduction;
} }
/********************************************************************************************* /*********************************************************************************************
* @name Getters / Setters * @name Getters / Setters
********************************************************************************************* */ ********************************************************************************************* */
/** /**
* @brief Checks if the fortitude skill is active * @brief Checks if the fortitude skill is active
* *
@ -789,7 +807,7 @@ function bool CanNotBeGrabbed()
*/ */
simulated private event bool IsRageActive() simulated private event bool IsRageActive()
{ {
return PerkSkills[EBerserkerRage].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerRage); return PerkSkills[EBerserkerRage].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerRage) && !ShouldDisableZedTimeSkillsForWeekly();
} }
/** /**
@ -799,12 +817,12 @@ simulated private event bool IsRageActive()
*/ */
simulated final private event bool IsSpartanActive() simulated final private event bool IsSpartanActive()
{ {
return PerkSkills[EBerserkerSpartan].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerSpartan); return PerkSkills[EBerserkerSpartan].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
} }
simulated private event bool CouldSpartanBeActive() simulated private event bool CouldSpartanBeActive()
{ {
return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan); return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
} }
/** /**
@ -814,7 +832,12 @@ simulated private event bool CouldSpartanBeActive()
*/ */
simulated function bool IsFastInZedTime() simulated function bool IsFastInZedTime()
{ {
return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan); return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
}
simulated function bool IsFastInZedTimeOutbreak()
{
return ShouldDisableZedTimeSkillsForWeekly();
} }
/** /**
@ -825,7 +848,7 @@ simulated function bool IsFastInZedTime()
*/ */
simulated event bool ShouldUseFastInstigatorDilation(KFWeapon Weap) simulated event bool ShouldUseFastInstigatorDilation(KFWeapon Weap)
{ {
if (PerkSkills[EBerserkerSpartan].bActive && Weap != none && IsPerkLevelAllowed(EBerserkerSpartan)) if (PerkSkills[EBerserkerSpartan].bActive && Weap != none && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly())
{ {
return Weap.GetWeaponPerkClass(default.Class) == default.Class; return Weap.GetWeaponPerkClass(default.Class) == default.Class;
} }
@ -833,6 +856,75 @@ simulated event bool ShouldUseFastInstigatorDilation(KFWeapon Weap)
return false; return false;
} }
/*********************************************************************************************
* @name Special Weekly Modes
********************************************************************************************* */
simulated event float GetZedTimeSpeedScaleForColliseum()
{
return IsSWATEnforcerActiveForWeekly() ? class'KFPerk_Swat'.default.SWATEnforcerZedTimeSpeedScale : 1.f;
}
function bool ShouldDisableZedTimeSkillsForWeekly()
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bColliseumSkillConditionsActive;
}
function bool IsSWATEnforcerActiveForWeekly()
{
return MyKFGI != none && MyKFGI.OutbreakEvent != none && MyKFGI.OutbreakEvent.ActiveEvent.bColliseumSkillConditionsActive;
}
simulated function bool ShouldKnockDownOnBump()
{
return IsSWATEnforcerActiveForWeekly() && WorldInfo.TimeDilation < 1.f;
}
simulated function OnBump(Actor BumpedActor, KFPawn_Human BumpInstigator, vector BumpedVelocity, rotator BumpedRotation)
{
local KFPawn_Monster KFPM;
local bool CanBump;
if (ShouldKnockDownOnBump() && Normal(BumpedVelocity) dot Vector(BumpedRotation) > 0.7f)
{
KFPM = KFPawn_Monster(BumpedActor);
if (KFPM != none)
{
// cooldown so that the same zed can't be bumped multiple frames back to back
// especially relevant if they can't be knocked down or stumbled so the player is always bumping them
if (WorldInfo.TimeSeconds - LastBumpTime > class'KFPerk_Swat'.default.BumpCooldown)
{
CurrentBumpedActors.length = 0;
CurrentBumpedActors.AddItem(BumpedActor);
CanBump = true;
}
// if still within the cooldown time, can still bump the actor as long as it hasn't been bumped yet
else if (CurrentBumpedActors.Find(BumpedActor) == INDEX_NONE)
{
CurrentBumpedActors.AddItem(BumpedActor);
CanBump = true;
}
LastBumpTime = WorldInfo.TimeSeconds;
if (CanBump)
{
if (KFPM.IsHeadless())
{
KFPM.TakeDamage(KFPM.HealthMax, BumpInstigator.Controller, BumpInstigator.Location,
Normal(vector(BumpedRotation)) * class'KFPerk_Swat'.default.BumpMomentum, class'KFPerk_Swat'.default.BumpDamageType);
}
else
{
KFPM.TakeDamage(class'KFPerk_Swat'.default.BumpDamageAmount, BumpInstigator.Controller, BumpInstigator.Location,
Normal(vector(BumpedRotation)) * class'KFPerk_Swat'.default.BumpMomentum, class'KFPerk_Swat'.default.BumpDamageType);
KFPM.Knockdown(BumpedVelocity * 3, vect(1, 1, 1), KFPM.Location, 1000, 100);
}
}
}
}
}
/********************************************************************************************* /*********************************************************************************************
* @name UI / HUD * @name UI / HUD
********************************************************************************************* */ ********************************************************************************************* */
@ -926,11 +1018,11 @@ DefaultProperties
DamageResistance=(Name="Damage Resistance",Increment=0.03f,Rank=0,StartingValue=0.f,MaxValue=0.15f) DamageResistance=(Name="Damage Resistance",Increment=0.03f,Rank=0,StartingValue=0.f,MaxValue=0.15f)
NightVision=(Name="Night Vision",Increment=0.f,Rank=0,StartingValue=0.f,MaxValue=0.f) 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=0.75,MaxValue=0.75) 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(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=4.f,MaxValue=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(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.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(EBerserkerParry)=(Name="Parry",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Parry",Increment=0.f,Rank=0,StartingValue=0.35,MaxValue=0.35) 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(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) 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

@ -74,6 +74,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
{ {
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
@ -82,7 +84,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
KFW = GetWeaponFromDamageCauser( DamageCauser ); KFW = GetWeaponFromDamageCauser( DamageCauser );
} }
if( (KFW != none && IsWeaponOnPerk( KFW,, self.class )) || (DamageType != none && IsDamageTypeOnPerk( DamageType )) ) if( (KFW != none && (IsWeaponOnPerk( KFW,, self.class ) || IsDual9mm(KFW) || Is9mm(KFW))) || (DamageType != none && IsDamageTypeOnPerk( DamageType )) )
{ {
TempDamage += InDamage * GetPassiveValue( WeaponDamage, CurrentLevel ); TempDamage += InDamage * GetPassiveValue( WeaponDamage, CurrentLevel );
if( IsRapidFireActive() ) if( IsRapidFireActive() )
@ -97,7 +99,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
// have the perks so tied into using that, it's easier to just specifically fix commando here. // have the perks so tied into using that, it's easier to just specifically fix commando here.
if( KFW != none && !DamageCauser.IsA('KFProj_Grenade')) if( KFW != none && !DamageCauser.IsA('KFProj_Grenade'))
{ {
if( IsBackupActive() && (IsBackupWeapon( KFW ) || KFW.Class.Name == 'KFWeap_Pistol_Dual9mm') ) if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW )) )
{ {
`QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue( PerkSkills[ECommandoBackup] )), bLogPerk ); `QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue( PerkSkills[ECommandoBackup] )), bLogPerk );
TempDamage += InDamage * GetSkillValue( PerkSkills[ECommandoBackup] ); TempDamage += InDamage * GetSkillValue( PerkSkills[ECommandoBackup] );
@ -234,7 +236,7 @@ function ModifyArmor( out byte MaxArmor )
*/ */
simulated function bool GetUsingTactialReload( KFWeapon KFW ) simulated function bool GetUsingTactialReload( KFWeapon KFW )
{ {
return ( IsTacticalReloadActive() && (IsWeaponOnPerk( KFW,, self.class ) || IsBackupWeapon( KFW )) ); return ( IsTacticalReloadActive() && (IsWeaponOnPerk( KFW,, self.class ) || IsBackupWeapon( KFW ) || IsDual9mm( KFW )) );
} }
/** /**
@ -278,7 +280,7 @@ simulated function ModifyMaxSpareAmmoAmount( KFWeapon KFW, out int MaxSpareAmmo,
local float TempMaxSpareAmmoAmount; local float TempMaxSpareAmmoAmount;
if( IsAmmoVestActive() && (IsWeaponOnPerk( KFW, TraderItem.AssociatedPerkClasses, self.class ) || if( IsAmmoVestActive() && (IsWeaponOnPerk( KFW, TraderItem.AssociatedPerkClasses, self.class ) ||
IsBackupWeapon( KFW )) ) IsBackupWeapon( KFW ) || IsDual9mm( KFW )) )
{ {
TempMaxSpareAmmoAmount = MaxSpareAmmo; TempMaxSpareAmmoAmount = MaxSpareAmmo;
TempMaxSpareAmmoAmount += MaxSpareAmmo * GetSkillValue( PerkSkills[ECommandoAmmoVest] ); TempMaxSpareAmmoAmount += MaxSpareAmmo * GetSkillValue( PerkSkills[ECommandoAmmoVest] );
@ -302,7 +304,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
local name StateName; local name StateName;
StateName = W.GetStateName(); StateName = W.GetStateName();
if( IsProfessionalActive() && (IsWeaponOnPerk( W,, self.class ) || IsBackupWeapon( W )) ) if( IsProfessionalActive() && (IsWeaponOnPerk( W,, self.class ) || IsBackupWeapon( W ) || IsDual9mm( W )) )
{ {
if( StateName == 'Reloading' || if( StateName == 'Reloading' ||
StateName == 'AltReloading' ) StateName == 'AltReloading' )
@ -315,7 +317,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
} }
} }
if( CouldRapidFireActive() && (Is9mm(W) || IsWeaponOnPerk( W,, self.class )) && ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE ) if( CouldRapidFireActive() && (Is9mm(W) || IsDual9mm( W ) || IsWeaponOnPerk( W,, self.class )) && ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
{ {
return RapidFireFiringRate; return RapidFireFiringRate;
} }

View File

@ -127,6 +127,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
if( DamageType != none && IsDamageIgnoredDT( DamageType ) ) if( DamageType != none && IsDamageIgnoredDT( DamageType ) )
{ {
return; return;
@ -437,7 +439,7 @@ simulated protected function int GetAmmoExtraAmmo()
*/ */
simulated function bool GetUsingTactialReload(KFWeapon KFW) simulated function bool GetUsingTactialReload(KFWeapon KFW)
{ {
return (IsTacticalReloadActive() && (IsWeaponOnPerk(KFW, , self.class) || IsBackupWeapon(KFW)) && TacticalReloadAsReloadRateClassNames.Find(KFW.class.Name) == INDEX_NONE); return (IsTacticalReloadActive() && (IsWeaponOnPerk(KFW, , self.class) || IsBackupWeapon(KFW) || IsDual9mm( KFW )) && TacticalReloadAsReloadRateClassNames.Find(KFW.class.Name) == INDEX_NONE);
} }
/** /**

View File

@ -298,6 +298,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )
@ -646,7 +648,7 @@ DefaultProperties
PerkBuildStatID=STATID_Medic_Build PerkBuildStatID=STATID_Medic_Build
SelfHealingSurgePct=0.1f SelfHealingSurgePct=0.1f
MaxSurvivalistResistance=0.5f //0.8 MaxSurvivalistResistance=0.70f //0.5f //0.8
CombatantSpeedModifier=0.1f CombatantSpeedModifier=0.1f
MaxHealingSpeedBoost=30 //15 //50 MaxHealingSpeedBoost=30 //15 //50

View File

@ -82,6 +82,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )

View File

@ -133,6 +133,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )
{ {

View File

@ -125,6 +125,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )
@ -315,7 +317,7 @@ event Destroyed()
simulated function bool GetUsingTactialReload( KFWeapon KFW ) simulated function bool GetUsingTactialReload( KFWeapon KFW )
{ {
`QALog( "Tactical Reload Active =" @ (IsTacticalReloadActive() && IsWeaponOnPerk( KFW,, self.class )), bLogPerk ); `QALog( "Tactical Reload Active =" @ (IsTacticalReloadActive() && IsWeaponOnPerk( KFW,, self.class )), bLogPerk );
return IsTacticalReloadActive() && (IsWeaponOnPerk( KFW, , self.class) || IsBackupWeapon( KFW )); return IsTacticalReloadActive() && (IsWeaponOnPerk( KFW, , self.class) || IsBackupWeapon( KFW ) || IsDual9mm( KFW ));
} }
/** /**
@ -324,23 +326,29 @@ simulated function bool GetUsingTactialReload( KFWeapon KFW )
*/ */
function float GetStunPowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ) function float GetStunPowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx )
{ {
if( IsDamageTypeOnPerk(class<KFDamageType>(DamageType)) ) if( IsDamageTypeOnPerk(class<KFDamageType>(DamageType)) && IsStunActive())
{ {
if( HitZoneIdx == HZI_Head && GetZTStunActive() ) `QALog( "(Stun)" @ GetSkillValue( PerkSkills[ESharpshooterStun] ), bLogPerk );
{ return GetSkillValue( PerkSkills[ESharpshooterStun] );
`QALog( "(ZT Stun)" @ GetSkillValue(PerkSkills[ESharpshooterZTStun]), bLogPerk );
return GetSkillValue( PerkSkills[ESharpshooterZTStun] );
}
else if( IsStunActive() )
{
`QALog( "(Stun)" @ GetSkillValue( PerkSkills[ESharpshooterStun] ), bLogPerk );
return GetSkillValue( PerkSkills[ESharpshooterStun] );
}
} }
return 0.f; return 0.f;
} }
/**
* @brief skills and weapons can guarantee a stun
* @return true/false
*/
function bool IsStunGuaranteed( optional class<DamageType> DamageType, optional byte HitZoneIdx )
{
if( IsDamageTypeOnPerk(class<KFDamageType>(DamageType)) && GetZTStunActive())
{
return bWasLastHitAHeadshot;
}
return false;
}
/** /**
* @brief Checks if the Stationary Aim skill is active * @brief Checks if the Stationary Aim skill is active
* *

View File

@ -155,6 +155,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
`QALog( GetFuncName() @ "BaseDamage =" @ InDamage, bLogPerk ); `QALog( GetFuncName() @ "BaseDamage =" @ InDamage, bLogPerk );
@ -337,7 +339,7 @@ simulated private static function float GetResupplyMaxSpareAmmoModifier()
*/ */
simulated function bool GetUsingTactialReload( KFWeapon KFW ) simulated function bool GetUsingTactialReload( KFWeapon KFW )
{ {
return IsTacticalReloadActive() && (IsWeaponOnPerk( KFW,, self.class ) || IsBackupWeapon( KFW )); return IsTacticalReloadActive() && (IsWeaponOnPerk( KFW,, self.class ) || IsBackupWeapon( KFW ) || IsDual9mm( KFW ));
} }
/** /**

View File

@ -142,6 +142,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
TempDamage += InDamage * GetPassiveValue( WeaponDamage, CurrentLevel ); TempDamage += InDamage * GetPassiveValue( WeaponDamage, CurrentLevel );
@ -462,7 +464,7 @@ simulated function float GetAoERadiusModifier()
simulated function float GetZedTimeModifier( KFWeapon W ) simulated function float GetZedTimeModifier( KFWeapon W )
{ {
local name StateName; local name StateName;
if( GetMadManActive() && !W.IsMeleeWeapon() || KFWeap_MeleeBase(W).default.bHasToBeConsideredAsRangedWeaponForPerks ) if( GetMadManActive() && (!W.IsMeleeWeapon() || KFWeap_MeleeBase(W).default.bHasToBeConsideredAsRangedWeaponForPerks ))
{ {
StateName = W.GetStateName(); StateName = W.GetStateName();
`Warn(StateName); `Warn(StateName);
@ -525,18 +527,17 @@ function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDa
} }
/** /**
* @brief skills and weapons can modify the stun power * @brief skills and weapons can guarantee a stun
* @return stun power modifier * @return true/false
*/ */
function float GetStunPowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ) function bool IsStunGuaranteed( optional class<DamageType> DamageType, optional byte HitZoneIdx )
{ {
if( GetIncapMasterActive() ) if( GetIncapMasterActive() )
{ {
`QALog( "(ZT Stun)" @ (GetSkillValue(PerkSkills[ESharpshooterZTStun]) * 5), bLogPerk ); return true;
return (GetSkillValue( PerkSkills[ESurvivalist_IncapMaster] ) );
} }
return 0.f; return false;
} }
simulated function float GetSnarePowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx ) simulated function float GetSnarePowerModifier( optional class<DamageType> DamageType, optional byte HitZoneIdx )
@ -849,6 +850,8 @@ DefaultProperties
ZedTimeModifyingStates(8)="BlunderbussDeployAndDetonate" ZedTimeModifyingStates(8)="BlunderbussDeployAndDetonate"
ZedTimeModifyingStates(9)="WeaponWindingUp" ZedTimeModifyingStates(9)="WeaponWindingUp"
ZedTimeModifyingStates(10)="MineReconstructorCharge" ZedTimeModifyingStates(10)="MineReconstructorCharge"
ZedTimeModifyingStates(11)="WeaponSonicGunSingleFiring"
ZedTimeModifyingStates(12)="WeaponSonicGunCharging"
PrimaryWeaponPaths(0)=class'KFWeapDef_AR15' PrimaryWeaponPaths(0)=class'KFWeapDef_AR15'
PrimaryWeaponPaths(1)=class'KFWeapDef_MB500' PrimaryWeaponPaths(1)=class'KFWeapDef_MB500'

View File

@ -207,7 +207,7 @@ static simulated private function bool Is9mm( KFWeapon KFW )
*/ */
simulated event float GetIronSightSpeedModifier( KFWeapon KFW ) simulated event float GetIronSightSpeedModifier( KFWeapon KFW )
{ {
if( IsTacticalMovementActive() && (Is9mm( KFW ) || IsWeaponOnPerk( KFW,, self.class )) ) if( IsTacticalMovementActive() && (Is9mm( KFW ) || IsDual9mm( KFW ) || IsWeaponOnPerk( KFW,, self.class )) )
{ {
`QALog( "Tactical Movement Mod:" @ KFW @ GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ),bLogPerk ); `QALog( "Tactical Movement Mod:" @ KFW @ GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ),bLogPerk );
return GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ); return GetSkillValue( PerkSkills[ESWAT_TacticalMovement] );
@ -237,7 +237,7 @@ function FinalizeSpeedVariables()
*/ */
simulated event float GetCrouchSpeedModifier( KFWeapon KFW ) simulated event float GetCrouchSpeedModifier( KFWeapon KFW )
{ {
if( IsTacticalMovementActive() && (Is9mm( KFW ) || IsWeaponOnPerk( KFW,, self.class )) ) if( IsTacticalMovementActive() && (Is9mm( KFW ) || IsDual9mm(KFW) || IsWeaponOnPerk( KFW,, self.class )) )
{ {
`QALog( "Tactical Movement Mod:" @ KFW @ GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ),bLogPerk ); `QALog( "Tactical Movement Mod:" @ KFW @ GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ),bLogPerk );
return GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ) * CurrentHealthPenalty; return GetSkillValue( PerkSkills[ESWAT_TacticalMovement] ) * CurrentHealthPenalty;
@ -268,6 +268,8 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
local KFWeapon KFW; local KFWeapon KFW;
local float TempDamage; local float TempDamage;
super.ModifyDamageGiven(InDamage, DamageCauser, MyKFPM, DamageInstigator, DamageType, HitZoneIdx);
TempDamage = InDamage; TempDamage = InDamage;
if( DamageCauser != none ) if( DamageCauser != none )
@ -277,7 +279,7 @@ simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCau
if( KFW != none ) if( KFW != none )
{ {
if( IsBackupActive() && (IsBackupWeapon( KFW ) || KFW.Class.Name == 'KFWeap_Pistol_Dual9mm') ) if( IsBackupActive() && (IsBackupWeapon( KFW ) || IsDual9mm( KFW )) )
{ {
`QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk ); `QALog( "Backup Damage" @ KFW @ GetPercentage( InDamage, InDamage * GetSkillValue(PerkSkills[ESWAT_Backup])), bLogPerk );
TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] ); TempDamage += InDamage * GetSkillValue( PerkSkills[ESWAT_Backup] );
@ -356,7 +358,7 @@ simulated function float GetZedTimeModifier( KFWeapon W )
local name StateName; local name StateName;
StateName = W.GetStateName(); StateName = W.GetStateName();
if( IsRapidAssaultActive() && (Is9mm(W) || IsWeaponOnPerk( W,, self.class ) || W.IsA('KFWeap_Pistol_Dual9mm') ) ) if( IsRapidAssaultActive() && (Is9mm(W) || IsWeaponOnPerk( W,, self.class ) || IsDual9mm( W ) ) )
{ {
if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE ) if( ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
{ {
@ -380,7 +382,7 @@ function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDa
StumbleModifier = 0.f; StumbleModifier = 0.f;
KFW = GetOwnerWeapon(); KFW = GetOwnerWeapon();
if( IsSpecialAmmunitionActive() && (Is9mm(KFW) || IsWeaponOnPerk( KFW,, self.class )) ) if( IsSpecialAmmunitionActive() && (Is9mm(KFW) || IsDual9mm( KFW ) || IsWeaponOnPerk( KFW,, self.class )) )
{ {
StumbleModifier += GetSkillValue( PerkSkills[ESWAT_SpecialAmmunition] ); StumbleModifier += GetSkillValue( PerkSkills[ESWAT_SpecialAmmunition] );
`QALog( "Special Ammunition Modifier" @ GetSkillValue( PerkSkills[ESWAT_SpecialAmmunition] ), bLogPerk ); `QALog( "Special Ammunition Modifier" @ GetSkillValue( PerkSkills[ESWAT_SpecialAmmunition] ), bLogPerk );
@ -404,7 +406,7 @@ function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDa
*/ */
simulated function bool GetIsUberAmmoActive( KFWeapon KFW ) simulated function bool GetIsUberAmmoActive( KFWeapon KFW )
{ {
return IsRapidAssaultActive() && (Is9mm(KFW) || IsWeaponOnPerk( KFW,, self.class ) || KFW.IsA('KFWeap_Pistol_Dual9mm')); return IsRapidAssaultActive() && (Is9mm(KFW) || IsWeaponOnPerk( KFW,, self.class ) || IsDual9mm( KFW ));
} }
simulated function bool ShouldKnockDownOnBump() simulated function bool ShouldKnockDownOnBump()
@ -520,7 +522,7 @@ simulated private function bool IsTacticalReloadActive()
*/ */
simulated function bool GetUsingTactialReload( KFWeapon KFW ) simulated function bool GetUsingTactialReload( KFWeapon KFW )
{ {
return ( IsTacticalReloadActive() && (Is9mm(KFW) || IsWeaponOnPerk( KFW,, self.class )) ); return ( IsTacticalReloadActive() && (Is9mm(KFW) || IsDual9mm( KFW ) || IsWeaponOnPerk( KFW,, self.class )) );
} }
/** /**

View File

@ -703,6 +703,12 @@ var int BeginningRoundVaultAmount;
var transient float NoGoStartTime; var transient float NoGoStartTime;
var transient bool bNoGoActive; var transient bool bNoGoActive;
/*********************************************************************************************
* @name Profile Stored values
********************************************************************************************* */
var transient byte StoredLocalUserNum;
cpptext cpptext
{ {
virtual UBOOL Tick( FLOAT DeltaSeconds, ELevelTick TickType ); virtual UBOOL Tick( FLOAT DeltaSeconds, ELevelTick TickType );
@ -824,6 +830,32 @@ simulated event PostBeginPlay()
} }
} }
function UpdateVOIP()
{
local KFPlayerInput KFPI;
local KFPlayerReplicationInfo KFPRI;
KFPRI = KFPlayerReplicationInfo( PlayerReplicationInfo );
KFPI = KFPlayerInput(PlayerInput);
if(KFPI == None || KFPRI == None)
{
// Retry
SetTimer(0.1f, false, nameof(UpdateVOIP) );
}
else
{
if(KFPI.bRequiresPushToTalk)
{
ClientStopNetworkedVoice();
}
else
{
ClientStartNetworkedVoice();
}
}
}
function SpawnDefaultHUD() function SpawnDefaultHUD()
{ {
super.SpawnDefaultHUD(); super.SpawnDefaultHUD();
@ -1018,6 +1050,7 @@ simulated event ReceivedPlayer()
KFEngine.LastURL.Op.Remove(i, 1); KFEngine.LastURL.Op.Remove(i, 1);
} }
} }
UpdateVOIP();
} }
} }
@ -1512,12 +1545,15 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful)
local KFProfileSettings Profile; local KFProfileSettings Profile;
local KFPlayerInput KFInput; local KFPlayerInput KFInput;
local KFGameInfo KFGI; local KFGameInfo KFGI;
local KFGameReplicationInfo KFGRI;
local KFGameEngine KFEngine; local KFGameEngine KFEngine;
local KFPlayerReplicationInfo KFPRI; local KFPlayerReplicationInfo KFPRI;
local string MatchmakingRegion; local string MatchmakingRegion;
local KFGoreManager GoreMgr; local KFGoreManager GoreMgr;
local UniqueNetId LobbyId, Zero; local UniqueNetId LobbyId, Zero;
StoredLocalUserNum = LocalUserNum;
Profile = KFProfileSettings(OnlineSub.PlayerInterface.GetProfileSettings(LocalUserNum)); Profile = KFProfileSettings(OnlineSub.PlayerInterface.GetProfileSettings(LocalUserNum));
`QAlog(`location@`showvar(Profile)@`showvar(bWasSuccessful), true); `QAlog(`location@`showvar(Profile)@`showvar(bWasSuccessful), true);
@ -1648,12 +1684,58 @@ function OnReadProfileSettingsComplete(byte LocalUserNum,bool bWasSuccessful)
{ {
OnlineSub.GetLobbyInterface().LobbyInvite(LobbyId, Zero, true); OnlineSub.GetLobbyInterface().LobbyInvite(LobbyId, Zero, true);
} }
// If the perk is not allowed for this game mode, search for one that is available starting from the index 0
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if( KFGRI != none && !KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
SavedPerkIndex = 0;
for(SavedPerkIndex=0 ; SavedPerkIndex<PerkList.length ; SavedPerkIndex++)
{
if( KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
continue;
}
}
// Save the new perk selected in the the profile settings
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex );
}
// Update our cached Emote Id // Update our cached Emote Id
class'KFEmoteList'.static.RefreshCachedEmoteId(); class'KFEmoteList'.static.RefreshCachedEmoteId();
class'KFHeadShotEffectList'.static.RefreshCachedHeadShotEffectId(); class'KFHeadShotEffectList'.static.RefreshCachedHeadShotEffectId();
} }
function UpdatePerkOnInit()
{
local KFGameReplicationInfo KFGRI;
local KFProfileSettings Profile;
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
// If the perk is not allowed for this game mode, search for one that is available starting from the index 0
if( KFGRI != none && !KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
SavedPerkIndex = 0;
for(SavedPerkIndex=0 ; SavedPerkIndex<PerkList.length ; SavedPerkIndex++)
{
if( KFGRI.IsPerkAllowed(PerkList[SavedPerkIndex].PerkClass) )
{
continue;
}
}
// Save the new perk selected in the the profile settings
Profile = KFProfileSettings(OnlineSub.PlayerInterface.GetProfileSettings(StoredLocalUserNum));
if( Profile != None )
{
Profile.SetProfileSettingValueInt( KFID_SavedPerkIndex, SavedPerkIndex );
}
}
}
/********************************************************************************************* /*********************************************************************************************
* @name Console Connection Handling * @name Console Connection Handling
@ -7268,6 +7350,13 @@ event byte GetPerkLevelFromPerkList(Class<KFPerk> PerkClass)
return 0; return 0;
} }
/** hit stat */
function NotifyHitTaken()
{
ClientNotifyHitTaken();
}
native reliable client private function ClientNotifyHitTaken();
/** Kill stat */ /** Kill stat */
function AddZedKill( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller ) function AddZedKill( class<KFPawn_Monster> MonsterClass, byte Difficulty, class<DamageType> DT, bool bKiller )
{ {
@ -11495,6 +11584,22 @@ reliable client function DrawLocalizedTextOnHud(string Message, float DisplayTim
} }
} }
function bool CanUseHealObject()
{
local class<KFPowerUp> KFPowerUpClass;
local KFGameInfo GameInfo;
local bool CanHealPowerUp;
local bool CanHealGameMode;
GameInfo = KFGameInfo(WorldInfo.Game);
KFPowerUpClass = GetPowerUpClass();
CanHealPowerUp = KFPowerUpClass == none || KFPowerUpClass.default.CanBeHealedWhilePowerUpIsActive;
CanHealGameMode = GameInfo == none || GameInfo.OutbreakEvent == none || !GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed;
return CanHealPowerUp && CanHealGameMode;
}
event OnLoginOnOtherPlatformDoneAndFriendsReady() event OnLoginOnOtherPlatformDoneAndFriendsReady()
{ {
if (MyGFxManager != none) if (MyGFxManager != none)

View File

@ -0,0 +1,14 @@
//=============================================================================
// KFPowerUp_HellishRage
//=============================================================================
// Base class for the hellish rage power up
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFPowerUp_HellishRage_NoCostHeal extends KFPowerUp_HellishRage;
DefaultProperties
{
HealthCost=0
}

View File

@ -100,7 +100,7 @@ simulated function bool GetImpactResult(Actor HitActor, PrimitiveComponent HitCo
// NOTE: Door actors fall into this category! // NOTE: Door actors fall into this category!
// pass through meshes that can move // pass through meshes that can move
return !StaticMeshComp.CanBecomeDynamic(); return true;
} }
KFP = KFPawn_Human(HitActor); KFP = KFPawn_Human(HitActor);
@ -108,16 +108,16 @@ simulated function bool GetImpactResult(Actor HitActor, PrimitiveComponent HitCo
{ {
// bounce off of player pawns, stick to other pawns // bounce off of player pawns, stick to other pawns
return false; return false;
} }
D = KFDestructibleActor(HitActor); D = KFDestructibleActor(HitActor);
if (D != none) if (D != none)
{ {
// don't react to client-side-only destructibles, stick to others // don't react to client-side-only destructibles, stick to others
return D.ReplicationMode != RT_ClientSide; return D.ReplicationMode != RT_ClientSide;
} }
return true; return true;

View File

@ -71,4 +71,5 @@ simulated event OnGameEnd(class<GameInfo> GameClass);
simulated function OnBossDied(); simulated function OnBossDied();
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum); simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum);
simulated event OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass); simulated event OnTriggerUsed(class<Trigger_PawnsOnly> TriggerClass);
simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex); simulated event OnTryCompleteObjective(int ObjectiveIndex, int EventIndex);
simulated function OnHitTaken();

View File

@ -27,6 +27,7 @@ enum ESharedContentUnlock
SCU_Minigun, SCU_Minigun,
SCU_MineReconstructor, SCU_MineReconstructor,
SCU_FrostFang, SCU_FrostFang,
SCU_GravityImploder,
}; };
@ -325,4 +326,8 @@ defaultproperties
Name=KFWeap_Rifle_FrostShotgunAxe, Name=KFWeap_Rifle_FrostShotgunAxe,
IconPath="WEP_UI_Frost_Shotgun_Axe_TEX.UI_WeaponSelect_FrostGun", IconPath="WEP_UI_Frost_Shotgun_Axe_TEX.UI_WeaponSelect_FrostGun",
ID=8609)} ID=8609)}
SharedContentList(SCU_GravityImploder)={(
Name=KFWeap_GravityImploder,
IconPath="WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder",
ID=8778)}
} }

View File

@ -15,7 +15,7 @@ DefaultProperties
WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_Bullpup" WeaponClassPath="KFGameContent.KFWeap_AssaultRifle_Bullpup"
BuyPrice=650 BuyPrice=650
AmmoPricePerMag=30 AmmoPricePerMag=32 //30
ImagePath="ui_weaponselect_tex.UI_WeaponSelect_Bullpup" ImagePath="ui_weaponselect_tex.UI_WeaponSelect_Bullpup"
EffectiveRange=68 EffectiveRange=68

View File

@ -0,0 +1,28 @@
//=============================================================================
// KFWeapDef_GravityImploder
//=============================================================================
// A lightweight container for basic weapon properties that can be safely
// accessed without a weapon actor (UI, remote clients).
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_GravityImploder extends KFWeaponDefinition
abstract;
defaultproperties
{
WeaponClassPath="KFGameContent.KFWeap_GravityImploder"
BuyPrice=2000
AmmoPricePerMag=70//40
ImagePath="WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder"
EffectiveRange=95 // Based on comment Slightly less than M79 Grenade Launcher
SharedUnlockId=SCU_GravityImploder
}

View File

@ -0,0 +1,25 @@
//=============================================================================
// KFWeapDef_HRG_SonicGun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeapDef_HRG_SonicGun extends KFWeaponDefinition
abstract;
DefaultProperties
{
WeaponClassPath="KFGameContent.KFWeap_HRG_SonicGun"
BuyPrice=1100
AmmoPricePerMag=65 //75
ImagePath="WEP_UI_HRG_SonicGun_TEX.UI_WeaponSelect_HRG_SonicGun"
EffectiveRange=70
UpgradePrice[0]=700
UpgradePrice[1]=1500
UpgradeSellPrice[0]=525
UpgradeSellPrice[1]=1650
}

View File

@ -440,7 +440,6 @@ simulated function UpdateInteractionMessage()
{ {
local KFPlayerController InstigatorKFPC; local KFPlayerController InstigatorKFPC;
local bool bCannotBeHealed; local bool bCannotBeHealed;
local KFPowerUp PowerUp;
//Update Interaction message //Update Interaction message
if (Instigator != none && Instigator.IsLocallyControlled() && Instigator.Health > 0) if (Instigator != none && Instigator.IsLocallyControlled() && Instigator.Health > 0)
@ -452,9 +451,8 @@ simulated function UpdateInteractionMessage()
return; return;
} }
//Check if we have a power up that disables healing //Check if the player can heal
PowerUp = InstigatorKFPC.GetPowerUp(); bCannotBeHealed = !InstigatorKFPC.CanUseHealObject();
bCannotBeHealed = PowerUp != none && !PowerUp.CanBeHealedWhilePowerUpIsActive;
if (bIsQuickHealMessageShowing) if (bIsQuickHealMessageShowing)
{ {

View File

@ -3406,4 +3406,120 @@ defaultproperties
//8614 Frost Fang | Burned Land //8614 Frost Fang | Burned Land
Skins.Add((Id=8614, Weapondef=class'KFWeapDef_Rifle_FrostShotgunAxe', MIC_1P=("WEP_SkinSet39_MAT.Wep_1stP_Frost_Shotgun_BurnedLand_MIC"), MIC_3P="WEP_SkinSet39_MAT.Wep_3stP_Frost_Shotgun_BurnedLand_MIC", MIC_Pickup="WEP_SkinSet39_MAT.Wep_3rdP_Frost_Shotgun_BurnedLand_Pickup_MIC")) Skins.Add((Id=8614, Weapondef=class'KFWeapDef_Rifle_FrostShotgunAxe', MIC_1P=("WEP_SkinSet39_MAT.Wep_1stP_Frost_Shotgun_BurnedLand_MIC"), MIC_3P="WEP_SkinSet39_MAT.Wep_3stP_Frost_Shotgun_BurnedLand_MIC", MIC_Pickup="WEP_SkinSet39_MAT.Wep_3rdP_Frost_Shotgun_BurnedLand_Pickup_MIC"))
//Neon Caulk n Burn
Skins.Add((Id=8654, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet40_MAT.neon_caulkburn.Neon_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_caulkburn.Neon_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_caulkburn.Neon_CaulkBurn_3P_Pickup_MIC"))
//Neon Crovel
Skins.Add((Id=8655, Weapondef=class'KFWeapDef_Crovel', MIC_1P=("WEP_SkinSet40_MAT.neon_crovel.Neon_Crovel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_crovel.Neon_Crovel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_crovel.Neon_Crovel_3P_Pickup_MIC"))
//Neon HX25
Skins.Add((Id=8656, Weapondef=class'KFWeapDef_HX25', MIC_1P=("WEP_SkinSet40_MAT.neon_hx25.Neon_HX25_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_hx25.Neon_HX25_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_hx25.Neon_HX25_3P_Pickup_MIC"))
//Neon MP5RAS
Skins.Add((Id=8657, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet40_MAT.neon_mp5ras.Neon_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_mp5ras.Neon_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_mp5ras.Neon_MP5RAS_3P_Pickup_MIC"))
//Neon 1858 Revolver
Skins.Add((Id=8658, Weapondef=class'KFWeapDef_Remington1858', MIC_1P=("WEP_SkinSet40_MAT.neon_remington1858.Neon_Remington1858_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_remington1858.Neon_Remington1858_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_remington1858.Neon_Remington1858_3P_Pickup_MIC"))
//Neon Eviscerator
Skins.Add((Id=8659, Weapondef=class'KFWeapDef_Eviscerator', MIC_1P=("WEP_SkinSet40_MAT.neon_sawblade.Neon_SawBlade_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_sawblade.Neon_SawBlade_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_sawblade.Neon_SawBlade_3P_Pickup_MIC"))
//Neon Berserker Knife
Skins.Add((Id=8660, Weapondef=class'KFWeapDef_Knife_Berserker', MIC_1P=("WEP_SkinSet40_MAT.neon_berserkerknife.Neon_BerserkerKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_berserkerknife.Neon_BerserkerKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_berserkerknife.Neon_BerserkerKnife_3P_Pickup_MIC"))
//Neon KF-BAR
Skins.Add((Id=8661, Weapondef=class'KFWeapDef_Knife_Commando', MIC_1P=("WEP_SkinSet40_MAT.neon_commandoknife.Neon_CommandoKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_commandoknife.Neon_CommandoKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_commandoknife.Neon_CommandoKnife_3P_Pickup_MIC"))
//Neon Demo Knife
Skins.Add((Id=8662, Weapondef=class'KFWeapDef_Knife_Demo', MIC_1P=("WEP_SkinSet40_MAT.neon_demoknife.Neon_DemoKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_demoknife.Neon_DemoKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_demoknife.Neon_DemoKnife_3P_Pickup_MIC"))
//Neon Firemans Knife
Skins.Add((Id=8663, Weapondef=class'KFWeapDef_Knife_Firebug', MIC_1P=("WEP_SkinSet40_MAT.neon_firebugknife.Neon_FirebugKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_firebugknife.Neon_FirebugKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_firebugknife.Neon_FirebugKnife_3P_Pickup_MIC"))
//Neon Gunslinger Knife
Skins.Add((Id=8664, Weapondef=class'KFWeapDef_Knife_Gunslinger', MIC_1P=("WEP_SkinSet40_MAT.neon_gunslingerknife.Neon_GunslingerKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_gunslingerknife.Neon_GunslingerKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_gunslingerknife.Neon_GunslingerKnife_3P_Pickup_MIC"))
//Neon HMTech-001 Scalpel
Skins.Add((Id=8665, Weapondef=class'KFWeapDef_Knife_Medic', MIC_1P=("WEP_SkinSet40_MAT.neon_medicknife.Neon_MedicKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_medicknife.Neon_MedicKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_medicknife.Neon_MedicKnife_3P_Pickup_MIC"))
//Neon Kukri
Skins.Add((Id=8666, Weapondef=class'KFWeapDef_Knife_Sharpshooter', MIC_1P=("WEP_SkinSet40_MAT.neon_sharpshooterknife.Neon_SharpshooterKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_sharpshooterknife.Neon_SharpshooterKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_sharpshooterknife.Neon_SharpshooterKnife_3P_Pickup_MIC"))
//Neon Support Knife
Skins.Add((Id=8667, Weapondef=class'KFWeapDef_Knife_Support', MIC_1P=("WEP_SkinSet40_MAT.neon_supportknife.Neon_SupportKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_supportknife.Neon_SupportKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_supportknife.Neon_SupportKnife_3P_Pickup_MIC"))
//Neon Gore Shiv
Skins.Add((Id=8668, Weapondef=class'KFWeapDef_Knife_Survivalist', MIC_1P=("WEP_SkinSet40_MAT.neon_survivalistknife.Neon_SurvivalistKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_survivalistknife.Neon_SurvivalistKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_survivalistknife.Neon_SurvivalistKnife_3P_Pickup_MIC"))
//Neon Tactical Knife
Skins.Add((Id=8669, Weapondef=class'KFWeapDef_Knife_SWAT', MIC_1P=("WEP_SkinSet40_MAT.neon_swatknife.Neon_SWATKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neon_swatknife.Neon_SWATKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neon_swatknife.Neon_SWATKnife_3P_Pickup_MIC"))
//NeonRGB Caulk n Burn
Skins.Add((Id=8670, Weapondef=class'KFWeapDef_CaulkBurn', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_caulkburn.NeonRGB_CaulkBurn_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_caulkburn.NeonRGB_CaulkBurn_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_caulkburn.NeonRGB_CaulkBurn_3P_Pickup_MIC"))
//NeonRGB Crovel
Skins.Add((Id=8671, Weapondef=class'KFWeapDef_Crovel', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_crovel.NeonRGB_Crovel_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_crovel.NeonRGB_Crovel_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_crovel.NeonRGB_Crovel_3P_Pickup_MIC"))
//NeonRGB HX25
Skins.Add((Id=8672, Weapondef=class'KFWeapDef_HX25', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_hx25.NeonRGB_HX25_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_hx25.NeonRGB_HX25_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_hx25.NeonRGB_HX25_3P_Pickup_MIC"))
//NeonRGB MP5RAS
Skins.Add((Id=8673, Weapondef=class'KFWeapDef_MP5RAS', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_mp5ras.NeonRGB_MP5RAS_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_mp5ras.NeonRGB_MP5RAS_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_mp5ras.NeonRGB_MP5RAS_3P_Pickup_MIC"))
//NeonRGB 1858 Revolver
Skins.Add((Id=8674, Weapondef=class'KFWeapDef_Remington1858', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_remington1858.NeonRGB_Remington1858_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_remington1858.NeonRGB_Remington1858_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_remington1858.NeonRGB_Remington1858_3P_Pickup_MIC"))
//NeonRGB Eviscerator
Skins.Add((Id=8675, Weapondef=class'KFWeapDef_Eviscerator', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_sawblade.NeonRGB_SawBlade_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_sawblade.NeonRGB_SawBlade_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_sawblade.NeonRGB_SawBlade_3P_Pickup_MIC"))
//NeonRGB Berserker Knife
Skins.Add((Id=8676, Weapondef=class'KFWeapDef_Knife_Berserker', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_berserkerknife.NeonRGB_BerserkerKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_berserkerknife.NeonRGB_BerserkerKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_berserkerknife.NeonRGB_BerserkerKnife_3P_Pickup_MIC"))
//NeonRGB KF-BAR
Skins.Add((Id=8677, Weapondef=class'KFWeapDef_Knife_Commando', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_commandoknife.NeonRGB_CommandoKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_commandoknife.NeonRGB_CommandoKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_commandoknife.NeonRGB_CommandoKnife_3P_Pickup_MIC"))
//NeonRGB Demo Knife
Skins.Add((Id=8678, Weapondef=class'KFWeapDef_Knife_Demo', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_demoknife.NeonRGB_DemoKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_demoknife.NeonRGB_DemoKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_demoknife.NeonRGB_DemoKnife_3P_Pickup_MIC"))
//NeonRGB Firemans Knife
Skins.Add((Id=8679, Weapondef=class'KFWeapDef_Knife_Firebug', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_firebugknife.NeonRGB_FirebugKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_firebugknife.NeonRGB_FirebugKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_firebugknife.NeonRGB_FirebugKnife_3P_Pickup_MIC"))
//NeonRGB Gunslinger Knife
Skins.Add((Id=8680, Weapondef=class'KFWeapDef_Knife_Gunslinger', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_gunslingerknife.NeonRGB_GunslingerKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_gunslingerknife.NeonRGB_GunslingerKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_gunslingerknife.NeonRGB_GunslingerKnife_3P_Pickup_MIC"))
//NeonRGB HMTech-001 Scalpel
Skins.Add((Id=8681, Weapondef=class'KFWeapDef_Knife_Medic', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_medicknife.NeonRGB_MedicKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_medicknife.NeonRGB_MedicKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_medicknife.NeonRGB_MedicKnife_3P_Pickup_MIC"))
//NeonRGB Kukri
Skins.Add((Id=8682, Weapondef=class'KFWeapDef_Knife_Sharpshooter', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_sharpshooterknife.NeonRGB_SharpshooterKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_sharpshooterknife.NeonRGB_SharpshooterKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_sharpshooterknife.NeonRGB_SharpshooterKnife_3P_Pickup_MIC"))
//NeonRGB Support Knife
Skins.Add((Id=8683, Weapondef=class'KFWeapDef_Knife_Support', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_supportknife.NeonRGB_SupportKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_supportknife.NeonRGB_SupportKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_supportknife.NeonRGB_SupportKnife_3P_Pickup_MIC"))
//NeonRGB Gore Shiv
Skins.Add((Id=8684, Weapondef=class'KFWeapDef_Knife_Survivalist', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_survivalistknife.NeonRGB_SurvivalistKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_survivalistknife.NeonRGB_SurvivalistKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_survivalistknife.NeonRGB_SurvivalistKnife_3P_Pickup_MIC"))
//NeonRGB Tactical Knife
Skins.Add((Id=8685, Weapondef=class'KFWeapDef_Knife_SWAT', MIC_1P=("WEP_SkinSet40_MAT.neonrgb_swatknife.NeonRGB_SWATKnife_1P_Mint_MIC"), MIC_3P="WEP_SkinSet40_MAT.neonrgb_swatknife.NeonRGB_SWATKnife_3P_Mint_MIC", MIC_Pickup="WEP_SkinSet40_MAT.neonrgb_swatknife.NeonRGB_SWATKnife_3P_Pickup_MIC"))
//GravityImploder Standard
Skins.Add((Id=8778, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_1P_Gravity_Imploder_MAT.Wep_1stP_Gravity_Imploder_MIC"), MIC_3P="WEP_3P_Gravity_Imploder_MAT.Wep_3rdP_Gravity_Imploder_MIC", MIC_Pickup="WEP_3p_Gravity_Imploder_MAT.Wep_3rdP_Gravity_Imploder_Pickup_MIC"))
//GravityImploder Area51
Skins.Add((Id=8779, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_SkinSet41_MAT.WEP_SkinSet_1stP_Gravity_Imploder_Area51_MIC"), MIC_3P="WEP_SkinSet41_MAT.Wep_SkinSet_3rdP_Gravity_Imploder_Area51_MIC", MIC_Pickup="WEP_SkinSet41_MAT.Wep_3rdP_Gravity_Imploder_Pickup_Area51_MIC"));
//GravityImploder Banzai
Skins.Add((Id=8780, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_SkinSet41_MAT.WEP_SkinSet_1stP_Gravity_Imploder_Banzai_MIC"), MIC_3P="WEP_SkinSet41_MAT.Wep_SkinSet_3rdP_Gravity_Imploder_Banzai_MIC", MIC_Pickup="WEP_SkinSet41_MAT.Wep_3rdP_Gravity_Imploder_Pickup_Banzai_MIC"));
//GravityImploder Jungle
Skins.Add((Id=8781, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_SkinSet41_MAT.WEP_SkinSet_1stP_Gravity_Imploder_Cambodia_MIC"), MIC_3P="WEP_SkinSet41_MAT.Wep_SkinSet_3rdP_Gravity_Imploder_Cambodia_MIC", MIC_Pickup="WEP_SkinSet41_MAT.Wep_3rdP_Gravity_Imploder_Pickup_Cambodia_MIC"));
//GravityImploder High Tech
Skins.Add((Id=8782, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_SkinSet41_MAT.WEP_SkinSet_1stP_Gravity_Imploder_HighTech_MIC"), MIC_3P="WEP_SkinSet41_MAT.Wep_SkinSet_3rdP_Gravity_Imploder_HighTech_MIC", MIC_Pickup="WEP_SkinSet41_MAT.Wep_3rdP_Gravity_Imploder_Pickup_HighTech_MIC"));
//GravityImploder Rust
Skins.Add((Id=8783, Weapondef=class'KFWeapDef_GravityImploder', MIC_1P=("WEP_SkinSet41_MAT.WEP_SkinSet_1stP_Gravity_Imploder_Rust_MIC"), MIC_3P="WEP_SkinSet41_MAT.Wep_SkinSet_3rdP_Gravity_Imploder_Rust_MIC", MIC_Pickup="WEP_SkinSet41_MAT.Wep_3rdP_Gravity_Imploder_Pickup_Rust_MIC"));
//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"));
} }

View File

@ -332,11 +332,20 @@ function float GetArmorDamageTypeModifier(class<DamageType> DT)
{ {
DamageModifier = FMax(Lerp(1.f, DamageModifier, GameResistancePct), 0.f); DamageModifier = FMax(Lerp(1.f, DamageModifier, GameResistancePct), 0.f);
} }
if(DT.default.ArmorDamageModifier != 1)
{
DamageModifier *= DT.default.ArmorDamageModifier;
}
return DamageModifier; return DamageModifier;
} }
} }
if(DT.default.ArmorDamageModifier != 1)
{
return DT.default.ArmorDamageModifier;
}
return 1.f; return 1.f;
} }

View File

@ -152,4 +152,5 @@ const STATID_ACHIEVE_BiolapseCollectibles = 4054;
const STATID_ACHIEVE_DesolationCollectibles = 4055; const STATID_ACHIEVE_DesolationCollectibles = 4055;
const STATID_ACHIEVE_HellmarkStationCollectibles = 4056; const STATID_ACHIEVE_HellmarkStationCollectibles = 4056;
const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057; const STATID_ACHIEVE_ElysiumEndlessWaveFifteen = 4057;
const STATID_ACHIEVE_Dystopia2029Collectibles = 4058;
/** `endif */ /** `endif */

View File

@ -0,0 +1,24 @@
//=============================================================================
// KFDT_Ballistic_GravityImploderImpact
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_GravityImploderImpact extends KFDT_Ballistic_Shell
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=750
KDeathVel=1500
StumblePower=250
KnockdownPower=50
GunHitPower=150
WeaponDef=class'KFWeapDef_GravityImploder'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
}

View File

@ -0,0 +1,23 @@
//=============================================================================
// KFDT_Ballistic_GravityImploderImpactAlt
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_GravityImploderImpactAlt extends KFDT_Ballistic_Shell
abstract
hidedropdown;
defaultproperties
{
KDamageImpulse=2000
KDeathUpKick=750
KDeathVel=1500
StumblePower=250
GunHitPower=150
WeaponDef=class'KFWeapDef_GravityImploder'
ModifierPerkList(0)=class'KFPerk_Demolitionist'
}

View File

@ -0,0 +1,46 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** Play damage type specific impact effects when taking damage */
static function PlayImpactHitEffects(KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator)
{
// Play burn effect when dead
if (P.bPlayedDeath && P.WorldInfo.TimeSeconds > P.TimeOfDeath)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Impact_AltFire'
OverrideImpactSound=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Hit_Surface'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=250
GunHitPower=120
MicrowavePower=25
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,46 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** Play damage type specific impact effects when taking damage */
static function PlayImpactHitEffects(KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator)
{
// Play burn effect when dead
if (P.bPlayedDeath && P.WorldInfo.TimeSeconds > P.TimeOfDeath)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_Microwave_Assault_EMIT.FX_Microwave_Assault_Impact'
OverrideImpactSound=AkEvent'WW_WEP_SA_DragonsBreath.Play_Bullet_DragonsBreath_Impact_Dirt'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=50
GunHitPower=60
MicrowavePower=50
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,47 @@
//=============================================================================
// KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged
//=============================================================================
// Sonic Boom impact damage for the HRG Sonic Gun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged extends KFDT_Ballistic_Rifle
abstract
hidedropdown;
/** Play damage type specific impact effects when taking damage */
static function PlayImpactHitEffects(KFPawn P, vector HitLocation, vector HitDirection, byte HitZoneIndex, optional Pawn HitInstigator)
{
// Play burn effect when dead
if (P.bPlayedDeath && P.WorldInfo.TimeSeconds > P.TimeOfDeath)
{
return;
}
super.PlayImpactHitEffects(P, HitLocation, HitDirection, HitZoneIndex, HitInstigator);
}
defaultproperties
{
OverrideImpactEffect=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Impact'
OverrideImpactSound=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Hit_Surface'
ArmorDamageModifier=1.5f
KDamageImpulse=0
KDeathUpKick=0
KDeathVel=0
RadialDamageImpulse=5000
bExtraMomentumZ=True
StumblePower=0
GunHitPower=30
MicrowavePower=75
bHasToSpawnMicrowaveFire=false
EffectGroup=FXG_MicrowaveBlast
bCanObliterate=true
bCanGib=true
ModifierPerkList(0)=class'KFPerk_Sharpshooter'
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

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

View File

@ -0,0 +1,16 @@
//=============================================================================
// KFDT_Bludgeon_HRG_SonicGun
//=============================================================================
// Killing Floor 2
// Copyright (C) 2017 Tripwire Interactive LLC
//=============================================================================
class KFDT_Bludgeon_HRG_SonicGun extends KFDT_Bludgeon_RifleButt
abstract
hidedropdown;
DefaultProperties
{
ModifierPerkList(0)=class'KFPerk_Survivalist'
//defaults
WeaponDef=class'KFWeapDef_HRG_SonicGun'
}

View File

@ -0,0 +1,33 @@
//=============================================================================
// KFDT_Explosive_GravityImploder
//=============================================================================
// Explosive damage type for the Gravity Imploder explosion
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFDT_Explosive_GravityImploder extends KFDT_Explosive
abstract
hidedropdown;
defaultproperties
{
bShouldSpawnPersistentBlood=true
// physics impact
//GibImpulseScale=0.9
//KDeathUpKick=1000
//KDeathVel=300
//RadialDamageImpulse=-1000
//KDamageImpulse=550
RadialDamageImpulse=-200
GibImpulseScale=0.85
KDeathUpKick=-200
KDeathVel=200
StumblePower=200
ModifierPerkList(0)=class'KFPerk_Demolitionist'
WeaponDef=class'KFWeapDef_GravityImploder'
}

View File

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

View File

@ -6,11 +6,15 @@
// Killing Floor 2 // Killing Floor 2
// Copyright (C) 2016 Tripwire Interactive LLC // Copyright (C) 2016 Tripwire Interactive LLC
//============================================================================= //=============================================================================
class KFDT_Freeze_FreezeThrower_IceShards extends KFDT_Freeze class KFDT_Freeze_FreezeThrower_IceShards extends KFDT_Ballistic_Shotgun
abstract; abstract;
defaultproperties defaultproperties
{ {
KDamageImpulse=500
KDeathUpKick=-500
KDeathVel=350
WeaponDef=class'KFWeapDef_FreezeThrower' WeaponDef=class'KFWeapDef_FreezeThrower'
FreezePower=0 FreezePower=0
StumblePower=25 StumblePower=25

View File

@ -11,16 +11,17 @@ class KFDT_Piercing_Crossbow extends KFDT_Piercing
abstract abstract
hidedropdown; hidedropdown;
var float HeadStunPower;
defaultproperties defaultproperties
{ {
KDamageImpulse=1500 KDamageImpulse=1500
KDeathUpKick=250 KDeathUpKick=250
KDeathVel=150 KDeathVel=150
KnockdownPower=20 KnockdownPower=20
StunPower=101 //90 HeadStunPower=1000 // Stun ensured when hit in the head
StunPower=30 // Stun used otherwise
StumblePower=250 StumblePower=250
GunHitPower=100 GunHitPower=100
MeleeHitPower=40 MeleeHitPower=40

View File

@ -0,0 +1,15 @@
//=============================================================================
// KFExplosion_GravityImplosion
//=============================================================================
// Implosive damage type for the Gravity Imploder "explosion"
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFExplosion_GravityImplosion extends KFExplosionActor;
defaultproperties
{
}

View File

@ -41,6 +41,8 @@ var byte WaveMax; // The "end" wave
var int WaveNum; // The wave we are currently in var int WaveNum; // The wave we are currently in
var bool bHumanDeathsLastWave; //Track this separate from player count in case someone dies and leaves var bool bHumanDeathsLastWave; //Track this separate from player count in case someone dies and leaves
var int ObjectiveSpawnDelay; // How long should the first wave be delayed if there is an active objective. var int ObjectiveSpawnDelay; // How long should the first wave be delayed if there is an active objective.
// The boss waves spams the WaveEnd functions, adding this to prevent it (was affecting seasonal events).
var protected transient bool bWaveStarted;
/** Whether this game mode should play music from the get-go (lobby) */ /** Whether this game mode should play music from the get-go (lobby) */
static function bool ShouldPlayMusicAtStart() static function bool ShouldPlayMusicAtStart()
@ -935,15 +937,17 @@ function ResetAllPickups()
/** Overridden to scale the number of active pickups by wave */ /** Overridden to scale the number of active pickups by wave */
function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups ) function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
{ {
NumPickups *= (float(WaveNum) / float(WaveMax)); if(NumPickups != 0)
// 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) )
{ {
NumPickups = 1; 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) )
{
NumPickups = 1;
}
} }
super.ResetPickups( PickupList, NumPickups ); super.ResetPickups( PickupList, NumPickups );
} }
@ -1071,6 +1075,8 @@ function WaveStarted()
//So the server browser can have our new wave information //So the server browser can have our new wave information
UpdateGameSettings(); UpdateGameSettings();
bWaveStarted = true;
} }
/** Do something when there are no AIs left */ /** Do something when there are no AIs left */
@ -1111,6 +1117,9 @@ function WaveEnded(EWaveEndCondition WinCondition)
local int i; local int i;
local KFPlayerController KFPC; local KFPlayerController KFPC;
if(!bWaveStarted)
return;
if (WorldInfo.NetMode == NM_DedicatedServer) if (WorldInfo.NetMode == NM_DedicatedServer)
{ {
scripttrace(); scripttrace();
@ -1182,6 +1191,7 @@ function WaveEnded(EWaveEndCondition WinCondition)
// To allow any statistics that are recorded on the very last zed killed at the end of the wave, // To allow any statistics that are recorded on the very last zed killed at the end of the wave,
// wait a single frame to allow them to finalize. // wait a single frame to allow them to finalize.
SetTimer( WorldInfo.DeltaSeconds, false, nameOf(Timer_FinalizeEndOfWaveStats) ); SetTimer( WorldInfo.DeltaSeconds, false, nameOf(Timer_FinalizeEndOfWaveStats) );
bWaveStarted=false;
} }
/** All stats should be finalized here */ /** All stats should be finalized here */
@ -1822,7 +1832,8 @@ DefaultProperties
AARDisplayDelay=15 AARDisplayDelay=15
bCanPerkAlwaysChange=false bCanPerkAlwaysChange=false
MaxGameDifficulty=3 MaxGameDifficulty=3
bWaveStarted=false
ObjectiveSpawnDelay=5 ObjectiveSpawnDelay=5
SpawnManagerClasses(0)=class'KFGame.KFAISpawnManager_Short' SpawnManagerClasses(0)=class'KFGame.KFAISpawnManager_Short'
@ -1871,35 +1882,35 @@ DefaultProperties
// Short Wave // Short Wave
LateArrivalStarts(0)={( LateArrivalStarts(0)={(
StartingDosh[0]=550, StartingDosh[0]=700, //550
StartingDosh[1]=650, StartingDosh[1]=850, //650
StartingDosh[2]=1200, StartingDosh[2]=1650, //1200
StartingDosh[3]=1500 StartingDosh[3]=2200 //1500
)} )}
// Normal Wave // Normal Wave
LateArrivalStarts(1)={( LateArrivalStarts(1)={(
StartingDosh[0]=450, StartingDosh[0]=600, //450
StartingDosh[1]=600, StartingDosh[1]=800, //600
StartingDosh[2]=750, StartingDosh[2]=1000, //750
StartingDosh[3]=800, StartingDosh[3]=1100, //800
StartingDosh[4]=1100, StartingDosh[4]=1500, //1100
StartingDosh[5]=1400, StartingDosh[5]=2000, //1400
StartingDosh[6]=1500, StartingDosh[6]=2200, //1500
StartingDosh[7]=1600 StartingDosh[7]=2400 //1600
)} )}
// Long Wave // Long Wave
LateArrivalStarts(2)={( LateArrivalStarts(2)={(
StartingDosh[0]=450, StartingDosh[0]=600, //450
StartingDosh[1]=550, StartingDosh[1]=700, //550
StartingDosh[2]=750, StartingDosh[2]=1000, //750
StartingDosh[3]=1000, StartingDosh[3]=1300, //1000
StartingDosh[4]=1200, StartingDosh[4]=1650, //1200
StartingDosh[5]=1300, StartingDosh[5]=1800, //1300
StartingDosh[6]=1400, StartingDosh[6]=2000, //1400
StartingDosh[7]=1500, StartingDosh[7]=2200, //1500
StartingDosh[8]=1600, StartingDosh[8]=2400, //1600
StartingDosh[9]=1600 StartingDosh[9]=2400 //1600
)} )}
} }

View File

@ -129,6 +129,13 @@ function SetPickupItemList()
//So many loops //So many loops
foreach AllActors(class'KFPickupFactory_Item', ItemFactory) foreach AllActors(class'KFPickupFactory_Item', ItemFactory)
{ {
//we dont want item pickups, so kiss them goodbye
if(OutbreakEvent.ActiveEvent.OverrideItemPickupModifier == 0)
{
ItemFactory.ShutDown();
ItemFactory.ItemPickups.Remove(0, ItemFactory.ItemPickups.Length);
continue;
}
foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem) foreach OutbreakEvent.ActiveEvent.TraderWeaponList.SaleItems(TraderItem)
{ {
for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx) for (Idx = ItemFactory.ItemPickups.Length - 1; Idx >= 0; --Idx)
@ -211,15 +218,81 @@ function ResetPermanentZed()
} }
} }
function float GetAdjustedAIDoshValue( class<KFPawn_Monster> MonsterClass )
{
return super.GetAdjustedAIDoshValue(MonsterClass) * OutbreakEvent.ActiveEvent.DoshOnKillGlobalModifier;
}
protected function ScoreMonsterKill( Controller Killer, Controller Monster, KFPawn_Monster MonsterPawn )
{
super.ScoreMonsterKill(Killer, Monster, MonsterPawn);
if(OutbreakEvent.ActiveEvent.bHealAfterKill)
{
if( MonsterPawn != none && MonsterPawn.DamageHistory.Length > 0 )
{
HealAfterKilling( MonsterPawn, Killer );
}
}
}
/** Heal players after a Zed was killed, based in more heal to the player that was the killer and less heal to the players that damaged the Zed */
function HealAfterKilling(KFPawn_Monster MonsterPawn , Controller Killer)
{
local int i;
local KFPlayerController KFPC;
local KFPlayerReplicationInfo DamagerKFPRI;
local array<DamageInfo> DamageHistory;
local array<KFPlayerController> Attackers;
local KFPawn_Human PawnHuman;
DamageHistory = MonsterPawn.DamageHistory;
for ( i = 0; i < DamageHistory.Length; i++ )
{
if( DamageHistory[i].DamagerController != none
&& DamageHistory[i].DamagerController.bIsPlayer
&& DamageHistory[i].DamagerPRI.GetTeamNum() == 0
&& DamageHistory[i].DamagerPRI != none )
{
DamagerKFPRI = KFPlayerReplicationInfo(DamageHistory[i].DamagerPRI);
if( DamagerKFPRI != none )
{
KFPC = KFPlayerController(DamagerKFPRI.Owner);
if( KFPC != none )
{
if(Attackers.Find(KFPC) < 0)
{
PawnHuman = KFPawn_Human(KFPC.Pawn);
Attackers.AddItem(KFPC);
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 )
{
KFPC.ReceivePowerUp(class'KFPowerUp_HellishRage_NoCostHeal');
}
}
else
{
`Log("Heal by Assistance: "$MonsterPawn.HealByAssistance);
PawnHuman.HealDamageForce(MonsterPawn.HealByAssistance, KFPC, class'KFDT_Healing', false, false );
}
}
}
}
}
}
}
function StartMatch() function StartMatch()
{ {
super.StartMatch(); super.StartMatch();
//Set timer for global ticking damage
if (OutbreakEvent.ActiveEvent.GlobalDamageTickRate > 0.f && OutbreakEvent.ActiveEvent.GlobalDamageTickAmount > 0.f)
{
SetTimer(OutbreakEvent.ActiveEvent.GlobalDamageTickRate, true, 'ApplyGlobalDamage', OutbreakEvent);
}
} }
function CreateDifficultyInfo(string Options) function CreateDifficultyInfo(string Options)
@ -321,6 +394,8 @@ function TickZedTime( float DeltaTime )
function WaveEnded(EWaveEndCondition WinCondition) function WaveEnded(EWaveEndCondition WinCondition)
{ {
local KFPawn_Human Pawn;
super.WaveEnded(WinCondition); super.WaveEnded(WinCondition);
if (OutbreakEvent.ActiveEvent.bPermanentZedTime && ZedTimeRemaining > ZedTimeBlendOutTime) if (OutbreakEvent.ActiveEvent.bPermanentZedTime && ZedTimeRemaining > ZedTimeBlendOutTime)
@ -328,6 +403,16 @@ function WaveEnded(EWaveEndCondition WinCondition)
ClearZedTimePCTimers(); ClearZedTimePCTimers();
ZedTimeRemaining = ZedTimeBlendOutTime; ZedTimeRemaining = ZedTimeBlendOutTime;
} }
if (OutbreakEvent.ActiveEvent.bHealPlayerAfterWave)
{
foreach WorldInfo.AllPawns(class'KFPawn_Human', Pawn)
{
Pawn.Health = Pawn.HealthMax;
}
}
DisableGlobalDamage();
} }
function ClearZedTimePCTimers() function ClearZedTimePCTimers()
@ -360,6 +445,24 @@ function EndOfMatch(bool bVictory)
function StartWave() function StartWave()
{ {
super.StartWave(); super.StartWave();
// Stop Global Damage for boss wave
if (!OutbreakEvent.ActiveEvent.bApplyGlobalDamageBossWave && WaveNum == WaveMax)
{
DisableGlobalDamage();
}
// In case there was a previous boss wave. Not sure if possible
else if (OutbreakEvent.ActiveEvent.GlobalDamageTickRate > 0.f && OutbreakEvent.ActiveEvent.GlobalDamageTickAmount > 0.f)
{
if(!IsTimerActive('EnableGlobalDamage', self))
{
SetTimer(OutbreakEvent.ActiveEvent.DamageDelayAfterWaveStarted, false, 'EnableGlobalDamage', self);
}
// Check if we are in the zed frustration time to stop applying damage
SetTimer(1.0f, true, 'CheckForZedFrustrationMode', self);
}
if (OutbreakEvent.ActiveEvent.bPermanentZedTime) if (OutbreakEvent.ActiveEvent.bPermanentZedTime)
{ {
//If we're a boss wave, wait until the camera animation is going //If we're a boss wave, wait until the camera animation is going
@ -378,6 +481,40 @@ function StartWave()
{ {
SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave)); SetTimer(OutbreakEvent.ActiveEvent.AdditionalBossWaveStartDelay, true, nameof(SpawnBossWave));
} }
}
function EnableGlobalDamage()
{
MyKFGRI.SetGlobalDamage(true);
SetTimer(OutbreakEvent.ActiveEvent.GlobalDamageTickRate, true, 'ApplyGlobalDamage', OutbreakEvent);
}
function DisableGlobalDamage()
{
MyKFGRI.SetGlobalDamage(false);
if (IsTimerActive('ApplyGlobalDamage', OutbreakEvent))
{
ClearTimer('ApplyGlobalDamage', OutbreakEvent);
}
if (IsTimerActive('EnableGlobalDamage', self))
{
ClearTimer('EnableGlobalDamage', self);
}
}
function CheckForZedFrustrationMode()
{
if(IsTimerActive('ApplyGlobalDamage', OutbreakEvent))
{
if(class'KFAIController'.default.FrustrationThreshold > 0 && MyKFGRI.AIRemaining <= class'KFAIController'.default.FrustrationThreshold)
{
DisableGlobalDamage();
ClearTimer('CheckForZedFrustrationMode', self);
}
}
} }
function BossCameraZedTimeRecheck() function BossCameraZedTimeRecheck()
@ -477,6 +614,8 @@ function InitAllPickups()
{ {
NumWeaponPickups = ItemPickups.Length * (OutbreakEvent.ActiveEvent.OverrideItemPickupModifier >= 0.f ? OutbreakEvent.ActiveEvent.OverrideItemPickupModifier : DifficultyInfo.GetItemPickupModifier()); 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()); 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(`__TW_SDK_)
if( BaseMutator != none ) if( BaseMutator != none )
@ -528,6 +667,7 @@ function ResetPickups( array<KFPickupFactory> PickupList, int NumPickups )
else if (OutbreakEvent.ActiveEvent.WaveItemPickupModifiers.Length >= WaveMax && KFPickupFactory_Item(PickupList[0]) != none) else if (OutbreakEvent.ActiveEvent.WaveItemPickupModifiers.Length >= WaveMax && KFPickupFactory_Item(PickupList[0]) != none)
{ {
NumPickups *= OutbreakEvent.ActiveEvent.WaveItemPickupModifiers[WaveNum]; NumPickups *= OutbreakEvent.ActiveEvent.WaveItemPickupModifiers[WaveNum];
if(OutbreakEvent.ActiveEvent.OverrideItemPickupModifier == 0) NumPickups = 0;
super(KFGameInfo).ResetPickups(PickupList, NumPickups); super(KFGameInfo).ResetPickups(PickupList, NumPickups);
} }
//Otherwise, use normal path //Otherwise, use normal path
@ -560,7 +700,25 @@ function bool AllowPrimaryWeapon(string ClassPath)
{ {
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item) foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
{ {
if (Item.ClassName == name(ClassPath)) if ( name(Item.WeaponDef.default.WeaponClassPath) == name(ClassPath) )
{
return true;
}
}
return false;
}
return true;
}
/** Whether or not a specific secondary weapon is allowed. Called at player spawn time while setting inventory. */
function bool AllowSecondaryWeapon(string ClassPath)
{
local STraderItem Item;
if (OutbreakEvent.ActiveEvent.SpawnWeaponList != none && OutbreakEvent.ActiveEvent.bSpawnWeaponListAffectsSecondaryWeapons)
{
foreach OutbreakEvent.ActiveEvent.SpawnWeaponList.SaleItems(Item)
{
if ( name(Item.WeaponDef.default.WeaponClassPath) == name(ClassPath) )
{ {
return true; return true;
} }
@ -580,6 +738,27 @@ function int AdjustStartingGrenadeCount(int CurrentCount)
return CurrentCount; return CurrentCount;
} }
/** Allows gametype to validate a perk for the current match */
function bool IsPerkAllowed(class<KFPerk> PerkClass)
{
Local int index;
if(OutbreakEvent.ActiveEvent.PerksAvailableList.length == 0)
{
return true;
}
for( index=0 ; index<OutbreakEvent.ActiveEvent.PerksAvailableList.length ; index++)
{
if(OutbreakEvent.ActiveEvent.PerksAvailableList[index] == PerkClass)
{
return true;
}
}
return false;
}
function RestartPlayer(Controller NewPlayer) function RestartPlayer(Controller NewPlayer)
{ {
local KFPawn_Human KFPH; local KFPawn_Human KFPH;
@ -609,6 +788,7 @@ function DoDeathExplosion(Pawn DeadPawn, KFGameExplosion ExplosionTemplate, clas
} }
} }
defaultproperties defaultproperties
{ {
//Overrides //Overrides

View File

@ -100,7 +100,7 @@ defaultproperties
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'), (ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'), (ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.PawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster'),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',bStartEnraged=true,bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.BigPawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster') (ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',bStartEnraged=true,bExplosiveDeath=true,ExplosionTemplate=KFGameExplosion'GP_Weekly_ARCH.BigPawnExplosionTemplate',ExplosionIgnoreClass=class'KFPawn_Monster')
)}, )}
)} )}
//Zombies //Zombies
@ -310,9 +310,104 @@ defaultproperties
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0), (ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0), (ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0) (ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',BeefcakeScaleIncreases=(0.01,0.01,0.01,0.01),MaxBeefcake=1.25,BeefcakeHealthIncreases=(0.0,0.0,0.0,0.0),MaxBeefcakeHealth=1.0)
)}, )}
)} )}
//Blood Thirst
SetEvents[8]={(
EventDifficulty = 1, //2
GameLength = GL_Normal,
GlobalDamageTickRate = 2.0,
GlobalDamageTickAmount = 6.0, //5.0,
bHealAfterKill = true,
bCannotBeHealed = true,
bGlobalDamageAffectsShield = false,
bHealPlayerAfterWave = true,
bApplyGlobalDamageBossWave = false,
DamageDelayAfterWaveStarted = 10.0f,
SpawnRateMultiplier=6.0, //8.0,
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=1.0,DamageDealtScale=0.75)
)},
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealByKill=12,HealByAssistance=8, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedStalker',HealByKill=7,HealByAssistance=5, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawler',HealByKill=5,HealByAssistance=3, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedCrawlerKing',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealByKill=7,HealByAssistance=5, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealByKill=16, HealByAssistance=11, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHusk',HealByKill=12,HealByAssistance=8, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_EMP',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Laser',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedDAR_Rocket',HealByKill=10,HealByAssistance=7, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealByKill=50,HealByAssistance=35, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealByKill=60,HealByAssistance=42, InitialGroundSpeedModifierScale=1.20),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealByKill=36,HealByAssistance=25, InitialGroundSpeedModifierScale=1.20)
)}
)}
//Coliseum
SetEvents[9]={(
EventDifficulty=3,
GameLength=GL_Normal,
PerksAvailableList=(class'KFPerk_Berserker'),
SpawnWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.ColliseumWeeklySpawnList',
bSpawnWeaponListAffectsSecondaryWeapons=true,
TraderWeaponList=KFGFxObject_TraderItems'GP_Trader_ARCH.ColliseumWeeklyTraderList',
bColliseumSkillConditionsActive=true,
bModifyZedTimeOnANearZedKill=true,
ZedTimeOnANearZedKill=0.6,
PickupResetTime=PRS_Wave,
OverrideItemPickupModifier=0,
DoshOnKillGlobalModifier=0.7,
SpawnRateMultiplier=2.0,
WaveAICountScale=(0.75, 0.7, 0.65, 0.6, 0.55, 0.5),
ZedsToAdjust={(
(ClassToAdjust=class'KFGameContent.KFPawn_ZedPatriarch',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedMatriarch',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedHans',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundKing',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloatKing',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedScrake',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpound',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedFleshpoundMini',HealthScale=0.75,DamageDealtScale=0.6),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefast',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedGorefastDualBlade',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Cyst',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Alpha',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_AlphaKing',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedClot_Slasher',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedBloat',HealthScale=1.0,DamageDealtScale=0.75),
(ClassToAdjust=class'KFGameContent.KFPawn_ZedSiren',HealthScale=1.0,DamageDealtScale=0.75)
)},
SpawnReplacementList={(
(SpawnEntry=AT_AlphaClot,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=0.1),
(SpawnEntry=AT_SlasherClot,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=0.1),
(SpawnEntry=AT_Crawler,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=1.0),
(SpawnEntry=AT_Stalker,NewClass=(class'KFGameContent.KFPawn_ZedGorefast'),PercentChance=1.0),
(SpawnEntry=AT_Bloat,NewClass=(class'KFGameContent.KFPawn_ZedFleshpoundMini'),PercentChance=0.5),
(SpawnEntry=AT_Siren,NewClass=(class'KFGameContent.KFPawn_ZedFleshpoundMini'),PercentChance=0.5),
(SpawnEntry=AT_Husk,NewClass=(class'KFGameContent.KFPawn_ZedScrake'),PercentChance=1.0),
(SpawnEntry=AT_GoreFast,NewClass=(class'KFGameContent.KFPawn_ZedGorefastDualBlade'),PercentChance=0.3),
(SpawnEntry=AT_Scrake,NewClass=(class'KFGameContent.KFPawn_ZedFleshpound'),PercentChance=0.5)
)}
)}
//Test events from here down. These don't end up in the regular rotation. //Test events from here down. These don't end up in the regular rotation.
// The override ID starts from one higher than the last SetEvents entry above. // The override ID starts from one higher than the last SetEvents entry above.
// Ex: Big head = 7, Horde = 8 // Ex: Big head = 7, Horde = 8

View File

@ -415,7 +415,9 @@ DefaultProperties
Begin Object Name=KFPawnSkeletalMeshComponent Begin Object Name=KFPawnSkeletalMeshComponent
// Enabling kinematic for physics interaction while alive. (see also MinDistFactorForKinematicUpdate) // Enabling kinematic for physics interaction while alive. (see also MinDistFactorForKinematicUpdate)
bUpdateKinematicBonesFromAnimation=true bUpdateKinematicBonesFromAnimation=true
End Object // Beam weapons (microwave gun, flamey things, etc.) won't hit his head without this
BlockNonZeroExtent=true
End Object
// --------------------------------------------- // ---------------------------------------------
// Stats // Stats

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) if (ShieldHealthPctByte == 0)
{ {

View File

@ -26,18 +26,18 @@ defaultproperties
DoshValue=75 //200 //25 //50 DoshValue=75 //200 //25 //50
// Stats // Stats
XPValues(0)=17 XPValues(0)=17
XPValues(1)=22 XPValues(1)=22
XPValues(2)=30 XPValues(2)=30
XPValues(3)=34 XPValues(3)=34
Begin Object Name=MeleeHelper_0 Begin Object Name=MeleeHelper_0
BaseDamage=49.f BaseDamage=49.f
MaxHitRange=250.f MaxHitRange=250.f
MomentumTransfer=55000.f MomentumTransfer=55000.f
MyDamageType=class'KFDT_Bludgeon_Fleshpound' MyDamageType=class'KFDT_Bludgeon_Fleshpound'
End Object End Object
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(0.62))) DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(0.62)))

View File

@ -692,6 +692,9 @@ function SetBattlePhase(int Phase)
ArmorInfo.ExplodeArmor(HEAD_ARMOR_IDX); ArmorInfo.ExplodeArmor(HEAD_ARMOR_IDX);
ArmorInfo.ExplodeArmor(CLAW_ARMOR_IDX); ArmorInfo.ExplodeArmor(CLAW_ARMOR_IDX);
ArmorInfo.UpdateArmorUI(); ArmorInfo.UpdateArmorUI();
// Forcing armor to be updated.
OnArmorZoneStatusUpdated();
} }
DoStumble(); DoStumble();

View File

@ -163,6 +163,24 @@ simulated function SpawnFlightEffects()
} }
} }
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
Explode(HitLocation, HitNormal);
}
}
Super.SyncOriginalLocation();
}
defaultproperties defaultproperties
{ {
Physics=PHYS_Falling Physics=PHYS_Falling

View File

@ -280,26 +280,7 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) && ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0))) if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) && ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{ {
//for (Index = 0; Index < vActorsTouched.Length; Index++) if( LastTouched.Actor == Other && TouchTimeThreshhold > 0 && `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
//{
// if(vActorsTouched[Index] == Other)
// {
// return;
// }
//}
//if(Other == LastActorTouched)
//{
// return;
//}
//LastActorTouched = Other;
//bForceNetUpdate=true;
//vActorsTouched.AddItem(Other);
// Don't touch the same actor multiple time's immediately after just
// touching it if the TouchTimeThreshhold is set to greater than 0.
// This was causing projectiles just to "stop" sometimes when hitting
// dead/ragdolled pawns because it was counting as multiple penetrations
if( LastTouched.Actor == Other && TouchTimeThreshhold > 0
&& `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
{ {
return; return;
} }
@ -311,13 +292,10 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
{ {
ProcessBulletTouch(Other, HitLocation, HitNormal); ProcessBulletTouch(Other, HitLocation, HitNormal);
} }
// Reflect off Wall w/damping but allow penetration if the pawn is dead
//if(KFPawn_Monster(Other) == None || KFPawn_Monster(Other).Health > 0) VNorm = (Velocity dot HitNormal) * HitNormal;
//{ Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
VNorm = (Velocity dot HitNormal) * HitNormal; Speed = VSize(Velocity);
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
//}
} }
else if (!bDud && !bIsTimedExplosive) else if (!bDud && !bIsTimedExplosive)
{ {
@ -350,7 +328,6 @@ simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNorma
StopSimulating(); StopSimulating();
} }
} }
simulated protected function StopSimulating() simulated protected function StopSimulating()
@ -370,6 +347,35 @@ simulated protected function StopSimulating()
} }
} }
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
ServerForceExplosion();
}
}
Super.SyncOriginalLocation();
}
reliable server function ServerForceExplosion()
{
local vector ExplosionNormal;
if (Instigator.Role == ROLE_Authority && !bHasExploded && !bHasDisintegrated)
{
ExplosionNormal = vect(0,0,1) >> Rotation;
CallExplode(Location, ExplosionNormal);
}
}
defaultproperties defaultproperties
{ {
TouchTimeThreshhold = 60.0f TouchTimeThreshhold = 60.0f
@ -392,6 +398,10 @@ defaultproperties
DampenFactorParallel=0 DampenFactorParallel=0
WallHitDampenFactor=0.5 WallHitDampenFactor=0.5
WallHitDampenFactorParallel=0.5 WallHitDampenFactorParallel=0.5
bNetTemporary=False
NetPriority=5
NetUpdateFrequency=200
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
bUseClientSideHitDetection=true bUseClientSideHitDetection=true

View File

@ -0,0 +1,188 @@
//=============================================================================
// KFProj_Grenade_GravityImploder
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_Grenade_GravityImploder extends KFProj_BallisticExplosive
hidedropdown;
/* 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)
{
super.BeginState(PrevStateName);
if (Role == ROLE_Authority)
{
SetTimer(DetonationTime, false, nameOf(Timer_Detonate));
}
}
}
simulated state VortexState
{
simulated event BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
ClearTimer(nameof(Timer_Detonate));
bVortexActive = true;
if (Role == ROLE_Authority)
{
SetTimer(VortexDuration, false, 'Timer_EndVortex');
}
}
simulated event Tick(float DeltaTime)
{
local float ImpulseModifier;
if(bVortexActive && (WorldInfo.NetMode == NM_Client || WorldInfo.NetMode == NM_Standalone))
{
// ImpulseModifier = (bReduceGibImpulseOnTick) ? (1.0f - AccumulatedTime / Lifetime) : 1.0f;
ImpulseModifier = 1.0f;
RadialImpulseComponent.ImpulseRadius = VortexRadius;
RadialImpulseComponent.ImpulseStrength = VortexImpulseStrength * ImpulseModifier;
RadialImpulseComponent.bVelChange = true;
RadialImpulseComponent.ImpulseFalloff = RIF_Constant;
RadialImpulseComponent.FireImpulse(Location);
}
}
}
/**
* Set the initial velocity and cook time
*/
simulated event PostBeginPlay()
{
Super.PostBeginPlay();
AdjustCanDisintigrate();
GotoState('GrenadeState');
}
simulated function Timer_Detonate()
{
Detonate();
}
simulated function Detonate()
{
Explode(Location, vect(0,0,1) >> Rotation);
}
simulated function Explode(vector HitLocation, vector HitNormal)
{
super.Explode(HitLocation, HitNormal);
GotoState('VortexState');
}
simulated function Timer_EndVortex()
{
bVortexActive = false;
DeferredDestroy(0.15);
}
/** 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) );
}
}
defaultproperties
{
TouchTimeThreshhold = 60.0f
Physics=PHYS_Falling
Speed=3200
MaxSpeed=3200
TerminalVelocity=3200
GravityScale=1.0
LifeSpan=0.f
bWarnAIWhenFired=true
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'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion_Concussive_Force'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=0,G=25,B=250,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=ImploTemplate0
Damage=350 //150
DamageRadius=375 //425
DamageFalloffExponent=0.2 //0.25
DamageDelay=0.f
MomentumTransferScale=-10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_GravityImploder'
KnockDownStrength=0
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Yellow_Explosion'
ExplosionSound=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Grenade_Yellow_Implosion'
// 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=ImploTemplate0
bIsTimedExplosive=false;
DetonationTime=5.0
VortexRadius=450
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,584 @@
//=============================================================================
// KFProj_Grenade_GravityImploderAlt
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_Grenade_GravityImploderAlt extends KFProj_BallisticExplosive
hidedropdown;
/** Factor added to the rolling speed of the ball when bouncing **/
var(Projectile) float RollingFactor;
/** Indicates that the ball hit the wall and is doing rolling animations **/
var transient bool bIsRolling;
/** Amount of roll stored for this cannonball **/
var transient float CurrentRoll;
var bool bHasAlreadyBounced;
/** Collider **/
var Object Collider;
/** Time before starting the implosion effect **/
var float PreparationTime;
/** Vortex params. */
var float VortexDuration;
var float VortexTime;
var float VortexRadius;
var float VortexAbsorptionStrength;
var float VortexElevationStrength;
var bool bVortexReduceImpulseOnDist;
var protected transient bool bFirstAbsorption;
var protected transient vector VortexLocation;
var protected vector VortexNormal;
var protected KFImpactEffectInfo VortexImpactEffects;
simulated state PreparingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
SetTimer( PreparationTime, false, nameOf(Timer_Ready) );
}
simulated event Tick(float DeltaTime)
{
local vector RollDelta;
local rotator NewRotation;
// Let's roll (only in the client)
if ( bIsRolling && WorldInfo.NetMode != NM_DedicatedServer && Physics != PHYS_None && (Velocity.X != 0 || Velocity.Y != 0) )
{
CurrentRoll -= (Abs(Velocity.X) + Abs(Velocity.Y)) * DeltaTime * RollingFactor;
RollDelta = ((vect(1, 0 , 0) * (Velocity.X)) + (vect(0, 1, 0) * (Velocity.Y) ));
NewRotation = Rotator(RollDelta);
NewRotation.pitch += CurrentRoll;
SetRotation(NewRotation);
}
Super.Tick(DeltaTime);
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
VortexNormal = HitNormal;
ProcessRebound(HitNormal, Wall, WallComp);
if( !bDud && !bIsTimedExplosive )
{
Super.HitWall(HitNormal, Wall, WallComp);
}
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
local bool bWantsClientSideDudHit;
local float TraveledDistance;
local Vector VNorm;
//local int Index;
// If we collided with a Siren shield, let the shield code handle touches
if( Other.IsA('KFTrigger_SirenProjectileShield') )
{
return;
}
if ( !bCollideWithTeammates && Pawn(Other) != None )
{
// Don't hit teammates
if( Other.GetTeamNum() == GetTeamNum() )
{
return;
}
}
// Need to do client side dud hits if this is a client
if( Instigator != none && Instigator.Role < ROLE_Authority )
{
bWantsClientSideDudHit = true;
}
TraveledDistance = (`TimeSince(CreationTime) * Speed);
TraveledDistance *= TraveledDistance;
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) && ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{
// Don't touch the same actor multiple time's immediately after just
// touching it if the TouchTimeThreshhold is set to greater than 0.
// This was causing projectiles just to "stop" sometimes when hitting
// dead/ragdolled pawns because it was counting as multiple penetrations
if( LastTouched.Actor == Other && TouchTimeThreshhold > 0
&& `TimeSince(LastTouched.Time) <= TouchTimeThreshhold )
{
return;
}
//TODO: Add an impact sound here
SetIsDud(bWantsClientSideDudHit, HitNormal);
if (Other != Instigator && !Other.bStatic && Other.GetTeamNum() != GetTeamNum() && !CheckRepeatingTouch(Other))
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
// Reflect off Wall w/damping but allow penetration if the pawn is dead
//if(KFPawn_Monster(Other) == None || KFPawn_Monster(Other).Health > 0)
//{
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * DampenFactor + (Velocity - VNorm) * DampenFactorParallel;
Speed = VSize(Velocity);
//}
}
else if (!bDud && !bIsTimedExplosive)
{
// Process impact hits
if (Other != Instigator && !Other.bStatic)
{
// check/ignore repeat touch events
if( !CheckRepeatingTouch(Other) && Other.GetTeamNum() != GetTeamNum())
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
}
if( WorldInfo.NetMode == NM_Standalone ||
(WorldInfo.NetMode == NM_ListenServer && Instigator != none && Instigator.IsLocallyControlled()) )
{
Super.ProcessTouch( Other, HitLocation, HitNormal );
return;
}
if( Owner != none && KFWeapon( Owner ) != none && Instigator != none )
{
if( Instigator.Role < ROLE_Authority && Instigator.IsLocallyControlled() )
{
KFWeapon(Owner).HandleClientProjectileExplosion(HitLocation, self);
Super.ProcessTouch( Other, HitLocation, HitNormal );
return;
}
}
}
}
}
simulated state WaitingToImplode
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
}
simulated event HitWall(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
if (HitNormal Dot vect(0,0,1) > 0.5f)
{
GotoState('ImplodingState');
return;
}
ProcessRebound(HitNormal, Wall, WallComp);
if(!bDud && !bIsTimedExplosive)
{
Super.HitWall(HitNormal, Wall, WallComp);
}
}
simulated function Tick(float Delta)
{
if (vSize(Velocity) < 0.05f)
{
GotoState('ImplodingState');
return;
}
super.Tick(Delta);
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
// Prevent default funcionality;
super.ProcessTouch(Other, HitLocation, HitNormal);
}
}
simulated state ImplodingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
StopSimulating();
AdjustVortexForPerk();
if ( WorldInfo.NetMode != NM_Client )
{
Velocity=vect(0,0,0);
Acceleration=vect(0,0,0);
RotationRate=rot(0,0,0);
GravityScale=0.0;
bFirstAbsorption=true;
VortexTime=0.0f;
SetTimer(VortexDuration, false, nameOf(Detonation_Ready) );
}
VortexLocation = Location + vect(0,0,1) * 125;
// Start VGC
StartVortexVFX();
}
simulated function StartVortexVFX()
{
if(VortexImpactEffects != None)
{
if(VortexImpactEffects.DefaultImpactEffect.ParticleTemplate != None)
{
WorldInfo.MyEmitterPool.SpawnEmitter(VortexImpactEffects.DefaultImpactEffect.ParticleTemplate, VortexLocation, rotator(VortexNormal));
}
if(VortexImpactEffects.DefaultImpactEffect.Sound != None)
{
PlaySoundBase(VortexImpactEffects.DefaultImpactEffect.Sound, true,,, VortexLocation);
}
}
}
simulated function EndState(Name NextStateName)
{
super.EndState(NextStateName);
}
simulated event Tick(float DeltaTime)
{
Super.Tick(DeltaTime);
// Avoids to be moved in case there's any force applied.
SetLocation(VortexLocation);
`if(`notdefined(ShippingPC))
if( KFWeap_GravityImploder(Owner) != none && KFWeap_GravityImploder(Owner).bDebugDrawVortex)
{
DrawDebugSphere(Location, VortexRadius, 125, 0, 0, 255, false);
}
`endif
if (WorldInfo.NetMode < NM_Client)
{
VortexTime += DeltaTime;
AbsorbEnemies();
bFirstAbsorption=false;
}
}
function AdjustVortexForPerk()
{
local KFPlayerController KFPC;
local KFPerk Perk;
KFPC = KFPlayerController(InstigatorController);
if( KFPC != none )
{
Perk = KFPC.GetPerk();
if(Perk != none)
{
VortexRadius = default.VortexRadius * Perk.GetAoERadiusModifier();
}
}
}
simulated function AbsorbEnemies()
{
local Actor Victim;
local TraceHitInfo HitInfo;
local KFPawn KFP;
local KFPawn_Monster KFPM;
local float ColRadius, ColHeight;
local float Dist;
local vector Dir;
local vector Momentum;
local float MomentumModifier;
foreach CollidingActors(class'Actor', Victim, VortexRadius, VortexLocation, true,, HitInfo)
{
KFP = KFPawn(Victim);
KFPM = KFPawn_Monster(Victim);
if (Victim != Self
&& (!Victim.bWorldGeometry || Victim.bCanBeDamaged)
&& (NavigationPoint(Victim) == None)
&& Victim != Instigator
&& KFP != None
&& KFPawn_Human(Victim) == none // No player's character
&& (KFPM == none || VortexTime < VortexDuration*KFPM.GetVortexAttractionModifier()) )
{
KFP.GetBoundingCylinder(ColRadius, ColHeight);
if (bFirstAbsorption)
{
Dir = vect(0,0,1);
Momentum = Dir * VortexElevationStrength;
}
else
{
Dir = Normal(VortexLocation - KFP.Location);
Dist = FMax(vSize(Dir) - ColRadius, 0.f);
MomentumModifier = bVortexReduceImpulseOnDist ? (1.0f - Dist / VortexRadius) : 1.0f;
Momentum = Dir * VortexAbsorptionStrength * MomentumModifier + vect(0,0,1) * (Dist/VortexRadius) * VortexAbsorptionStrength;
}
if(KFPM != none)
{
Momentum *= KFPM.GetVortexAttractionModifier();
}
KFP.AddVelocity( Momentum, KFP.Location - 0.5 * (ColHeight + ColRadius) * Dir, class 'KFDT_Explosive_GravityImploder');
}
}
}
}
simulated state DetonatingState
{
simulated function BeginState(Name PrevStateName)
{
super.BeginState(PrevStateName);
Detonate();
}
}
simulated function PostBeginPlay()
{
Super.PostBeginPlay();
GotoState('PreparingState');
}
simulated function Timer_Ready()
{
// GotoState('ImplodingState');
GotoState('WaitingToImplode');
}
simulated function Detonation_Ready()
{
GotoState('DetonatingState');
}
simulated function Detonate()
{
local vector ExplosionNormal, vExplosionOffset;
// Check if the bomb should explode right now
if (!bHasExploded && !bHasDisintegrated)
{
ExplosionNormal = vect(0,0,1) >> Rotation;
vExplosionOffset.x = 0;
vExplosionOffset.y = 0;
vExplosionOffset.z = 10;
SetLocation(VortexLocation + vExplosionOffset);
CallExplode(VortexLocation, ExplosionNormal);
}
// If not, mark the bomb to explode as soon as it hits something
else
{
bIsTimedExplosive = false;
bNetDirty = true;
}
}
simulated function SetIsDud(bool bWantsClientSideDudHit, vector HitNormal)
{
// This projectile doesn't dud.
}
simulated protected function StopSimulating()
{
Velocity = vect(0,0,0);
Acceleration = vect(0,0,0);
RotationRate = rot(0,0,0);
SetCollision(FALSE, FALSE);
StopFlightEffects();
bRotationFollowsVelocity = FALSE;
}
simulated function ProcessRebound(vector HitNormal, actor Wall, PrimitiveComponent WallComp)
{
local Vector VNorm;
local rotator NewRotation;
local Vector Offset;
local bool bWantsClientSideDudHit;
local TraceHitInfo HitInfo;
local float TraveledDistance;
bIsRolling = true;
// Need to do client side dud hits if this is a client
if( Instigator != none && Instigator.Role < ROLE_Authority )
{
bWantsClientSideDudHit = true;
}
TraveledDistance = (`TimeSince(CreationTime) * Speed);
TraveledDistance *= TraveledDistance;
// Bounce off the wall and cause the shell to dud if we hit too close
if( bDud || ((TraveledDistance < ArmDistSquared) || bIsTimedExplosive || (OriginalLocation == vect(0,0,0) && ArmDistSquared > 0)))
{
// Reflect off Wall w/damping
VNorm = (Velocity dot HitNormal) * HitNormal;
Velocity = -VNorm * WallHitDampenFactor + (Velocity - VNorm) * WallHitDampenFactorParallel;
Speed = VSize(Velocity);
if( (!bDud || ( bWantsClientSideDudHit && !bClientDudHit)) )
{
SetIsDud(bWantsClientSideDudHit, HitNormal);
}
if ( WorldInfo.NetMode != NM_DedicatedServer && Pawn(Wall) == none && bHasAlreadyBounced == false )
{
// do the impact effects
bHasAlreadyBounced = true;
`ImpactEffectManager.PlayImpactEffects(Location, Instigator, HitNormal, GrenadeBounceEffectInfo, true );
}
// if we hit a pawn or we are moving too slowly stop moving and lay down flat
if ( Speed < MinSpeedBeforeStop )
{
ImpactedActor = Wall;
SetPhysics(PHYS_None);
if( ProjEffects != none )
{
ProjEffects.SetTranslation(LandedTranslationOffset);
}
// Position the shell on the ground
RotationRate.Yaw = 0;
RotationRate.Pitch = 0;
RotationRate.Roll = 0;
NewRotation = Rotation;
NewRotation.Pitch = 0;
if(ResetRotationOnStop)
{
SetRotation(NewRotation);
}
Offset.Z = LandedTranslationOffset.X;
SetLocation(Location + Offset);
}
if( !Wall.bStatic && Wall.bCanBeDamaged && (DamageRadius == 0 || bDamageDestructiblesOnTouch) && !CheckRepeatingTouch(Wall) )
{
HitInfo.HitComponent = WallComp;
HitInfo.Item = INDEX_None;
Wall.TakeDamage( Damage, InstigatorController, Location, MomentumTransfer * Normal(Velocity), MyDamageType, HitInfo, self);
}
}
}
defaultproperties
{
TouchTimeThreshhold = 60.0f
Physics=PHYS_Falling
Speed=3200
MaxSpeed=3200
TerminalVelocity=3200
GravityScale=1.0
MomentumTransfer=100000
LifeSpan=0.f
bWarnAIWhenFired=true
RollingFactor=1100
MinSpeedBeforeStop=5
ResetRotationOnStop=false
// Rolling and dampen values
DampenFactor=0.1
DampenFactorParallel=0
WallHitDampenFactor=0.4 //0.5
WallHitDampenFactorParallel=0.4 //0.5
bCollideComplex=TRUE // Ignore simple collision on StaticMeshes, and collide per poly
bUseClientSideHitDetection=true
bNoReplicationToInstigator=false
bAlwaysReplicateExplosion=true;
bUpdateSimulatedPosition=true
Begin Object Name=CollisionCylinder
CollisionRadius=0.f
CollisionHeight=0.f
BlockNonZeroExtent=false
End Object
ExplosionActorClass=class'KFExplosionActor'
ProjFlightTemplate=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Blue_Projectile'
ProjFlightTemplateZedTime=ParticleSystem'WEP_Gravity_Imploder_EMIT.FX_Blue_Projectile_ZEDTIME'
GrenadeBounceEffectInfo=KFImpactEffectInfo'FX_Impacts_ARCH.DefaultGrenadeImpacts'
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AltExploEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Explosion_Concussive_Force'
// Grenade explosion light
Begin Object Class=PointLightComponent Name=ExplosionPointLight
LightColor=(R=0,G=50,B=171,A=255)
Brightness=4.f
Radius=2000.f
FalloffExponent=10.f
CastShadows=False
CastStaticShadows=FALSE
CastDynamicShadows=False
bCastPerObjectShadows=false
bEnabled=FALSE
LightingChannels=(Indoor=TRUE,Outdoor=TRUE,bInitialized=TRUE)
End Object
// explosion
Begin Object Class=KFGameExplosion Name=ExploTemplate0
Damage=1
DamageRadius=450 //600
DamageFalloffExponent=0.f //2
DamageDelay=0.f
MomentumTransferScale=10000
// Damage Effects
MyDamageType=class'KFDT_Explosive_GravityImploderWave'
KnockDownStrength=150
FractureMeshRadius=200.0
FracturePartVel=500.0
ExplosionEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Explosion'
ExplosionSound=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Grenade_Blue_Explosion'
// Dynamic Light
ExploLight=ExplosionPointLight
ExploLightStartFadeOutTime=0.0
ExploLightFadeOutTime=0.2
// Camera Shake
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.Light_Explosion_Rumble'
CamShakeInnerRadius=200
CamShakeOuterRadius=900
CamShakeFalloff=1.5f
bOrientCameraShakeTowardsEpicenter=true
bIgnoreInstigator=false
End Object
ExplosionTemplate=ExploTemplate0
bIsTimedExplosive=true;
PreparationTime=0.8 //1.0
VortexDuration=0.5 //0.7
VortexRadius=500 //650
VortexAbsorptionStrength=120 //100
VortexElevationStrength=700
bVortexReduceImpulseOnDist=false
bFirstAbsorption=true
VortexImpactEffects=KFImpactEffectInfo'WEP_Gravity_Imploder_ARCH.Blue_Attract'
}

View File

@ -8,7 +8,7 @@
// Roberto Moreno (Saber Interactive) // Roberto Moreno (Saber Interactive)
//============================================================================= //=============================================================================
class KFProj_LightingFlare_HRGScorcher extends KFProj_RicochetBullet class KFProj_LightingFlare_HRGScorcher extends KFProjectile
hidedropdown; hidedropdown;
/** Time projectile is alive after being sticked to an actor or a pawn */ /** Time projectile is alive after being sticked to an actor or a pawn */
@ -120,6 +120,10 @@ simulated event HitWall( vector HitNormal, actor Wall, PrimitiveComponent WallCo
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal) simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{ {
LastHitNormal = HitNormal; LastHitNormal = HitNormal;
if (Other != Instigator && !Other.bStatic && DamageRadius == 0.0 )
{
ProcessBulletTouch(Other, HitLocation, HitNormal);
}
super.ProcessTouch(Other, HitLocation, HitNormal); super.ProcessTouch(Other, HitLocation, HitNormal);
SetTimer(StickedTime, false, nameof(Timer_Explode)); SetTimer(StickedTime, false, nameof(Timer_Explode));
StartStickedEffects(); StartStickedEffects();
@ -165,6 +169,23 @@ simulated event Tick( float DeltaTime )
} }
} }
// Last location needs to be correct, even on first tick.
simulated function SyncOriginalLocation()
{
local Actor HitActor;
local vector HitLocation, HitNormal;
local TraceHitInfo HitInfo;
if (Role < ROLE_Authority && Instigator != none && Instigator.IsLocallyControlled())
{
HitActor = Trace(HitLocation, HitNormal, OriginalLocation, Location,,, HitInfo, TRACEFLAG_Bullet);
if (HitActor != none)
{
StickHelper.TryStick(HitNormal, HitLocation, HitActor);
}
}
}
defaultproperties defaultproperties
{ {
Physics=PHYS_Falling Physics=PHYS_Falling
@ -186,7 +207,6 @@ defaultproperties
CurrentStickedTime=0.0 CurrentStickedTime=0.0
StickedLightFadeStartTime=4.0 StickedLightFadeStartTime=4.0
StickedLightFadeTime=1.0 StickedLightFadeTime=1.0
BouncesLeft=0
TouchTimeThreshhold=0.15 TouchTimeThreshhold=0.15
//Sticking to environment or pinning to enemies //Sticking to environment or pinning to enemies
@ -197,6 +217,10 @@ defaultproperties
bCollideActors=true bCollideActors=true
bCollideComplex=true bCollideComplex=true
bPushedByEncroachers=false
bDamageDestructiblesOnTouch=true
bWaitForEffects=true
ProjEffectsFadeOutDuration=0.25
//Network due to sticking feature //Network due to sticking feature
bNetTemporary=false bNetTemporary=false
NetPriority=5 NetPriority=5

View File

@ -228,7 +228,8 @@ simulated event HitWall( vector HitNormal, Actor Wall, PrimitiveComponent WallCo
return; return;
} }
if( CanStick(Wall, HitNormal) && Wall.bStatic == true ) // Stick to static walls and destructible environment objects.
if( CanStick(Wall, HitNormal) && (Wall.bStatic == true || (Wall.bCanBeDamaged && KFPawn(Wall) == none)) )
{ {
Stick( Location, HitNormal ); Stick( Location, HitNormal );
} }

View File

@ -0,0 +1,55 @@
//=============================================================================
// KFProj_SonicBlastFullyCharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastFullyCharged_HRG_SonicGun extends KFProj_Bullet;
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 1.0 );
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_AltFire_Impacts'
bWarnAIWhenFired=true
Lifespan=10.0
MaxSpeed=10000.0 //7200.0
Speed=10000.0 //7200.0
TerminalVelocity=7200
GravityScale=0.0//0.7
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,113 @@
//=============================================================================
// KFProj_SonicBlastHalfCharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastHalfCharged_HRG_SonicGun extends KFProj_Bullet;
var bool bDebugShowProjectile;
var bool bDebugPersistentLines;
`define SONICBLASTHALFCHARGED_COLLISION 30.0
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 2.0 );
}
simulated event Tick(float DeltaTime)
{
//cylinders debug
//local vector A, B;
//A = Location;
//B.X = `SONICBLASTHALFCHARGED_COLLISION;
//B.Y = `SONICBLASTHALFCHARGED_COLLISION;
//B.Z = `SONICBLASTHALFCHARGED_COLLISION;
//DrawDebugBox( A, B, 255, 255, 0, bDebugPersistentLines); // SLOW! Use for debugging only!
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
// bDebugShowProjectile=true
// bDebugPersistentLines=false
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile_AltFire'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_AltFire_Impacts'
bWarnAIWhenFired=true
Lifespan=1.8 //3.0
TouchTimeThreshhold=0.2
MaxSpeed=3600.0
Speed=3600.0
TerminalVelocity=3600
Physics=PHYS_Projectile
GravityScale=0.0//0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=false
bCollideActors=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=false
bCanDisintegrate=false
bIgnoreFoliageTouch=true
Begin Object Name=CollisionCylinder
CollisionRadius=0
CollisionHeight=0
BlockNonZeroExtent=false
BlockZeroExtent=true
// for siren scream
CollideActors=true
End Object
// Since we're still using an extent cylinder, we need a line at 0
ExtraLineCollisionOffsets.Add(())
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = -`SONICBLASTHALFCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = `SONICBLASTHALFCHARGED_COLLISION))
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,117 @@
//=============================================================================
// KFProj_SonicBlastUncharged_HRG_SonicGun
//=============================================================================
// HRG Sonic Gun sonic projectile for default fire
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFProj_SonicBlastUncharged_HRG_SonicGun extends KFProj_Bullet;
`define SONICBLASTUNCHARGED_COLLISION 45.0
var bool bDebugShowProjectile;
var bool bDebugPersistentLines;
/**
* Initialize the Projectile
*/
function Init(vector Direction)
{
super(KFProjectile).Init( Direction );
}
simulated function SpawnFlightEffects()
{
super.SpawnFlightEffects();
//TODO: Remove. Temporal to see change in FX
ProjEffects.SetScale( 3.5 ); //5.0
}
simulated event Tick(float DeltaTime)
{
//cylinders debug
//local vector A, B;
//A = Location;
//B.X = `SONICBLASTUNCHARGED_COLLISION;
//B.Y = `SONICBLASTUNCHARGED_COLLISION;
//B.Z = `SONICBLASTUNCHARGED_COLLISION;
//DrawDebugBox( A, B, 255, 255, 0, bDebugPersistentLines); // SLOW! Use for debugging only!
}
simulated function ProcessTouch(Actor Other, Vector HitLocation, Vector HitNormal)
{
super.ProcessTouch(Other, HitLocation, HitNormal);
if (PenetrationPower <= 0)
{
Shutdown();
}
}
defaultproperties
{
bDebugShowProjectile=true
bDebugPersistentLines=false
ProjFlightTemplate = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile'
ProjFlightTemplateZedTime = ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_Projectile'
ImpactEffects = KFImpactEffectInfo'WEP_HRG_SonicGun_ARCH.HRG_SonicGun_Projectile_Impacts'
bWarnAIWhenFired=true
Lifespan=1.5 //1.25
TouchTimeThreshhold=0.4
MaxSpeed=2000.0 //1400.0
Speed=2000.0 //1400.0
TerminalVelocity=1800
Physics=PHYS_Projectile
GravityScale=0.0//0.7
GlassShatterType=FMGS_ShatterAll
bCollideComplex=false
bCollideActors=true
bBlockedByInstigator=false
bAlwaysReplicateExplosion=true
bNetTemporary=false
NetPriority=5
NetUpdateFrequency=200
bNoReplicationToInstigator=false
bUseClientSideHitDetection=true
bUpdateSimulatedPosition=true
bSyncToOriginalLocation=true
bSyncToThirdPersonMuzzleLocation=true
PinBoneIdx=INDEX_None
bCanBeDamaged=false
bCanDisintegrate=false
bIgnoreFoliageTouch=true
Begin Object Name=CollisionCylinder
CollisionRadius=0.f
CollisionHeight=0.f
BlockNonZeroExtent=false
BlockZeroExtent=true
// for siren scream
CollideActors=true
End Object
// Since we're still using an extent cylinder, we need a line at 0
ExtraLineCollisionOffsets.Add(())
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Z = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION, Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION, Z = `SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = `SONICBLASTUNCHARGED_COLLISION, Z = -`SONICBLASTUNCHARGED_COLLISION))
ExtraLineCollisionOffsets.Add((Y = -`SONICBLASTUNCHARGED_COLLISION, Z = -`SONICBLASTUNCHARGED_COLLISION))
ProjDisintegrateTemplate=ParticleSystem'ZED_Siren_EMIT.FX_Siren_grenade_disable_01'
AssociatedPerkClass=class'KFPerk_Sharpshooter'
}

View File

@ -0,0 +1,140 @@
//=============================================================================
// KFSeasonalEventStats_Spring2021
//=============================================================================
// Tracks event-specific challenges/accomplishments for Spring 2021
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFSeasonalEventStats_Spring2021 extends KFSeasonalEventStats;
var transient private const int BossKillsRequired, EDARKillsRequired, WavesWithoutDamageRequired, EndlessWaveRequired;
var transient bool bHitTakenThisWave;
private event Initialize(string MapName)
{
local string CapsMapName;
CapsMapName = Caps(MapName);
bObjectiveIsValidForMap[0] = 1; // Kill 15 Bosses on any map or mode
bObjectiveIsValidForMap[1] = 0; // Complete the Weekly on Dystopia 2029
bObjectiveIsValidForMap[2] = 0; // Kill 100 E.D.A.R.s on Dystopia 2029
bObjectiveIsValidForMap[3] = 0; // Complete a wave without taking any damage 10 times on Dystopia 2029
bObjectiveIsValidForMap[4] = 0; // Complete wave 15 on Endless Hard or higher difficulty on Dystopia 2029
if (CapsMapName == "KF-DYSTOPIA2029")
{
bObjectiveIsValidForMap[1] = 1;
bObjectiveIsValidForMap[2] = 1;
bObjectiveIsValidForMap[3] = 1;
bObjectiveIsValidForMap[4] = 1;
}
SetSeasonalEventStatsMax(BossKillsRequired, 0, EDARKillsRequired, WavesWithoutDamageRequired, 0);
}
private event GrantEventItems()
{
if (Outer.IsEventObjectiveComplete(0) &&
Outer.IsEventObjectiveComplete(1) &&
Outer.IsEventObjectiveComplete(2) &&
Outer.IsEventObjectiveComplete(3) &&
Outer.IsEventObjectiveComplete(4))
{
// "Cyborg | Companion Backpack | Precious"
GrantEventItem(8716);
}
}
simulated event OnGameWon(class<GameInfo> GameClass, int Difficulty, int GameLength, bool bCoOp)
{
// Dystopia weekly
if (bObjectiveIsValidForMap[1] != 0)
{
if (GameClass == class'KFGameInfo_WeeklySurvival')
{
FinishedObjective(SEI_Spring, 1);
}
}
}
simulated function OnBossDied()
{
local int ObjIdx;
// Boss kills in any map
ObjIdx = 0;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= BossKillsRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
simulated function OnZedKilled(class<KFPawn_Monster> MonsterClass, int Difficulty, class<DamageType> DT)
{
local int ObjIdx;
// E.D.A.R kills
ObjIdx = 2;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (ClassIsChildOf(MonsterClass, class'KFPawn_ZedDAR'))
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= EDARKillsRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
}
simulated function OnHitTaken()
{
bHitTakenThisWave=true;
}
simulated event OnWaveCompleted(class<GameInfo> GameClass, int Difficulty, int WaveNum)
{
local int ObjIdx;
// No damage wave completed
ObjIdx = 3;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (!bHitTakenThisWave)
{
IncrementSeasonalEventStat(ObjIdx, 1);
if (Outer.GetSeasonalEventStatValue(ObjIdx) >= WavesWithoutDamageRequired)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
bHitTakenThisWave = false;
}
// Wavesin Endless hard
ObjIdx = 4;
if (bObjectiveIsValidForMap[ObjIdx] != 0)
{
if (WaveNum >= EndlessWaveRequired && GameClass == class'KFGameInfo_Endless' && Difficulty >= `DIFFICULTY_HARD)
{
FinishedObjective(SEI_Spring, ObjIdx);
}
}
}
defaultproperties
{
BossKillsRequired=15
EDARKillsRequired=50
WavesWithoutDamageRequired=10
EndlessWaveRequired=15
bHitTakenThisWave=false
}

View File

@ -0,0 +1,54 @@
//=============================================================================
// KFWeapAttach_GravityImploder
//=============================================================================
//
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeapAttach_GravityImploder extends KFWeaponAttachment;
`define GRAVITYIMPLODER_MIC_LED_INDEX 1
/** Weapons material colors for each fire mode. */
var LinearColor DefaultFireMaterialColor;
var LinearColor AltFireMaterialColor;
simulated event PreBeginPlay()
{
Super.PreBeginPlay();
if ( WorldInfo.NetMode == NM_DedicatedServer )
{
return;
}
if ( WeaponMIC == None && WeapMesh != None )
{
WeaponMIC = WeapMesh.CreateAndSetMaterialInstanceConstant(`GRAVITYIMPLODER_MIC_LED_INDEX);
WeaponMIC.SetVectorParameterValue('Vector_Center_Color_A', DefaultFireMaterialColor);
}
}
simulated function bool ThirdPersonFireEffects(vector HitLocation, KFPawn P, byte ThirdPersonAnimRateByte )
{
local LinearColor MatColor;
if(P.FiringMode == 0) // DEFAULT_FIREMODE
{
MatColor = DefaultFireMaterialColor;
}
else if (P.FiringMode == 1) // ALTFIRE_FIREMODE
{
MatColor = AltFireMaterialColor;
}
WeaponMIC.SetVectorParameterValue('Vector_Center_Color_A', MatColor);
return super.ThirdPersonFireEffects(HitLocation, P, ThirdPersonAnimRateByte);
}
defaultproperties
{
DefaultFireMaterialColor = (R = 0.965f,G = 0.2972f, B = 0.0f)
AltFireMaterialColor = (R = 0.0f, G = 0.9631f, B = 0.96581f)
}

View File

@ -39,7 +39,7 @@ defaultproperties
// Ammo // Ammo
MagazineCapacity[0]=30 MagazineCapacity[0]=30
SpareAmmoCapacity[0]=270 SpareAmmoCapacity[0]=270
InitialSpareMags[0]=4 InitialSpareMags[0]=3 //4
bCanBeReloaded=true bCanBeReloaded=true
bReloadFromMagazine=true bReloadFromMagazine=true
@ -62,7 +62,7 @@ defaultproperties
HippedRecoilModifier=1.5 HippedRecoilModifier=1.5
// Inventory / Grouping // Inventory / Grouping
InventorySize=6 InventorySize=5 //6
GroupPriority=50 GroupPriority=50
WeaponSelectTexture=Texture2D'ui_weaponselect_tex.UI_WeaponSelect_Bullpup' WeaponSelectTexture=Texture2D'ui_weaponselect_tex.UI_WeaponSelect_Bullpup'
AssociatedPerkClasses(0)=class'KFPerk_Commando' AssociatedPerkClasses(0)=class'KFPerk_Commando'
@ -75,7 +75,7 @@ defaultproperties
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Bullpup' InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_Bullpup'
FireInterval(DEFAULT_FIREMODE)=+0.0909 // 660 RPM FireInterval(DEFAULT_FIREMODE)=+0.0909 // 660 RPM
Spread(DEFAULT_FIREMODE)=0.0085 Spread(DEFAULT_FIREMODE)=0.0085
InstantHitDamage(DEFAULT_FIREMODE)=30.0 //25 InstantHitDamage(DEFAULT_FIREMODE)=32.0 //30.0 //25
FireOffset=(X=30,Y=4.5,Z=-5) FireOffset=(X=30,Y=4.5,Z=-5)
// ALT_FIREMODE // ALT_FIREMODE
@ -85,7 +85,7 @@ defaultproperties
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_AssaultRifle' WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Bullet_AssaultRifle'
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_Bullpup' InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_Bullpup'
FireInterval(ALTFIRE_FIREMODE)=+0.1 FireInterval(ALTFIRE_FIREMODE)=+0.1
InstantHitDamage(ALTFIRE_FIREMODE)=30.0 //25 InstantHitDamage(ALTFIRE_FIREMODE)=32.0 //30.0 //25
Spread(ALTFIRE_FIREMODE)=0.0085 Spread(ALTFIRE_FIREMODE)=0.0085
// BASH_FIREMODE // BASH_FIREMODE

View File

@ -39,6 +39,24 @@ static simulated event EFilterTypeUI GetTraderFilter()
return FT_Projectile; return FT_Projectile;
} }
simulated function float GetUpgradedAfflictionPower(EAfflictionType AfflictionType, float InPower, optional int FireMode = INDEX_NONE, optional int UpgradeIndex = INDEX_NONE)
{
local class<KFDT_Piercing_Crossbow> DT;
local KFPerk Perk;
Perk = GetPerk();
if(AfflictionType == AF_Stun && Perk != none && Perk.bWasLastHitAHeadshot)
{
DT = class<KFDT_Piercing_Crossbow>(InstantHitDamageTypes[DEFAULT_FIREMODE]);
if (DT != none)
{
return super.GetUpgradedAfflictionPower(AfflictionType, DT.default.HeadStunPower, FireMode, UpgradeIndex);
}
}
return super.GetUpgradedAfflictionPower(AfflictionType, InPower, FireMode, UpgradeIndex);
}
defaultproperties defaultproperties
{ {
// Inventory // Inventory

View File

@ -0,0 +1,187 @@
//=============================================================================
// KFWeap_GravityImploder
//=============================================================================
// The unique and amazing Gravity Imploder weapon
//=============================================================================
// Killing Floor 2
// Copyright (C) 2019 Tripwire Interactive LLC
//=============================================================================
class KFWeap_GravityImploder extends KFWeapon;
`define GRAVITYIMPLODER_MIC_LED_INDEX 1
/** Reduction for the amount of damage dealt to the weapon owner (including damage by the explosion) */
var float SelfDamageReductionValue;
/** Weapons material colors for each fire mode. */
var LinearColor DefaultFireMaterialColor;
var LinearColor AltFireMaterialColor;
var bool bLastFireWasAlt;
var const bool bDebugDrawVortex;
simulated function Activate()
{
super.Activate();
UpdateMaterial();
}
simulated function UpdateMaterial()
{
local LinearColor MatColor;
MatColor = bLastFireWasAlt ? AltFireMaterialColor : DefaultFireMaterialColor;
if( WeaponMICs.Length > `GRAVITYIMPLODER_MIC_LED_INDEX )
{
WeaponMICs[`GRAVITYIMPLODER_MIC_LED_INDEX].SetVectorParameterValue('Vector_Center_Color_A', MatColor);
}
}
simulated function Projectile ProjectileFire()
{
UpdateMaterial();
return super.ProjectileFire();
}
simulated function BeginFire( Byte FireModeNum )
{
super.BeginFire(FireModeNum);
if(FireModeNum == ALTFIRE_FIREMODE && !bLastFireWasAlt)
{
bLastFireWasAlt=true;
}
else if (FireModeNum == DEFAULT_FIREMODE && bLastFireWasAlt)
{
bLastFireWasAlt=false;
}
}
simulated function AltFireMode()
{
StartFire(ALTFIRE_FIREMODE);
}
// Reduce damage to self
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;
}
}
defaultproperties
{
// Content
PackageKey="Gravity_Imploder"
FirstPersonMeshName="WEP_1P_Gravity_Imploder_MESH.Wep_1stP_Gravity_Imploder_Rig"
FirstPersonAnimSetNames(0)="WEP_1P_Gravity_Imploder_ANIM.Wep_1stP_Gravity_Imploder_Anim"
PickupMeshName="WEP_3P_Gravity_Imploder_MESH.WEP_3rdP_Gravity_Imploder_Pickup"
AttachmentArchetypeName="WEP_Gravity_Imploder_ARCH.Wep_Gravity_Imploder_3P"
MuzzleFlashTemplateName="WEP_Gravity_Imploder_ARCH.Wep_Gravity_Imploder_MuzzleFlash"
// Inventory / Grouping
InventorySize=7 //8
GroupPriority=125 //75
WeaponSelectTexture=Texture2D'WEP_UI_Gravity_Imploder_TEX.UI_WeaponSelect_Gravity_Imploder'
AssociatedPerkClasses(0)=class'KFPerk_Demolitionist'
// FOV
MeshFOV=75
MeshIronSightFOV=40
PlayerIronSightFOV=65
// Depth of field
DOF_FG_FocalRadius=50
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=6 //5
SpareAmmoCapacity[0]=42 //35
InitialSpareMags[0]=2 //4
AmmoPickupScale[0]=1 //1
bCanBeReloaded=true
bReloadFromMagazine=true
// Zooming/Position
PlayerViewOffset=(X=5.5,Y=8,Z=-2) //(X=11.0,Y=8,Z=-2)
IronSightPosition=(X=10,Y=0,Z=-1.9) //(X=10,Y=0,Z=0)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=750 //500
minRecoilPitch=675//400
maxRecoilYaw=250 //150
minRecoilYaw=-250 //-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_Grenade'
FiringStatesArray(DEFAULT_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_Grenade_GravityImploder'
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpact'
InstantHitDamage(DEFAULT_FIREMODE)=150
FireInterval(DEFAULT_FIREMODE)=1.33 //45 RPM
Spread(DEFAULT_FIREMODE)=0.02 //0
PenetrationPower(DEFAULT_FIREMODE)=0
FireOffset=(X=25,Y=3.0,Z=-2.5)
// ALTFIRE_FIREMODE (swap fire mode)
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'ui_firemodes_tex.UI_FireModeSelect_Electricity'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_Grenade_GravityImploderAlt'
FireInterval(ALTFIRE_FIREMODE)=1.33 //45 RPM
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Ballistic_GravityImploderImpactAlt'
InstantHitDamage(ALTFIRE_FIREMODE)=200
Spread(ALTFIRE_FIREMODE)=0.02 //0.0085
AmmoCost(ALTFIRE_FIREMODE)=1
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_GravityImploder'
InstantHitDamage(BASH_FIREMODE)=26
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_1P')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Dry_Fire'
WeaponFireSnd(ALTFIRE_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_3P', FirstPersonCue=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Shoot_1P')
WeaponDryFireSnd(ALTFIRE_FIREMODE)=AkEvent'WW_WEP_Gravity_Imploder.Play_WEP_Gravity_Imploder_Dry_Fire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
SelfDamageReductionValue=0.f //0.25f
bLastFireWasAlt=false
DefaultFireMaterialColor = (R = 0.965f,G = 0.2972f, B = 0.0f)
AltFireMaterialColor = (R = 0.0f, G = 0.9631f, B = 0.96581f)
bHasFireLastAnims=true
NumBloodMapMaterials=2
}

View File

@ -0,0 +1,613 @@
//=============================================================================
// KFWeap_HRG_SonicGun
//=============================================================================
// The HRG Sonic Gun weapon
//=============================================================================
// Killing Floor 2
// Copyright (C) 2020 Tripwire Interactive LLC
//=============================================================================
class KFWeap_HRG_SonicGun extends KFWeapon;
`define SONICGUN_MIC_SIGHT_INDEX 1
var(Animations) const editconst name ChargeAnim;
var(Animations) const editconst name ChargeAnimLast;
var(Animations) const editconst name ChargeAnimIron;
var(Animations) const editconst name ChargeAnimIronLast;
/** How long to wait after firing to force reload */
var() float ForceReloadTime;
var transient int CurrentChargeLevel;
/** Maximum times weapon can be charged */
var int MaxChargeLevel;
/** How much multiply damage does default fire projectile do by charge level*/
var Array<float> SonicBlastDamageByChargeLevel;
/** how much multiply momentum for default fire projectile by charge level */
var Array<float> SonicBlastMomentumByChargeLevel;
/** how much multiply penetration power for default fire projectile by charge level */
var Array<float> SonicBlastPenetrationPowerByChargeLevel;
/** DamageTypes for default fire projectile by charge level*/
var Array< class<DamageType> > SonicBlastDamageTypeByChargeLevel;
/** Projectile classes for default fire projectile by charge level*/
var Array< class<KFProjectile> > SonicBlastProjectileClassByChargeLevel;
/** Sounds for default fire by charge level*/
var Array<WeaponFireSndInfo> SonicBlastFireSoundByChargeLevel;
/** Sounds for charge */
var Array<WeaponFireSndInfo> SonicBlastFireSoundCharge;
/** Sounds for charge sound by charge level*/
var Array<AkEvent> ChargeSoundByChargeLevel;
/** How much momentum to apply when fired in double barrel */
var(Recoil) float FullyChargedKickMomentum;
/** How much to reduce shoot momentum when falling */
var(Recoil) float FallingMomentumReduction;
/** VFX to play from the muzzle when firing the charged shot */
var ParticleSystem MuzzleEffectDefaultFire;
/** VFX to play from the muzzle when firing the charged shot */
var ParticleSystem MuzzleEffectChargedFire;
struct MomentumMultiplierByZed
{
var Name ZedClassName;
var float MomentumMultiplier;
};
var array<MomentumMultiplierByZed> MomentumMultiplierByZedArray;
/** Colors for holographic sight by charge level */
var const Array<LinearColor> HolographicSightByChargeLevel;
var const Array<LinearColor> HolographicSightScanlineByChargeLevel;
var Array<bool> HolographicSightUseDefaultByChargeLevel;
simulated function PostBeginPlay()
{
CurrentChargeLevel=0;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[0])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[0]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[0]);
}
else {
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
/**
* 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;
P = super.ProjectileFire();
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;
}
}
simulated function StartFire(byte FireModeNum)
{
if (FireModeNum == ALTFIRE_FIREMODE)
{
if (!IsCanIncrementCharge())
{
return;
}
}
super.StartFire(FireModeNum);
}
/*********************************************************************************************
* State WeaponSonicGunCharging
* The weapon is in this state while detonating a charge
*********************************************************************************************/
simulated function GotoActiveState();
simulated state WeaponSonicGunCharging
{
ignores AllowSprinting;
simulated event BeginState( name PreviousStateName )
{
local KFPerk InstigatorPerk;
if (!IsCanIncrementCharge())
{
ClearPendingFire(CurrentFireMode);
GotoActiveState();
return;
}
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
SetZedTimeResist( InstigatorPerk.GetZedTimeModifier(self) );
}
IncrementChargeAndPlayAnimation();
}
simulated function GotoActiveState()
{
GotoState('Active');
}
}
simulated state WeaponSonicGunSingleFiring extends WeaponSingleFiring
{
simulated function BeginState(name PreviousStateName)
{
local vector UsedKickMomentum;
// Push the player back when they fire a fully charged sonic blast
if (Instigator != none && CurrentChargeLevel == 1 ) //2
{
UsedKickMomentum.X = -FullyChargedKickMomentum;
if( Instigator.Physics == PHYS_Falling )
{
UsedKickMomentum = UsedKickMomentum >> Instigator.GetViewRotation();
UsedKickMomentum *= FallingMomentumReduction;
}
else
{
UsedKickMomentum = UsedKickMomentum >> Instigator.Rotation;
UsedKickMomentum.Z = 0;
}
Instigator.AddVelocity(UsedKickMomentum,Instigator.Location,none);
}
//We want to do it at the end because the kickmomentum needs to use CurrentChargeLevel and this is reset in FireAmmunition
Super.BeginState(PreviousStateName);
}
simulated function FireAmmunition()
{
super.FireAmmunition();
CurrentChargeLevel=0;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[0])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[0]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[0]);
}
else
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
}
// 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 bool IsCanIncrementCharge()
{
return CurrentChargeLevel < MaxChargeLevel && AmmoCount[DEFAULT_FIREMODE] > 0;
}
simulated function IncrementChargeAndPlayAnimation()
{
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) ? ChargeAnimIronLast : ChargeAnimIron;
}
else
{
SelectedAnim = ShouldPlayFireLast(DEFAULT_FIREMODE) ? ChargeAnimLast : ChargeAnim;
}
AnimDuration = MySkelMesh.GetAnimLength(SelectedAnim);
bInSprintState = IsInState('WeaponSprinting');
if (WorldInfo.NetMode != NM_DedicatedServer)
{
if ( KFPawn(Owner).IsLocallyControlled() )
{
PlaySoundBase(SonicBlastFireSoundCharge[CurrentChargeLevel].FirstPersonCue);
}
if (bInSprintState)
{
AnimDuration *= 0.25f;
PlayAnimation(SelectedAnim, AnimDuration);
}
else
{
PlayAnimation(SelectedAnim);
}
}
// Don't want to play muzzle effects or shoot animation on detonate in 3p
//IncrementFlashCount();
//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));
}
CurrentChargeLevel++;
if( WeaponMICs.Length > `SONICGUN_MIC_SIGHT_INDEX )
{
if (!HolographicSightUseDefaultByChargeLevel[CurrentChargeLevel])
{
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Center_Color_A', HolographicSightByChargeLevel[CurrentChargeLevel]);
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].SetVectorParameterValue('Vector_Scanline_Color_Mult', HolographicSightScanlineByChargeLevel[CurrentChargeLevel]);
}
else {
WeaponMICs[`SONICGUN_MIC_SIGHT_INDEX].ClearParameterValues();
}
}
}
/** Returns trader filter index based on weapon type */
static simulated event EFilterTypeUI GetTraderFilter()
{
return FT_Explosive;
}
simulated function float GetForceReloadDelay()
{
return fMax( ForceReloadTime - FireInterval[CurrentFireMode], 0.f );
}
//Overriding to be able to change projectile stats depending on the charge level
simulated function KFProjectile SpawnProjectile( class<KFProjectile> KFProjClass, vector RealStartLoc, vector AimDir )
{
local KFProjectile SpawnedProjectile;
local int ProjDamage;
// Spawn projectile
SpawnedProjectile = Spawn( KFProjClass, Self,, RealStartLoc,,,true);
if( SpawnedProjectile != none && !SpawnedProjectile.bDeleteMe )
{
// Mirror damage and damage type from weapon. This is set on the server only and
// these properties are replicated via TakeHitInfo
if ( InstantHitDamage.Length > CurrentFireMode && InstantHitDamageTypes.Length > CurrentFireMode )
{
InstantHitDamage[DEFAULT_FIREMODE] = SonicBlastDamageByChargeLevel[CurrentChargeLevel];
InstantHitMomentum[DEFAULT_FIREMODE]=SonicBlastMomentumByChargeLevel[CurrentChargeLevel];
InstantHitDamageTypes[DEFAULT_FIREMODE]=SonicBlastDamageTypeByChargeLevel[CurrentChargeLevel];
ProjDamage = GetModifiedDamage(CurrentFireMode);
SpawnedProjectile.Damage = ProjDamage;
SpawnedProjectile.MyDamageType = InstantHitDamageTypes[DEFAULT_FIREMODE];
}
// Set the penetration power for this projectile
// because of clientside hit detection, we need two variables --
// one that replicates on init and one that updates but doesn't replicate
PenetrationPower[DEFAULT_FIREMODE]=SonicBlastPenetrationPowerByChargeLevel[CurrentChargeLevel];
SpawnedProjectile.InitialPenetrationPower = GetInitialPenetrationPower(CurrentFireMode);
SpawnedProjectile.PenetrationPower = SpawnedProjectile.InitialPenetrationPower;
SpawnedProjectile.UpgradeDamageMod = GetUpgradeDamageMod();
SpawnedProjectile.Init( AimDir );
}
// return it up the line
return SpawnedProjectile;
}
//Overriding to make KFProjectile Class for default fire mode to be dependant on charge level
simulated function class<KFProjectile> GetKFProjectileClass()
{
if (CurrentFireMode == DEFAULT_FIREMODE)
{
return SonicBlastProjectileClassByChargeLevel[CurrentChargeLevel];
}
return super.GetKFProjectileClass();
}
//Overriding to get current PenetrationPower, not default.PenetrationPower
simulated function float GetUpgradedPenetration(optional int FireMode = DEFAULT_FIREMODE, optional int UpgradeIndex = INDEX_NONE)
{
if (UpgradeIndex == INDEX_NONE)
{
UpgradeIndex = CurrentWeaponUpgradeIndex;
}
return int(GetUpgradedStatValue(PenetrationPower[FireMode], EWeaponUpgradeStat(EWUS_Penetration0 + UpgradeFireModes[FireMode]), UpgradeIndex));
}
//Overriding to change shot sounds for default fire mode to be dependant on charge level
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
WeaponFireSnd[DEFAULT_FIREMODE]=SonicBlastFireSoundByChargeLevel[CurrentChargeLevel];
super.PlayFireEffects(FireModeNum, HitLocation);
}
simulated function ProcessInstantHitEx(byte FiringMode, ImpactInfo Impact, optional int NumHits, optional out float out_PenetrationVal, optional int ImpactNum )
{
local KFPerk InstigatorPerk;
local int IndexMomentumMultiplierByZed;
InstigatorPerk = GetPerk();
if( InstigatorPerk != none )
{
InstigatorPerk.UpdatePerkHeadShots( Impact, InstantHitDamageTypes[FiringMode], ImpactNum );
}
//Modifying momentum by zed impacted
if (Impact.HitActor != None && KFPawn_Monster(Impact.HitActor) != None)
{
IndexMomentumMultiplierByZed = MomentumMultiplierByZedArray.Find('ZedClassName', Impact.HitActor.Class.Name);
if (IndexMomentumMultiplierByZed != INDEX_NONE)
{
InstantHitMomentum[DEFAULT_FIREMODE] *= MomentumMultiplierByZedArray[IndexMomentumMultiplierByZed].MomentumMultiplier;
}
}
super.ProcessInstantHitEx( FiringMode, Impact, NumHits, out_PenetrationVal, ImpactNum );
}
simulated function CauseMuzzleFlash(byte FireModeNum)
{
if (MuzzleFlash == None)
{
AttachMuzzleFlash();
}
if (CurrentChargeLevel > 0)
{
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleEffectChargedFire;
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleEffectChargedFire);
}
else
{
MuzzleFlash.MuzzleFlash.ParticleSystemTemplate = MuzzleEffectDefaultFire;
MuzzleFlash.MuzzleFlash.PSC.SetTemplate(MuzzleEffectDefaultFire);
}
super.CauseMuzzleFlash(FireModeNum);
}
defaultproperties
{
// Content
PackageKey="HRG_SonicGun"
FirstPersonMeshName="wep_1p_hrg_sonicgun_mesh.WEP_1stP_HRG_SonicGun_Rig"
FirstPersonAnimSetNames(0)="wep_1p_hrg_sonicgun_anim.Wep_1stP_HRG_SonicGun_Anim"
PickupMeshName="wep_3p_hrg_sonicgun_mesh.WEP_3rdP_HRG_SonicGun_Pickup"
AttachmentArchetypeName="wep_hrg_sonicgun_arch.Wep_HRG_SonicGun_3P"
MuzzleFlashTemplateName="WEP_HRG_SonicGun_ARCH.Wep_HRG_SonicGun_MuzzleFlash"
// Inventory / Grouping
InventorySize=7
GroupPriority=75
WeaponSelectTexture=Texture2D'WEP_UI_HRG_SonicGun_TEX.UI_WeaponSelect_HRG_SonicGun'
AssociatedPerkClasses(0)=class'KFPerk_Sharpshooter'
// FOV
MeshFOV=75
MeshIronSightFOV=40
PlayerIronSightFOV=65
// Depth of field
DOF_FG_FocalRadius=50
DOF_FG_MaxNearBlurSize=3.5
// Ammo
MagazineCapacity[0]=12 //8
SpareAmmoCapacity[0]=96 //72
InitialSpareMags[0]=1
bCanBeReloaded=true
bReloadFromMagazine=true
// Zooming/Position
PlayerViewOffset=(X=11.0,Y=8,Z=-2)
IronSightPosition=(X=10,Y=-0.1,Z=-0.2)
// AI warning system
bWarnAIWhenAiming=true
AimWarningDelay=(X=0.4f, Y=0.8f)
AimWarningCooldown=0.0f
// Recoil
maxRecoilPitch=200 //500
minRecoilPitch=150 //400
maxRecoilYaw=50 //150
minRecoilYaw=-50 //-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)=WeaponSonicGunSingleFiring
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Projectile
WeaponProjectiles(DEFAULT_FIREMODE)=class'KFProj_SonicBlastUncharged_HRG_SonicGun'
InstantHitDamage(DEFAULT_FIREMODE)=125
InstantHitDamageTypes(DEFAULT_FIREMODE)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged'
InstantHitMomentum(DEFAULT_FIREMODE)=200000
FireInterval(DEFAULT_FIREMODE)=0.5 //0.75
Spread(DEFAULT_FIREMODE)=0.005
PenetrationPower(DEFAULT_FIREMODE)=2.0
FireOffset=(X=25,Y=3.0,Z=-2.5)
FullyChargedKickMomentum=0 //1000
FallingMomentumReduction=0.5
// ALTFIRE_FIREMODE (remote detonate)
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSonicGunCharging
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Custom
AmmoCost(ALTFIRE_FIREMODE)=0
// BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_HRG_SonicGun'
InstantHitDamage(BASH_FIREMODE)=26
// Custom animations
FireSightedAnims=(Shoot_Iron, Shoot_Iron2, Shoot_Iron3)
BonesToLockOnEmpty=(RW_BoltAssembly1, RW_BoltAssembly2, RW_BoltAssembly3)
bHasFireLastAnims=true
// Fire Effects
WeaponFireSnd(DEFAULT_FIREMODE)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Bass', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Bass')
WeaponDryFireSnd(DEFAULT_FIREMODE)=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_DryFire'
EjectedShellForegroundDuration=1.5f
// Attachments
bHasIronSights=true
bHasFlashlight=false
WeaponFireWaveForm=ForceFeedbackWaveform'FX_ForceFeedback_ARCH.Gunfire.Medium_Recoil'
ChargeAnim=Alt_Fire
ChargeAnimLast=Alt_Fire_Last
ChargeAnimIron=Alt_Fire_Iron
ChargeAnimIronLast=Alt_Fire_Iron_Last
WeaponUpgrades[1]=(Stats=((Stat=EWUS_Damage0, Scale=1.15f), (Stat=EWUS_Weight, Add=1)))
WeaponUpgrades[2]=(Stats=((Stat=EWUS_Damage0, Scale=1.3f), (Stat=EWUS_Weight, Add=2)))
ForceReloadTime=0.3
bAllowClientAmmoTracking=true
AimCorrectionSize=0.f
MuzzleEffectDefaultFire=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Muzzle'
MuzzleEffectChargedFire=ParticleSystem'WEP_HRG_SonicGun_EMIT.FX_SonicGun_Muzzle_AltFire'
SonicBlastDamageByChargeLevel(0)=110 //100
//SonicBlastDamageByChargeLevel(1)=170 //160
SonicBlastDamageByChargeLevel(1)=280 //310 //280
SonicBlastPenetrationPowerByChargeLevel(0)=4.0
//SonicBlastPenetrationPowerByChargeLevel(1)=3.0 //1.0
SonicBlastPenetrationPowerByChargeLevel(1)=2.0 //0.0
SonicBlastMomentumByChargeLevel(0)=100000 //80000 //60000
//SonicBlastMomentumByChargeLevel(1)=50000 //40000
SonicBlastMomentumByChargeLevel(1)=40000 //20000
SonicBlastDamageTypeByChargeLevel(0)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastUncharged'
//SonicBlastDamageTypeByChargeLevel(1)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastHalfCharged'
SonicBlastDamageTypeByChargeLevel(1)=class'KFDT_Ballistic_HRG_SonicGun_SonicBlastFullyCharged'
SonicBlastProjectileClassByChargeLevel(0)=class'KFProj_SonicBlastUncharged_HRG_SonicGun'
//SonicBlastProjectileClassByChargeLevel(1)=class'KFProj_SonicBlastHalfCharged_HRG_SonicGun'
SonicBlastProjectileClassByChargeLevel(1)=class'KFProj_SonicBlastFullyCharged_HRG_SonicGun'
SonicBlastFireSoundByChargeLevel(0)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Bass', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Bass')
//SonicBlastFireSoundByChargeLevel(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_Mid', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_Mid')
SonicBlastFireSoundByChargeLevel(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_3P_Fire_High', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_1P_Fire_High')
SonicBlastFireSoundCharge(0)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Once', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Once')
SonicBlastFireSoundCharge(1)=(DefaultCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Twice', FirstPersonCue=AkEvent'WW_WEP_HRG_SonicGun.Play_WEP_HRG_SonicGun_Charge_Twice')
ChargeSoundByChargeLevel(0)=AkEvent'WW_WEP_Seeker_6.Play_Seeker_6_Reload_1'
ChargeSoundByChargeLevel(1)=AkEvent'WW_WEP_Lazer_Cutter.Play_WEP_LaserCutter_Handling_Equip'
//AkEvent'WW_WEP_Helios.Play_WEP_Helios_Handling_Equip'
MaxChargeLevel=1 //2
MomentumMultiplierByZedArray(0)=(ZedClassName="KFPawn_ZedClot_Cyst", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(1)=(ZedClassName="KFPawn_ZedClot_Alpha", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(2)=(ZedClassName="KFPawn_ZedClot_Slasher", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(3)=(ZedClassName="KFPawn_ZedCrawler", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(4)=(ZedClassName="KFPawn_ZedGorefast", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(5)=(ZedClassName="KFPawn_ZedStalker", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(6)=(ZedClassName="KFPawn_ZedScrake", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(7)=(ZedClassName="KFPawn_ZedFleshpound", MomentumMultiplier=1.3)
MomentumMultiplierByZedArray(8)=(ZedClassName="KFPawn_ZedFleshpoundMini", MomentumMultiplier=1.3)
MomentumMultiplierByZedArray(9)=(ZedClassName="KFPawn_ZedBloat", MomentumMultiplier=1.7)
MomentumMultiplierByZedArray(10)=(ZedClassName="KFPawn_ZedSiren", MomentumMultiplier=0.8)
MomentumMultiplierByZedArray(11)=(ZedClassName="KFPawn_ZedHusk", MomentumMultiplier=0.8)
MomentumMultiplierByZedArray(12)=(ZedClassName="KFPawn_ZedClot_AlphaKing", MomentumMultiplier=1.0) //elite clot
MomentumMultiplierByZedArray(13)=(ZedClassName="KFPawn_ZedCrawlerKing", MomentumMultiplier=1.0) //elite crawler
MomentumMultiplierByZedArray(14)=(ZedClassName="KFPawn_ZedGorefastDualBlade", MomentumMultiplier=1.3) //elite gorefast
MomentumMultiplierByZedArray(15)=(ZedClassName="KFPawn_ZedDAR_EMP", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(16)=(ZedClassName="KFPawn_ZedDAR_Laser", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(17)=(ZedClassName="KFPawn_ZedDAR_Rocket", MomentumMultiplier=1.4)
MomentumMultiplierByZedArray(18)=(ZedClassName="KFPawn_ZedBloatKingSubspawn", MomentumMultiplier=1.0)
MomentumMultiplierByZedArray(19)=(ZedClassName="KFPawn_ZedHans", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(20)=(ZedClassName="KFPawn_ZedPatriarch", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(21)=(ZedClassName="KFPawn_ZedFleshpoundKing", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(22)=(ZedClassName="KFPawn_ZedBloatKing", MomentumMultiplier=1.2)
MomentumMultiplierByZedArray(23)=(ZedClassName="KFPawn_ZedMatriarch", MomentumMultiplier=1.2)
//If no set any of the following colors, the default color from the material will be used
HolographicSightByChargeLevel(0)=(R=0.88f,G=0.36f,B=0.11f, A=0.92f)
HolographicSightByChargeLevel(1)=(R=0.27f,G=0.5f,B=2.35f, A=0.92f)
HolographicSightScanlineByChargeLevel(0)=(R=0.5f,G=0.96f,B=0.96f, A=0.92f)
HolographicSightScanlineByChargeLevel(1)=(R=0.88f,G=0.36f,B=0.11f, A=0.92f)
HolographicSightUseDefaultByChargeLevel(0)=false
HolographicSightUseDefaultByChargeLevel(1)=false
NumBloodMapMaterials=2
}

View File

@ -209,8 +209,8 @@ defaultproperties
// Recoil // Recoil
maxRecoilPitch=150 maxRecoilPitch=150
minRecoilPitch=115 minRecoilPitch=115
maxRecoilYaw=115 maxRecoilYaw=80 //115
minRecoilYaw=-115 minRecoilYaw=-80 //-115
RecoilRate=0.085 RecoilRate=0.085
RecoilMaxYawLimit=500 RecoilMaxYawLimit=500
RecoilMinYawLimit=65035 RecoilMinYawLimit=65035
@ -223,7 +223,7 @@ defaultproperties
RecoilViewRotationScale=0.25 RecoilViewRotationScale=0.25
IronSightMeshFOVCompensationScale=1.5 IronSightMeshFOVCompensationScale=1.5
HippedRecoilModifier=1.5 HippedRecoilModifier=1.5
AltFireRecoilScale=4.0f AltFireRecoilScale=6.0f //4.0f
// Inventory // Inventory
InventorySize=7 InventorySize=7
@ -234,23 +234,23 @@ defaultproperties
FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_Cryogun' FireModeIconPaths(DEFAULT_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_Cryogun'
FiringStatesArray(DEFAULT_FIREMODE)=SprayingFire FiringStatesArray(DEFAULT_FIREMODE)=SprayingFire
WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Custom WeaponFireTypes(DEFAULT_FIREMODE)=EWFT_Custom
FireInterval(DEFAULT_FIREMODE)=+0.07 // 850 RPM FireInterval(DEFAULT_FIREMODE)=+0.1 //+0.07 // 850 RPM
FireOffset=(X=30,Y=4.5,Z=-5) FireOffset=(X=30,Y=4.5,Z=-5)
//MinFireDuration=0.25 //MinFireDuration=0.25
MinAmmoConsumed=4 MinAmmoConsumed=3 //4
// ALT_FIREMODE // ALT_FIREMODE
FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_2nd_Cryogun' FireModeIconPaths(ALTFIRE_FIREMODE)=Texture2D'wep_ui_cryogun_tex.UI_FireModeSelect_2nd_Cryogun'
FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring FiringStatesArray(ALTFIRE_FIREMODE)=WeaponSingleFiring
WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile WeaponFireTypes(ALTFIRE_FIREMODE)=EWFT_Projectile
WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_FreezeThrower_IceShards' WeaponProjectiles(ALTFIRE_FIREMODE)=class'KFProj_FreezeThrower_IceShards'
InstantHitDamage(ALTFIRE_FIREMODE)=20.0 InstantHitDamage(ALTFIRE_FIREMODE)=35.0 //20.0
InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Freeze_FreezeThrower_IceShards' InstantHitDamageTypes(ALTFIRE_FIREMODE)=class'KFDT_Freeze_FreezeThrower_IceShards'
FireInterval(ALTFIRE_FIREMODE)=0.6f FireInterval(ALTFIRE_FIREMODE)=0.6f
PenetrationPower(ALTFIRE_FIREMODE)=4.0 PenetrationPower(ALTFIRE_FIREMODE)=4.0
AmmoCost(ALTFIRE_FIREMODE)=10 AmmoCost(ALTFIRE_FIREMODE)=10
NumPellets(ALTFIRE_FIREMODE)=12 NumPellets(ALTFIRE_FIREMODE)=8 //12
Spread(ALTFIRE_FIREMODE)=0.15f Spread(ALTFIRE_FIREMODE)=0.12f //0.15f
// BASH_FIREMODE // BASH_FIREMODE
InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_Freezethrower' InstantHitDamageTypes(BASH_FIREMODE)=class'KFDT_Bludgeon_Freezethrower'

View File

@ -75,8 +75,15 @@ simulated state WeaponDoubleBarrelFiring extends WeaponSingleFiring
simulated function BeginState(name PreviousStateName) simulated function BeginState(name PreviousStateName)
{ {
local vector UsedKickMomentum; local vector UsedKickMomentum;
local KFMapInfo KFMI;
Super.BeginState(PreviousStateName); Super.BeginState(PreviousStateName);
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if(KFMI != none && !KFMI.bAllowShootgunJump)
{
return;
}
// Push the player back when they fire both barrels // Push the player back when they fire both barrels
if (Instigator != none ) if (Instigator != none )
{ {

View File

@ -26,13 +26,8 @@ simulated function AltFireMode()
{ {
return; return;
} }
if (ReloadStatus == RS_Reloading)
{
return;
}
if (AmmoCount[0] <= 1) if (AmmoCount[0] == 1)
{ {
StartFire(DEFAULT_FIREMODE); StartFire(DEFAULT_FIREMODE);
} }
@ -93,8 +88,15 @@ simulated state WeaponQuadBarrelFiring extends WeaponSingleFiring
simulated function BeginState(name PreviousStateName) simulated function BeginState(name PreviousStateName)
{ {
local vector UsedKickMomentum; local vector UsedKickMomentum;
local KFMapInfo KFMI;
Super.BeginState(PreviousStateName); Super.BeginState(PreviousStateName);
KFMI = KFMapInfo(WorldInfo.GetMapInfo());
if(KFMI != none && !KFMI.bAllowShootgunJump)
{
return;
}
// Push the player back when they fire both barrels // Push the player back when they fire both barrels
if (Instigator != none) if (Instigator != none)
{ {

View File

@ -348,7 +348,7 @@ cpptext
defaultproperties defaultproperties
{ {
// as of August 2020 // as of January 2021
ConsumablesCount=80 ConsumablesCount=80
DurablesCount=49 DurablesCount=54
} }

View File

@ -74,11 +74,13 @@ function bool execute(string cmd, out string result, PlayerController pc)
} }
else if (cmd ~= "AdminKick" || cmd ~= "Kick") else if (cmd ~= "AdminKick" || cmd ~= "Kick")
{ {
WorldInfo.Game.ExileServerUsingKickBan();
WorldInfo.Game.AccessControl.Kick(args/*, "Engine.AccessControl.KickedMsg"*/); WorldInfo.Game.AccessControl.Kick(args/*, "Engine.AccessControl.KickedMsg"*/);
return true; return true;
} }
else if (cmd ~= "AdminKickBan" || cmd ~= "KickBan") else if (cmd ~= "AdminKickBan" || cmd ~= "KickBan")
{ {
WorldInfo.Game.ExileServerUsingKickBan();
WorldInfo.Game.AccessControl.KickBan(args/*, "Engine.AccessControl.KickAndPermaBan"*/); WorldInfo.Game.AccessControl.KickBan(args/*, "Engine.AccessControl.KickAndPermaBan"*/);
return true; return true;
} }
@ -131,11 +133,13 @@ function bool execute(string cmd, out string result, PlayerController pc)
{ {
if (cmd ~= "KickBan") if (cmd ~= "KickBan")
{ {
WorldInfo.Game.ExileServerUsingKickBan();
adminuser.KickBan(args/*, "Engine.AccessControl.KickAndPermaBan"*/); adminuser.KickBan(args/*, "Engine.AccessControl.KickAndPermaBan"*/);
return true; return true;
} }
else if (cmd ~= "Kick") else if (cmd ~= "Kick")
{ {
WorldInfo.Game.ExileServerUsingKickBan();
adminuser.Kick(args/*, "Engine.AccessControl.KickedMsg"*/); adminuser.Kick(args/*, "Engine.AccessControl.KickedMsg"*/);
return true; return true;
} }
@ -224,6 +228,7 @@ function string SessionBan(string TargetPlayer, optional string reason)
if ( TargetPlayerPC != none ) if ( TargetPlayerPC != none )
{ {
`{AccessControl} (WorldInfo.Game.AccessControl).KickSessionBanPlayer(TargetPlayerPC, TargetPlayerPC.PlayerReplicationInfo.UniqueId, "Engine.AccessControl.KickAndSessionBan"); `{AccessControl} (WorldInfo.Game.AccessControl).KickSessionBanPlayer(TargetPlayerPC, TargetPlayerPC.PlayerReplicationInfo.UniqueId, "Engine.AccessControl.KickAndSessionBan");
WorldInfo.Game.ExileServerUsingKickBan();
return TargetPlayer$" banned for this session"; return TargetPlayer$" banned for this session";
} }
return "Player "$TargetPlayer$" not found"; return "Player "$TargetPlayer$" not found";

View File

@ -109,7 +109,7 @@ var array<string> playerActions;
*/ */
var bool separateSpectators; var bool separateSpectators;
var array<string> notAllowedBanConsoleCommands; var array<string> consoleCommandsToGetServerExiled;
function init(WebAdmin webapp) function init(WebAdmin webapp)
{ {
@ -785,8 +785,7 @@ function int handleCurrentPlayersAction(WebAdminQuery q)
{ {
webadmin.addMessage(q, msgNoHumanPlayer, MT_Warning); webadmin.addMessage(q, msgNoHumanPlayer, MT_Warning);
} }
else else {
{
// Default to just the normal kick message // Default to just the normal kick message
kickMessage = "Engine.AccessControl.KickedMsg"; kickMessage = "Engine.AccessControl.KickedMsg";
if (action ~= "mutevoice") if (action ~= "mutevoice")
@ -823,10 +822,55 @@ function int handleCurrentPlayersAction(WebAdminQuery q)
} }
`endif `endif
else if (action ~= "banip" || action ~= "ban ip" || action ~= "banid" || action ~= "ban unique id" || action ~= "banhash" || else if (action ~= "banip" || action ~= "ban ip")
action ~= "ban client hash" || action ~= "sessionban" || action ~= "session ban")
{ {
webadmin.addMessage(q, msgNotAllowed, MT_Error); banByIP(PC);
kickMessage = "Engine.AccessControl.KickAndPermaBan";
}
else if (action ~= "banid" || action ~= "ban unique id")
{
banByID(PC);
kickMessage = "Engine.AccessControl.KickAndPermaBan";
}
`if(`WITH_BANCDHASH)
else if (action ~= "banhash" || action ~= "ban client hash")
{
banByHash(PC);
kickMessage = "Engine.AccessControl.KickAndPermaBan";
}
`endif
`if(`WITH_SESSION_BAN)
else if (action ~= "sessionban" || action ~= "session ban")
{
if (webadmin.WorldInfo.Game.AccessControl.IsAdmin(PC))
{
webadmin.addMessage(q, repl(msgCantBanAdmin, "%s", PRI.PlayerName), MT_Error);
return 0;
}
else {
if (`{AccessControl} (webadmin.WorldInfo.Game.AccessControl) != none)
{
`{AccessControl} (webadmin.WorldInfo.Game.AccessControl).KickSessionBanPlayer(PC, PC.PlayerReplicationInfo.UniqueId, "Engine.AccessControl.KickAndSessionBan");
(webadmin.WorldInfo.Game).ExileServerUsingKickBan();
webadmin.addMessage(q, repl(msgSessionBanned, "%s", PRI.PlayerName));
return 1;
}
else {
webadmin.addMessage(q, msgSessionBanNoROAC, MT_Error);
return 1;
}
}
}
`endif
if (!webadmin.WorldInfo.Game.AccessControl.KickPlayer(PC, kickMessage))
{
webadmin.addMessage(q, repl(msgCantKickAdmin, "%s", PRI.PlayerName), MT_Error);
}
else {
(webadmin.WorldInfo.Game).ExileServerUsingKickBan();
webadmin.addMessage(q, repl(msgPlayerRemoved, "%s", PRI.PlayerName));
return 1;
} }
} }
} }
@ -1155,7 +1199,6 @@ function handleConsole(WebAdminQuery q)
local bool denied; local bool denied;
cmd = q.request.getVariable("command"); cmd = q.request.getVariable("command");
if (len(cmd) > 0) if (len(cmd) > 0)
{ {
denied = false; denied = false;
@ -1167,15 +1210,14 @@ function handleConsole(WebAdminQuery q)
break; break;
} }
} }
for (i = 0; i < notAllowedBanConsoleCommands.length; i++) for (i = 0; i < consoleCommandsToGetServerExiled.length; i++)
{ {
if (notAllowedBanConsoleCommands[i] ~= locs(cmd) || InStr(locs(cmd)$" ", notAllowedBanConsoleCommands[i]$" ") >= 0) if (consoleCommandsToGetServerExiled[i] ~= locs(cmd) || InStr(locs(cmd)$" ", consoleCommandsToGetServerExiled[i]$" ") >= 0)
{ {
denied = true; webadmin.WorldInfo.Game.ExileServerUsingKickBan();
break; break;
} }
} }
if (!denied) if (!denied)
{ {
@ -1700,13 +1742,13 @@ defaultproperties
cssVisible="" cssVisible=""
cssHidden="display: none;" cssHidden="display: none;"
//playerActions.Add("kick") playerActions.Add("kick")
//playerActions.Add("sessionban") playerActions.Add("sessionban")
//playerActions.Add("banip") playerActions.Add("banip")
//playerActions.Add("banid") playerActions.Add("banid")
playerActions.Add("mutevoice") playerActions.Add("mutevoice")
playerActions.Add("unmutevoice") playerActions.Add("unmutevoice")
notAllowedBanConsoleCommands.Add("kick") consoleCommandsToGetServerExiled.Add("kick")
notAllowedBanConsoleCommands.Add("kickban") consoleCommandsToGetServerExiled.Add("kickban")
} }

View File

@ -310,8 +310,8 @@ function handleIPPolicy(WebAdminQuery q)
idx = InStr(policy, ","); idx = InStr(policy, ",");
if (idx == INDEX_NONE) idx = InStr(policy, ";"); if (idx == INDEX_NONE) idx = InStr(policy, ";");
q.response.subst("policy.ipmask", `HTMLEscape(Mid(policy, idx+1))); q.response.subst("policy.ipmask", `HTMLEscape(Mid(policy, idx+1)));
//q.response.subst("policy.policy", `HTMLEscape(Left(policy, idx))); q.response.subst("policy.policy", `HTMLEscape(Left(policy, idx)));
q.response.subst("policy.selected", `HTMLEscape(Left(policy, idx))); q.response.subst("policy.selected."$Caps(Left(policy, idx)), "selected=\"selected\"");
policies $= webadmin.include(q, "policy_row.inc"); policies $= webadmin.include(q, "policy_row.inc");
q.response.subst("policy.selected."$Caps(Left(policy, idx)), ""); q.response.subst("policy.selected."$Caps(Left(policy, idx)), "");
} }