2020-12-13 15:01:13 +00:00
|
|
|
//=============================================================================
|
|
|
|
// KFPawn_ZedHusk
|
|
|
|
//=============================================================================
|
|
|
|
// Husk
|
|
|
|
// Attack Sequences:
|
|
|
|
// Atk_Combo1_V1
|
|
|
|
// Atk_Flame_V1
|
|
|
|
// Atk_Shoot_V1
|
|
|
|
// Atk_Shoot_V2
|
|
|
|
// Atk_Suicide_V1
|
|
|
|
//=============================================================================
|
|
|
|
// Killing Floor 2
|
|
|
|
// Copyright (C) 2016 Tripwire Interactive LLC
|
|
|
|
//=============================================================================
|
|
|
|
class KFPawn_ZedHusk extends KFPawn_Monster;
|
|
|
|
|
|
|
|
/** Struct containing difficulty-based settings for the fireball */
|
|
|
|
struct sHuskFireballSettings
|
|
|
|
{
|
|
|
|
/** Whether the explosion should trigger a secondary ground fire explosion */
|
|
|
|
var bool bSpawnGroundFire;
|
|
|
|
|
|
|
|
/** How much momentum to apply to the fireball */
|
|
|
|
var float ExplosionMomentum;
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Fireball projectile attack */
|
|
|
|
var protected const class<KFProj_Husk_Fireball> FireballClass;
|
|
|
|
|
|
|
|
/** Fireball settings, set per difficulty */
|
|
|
|
var transient sHuskFireballSettings FireballSettings;
|
|
|
|
|
|
|
|
/** Player-controlled offset for firing fireballs. */
|
|
|
|
var protected vector PlayerFireOffset;
|
|
|
|
|
|
|
|
/** HitZoneIndex of backpack zone */
|
|
|
|
const BackpackZoneIndex = 3;
|
|
|
|
|
|
|
|
/** Explosion template for backpack/suicide */
|
|
|
|
var protected KFGameExplosion ExplosionTemplate;
|
|
|
|
|
|
|
|
/** Set when husk blows up to make sure it only happens once */
|
|
|
|
var protected transient bool bHasExploded;
|
|
|
|
var protected transient bool bHasSuicideExploded;
|
|
|
|
|
|
|
|
/** Chest light */
|
|
|
|
var protected PointLightComponent ChestLightComponent;
|
|
|
|
var protected const name ChestLightSocketName;
|
|
|
|
var protected const float FireballChargeLightRadius;
|
|
|
|
var protected const float AmbientLightRadiusInterpSpeed;
|
|
|
|
var protected const float FireballLightRadiusInterpSpeed;
|
|
|
|
var protected const float FireballLightMinBrightness;
|
|
|
|
var protected const float FireballLightMaxBrightness;
|
|
|
|
var protected bool bUseFireballLightRadius;
|
|
|
|
|
|
|
|
/** Called from Possessed event when this controller has taken control of a Pawn */
|
|
|
|
function PossessedBy( Controller C, bool bVehicleTransition )
|
|
|
|
{
|
|
|
|
local KFGameReplicationInfo KFGRI;
|
|
|
|
|
|
|
|
super.PossessedBy( C, bVehicleTransition );
|
|
|
|
|
|
|
|
// Set our difficulty-based settings
|
|
|
|
if( !bVersusZed )
|
|
|
|
{
|
|
|
|
KFGRI = KFGameReplicationInfo( WorldInfo.GRI );
|
|
|
|
if( KFGRI != none )
|
|
|
|
{
|
|
|
|
FireballSettings = class<KFDifficulty_Husk>(DifficultySettings).static.GetFireballSettings( self, KFGRI );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize our light */
|
|
|
|
simulated function SetCharacterArch( KFCharacterInfoBase Info, optional bool bForce )
|
|
|
|
{
|
|
|
|
super.SetCharacterArch( Info, bForce );
|
|
|
|
|
|
|
|
if( WorldInfo.NetMode != NM_DedicatedServer && !ChestLightComponent.bAttached && WorldInfo.GetDetailMode() > DM_Low )
|
|
|
|
{
|
|
|
|
Mesh.AttachComponentToSocket( ChestLightComponent, ChestLightSocketName );
|
|
|
|
ChestLightComponent.SetEnabled( true );
|
|
|
|
`LightPool.RegisterPointLight( ChestLightComponent, LPP_GameplayUsed );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* Flamethrower attack handling
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/** Turns medium range flamethrower effect on */
|
|
|
|
simulated function ANIMNOTIFY_FlameThrowerOn()
|
|
|
|
{
|
|
|
|
if( IsDoingSpecialMove(SM_HoseWeaponAttack) )
|
|
|
|
{
|
|
|
|
KFSM_Husk_FlameThrowerAttack(SpecialMoves[SpecialMove]).TurnOnFlamethrower();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Turns medium range flamethrower effect off */
|
|
|
|
simulated function ANIMNOTIFY_FlameThrowerOff()
|
|
|
|
{
|
|
|
|
if( IsDoingSpecialMove(SM_HoseWeaponAttack) )
|
|
|
|
{
|
|
|
|
KFSM_Husk_FlameThrowerAttack(SpecialMoves[SpecialMove]).TurnOffFlamethrower();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Called from melee special move when it's interrupted */
|
|
|
|
function NotifyAnimInterrupt( optional AnimNodeSequence SeqNode )
|
|
|
|
{
|
|
|
|
if( MyKFAIC != none && (IsImpaired() || IsHeadless()) && !MyKFAIC.GetActiveCommand().IsA('AICommand_HeadlessWander') )
|
|
|
|
{
|
|
|
|
class'AICommand_HeadlessWander'.Static.HeadlessWander( MyKFAIC );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* Fireball projectile attack handling
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
simulated function ANIMNOTIFY_WarnZedsOfFireball()
|
|
|
|
{
|
|
|
|
local Actor HitActor;
|
|
|
|
local PlayerController PC;
|
|
|
|
local KFPawn_Monster HitMonster;
|
|
|
|
local vector FireLocation;
|
|
|
|
local vector TraceStart, TraceEnd, HitLocation, HitNormal;
|
|
|
|
local vector DangerPoint, AimDirection;
|
|
|
|
|
|
|
|
if( Role == ROLE_Authority )
|
|
|
|
{
|
|
|
|
if( IsHumanControlled() )
|
|
|
|
{
|
|
|
|
PC = PlayerController( Controller );
|
|
|
|
if( PC == none )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
FireLocation = GetPawnViewLocation() + (PlayerFireOffset >> GetViewRotation());
|
|
|
|
|
|
|
|
TraceStart = PC.PlayerCamera.CameraCache.POV.Location;
|
|
|
|
TraceEnd = PC.PlayerCamera.CameraCache.POV.Location + vector(PC.PlayerCamera.CameraCache.POV.Rotation)*5000.f;
|
|
|
|
|
|
|
|
HitActor = Trace( HitLocation, HitNormal, TraceEnd, TraceStart, TRUE,,,TRACEFLAG_Bullet );
|
|
|
|
|
|
|
|
if( HitActor != none )
|
|
|
|
{
|
|
|
|
AimDirection = HitLocation - FireLocation;
|
|
|
|
TraceEnd = HitLocation;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AimDirection = TraceEnd - FireLocation;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AimDirection = MyKFAIC.Enemy.Location - Location;
|
|
|
|
FireLocation = MyKFAIC.Enemy.Location;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach TraceActors(class'KFPawn_Monster', HitMonster, HitLocation, HitNormal, FireLocation, Location, vect(50,50,50))
|
|
|
|
{
|
|
|
|
if( HitMonster.MyKFAIC != none )
|
|
|
|
{
|
|
|
|
// Get the closest point from the hit monster to the line trace to determine which way it should evade
|
|
|
|
PointDistToLine(HitMonster.Location, AimDirection, Location, DangerPoint);
|
|
|
|
|
|
|
|
// Tell the zed to evade away from the DangerPoint
|
|
|
|
HitMonster.MyKFAIC.ReceiveLocationalWarning( DangerPoint, Location );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFireLightEnabled( bVersusZed ? false : true );
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function SetFireLightEnabled( bool bEnable )
|
|
|
|
{
|
|
|
|
if( WorldInfo.NetMode == NM_DedicatedServer || bPlayedDeath || ChestLightComponent == none || !ChestLightComponent.bAttached )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bUseFireballLightRadius = bEnable && !WorldInfo.bDropDetail && `TimeSince(ChestLightComponent.LastRenderTime) < 0.25f;
|
|
|
|
|
|
|
|
if( bEnable )
|
|
|
|
{
|
|
|
|
ChestLightComponent.MinBrightness = FireballLightMinBrightness;
|
|
|
|
ChestLightComponent.MaxBrightness = FireballLightMaxBrightness;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ChestLightComponent.MinBrightness = default.ChestLightComponent.MinBrightness;
|
|
|
|
ChestLightComponent.MaxBrightness = default.ChestLightComponent.MaxBrightness;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated event Tick( float DeltaTime )
|
|
|
|
{
|
|
|
|
super.Tick( DeltaTime );
|
|
|
|
|
|
|
|
if( WorldInfo.NetMode == NM_DedicatedServer || bPlayedDeath || ChestLightComponent == none || !ChestLightComponent.bAttached )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( bUseFireballLightRadius )
|
|
|
|
{
|
|
|
|
if( ChestLightComponent.Radius < FireballChargeLightRadius )
|
|
|
|
{
|
|
|
|
ChestLightComponent.SetRadius( FInterpConstantTo(ChestLightComponent.Radius, FireballChargeLightRadius, DeltaTime, FireballLightRadiusInterpSpeed) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( ChestLightComponent.Radius > default.ChestLightComponent.Radius )
|
|
|
|
{
|
|
|
|
ChestLightComponent.SetRadius( FInterpConstantTo(ChestLightComponent.Radius, default.ChestLightComponent.Radius, DeltaTime, AmbientLightRadiusInterpSpeed) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** AnimNotify which launches the fireball projectile */
|
|
|
|
simulated function ANIMNOTIFY_HuskFireballAttack()
|
|
|
|
{
|
|
|
|
local KFAIController_ZedHusk HuskAIC;
|
|
|
|
local KFSM_Husk_FireballAttack FireballSM;
|
|
|
|
|
|
|
|
if( MyKFAIC != none )
|
|
|
|
{
|
|
|
|
FireballSM = KFSM_Husk_FireBallAttack( SpecialMoves[SpecialMove] );
|
|
|
|
if( FireballSM != none )
|
|
|
|
{
|
|
|
|
FireballSM.NotifyFireballFired();
|
|
|
|
}
|
|
|
|
|
|
|
|
HuskAIC = KFAIController_ZedHusk(MyKFAIC);
|
|
|
|
if( HuskAIC != none )
|
|
|
|
{
|
|
|
|
HuskAIC.ShootFireball( FireballClass, FireballSM.GetFireOffset() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SetFireLightEnabled( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Overridden for updating spray collision */
|
|
|
|
simulated event vector GetWeaponStartTraceLocation( optional weapon CurrentWeapon )
|
|
|
|
{
|
|
|
|
local vector Loc;
|
|
|
|
local rotator Rot;
|
|
|
|
local KFAIController_ZedHusk HuskAIC;
|
|
|
|
|
|
|
|
if( MyKFAIC != none )
|
|
|
|
{
|
|
|
|
HuskAIC = KFAIController_ZedHusk(MyKFAIC);
|
|
|
|
if( HuskAIC != none )
|
|
|
|
{
|
|
|
|
Mesh.GetSocketWorldLocationAndRotation( HuskAIC.FireballSocketName, Loc, Rot );
|
|
|
|
return Loc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.GetWeaponStartTraceLocation();
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Overriden to ensure flame thrower turns off on death or destruction */
|
|
|
|
simulated function TerminateEffectsOnDeath()
|
|
|
|
{
|
|
|
|
if( IsDoingSpecialMove(SM_HoseWeaponAttack) )
|
|
|
|
{
|
|
|
|
SpecialMoveHandler.EndSpecialMove();
|
|
|
|
}
|
|
|
|
|
|
|
|
if( ChestLightComponent != none && ChestLightComponent.bAttached )
|
|
|
|
{
|
|
|
|
ChestLightComponent.DetachFromAny();
|
|
|
|
ChestLightComponent = none;
|
|
|
|
}
|
|
|
|
|
|
|
|
super.TerminateEffectsOnDeath();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* Explode / Suicide
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/** Called from SkeletalMeshComponent::PlayParticleEffect() */
|
|
|
|
simulated function OnAnimNotifyParticleSystemSpawned( const AnimNotify_PlayParticleEffect AnimNotifyData, ParticleSystemComponent PSC )
|
|
|
|
{
|
|
|
|
// Since anim notify particle systems can spawn after the special move ends, we need to kill any latent suicide FX
|
|
|
|
if( !IsDoingSpecialMove(GetSuicideSM()) && InStr(string(PSC.Template.Name), "suicide",, true) != INDEX_NONE )
|
|
|
|
{
|
|
|
|
PSC.SetActive( false );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
super.OnAnimNotifyParticleSystemSpawned( AnimNotifyData, PSC );
|
|
|
|
}
|
|
|
|
|
|
|
|
simulated function ESpecialMove GetSuicideSM()
|
|
|
|
{
|
|
|
|
return SM_Suicide;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Initialize GoreHealth (Server only) */
|
|
|
|
function ApplySpecialZoneHealthMod(float HealthMod)
|
|
|
|
{
|
|
|
|
Super.ApplySpecialZoneHealthMod(HealthMod);
|
|
|
|
|
|
|
|
HitZones[BackpackZoneIndex].GoreHealth = default.HitZones[BackpackZoneIndex].GoreHealth * HealthMod;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Override for Husk's backpack explosion */
|
|
|
|
function bool CanInjureHitZone(class<DamageType> DamageType, int HitZoneIdx)
|
|
|
|
{
|
|
|
|
if( HitZoneIdx == BackpackZoneIndex && (!bPlayedDeath || WorldInfo.TimeSeconds == TimeOfDeath) )
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.CanInjureHitZone(DamageType, HitZoneIdx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Reliably play any gore effects related to a zone/limb being dismembered */
|
|
|
|
simulated function HitZoneInjured(optional int HitZoneIdx=INDEX_None)
|
|
|
|
{
|
|
|
|
Super.HitZoneInjured(HitZoneIdx);
|
|
|
|
|
|
|
|
// Server only since we use a replicated explosion actor
|
|
|
|
if ( Role == ROLE_Authority && HitZoneIdx == BackpackZoneIndex )
|
|
|
|
{
|
|
|
|
TriggerExplosion( true );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Called when husk backpack is exploded or when husk suicides */
|
|
|
|
function TriggerExplosion(optional bool bIgnoreHumans)
|
|
|
|
{
|
|
|
|
local KFExplosionActorReplicated ExploActor;
|
|
|
|
local Controller DamageInstigator, OldController;
|
|
|
|
local bool bExplodeOnDeath;
|
|
|
|
|
|
|
|
bExplodeOnDeath = WorldInfo.TimeSeconds == TimeOfDeath;
|
|
|
|
|
|
|
|
// Only living husks can explode... and only once
|
|
|
|
if( !bHasExploded && (!bPlayedDeath || bExplodeOnDeath) )
|
|
|
|
{
|
|
|
|
OldController = Controller;
|
|
|
|
bHasExploded = true;
|
|
|
|
bHasSuicideExploded = !bIgnoreHumans;
|
|
|
|
|
|
|
|
if( Role == ROLE_Authority )
|
|
|
|
{
|
|
|
|
// explode using the given template
|
|
|
|
ExploActor = Spawn(class'KFExplosionActorReplicated', self);
|
|
|
|
if (ExploActor != None)
|
|
|
|
{
|
|
|
|
DamageInstigator = (bIgnoreHumans && LastHitBy != none && KFPlayerController(LastHitBy) != none) ? LastHitBy : MyKFAIC;
|
|
|
|
ExploActor.InstigatorController = DamageInstigator;
|
|
|
|
ExploActor.Instigator = self;
|
|
|
|
|
|
|
|
// Force ourselves to get hit. These settings are not replicated,
|
|
|
|
// but they only really make a difference on the server anyway.
|
|
|
|
ExploActor.Attachee = self;
|
|
|
|
if ( bIgnoreHumans )
|
|
|
|
{
|
|
|
|
ExplosionTemplate.ActorClassToIgnoreForDamage = class'KFPawn_Human';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ExplosionTemplate.ActorClassToIgnoreForDamage = none;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExploActor.Explode(ExplosionTemplate, vect(0,0,1));
|
|
|
|
}
|
|
|
|
|
|
|
|
// Make sure we're dead!
|
|
|
|
if( !bPlayedDeath || bExplodeOnDeath )
|
|
|
|
{
|
|
|
|
TakeRadiusDamage(DamageInstigator, 10000, ExplosionTemplate.DamageRadius, ExplosionTemplate.MyDamageType, ExplosionTemplate.MomentumTransferScale, Location, true, self);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OnExploded( OldController );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Overriden in subclasses. Determines if we should explode on death in specific game modes */
|
|
|
|
function bool WeeklyShouldExplodeOnDeath()
|
|
|
|
{
|
|
|
|
return !bHasExploded || !bHasSuicideExploded;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Do any explosion death-related actions */
|
|
|
|
simulated function OnExploded( Controller SuicideController );
|
|
|
|
|
|
|
|
/*********************************************************************************************
|
|
|
|
* Damage handling
|
|
|
|
**********************************************************************************************/
|
|
|
|
|
|
|
|
/** Make sure damage to myself is enough to kill me when it's my suicide attack */
|
|
|
|
function AdjustDamage(out int InDamage, out vector Momentum, Controller InstigatedBy, vector HitLocation, class<DamageType> DamageType, TraceHitInfo HitInfo, Actor DamageCauser)
|
|
|
|
{
|
|
|
|
Super.AdjustDamage( InDamage, Momentum, InstigatedBy, HitLocation, DamageType, HitInfo, DamageCauser );
|
|
|
|
|
|
|
|
if( MyKFAIC != none && MyKFAIC.IsSuicidal() && InstigatedBy == MyKFAIC && IsDoingSpecialMove(SM_Suicide) )
|
|
|
|
{
|
|
|
|
InDamage = 10000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function NotifyTakeHit(Controller InstigatedBy, vector HitLocation, int Damage, class<DamageType> DamageType, vector Momentum, Actor DamageCauser)
|
|
|
|
{
|
|
|
|
local KFAIDirector KFAID;
|
|
|
|
local Pawn NewEnemy;
|
|
|
|
|
|
|
|
// @todo: move to controller NotifyTakeHit
|
|
|
|
if( Role == ROLE_Authority && MyKFAIC != none && MyKFAIC.IsSuicidal() && AICommand_Husk_Suicide(MyKFAIC.GetActiveCommand()) == none )
|
|
|
|
{
|
|
|
|
MyKFAIC.AIActionStatus = "Suicidal!";
|
|
|
|
//TODO: Don't sprint if it's obvious that my initial suicide goal is a short distance from here
|
|
|
|
bIsSprinting = true; // Don't trust SetSprinting since the result might depend on game difficulty level
|
|
|
|
|
|
|
|
if( FRand() < 0.4f || MyKFAIC.Enemy == none || MyKFAIC.Enemy.Health <= 0 )
|
|
|
|
{
|
|
|
|
KFAID = KFGameInfo(WorldInfo.Game).GetAIDirector();
|
|
|
|
if( KFAID != none )
|
|
|
|
{
|
|
|
|
NewEnemy = Pawn( KFAID.FindEnemyFor( MyKFAIC, true ) );
|
|
|
|
if( NewEnemy != none )
|
|
|
|
{
|
|
|
|
MyKFAIC.SetEnemy( NewEnemy );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Super.NotifyTakeHit(InstigatedBy, HitLocation, Damage, DamageType, Momentum, DamageCauser);
|
|
|
|
}
|
|
|
|
|
|
|
|
function PlayHit( float Damage, Controller InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, TraceHitInfo HitInfo )
|
|
|
|
{
|
|
|
|
super.PlayHit( Damage, InstigatedBy, HitLocation, damageType, Momentum, HitInfo );
|
|
|
|
|
|
|
|
// This forces the husk to die immediately when hit by an emp during his suicide move
|
|
|
|
if( bEmpDisrupted && IsDoingSpecialMove(SM_Suicide) )
|
|
|
|
{
|
|
|
|
Died(InstigatedBy, DamageType, HitLocation);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Interrupt certain moves when bEmpDisrupted is set */
|
|
|
|
function OnStackingAfflictionChanged(byte Id)
|
|
|
|
{
|
|
|
|
Super.OnStackingAfflictionChanged(Id);
|
|
|
|
|
|
|
|
if( MyKFAIC == none || !IsAliveAndWell() )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( bEMPDisrupted )
|
|
|
|
{
|
|
|
|
if( IsDoingSpecialMove(SM_StandAndShootAttack) || IsDoingSpecialMove(SM_HoseWeaponAttack) )
|
|
|
|
{
|
|
|
|
EndSpecialMove();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Returns (hardcoded) dialog event ID for when trader gives advice to player who was killed by this zed type */
|
|
|
|
static function int GetTraderAdviceID()
|
|
|
|
{
|
|
|
|
return 45;//TRAD_AdviceHusk
|
|
|
|
}
|
|
|
|
|
|
|
|
DefaultProperties
|
|
|
|
{
|
|
|
|
LocalizationKey=KFPawn_ZedHusk
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Stats
|
|
|
|
XPValues(0)=15
|
|
|
|
XPValues(1)=20
|
|
|
|
XPValues(2)=27
|
|
|
|
XPValues(3)=31
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Content
|
|
|
|
MonsterArchPath="ZED_ARCH.ZED_Husk_Archetype"
|
|
|
|
DifficultySettings=class'KFDifficulty_Husk'
|
|
|
|
FireballClass= class'KFGameContent.KFProj_Husk_Fireball'
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Visuals
|
|
|
|
Begin Object Class=PointLightComponent Name=ChestLightComponent0
|
|
|
|
FalloffExponent=2.f
|
|
|
|
Brightness=0.5f
|
|
|
|
Radius=160.f
|
|
|
|
LightColor=(R=250,G=155,B=40,A=255)
|
|
|
|
CastShadows=false
|
|
|
|
bCastPerObjectShadows=false
|
|
|
|
bEnabled=false
|
|
|
|
LightingChannels=(Indoor=true,Outdoor=true,bInitialized=true)
|
|
|
|
|
|
|
|
// light anim
|
|
|
|
AnimationType=1
|
|
|
|
AnimationFrequency=2.0f
|
|
|
|
MinBrightness=0.4f
|
|
|
|
MaxBrightness=0.5f
|
|
|
|
End Object
|
|
|
|
ChestLightComponent=ChestLightComponent0
|
|
|
|
|
|
|
|
ChestLightSocketName=ChestLightSocket
|
|
|
|
FireballChargeLightRadius=256.f
|
|
|
|
AmbientLightRadiusInterpSpeed=300.f
|
|
|
|
FireballLightRadiusInterpSpeed=100.f
|
|
|
|
FireballLightMinBrightness=1.1f
|
|
|
|
FireballLightMaxBrightness=1.25f
|
|
|
|
|
|
|
|
// Explosion light
|
|
|
|
Begin Object Class=PointLightComponent Name=ExplosionPointLight
|
|
|
|
LightColor=(R=245,G=190,B=140,A=255)
|
|
|
|
bCastPerObjectShadows=false
|
|
|
|
End Object
|
|
|
|
|
|
|
|
// Backpack/Suicide Explosion
|
|
|
|
Begin Object Class=KFGameExplosion Name=ExploTemplate0
|
|
|
|
Damage=190
|
|
|
|
DamageRadius=500
|
|
|
|
DamageFalloffExponent=0.5f
|
|
|
|
DamageDelay=0.f
|
|
|
|
bFullDamageToAttachee=true
|
|
|
|
|
|
|
|
// Damage Effects
|
|
|
|
MyDamageType=class'KFDT_Explosive_HuskSuicide'
|
|
|
|
FractureMeshRadius=200.0
|
|
|
|
FracturePartVel=500.0
|
|
|
|
ExplosionEffects=KFImpactEffectInfo'FX_Impacts_ARCH.Explosions.HuskSuicide_Explosion'
|
|
|
|
ExplosionSound=AkEvent'WW_ZED_Husk.ZED_Husk_SFX_Suicide_Explode'
|
|
|
|
MomentumTransferScale=1.f
|
|
|
|
|
|
|
|
// Dynamic Light
|
|
|
|
ExploLight=ExplosionPointLight
|
|
|
|
ExploLightStartFadeOutTime=0.0
|
|
|
|
ExploLightFadeOutTime=0.5
|
|
|
|
|
|
|
|
// Camera Shake
|
|
|
|
CamShake=CameraShake'FX_CameraShake_Arch.Misc_Explosions.HuskSuicide'
|
|
|
|
CamShakeInnerRadius=450
|
|
|
|
CamShakeOuterRadius=900
|
|
|
|
CamShakeFalloff=1.f
|
|
|
|
bOrientCameraShakeTowardsEpicenter=true
|
|
|
|
End Object
|
|
|
|
ExplosionTemplate=ExploTemplate0
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Special Moves
|
|
|
|
Begin Object Name=SpecialMoveHandler_0
|
|
|
|
SpecialMoveClasses(SM_Taunt) = class'KFGame.KFSM_Zed_Taunt'
|
|
|
|
SpecialMoveClasses(SM_Suicide) = class'KFSM_Husk_Suicide'
|
|
|
|
SpecialMoveClasses(SM_Evade) = class'KFSM_Evade'
|
|
|
|
SpecialMoveClasses(SM_Evade_Fear) = class'KFSM_Evade_Fear'
|
|
|
|
SpecialMoveClasses(SM_StandAndShootAttack)= class'KFSM_Husk_FireBallAttack'
|
|
|
|
SpecialMoveClasses(SM_HoseWeaponAttack)= class'KFSM_Husk_FlameThrowerAttack'
|
|
|
|
End Object
|
|
|
|
|
|
|
|
// for reference: Vulnerability=( default, head, legs, arms, special)
|
|
|
|
IncapSettings(AF_Stun)= (Vulnerability=(0.5, 2.0, 0.5, 0.5, 2.0), Cooldown=5.0, Duration=1.5)
|
|
|
|
IncapSettings(AF_Knockdown)=(Vulnerability=(0.4), Cooldown=3)
|
|
|
|
IncapSettings(AF_Stumble)= (Vulnerability=(0.4), Cooldown=1.0)
|
|
|
|
IncapSettings(AF_GunHit)= (Vulnerability=(0.5, 0.5, 0.2, 0.2, 0.5), Cooldown=0.2)
|
|
|
|
IncapSettings(AF_MeleeHit)= (Vulnerability=(1.0), Cooldown=0.75)
|
|
|
|
IncapSettings(AF_FirePanic)=(Vulnerability=(0.0), Cooldown=5.0, Duration=2.0)
|
|
|
|
IncapSettings(AF_EMP)= (Vulnerability=(2.5), Cooldown=5.0, Duration=3.0)
|
|
|
|
IncapSettings(AF_Poison)= (Vulnerability=(0.15), Cooldown=20.5, Duration=5.0)
|
|
|
|
IncapSettings(AF_Microwave)=(Vulnerability=(3), Cooldown=8.5, Duration=4.0)
|
|
|
|
IncapSettings(AF_Freeze)= (Vulnerability=(1.0), Cooldown=1.5, Duration=1.0)
|
|
|
|
IncapSettings(AF_Snare)= (Vulnerability=(1.0, 2.0, 1.0, 1.0, 2.0), Cooldown=5.5, Duration=3.0)
|
|
|
|
IncapSettings(AF_Bleed)= (Vulnerability=(1.0))
|
|
|
|
|
|
|
|
Begin Object Name=Afflictions_0
|
|
|
|
FireFullyCharredDuration=5
|
|
|
|
AfflictionClasses(AF_EMP)=class'KFAffliction_EMPDisrupt'
|
|
|
|
End Object
|
|
|
|
|
|
|
|
ParryResistance=2
|
|
|
|
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(0.75))) //0.5
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_AssaultRifle', DamageScale=(0.65))) //0.5
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Shotgun', DamageScale=(1.0)))
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Handgun', DamageScale=(0.85))) //0.4
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Rifle', DamageScale=(0.7))) //1
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Slashing', DamageScale=(0.75))) //0.45
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Bludgeon', DamageScale=(0.85))) //0.45
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Fire', DamageScale=(0.5))) //0
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Microwave', DamageScale=(1.15)))
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Explosive', DamageScale=(0.75)))
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Piercing', DamageScale=(0.5)))
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Toxic', DamageScale=(0.25)))
|
|
|
|
|
|
|
|
//Special Case damage resistance
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_9mm', DamageScale=(1.0))
|
|
|
|
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Rem1858', DamageScale=(1.0))
|
|
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Movement / Physics
|
|
|
|
GroundSpeed=170.0f
|
|
|
|
SprintSpeed=450.0f
|
|
|
|
|
|
|
|
RotationRate=(Pitch=50000,Yaw=66000,Roll=50000)
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// AI / Navigation
|
|
|
|
ControllerClass=class'KFAIController_ZedHusk'
|
|
|
|
DamageRecoveryTimeHeavy=0.75f
|
|
|
|
DamageRecoveryTimeMedium=1.0f
|
|
|
|
|
|
|
|
KnockdownImpulseScale=1.0f
|
|
|
|
|
|
|
|
ElitePawnClass.Add(class'KFPawn_ZedDAR_EMP')
|
|
|
|
ElitePawnClass.Add(class'KFPawn_ZedDAR_Laser')
|
|
|
|
ElitePawnClass.Add(class'KFPawn_ZedDAR_Rocket')
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Gameplay
|
|
|
|
Begin Object Name=MeleeHelper_0
|
|
|
|
BaseDamage=15.f
|
|
|
|
MaxHitRange=180.f
|
|
|
|
MomentumTransfer=25000.f
|
|
|
|
MyDamageType=class'KFDT_Slashing_ZedWeak'
|
|
|
|
End Object
|
|
|
|
|
|
|
|
Health=462 // KF1=600
|
|
|
|
DoshValue=17
|
|
|
|
Mass=65.f
|
|
|
|
|
|
|
|
//DamageTypeModifiers.Add((DamageType=class'KFDT_Fire', DamageScale=(0.5f)))
|
|
|
|
|
|
|
|
// Penetration
|
|
|
|
PenetrationResistance=2.0
|
|
|
|
|
|
|
|
// Custom Hit Zones (HeadHealth, SkinTypes, etc...)
|
|
|
|
HeadlessBleedOutTime=5.f
|
|
|
|
HitZones[HZI_HEAD]=(ZoneName=head, BoneName=Head, Limb=BP_Head, GoreHealth=200, DmgScale=1.001, SkinID=1) // KF1=200 //154
|
|
|
|
HitZones[3] =(ZoneName=heart, BoneName=Spine2, Limb=BP_Special, GoreHealth=75, DmgScale=1.5, SkinID=2) //0.5
|
|
|
|
HitZones[8] =(ZoneName=rforearm, BoneName=RightForearm, Limb=BP_RightArm, GoreHealth=20, DmgScale=0.5, SkinID=3)
|
|
|
|
|
|
|
|
WeakSpotSocketNames.Add(WeakPointSocket1) // Backpack
|
|
|
|
|
|
|
|
bDisableTurnInPlace=false
|
|
|
|
|
|
|
|
`if(`notdefined(ShippingPC))
|
|
|
|
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Husk';
|
|
|
|
`endif
|
|
|
|
|
|
|
|
// ---------------------------------------------
|
|
|
|
// Spawning
|
|
|
|
MinSpawnSquadSizeType=EST_Medium
|
2021-09-02 21:46:08 +00:00
|
|
|
|
|
|
|
ZEDCowboyHatAttachName=Hat_Attach
|
2020-12-13 15:01:13 +00:00
|
|
|
}
|