1
0
KF2-Dev-Scripts/KFGame/Classes/KFPerk_Berserker.uc
2023-09-21 22:31:11 +03:00

1057 lines
32 KiB
Ucode
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//=============================================================================
// KFPerk_Berserker
//=============================================================================
// The berserker perk class
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
// Christian "schneidzekk" Schneider
//=============================================================================
class KFPerk_Berserker extends KFPerk
native;
//`include(KFOnlineStats.uci)
var const PerkSkill BerserkerDamage;
var const PerkSkill DamageResistance; // 0% resistance to all damage Max 25%
var const PerkSkill NightVision;
var const private float NinjaSprintModifer;
var const private float SmashStumbleModifier;
var const private int SmallRadiusSizeSQ;
var private bool bParryActive;
var const private float ParryDuration;
var const private float ParrySpeed;
var const private float FurySpeed;
var const private float SmashKnockdownMultiplier;
var const private float SpartanZedTimeResistance;
var const private float SpeedDamageModifier;
var const private float SmashHeadDamageModifier;
var const private float VampireAttackSpeedModifier;
var const private float ParryDamageReduction;
var const private int RageRadius;
var const private float RageFleeDuration;
var const private int RageFleeDistance;
var const private int RageDialogEvent;
// Events to play when parry skill is activated / deactivated
var AkEvent ParrySkillSoundModeStart;
var AkEvent ParrySkillSoundModeStop;
enum EBerserkPerkSkills
{
EBerserkerFortitude,
EBerserkerNinja,
EBerserkerVampire,
EBerserkerSpeed,
EBerserkerResistance,
EBerserkerParry,
EBerserkerSmash,
EBerserkerFury,
EBerserkerRage,
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
{
// specific abilities
virtual UBOOL UseBlueMeleeTrails();
virtual UBOOL UseRedMeleeTrails();
}
/*********************************************************************************************
* @name Perk init and spawning
******************************************************************************************** */
/** (Server) Modify Instigator settings based on selected perk */
function ApplySkillsToPawn()
{
super.ApplySkillsToPawn();
if( OwnerPawn != none )
{
OwnerPawn.bMovesFastInZedTime = IsFastInZedTime() || IsSWATEnforcerActiveForWeekly();
}
}
/**
* @brief Modifies skill related attributes
*/
simulated protected event PostSkillUpdate()
{
super.PostSkillUpdate();
// enable tick if we have the regeneration skill
SetTickIsDisabled( !IsNinjaActive() );
//clear parry
ParryTimer();
}
function ClearPerkEffects()
{
ParryTimer();
Super.ClearPerkEffects();
}
reliable client function ClientClearPerkEffects()
{
if (Role != ROLE_Authority)
{
super.ClientClearPerkEffects();
ParryTimer();
}
}
/**
* @brief script tick (server)
*
* @param DeltaTime time since the last tick
*/
event Tick( float DeltaTime )
{
super.Tick( DeltaTime );
if( IsNinjaActive() )
{
TickRegen( DeltaTime );
}
}
simulated event float GetZedTimeSpeedScale()
{
return GetZedTimeSpeedScaleForColliseum();
}
/*********************************************************************************************
* @name Passive skills functions
********************************************************************************************* */
/**
* @brief Modifies the damage dealt
*
* @param InDamage damage
* @param DamageCauser weapon or projectile (optional)
* @param MyKFPM the zed damaged (optional)
* @param DamageInstigator responsible controller (optional)
* @param class DamageType the damage type used (optional)
*/
simulated function ModifyDamageGiven( out int InDamage, optional Actor DamageCauser, optional KFPawn_Monster MyKFPM, optional KFPlayerController DamageInstigator, optional class<KFDamageType> DamageType, optional int HitZoneIdx )
{
local KFWeapon MyKFWeapon;
local float TempDamage;
TempDamage = InDamage;
if( DamageCauser != none )
{
if( DamageCauser.IsA( 'Weapon' ) )
{
MyKFWeapon = KFWeapon(DamageCauser);
}
else if( DamageCauser.IsA( 'Projectile' ) )
{
MyKFWeapon = KFWeapon(DamageCauser.Owner);
}
`QALog( GetFuncName() @ "Base damage:" @ InDamage , bLogPerk);
if( ((MyKFWeapon != none && IsWeaponOnPerk( MyKFWeapon,, self.class )) || IsDamageTypeOnPerk( DamageType )) && !IsBlastBrawlers(MyKFWeapon) )
{
TempDamage += InDamage * GetPassiveValue( BerserkerDamage, CurrentLevel );
if( IsSpeedActive() )
{
TempDamage += InDamage * static.GetSpeedDamageModifier();
`QALog( GetFuncName() @ "Speed extra damage:" @ InDamage * static.GetSpeedDamageModifier(), bLogPerk);
}
if( GetParryActive() )
{
TempDamage += InDamage * GetSkillValue( PerkSkills[EBerserkerParry] );
`QALog( GetFuncName() @ "Parry extra damage:" @ InDamage * GetSkillValue( PerkSkills[EBerserkerParry] ), bLogPerk);
}
if( HitZoneIdx == HZI_HEAD && IsSmashActive() )
{
TempDamage += InDamage * static.GetSmashHeadDamageModifier();
`QALog( GetFuncName() @ "Smash head hit extra damage:" @ InDamage * static.GetSmashHeadDamageModifier(), bLogPerk);
}
}
}
`QALog( "Total Damage Given" @ MyKFWeapon @ GetPercentage(InDamage, Round(TempDamage)) @ "Start/End" @ InDamage @ Round(TempDamage), bLogPerk );
InDamage = Round( TempDamage );
}
/**
* @brief Some perk skills modify the melee attack speed
*
* @param InDuration delay in between attacks
*/
simulated function ModifyMeleeAttackSpeed( out float InDuration, KFWeapon KFW )
{
local float TempDuration;
if( KFW == none || !KFW.IsMeleeWeapon() || IsBlastBrawlers(KFW) )
{
return;
}
TempDuration = InDuration;
if( IsSpeedActive() )
{
`QALog("Speed reduced the attack delay duration by:" @ TempDuration * GetSkillValue( PerkSkills[EBerserkerSpeed] ), bLogPerk);
TempDuration -= InDuration * GetSkillValue( PerkSkills[EBerserkerSpeed] );
`QALog( "Speed Melee Attack Speed pct" @ GetSkillValue( PerkSkills[EBerserkerSpeed] ) @ InDuration @ TempDuration, bLogPerk );
}
if( GetParryActive() )
{
`QALog("Parry reduced the attack delay duration by:" @ TempDuration * ParrySpeed, bLogPerk);
TempDuration -= InDuration * ParrySpeed;
`QALog( "Parry Melee Attack Speed pct" @ ParrySpeed, bLogPerk );
}
if( IsFuryActive() && KFW.CurrentFireMode == 0 )
{
`QALog("Fury reduced the attack delay duration by:" @ TempDuration * GetSkillValue( PerkSkills[EBerserkerFury] ), bLogPerk);
TempDuration -= InDuration * GetFurySpeed();
`QALog( "Fury Melee Attack Speed pct" @ GetFurySpeed(), bLogPerk );
}
if( IsVampireActive() )
{
`QALog("Vampire reduced the attack delay duration by:" @ TempDuration * static.GetVampireAttackSpeedModifier(), bLogPerk);
TempDuration -= InDuration * static.GetVampireAttackSpeedModifier();
`QALog( "Vampire Melee Attack Speed pct" @ static.GetVampireAttackSpeedModifier(), bLogPerk );
}
`QALog( "Total, Melee Attack Speed" @ GetPercentage( InDuration, TempDuration ) @ "Start/End" @ InDuration @ TempDuration, bLogPerk );
InDuration = TempDuration;
}
simulated final static function float GetFurySpeed()
{
return default.FurySpeed;
}
/**
* @brief Weapons and perk skills can affect the jog/sprint speed
*
* @param Speed jog speed
*/
simulated function ModifySpeed( out float Speed )
{
local KFWeapon MyKFWeapon;
local KFInventoryManager KFIM;
if( !IsNinjaActive() )
{
return;
}
MyKFWeapon = GetOwnerWeapon();
if( MyKFWeapon == none && CheckOwnerPawn() )
{
KFIM = KFInventoryManager(OwnerPawn.InvManager);
if( KFIM != none && KFIM.PendingWeapon != none )
{
MyKFWeapon = KFWeapon(KFIM.PendingWeapon);
}
}
if (MyKFWeapon != none &&
((MyKFWeapon.IsMeleeWeapon() && !IsBlastBrawlers(MyKFWeapon)) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{
Speed += Speed * GetSkillValue( PerkSkills[EBerserkerNinja] );
}
}
/**
* @brief Weapons and perk skills can affect the jog/sprint speed
*
* @param Speed sprint speed
*/
simulated function ModifySprintSpeed( out float Speed )
{
local KFWeapon MyKFWeapon;
local KFInventoryManager KFIM;
if( !IsNinjaActive() )
{
return;
}
MyKFWeapon = GetOwnerWeapon();
if( MyKFWeapon == none && CheckOwnerPawn() )
{
KFIM = KFInventoryManager(OwnerPawn.InvManager);
if( KFIM != none && KFIM.PendingWeapon != none )
{
MyKFWeapon = KFWeapon(KFIM.PendingWeapon);
}
}
if (MyKFWeapon != none &&
((MyKFWeapon.IsMeleeWeapon() && !IsBlastBrawlers(MyKFWeapon)) || IsWeaponOnPerk(MyKFWeapon,, self.class)))
{
Speed += Speed * static.GetNinjaSprintModifier();
}
}
simulated static final function float GetNinjaSprintModifier()
{
return default.NinjaSprintModifer;
}
/**
* @brief Modifies the damage taken
*
* @param InDamage damage
* @param DamageType the damage type used (optional)
*/
function ModifyDamageTaken( out int InDamage, optional class<DamageType> DamageType, optional Controller InstigatedBy )
{
local float TempDamage;
if( InDamage <= 0 )
{
return;
}
TempDamage = InDamage;
if( IsResistanceActive() )
{
TempDamage -= InDamage * GetSkillValue( PerkSkills[EBerserkerResistance] );
if( ClassIsChildOf( Damagetype, class'KFDT_Toxic' ) ||
ClassIsChildOf( Damagetype, class'KFDT_Sonic' ) )
{
TempDamage -= InDamage * GetSkillValue( PerkSkills[EBerserkerResistance] );
}
}
if( GetParryActive() )
{
TempDamage -= InDamage * static.GetParryDamageModifier();
`QALog( "Parry DamageResistance =" @ InDamage * static.GetParryDamageModifier(), bLogPerk );
}
TempDamage -= InDamage * GetPassiveDamageResistance( CurrentLevel );
`QALog( "Total DamageResistance" @ DamageType @ GetPercentage( InDamage, Round( TempDamage ) ) @ "Start/End" @ InDamage @ TempDamage, bLogPerk );
InDamage = Round( TempDamage );
}
/**
* @brief Calculates the additional ammo per perk level
*
* @param Level Current perk level
* @return additional ammo
*/
simulated private final static function float GetPassiveDamageResistance( int Level )
{
return default.DamageResistance.Increment * FFloor( float( Level ) / 5.f );
}
function ModifyBloatBileDoT( out float DoTScaler )
{
super.ModifyBloatBileDoT( DoTScaler );
`QALog( "BloatBile DotScaler" @ GetPercentage( DoTScaler, DoTScaler - GetSkillValue( PerkSkills[EBerserkerResistance] ) ),bLogPerk );
DotScaler -= GetSkillValue( PerkSkills[EBerserkerResistance] );
}
simulated static function GetPassiveStrings( out array<string> PassiveValues, out array<string> Increments, byte Level )
{
PassiveValues[0] = Round(GetPassiveValue( default.BerserkerDamage, Level ) * 100) $ "%";
PassiveValues[1] = Round(GetPassiveDamageResistance( Level ) * 100) $ "%";
PassiveValues[2] = "";
PassiveValues[3] = "";
Increments[0] = "[" @ Left( string( default.BerserkerDamage.Increment * 100 ), InStr(string(default.BerserkerDamage.Increment * 100), ".") + 2 )$"% /" @ default.LevelString @ "]";
Increments[1] = "[" @ Left( string( default.DamageResistance.Increment * 100 ), InStr(string(default.DamageResistance.Increment * 100), ".") + 2 )$"% / 5" @ default.LevelString @ "]";
Increments[2] = "";
Increments[3] = "";
}
/*********************************************************************************************
* @name Selectable skills functions
********************************************************************************************* */
/**
* @brief modifies the players health
*
* @param InHealth health
*/
function ModifyHealth( out int InHealth )
{
local float TempHealth;
TempHealth = InHealth;
if( IsFortitudeActive() )
{
TempHealth += InHealth * GetSKillValue( PerkSkills[EBerserkerFortitude] );
`QALog( "Health passive + Fortitude health" @ InHealth, bLogPerk );
}
InHealth = Round( TempHealth );
}
/**
* @brief Adds health points earned by killing with the vampire skill
*
* @param KFPC Owning controller
*/
function AddVampireHealth( KFPlayerController KFPC, class<DamageType> DT )
{
if( IsDamageTypeOnPerk( class<KFDamageType>(DT) ) && IsVampireActive() && KFPC.Pawn != none )
{
KFPC.Pawn.HealDamage( GetSkillValue( PerkSkills[EBerserkerVampire] ), KFPC, class'KFDT_Healing', false, false );
`QALog( "Vampire, HealDamage" @ GetSkillValue( PerkSkills[EBerserkerVampire] ), bLogPerk );
}
}
/**
* @brief Skills can effect the hard (secondary) melee attack damage
*
* @param int The damage to modify
*/
function ModifyHardAttackDamage( out int InDamage )
{
local float TempDamage;
TempDamage = InDamage;
if( IsSmashActive() )
{
TempDamage += InDamage * GetSkillValue( PerkSkills[EBerserkerSmash] );
`QALog( GetFuncName() @ "Smash extra damage:" @ InDamage * GetSkillValue( PerkSkills[EBerserkerSmash] ), bLogPerk);
}
`QALog( "Total Hard Atk Dmg" @ GetPercentage( InDamage, TempDamage != InDamage ? Round( TempDamage ) : InDamage ) @ "Start/End" @ InDamage @ ( TempDamage != InDamage ? Round( TempDamage ) : InDamage ), bLogPerk );
InDamage = Round( TempDamage );
}
/**
* @brief Skills can effect the light melee attack damage
*
* @param int The damage to modify
*/
function ModifyLightAttackDamage( out int InDamage )
{
local float TempDamage;
if( IsFuryActive() )
{
TempDamage = InDamage;
TempDamage += InDamage * GetSkillValue( PerkSkills[EBerserkerFury] );
InDamage = Round( TempDamage );
}
}
/**
* @brief Called when the parry time ends
*/
simulated function ParryTimer()
{
bParryActive = false;
SetTickIsDisabled( !IsNinjaActive() );
if( OwnerPC != none )
{
OwnerPC.SetPerkEffect( false );
}
OwnerPC.PlaySoundBase( ParrySkillSoundModeStop, true );
}
/**
* @brief Change this to effect intensity change when we have it
*
* @param float InDuration The effects duration
*/
function ModifyScreamEffectDuration( out float InDuration )
{
if( IsResistanceActive() )
{
InDuration *= 1 - GetSkillValue( PerkSkills[EBerserkerResistance]);
}
}
/**
* @brief skills and weapons can modify the stumbling power
* @return stumbling power modifier
*/
function float GetStumblePowerModifier( optional KFPawn KFP, optional class<KFDamageType> DamageType, optional out float CooldownModifier, optional byte BodyPart )
{
if( IsSmashActive() && IsDamageTypeOnPerk(DamageType) )
{
return static.GetSmashStumbleModifier();
}
return 0.f;
}
final static function float GetSmashStumbleModifier()
{
return default.SmashStumbleModifier;
}
/**
* @brief Gets the small radius kill xp based on the difficulty
*
* @param Difficulty game difficulty
* @return XP
*/
static function int GetSmallRadiusKillXP( byte Difficulty )
{
return default.SecondaryXPModifier[Difficulty];
}
/**
* @brief Gets the squared small kill radius
*
* @return UUs squared
*/
static function int GetSmallRadiusKillDistanceSQ()
{
return default.SmallRadiusSizeSQ;
}
/**
* @brief can the perk earn small radius kill xp
* @return perk == berserker && DT is on perk
*/
function bool CanEarnSmallRadiusKillXP( class<DamageType> DT )
{
return IsDamageTypeOnPerk( class<KFDamageType>(DT) ) || IsBackupDamageTypeOnPerk( DT );
}
simulated function float GetSirenScreamStrength()
{
if( IsResistanceActive() )
{
return 1 - GetSkillValue( PerkSkills[EBerserkerResistance] );
}
return super.GetSirenScreamStrength();
}
function NotifyZedTimeStarted()
{
local Pawn OtherPawn;
local KFPlayerController KFPC;
local KFPowerUp PowerUp;
local KFAIController KFAIC;
local KFGameInfo GameInfo;
local bool bScaredAI;
local bool bCannotBeHealed;
local KFGameReplicationInfo KFGRI;
if( IsRageActive() && OwnerPawn != none )
{
KFPC = KFPlayerController(OwnerPawn.Controller);
if( KFPC != none )
{
PowerUp = KFPC.GetPowerUp();
bCannotBeHealed = (PowerUp != none && !PowerUp.CanBeHealedWhilePowerUpIsActive);
GameInfo = KFGameInfo(WorldInfo.Game);
if(GameInfo != none)
{
bCannotBeHealed = bCannotBeHealed ||(GameInfo.OutbreakEvent != none && GameInfo.OutbreakEvent.ActiveEvent.bCannotBeHealed);
}
// VIP cannot heal
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
if (KFGRI != none
&& KFGRI.VIPRepPlayer != none
&& KFGRI.VIPRepPlayer == KFPlayerReplicationInfo(KFPC.PlayerReplicationInfo))
{
bCannotBeHealed = true;
}
}
if( bCannotBeHealed == false )
{
OwnerPawn.Health += OwnerPawn.HealthMax * GetSkillValue( PerkSkills[EBerserkerRage] );
OwnerPawn.Health = Min( OwnerPawn.Health, OwnerPawn.HealthMax );
}
foreach WorldInfo.AllPawns( class'Pawn', OtherPawn, OwnerPawn.Location, static.GetRageRadius() )
{
KFAIC = KFAIController(OtherPawn.Controller);
if( KFAIC != none )
{
KFAIC.DoPauseAI( static.GetRageFleeDuration(), true, false, true);
//KFAIC.DoFleeFrom( OwnerPawn, static.GetRageFleeDuration(), static.GetRageFleeDistance(),, true );
bScaredAI = true;
}
else
{
continue;
}
}
if( bScaredAI )
{
KFGameInfo(Owner.WorldInfo.Game).DialogManager.PlayDialogEvent( OwnerPawn, RageDialogEvent );
}
}
}
private static function int GetRageRadius()
{
return default.RageRadius;
}
private static function float GetRageFleeDuration()
{
return default.RageFleeDuration;
}
private static function int GetRageFleeDistance()
{
return default.RageFleeDistance;
}
/**
* @brief Skills can modify the zed time time dilation
*
* @param StateName used weapon's state
* @return time dilation modifier
*/
simulated function float GetZedTimeModifier( KFWeapon W )
{
local name StateName;
StateName = W.GetStateName();
if( IsWeaponOnPerk( W,, self.class ) && ZedTimeModifyingStates.Find( StateName ) != INDEX_NONE )
{
if( CouldSpartanBeActive() )
{
return default.SpartanZedTimeResistance;
}
}
return 0.f;
}
private static function float GetSpeedDamageModifier()
{
return default.SpeedDamageModifier;
}
private static function float GetSmashHeadDamageModifier()
{
return default.SmashHeadDamageModifier;
}
private static function float GetVampireAttackSpeedModifier()
{
return default.VampireAttackSpeedModifier;
}
private static function float GetParryDamageModifier()
{
return default.ParryDamageReduction;
}
/*********************************************************************************************
* @name Getters / Setters
********************************************************************************************* */
/**
* @brief Checks if the fortitude skill is active
*
* @return true if we have the skill enabled
*/
final private function bool IsFortitudeActive()
{
return PerkSkills[EBerserkerFortitude].bActive && IsPerkLevelAllowed(EBerserkerFortitude);
}
/**
* @brief Checks if the ninja skill is active
*
* @return true if we have the skill enabled
*/
simulated final private function bool IsNinjaActive()
{
return PerkSkills[EBerserkerNinja].bActive && IsPerkLevelAllowed(EBerserkerNinja);
}
/**
* @brief Checks if the Vampire skill is active
*
* @return true if we have the skill enabled
*/
simulated private function bool IsVampireActive()
{
return PerkSkills[EBerserkerVampire].bActive && IsPerkLevelAllowed(EBerserkerVampire);
}
/**
* @brief Checks if the Speed skill is active
*
* @return true if we have the skill enabled
*/
simulated final private function bool IsSpeedActive()
{
return PerkSkills[EBerserkerSpeed].bActive && IsPerkLevelAllowed(EBerserkerSpeed);
}
/**
* @brief Do we need to tick the perk?
*
* @return true if perk needs to be ticked
*/
simulated function bool PerkNeedsTick()
{
return IsNinjaActive();
}
/**
* @brief Player successfully parried an attack, save it if Parry skill active
*/
simulated function SetSuccessfullParry()
{
if( IsParryActive() )
{
bParryActive = true;
SetTickIsDisabled( false );
SetTimer( ParryDuration, false, nameOf( ParryTimer ));
if( OwnerPC != none )
{
OwnerPC.SetPerkEffect( true );
}
OwnerPC.PlaySoundBase( ParrySkillSoundModeStart, true );
}
}
/**
* @brief Checks if the Parry skill is active
*
* @return true if we have the skill enabled
*/
simulated function bool IsParryActive()
{
return PerkSkills[EBerserkerParry].bActive && IsPerkLevelAllowed(EBerserkerParry);
}
/**
* @brief Checks if the resistance skill is active
*
* @return true if we have the skill enabled
*/
simulated function bool IsResistanceActive()
{
return PerkSkills[EBerserkerResistance].bActive && IsPerkLevelAllowed(EBerserkerResistance);
}
/**
* @brief Check if conditions for the Parry skill are true
* @return true if parried attack successfully earlier and Parry skill active
*/
simulated event bool GetParryActive()
{
return IsParryActive() && bParryActive;
}
/**
* @brief Checks if the night vision skill is active
* @return true if we have the skill enabled
*/
simulated function bool HasNightVision()
{
return true;
}
/**
* @brief Checks if the Smash skill is active
*
* @return true if we have the skill enabled
*/
final simulated protected event bool IsSmashActive()
{
return PerkSkills[EBerserkerSmash].bActive && IsPerkLevelAllowed(EBerserkerSmash);
}
/**
* @brief Checks if the fury skill is active
*
* @return true if we have the skill enabled
*/
final simulated private function bool IsFuryActive()
{
return PerkSkills[EBerserkerFury].bActive && IsPerkLevelAllowed(EBerserkerFury);
}
/**
* @brief Checks if the player can be grabbed by clots
*
* @return true if we are not grabbable
*/
function bool CanNotBeGrabbed()
{
return true;
}
/**
* @brief Checks if the menace skill is active and if we are in zed time
*
* @return true if we have the skill enabled
*/
simulated private event bool IsRageActive()
{
return PerkSkills[EBerserkerRage].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerRage) && !ShouldDisableZedTimeSkillsForWeekly();
}
/**
* @brief Checks if the Spartan skill is active and if we are in zed time
*
* @return true if we have the skill enabled
*/
simulated final private event bool IsSpartanActive()
{
return PerkSkills[EBerserkerSpartan].bActive && WorldInfo.TimeDilation < 1.f && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
}
simulated private event bool CouldSpartanBeActive()
{
return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
}
/**
* @brief Spartan resists zed time. You move at normal speed.
*
* @return true if Spartan are active
*/
simulated function bool IsFastInZedTime()
{
return PerkSkills[EBerserkerSpartan].bActive && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly();
}
simulated function bool IsFastInZedTimeOutbreak()
{
return ShouldDisableZedTimeSkillsForWeekly();
}
/**
* @brief Checks if we should be using instigator for time dilation
* while in zed time. Specific to Spartan mode for Berserker.
*
* @return true if Spartan is active
*/
simulated event bool ShouldUseFastInstigatorDilation(KFWeapon Weap)
{
if (PerkSkills[EBerserkerSpartan].bActive && Weap != none && IsPerkLevelAllowed(EBerserkerSpartan) && !ShouldDisableZedTimeSkillsForWeekly())
{
return Weap.GetWeaponPerkClass(default.Class) == default.Class;
}
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
********************************************************************************************* */
simulated function class<EmitterCameraLensEffectBase> GetPerkLensEffect( class<KFDamageType> DmgType )
{
if( ClassIsChildOf( DmgType, class'KFDT_Toxic' ) )
{
return IsResistanceActive() ? DmgType.default.AltCameraLensEffectTemplate : super.GetPerkLensEffect( DmgType );
}
return super.GetPerkLensEffect( DmgType );
}
/*********************************************************************************************
* @name Logging / debug
********************************************************************************************* */
/** QA Logging - Report Perk Info */
simulated function LogPerkSkills()
{
super.LogPerkSkills();
if ( bLogPerk )
{
}
}
static function PrepareExplosive( Pawn ProjOwner, KFProjectile Proj, optional float AuxRadiusMod = 1.0f, optional float AuxDmgMod = 1.0f )
{
local KFPlayerController KFPC;
local KFPerk InstigatorPerk;
if( ProjOwner != none )
{
// Change the radius and damage based on the perk
if( ProjOwner.Role == ROLE_Authority )
{
KFPC = KFPlayerController( ProjOwner.Controller );
if( KFPC != none )
{
InstigatorPerk = KFPC.GetPerk();
Proj.ExplosionTemplate.DamageRadius *= InstigatorPerk.GetAoERadiusModifier() * AuxRadiusMod;
}
}
}
}
DefaultProperties
{
ParryDuration=8.f //6.f //10.f
ParrySpeed=0.05
FurySpeed=0.05
NinjaSprintModifer=0.25
SmashStumbleModifier=2.f
SpartanZedTimeResistance=1.f //Attack speed zed time resistance
SpeedDamageModifier=0.2
SmashHeadDamageModifier=0.25
VampireAttackSpeedModifier=0.2f
ParryDamageReduction=0.3f //0.25f //0.4f //0.75
RageRadius=1000 //300
RageFleeDuration=5.f //3
RageFleeDistance=2500 //5000
RageDialogEvent=229
RegenerationInterval=1
RegenerationAmount=1 //2
ZedTimeModifyingStates(0)="MeleeChainAttacking"
ZedTimeModifyingStates(1)="MeleeAttackBasic"
ZedTimeModifyingStates(2)="MeleeHeavyAttacking"
ZedTimeModifyingStates(3)="MeleeSustained"
ZedTimeModifyingStates(4)="WeaponFiring"
PerkIcon=Texture2D'UI_PerkIcons_TEX.UI_PerkIcon_Berserker'
ProgressStatID=STATID_Bsrk_Progress
PerkBuildStatID=STATID_Bsrk_Build
SecondaryXPModifier(0)=6
SecondaryXPModifier(1)=8
SecondaryXPModifier(2)=10
SecondaryXPModifier(3)=14
SmallRadiusSizeSQ=40000
PrimaryWeaponDef=class'KFWeapDef_Crovel'
KnifeWeaponDef=class'KFweapDef_Knife_Berserker'
GrenadeWeaponDef=class'KFWeapDef_Grenade_Berserker'
BerserkerDamage=(Name="Berserker Damage",Increment=0.01,Rank=0,StartingValue=0.f,MaxValue=0.25)
DamageResistance=(Name="Damage Resistance",Increment=0.02f,Rank=0,StartingValue=0.f,MaxValue=0.1f) //0.03f, 0, 0.f, 0.15f
NightVision=(Name="Night Vision",Increment=0.f,Rank=0,StartingValue=0.f,MaxValue=0.f)
PerkSkills(EBerserkerFortitude)=(Name="Fortitude",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Fortitude",Increment=0.f,Rank=0,StartingValue=1.0,MaxValue=1.0) //0.75
PerkSkills(EBerserkerNinja)=(Name="Ninja",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Ninja",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f)
PerkSkills(EBerserkerVampire)=(Name="Vampire",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Vampire",Increment=0.f,Rank=0,StartingValue=3.f,MaxValue=3.f) //4.f
PerkSkills(EBerserkerSpeed)=(Name="Speed",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Speed",Increment=0.f,Rank=0,StartingValue=0.2f,MaxValue=0.2f)
PerkSkills(EBerserkerResistance)=(Name="Resistance",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_PoisonResistance",Increment=0.f,Rank=0,StartingValue=0.15f,MaxValue=0.15f) //0.15 //0.2
PerkSkills(EBerserkerParry)=(Name="Parry",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Parry",Increment=0.f,Rank=0,StartingValue=0.35,MaxValue=0.35)
PerkSkills(EBerserkerSmash)=(Name="Smash",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Smash",Increment=0.f,Rank=0,StartingValue=0.5f,MaxValue=0.5f)
PerkSkills(EBerserkerFury)=(Name="Fury",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Intimidate",Increment=0.f,Rank=0,StartingValue=0.3f,MaxValue=0.3f)
PerkSkills(EBerserkerRage)=(Name="Rage",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Menace",Increment=0.f,Rank=0,StartingValue=0.5,MaxValue=0.5)
PerkSkills(EBerserkerSpartan)=(Name="Spartan",IconPath="UI_PerkTalent_TEX.berserker.UI_Talents_Berserker_Flash",Increment=0.f,Rank=0,StartingValue=0.f,MaxValue=0.f)
ParrySkillSoundModeStart=AkEvent'WW_GLO_Runtime.Play_Beserker_Parry_Mode'
ParrySkillSoundModeStop=AkEvent'WW_GLO_Runtime.Stop_Beserker_Parry_Mode'
// Skill tracking
HitAccuracyHandicap=2.5
HeadshotAccuracyHandicap=-2.0
AutoBuyLoadOutPath=(class'KFWeapDef_Crovel', class'KFWeapDef_Katana', class'KFWeapDef_Pulverizer', class'KFWeapDef_Eviscerator', class'KFWeapDef_AbominationAxe')
// Prestige Rewards
PrestigeRewardItemIconPaths[0]="WEP_SkinSet_Prestige01_Item_TEX.knives.BerserkerKnife_PrestigePrecious_Mint_large"
PrestigeRewardItemIconPaths[1]="WEP_SkinSet_Prestige02_Item_TEX.tier01.Crovel_PrestigePrecious_Mint_large"
PrestigeRewardItemIconPaths[2]="WEP_skinset_prestige03_itemtex.tier02.Katana_PrestigePrecious_Mint_large"
PrestigeRewardItemIconPaths[3]="wep_skinset_prestige04_itemtex.tier03.Pulverizer_PrestigePrecious_Mint_Large"
PrestigeRewardItemIconPaths[4]="WEP_SkinSet_Prestige05_Item_TEX.tier04.Eviscerator_PrestigePrecious_Mint_large"
}