1
0
KF2-Dev-Scripts/KFGameContent/Classes/KFPawn_ZedScrake.uc

414 lines
14 KiB
Ucode
Raw Normal View History

2020-12-13 15:01:13 +00:00
//=============================================================================
// KFPawn_ZedScrake
//=============================================================================
// Scrake
//=============================================================================
// Killing Floor 2
// Copyright (C) 2015 Tripwire Interactive LLC
//=============================================================================
class KFPawn_ZedScrake extends KFPawn_Monster;
var protected AkComponent ChainsawIdleAkComponent;
var protected AkEvent PlayChainsawIdleAkEvent;
var protected AkEvent StopChainsawIdleAkEvent;
// Chainsaw Particle Fx
var name ExhaustSocketName;
var ParticleSystem ExhaustTemplate;
var ParticleSystemComponent ExhaustPSC;
/** Threshold of health below which the Scrake will start rage charging on normal */
var(RageCharge) float RageHealthThresholdNormal;
/** Threshold of health below which the Scrake will start rage charging on hard */
var(RageCharge) float RageHealthThresholdHard;
/** Threshold of health below which the Scrake will start rage charging on suicidal */
var(RageCharge) float RageHealthThresholdSuicidal;
/** Threshold of health below which the Scrake will start rage charging on hell on earth */
var(RageCharge) float RageHealthThresholdHellOnEarth;
/** Threshold of health below which the Scrake will start rage charging (determined by difficulty) */
var(RageCharge) float RageHealthThreshold;
// handle chainsaw idle here instead of through an anim-notify so that we can actually turn it off
simulated event PostBeginPlay()
{
super.PostBeginPlay();
if( WorldInfo.NetMode != NM_DedicatedServer )
{
ChainsawIdleAkComponent.PlayEvent( PlayChainsawIdleAkEvent, true, true );
CreateExhaustFx();
}
}
/** Overridden to support loading the alternate body mic */
simulated function SetCharacterArch( KFCharacterInfoBase Info, optional bool bForce )
{
super.SetCharacterArch( Info );
// Set our secondary material, attach our healing syringes
if( WorldInfo.NetMode != NM_DedicatedServer && Mesh != None )
{
CharacterMICs[1] = Mesh.CreateAndSetMaterialInstanceConstant( 2 );
}
}
function PossessedBy( Controller C, bool bVehicleTransition )
{
local KFAIController_Monster KFAICM;
super.PossessedBy( C, bVehicleTransition );
if( !IsHumanControlled() )
{
KFAICM = KFAIController_Monster( C );
if( KFAICM != none )
{
// Determine what rage health threshold to use
if( KFAICM.Skill == class'KFGameDifficultyInfo'.static.GetDifficultyValue(0) ) // Normal
{
RageHealthThreshold = RageHealthThresholdNormal;
}
else if( KFAICM.Skill <= class'KFGameDifficultyInfo'.static.GetDifficultyValue(1) ) // Hard
{
RageHealthThreshold = RageHealthThresholdHard;
}
else if( KFAICM.Skill <= class'KFGameDifficultyInfo'.static.GetDifficultyValue(2) ) // Suicidal
{
RageHealthThreshold = RageHealthThresholdSuicidal;
}
else // Hell on Earth
{
RageHealthThreshold = RageHealthThresholdHellOnEarth;
}
}
}
else
{
if( WorldInfo.Game.GetModifiedGameDifficulty() == 0 )
{
RageHealthThreshold = RageHealthThresholdNormal;
}
else if( WorldInfo.Game.GetModifiedGameDifficulty() == 1 )
{
RageHealthThreshold = RageHealthThresholdHard;
}
else if( WorldInfo.Game.GetModifiedGameDifficulty() == 2 )
{
RageHealthThreshold = RageHealthThresholdSuicidal;
}
else
{
RageHealthThreshold = RageHealthThresholdHellOnEarth;
}
}
}
simulated function CreateExhaustFx()
{
local vector Loc;
local rotator Rot;
if ( ExhaustPSC == none && ExhaustTemplate != None )
{
if ( Mesh.GetSocketWorldLocationAndRotation(ExhaustSocketName, Loc, Rot) )
{
ExhaustPSC = new(self) class'ParticleSystemComponent';
ExhaustPSC.SetTemplate( ExhaustTemplate );
Mesh.AttachComponentToSocket(ExhaustPSC, ExhaustSocketName);
}
}
}
event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
{
2023-05-11 15:55:04 +00:00
local class<KFDamageType> KFDT;
2020-12-13 15:01:13 +00:00
super.TakeDamage( Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser );
if( bCanRage && !bPlayedDeath && (GetHealthPercentage() < RageHealthThreshold || GetHeadHealthPercent() < RageHealthThreshold) )
{
2023-05-11 15:55:04 +00:00
KFDT = class<KFDamageType>(DamageType);
if (KFDT != none && KFDT.default.bCanEnrage == false)
{
return;
}
2020-12-13 15:01:13 +00:00
SetEnraged( true );
}
}
/** Enrage this Scrake! */
//simulated function SetEnraged( bool bNewEnraged );
/** Return current rage status */
simulated event bool IsEnraged()
{
return bIsEnraged;
}
/** Returns TRUE if this zed can block attacks */
function bool CanBlock()
{
return !bIsEnraged && super.CanBlock();
}
/** Called on server when pawn should have been crippled (e.g. Headless) */
function CauseHeadTrauma( float BleedOutTime=5.f )
{
super.CauseHeadTrauma( BleedOutTime );
// End rage when decapped
SetEnraged( false );
}
/** Overridden to support secondary body material */
simulated event NotifyGoreMeshActive()
{
super.NotifyGoreMeshActive();
// Set our secondary MIC
if( WorldInfo.NetMode != NM_DedicatedServer && Mesh != None )
{
CharacterMICs[1] = Mesh.CreateAndSetMaterialInstanceConstant( 2 );
}
}
simulated function TerminateEffectsOnDeath()
{
CleanupChainsaw();
super.TerminateEffectsOnDeath();
}
simulated function CleanupChainsaw()
{
local MaterialInstanceConstant ChainsawBladeMIC;
if( WorldInfo.NetMode != NM_DedicatedServer )
{
ChainsawBladeMIC = Mesh.CreateAndSetMaterialInstanceConstant(1);
ChainsawBladeMIC.SetScalarParameterValue('Animation_Scalar', 0.f);
ChainsawIdleAkComponent.PlayEvent( StopChainsawIdleAkEvent );
// Murder chainsaw Fx
if( ExhaustPSC != none )
{
ExhaustPSC.DeactivateSystem();
DetachComponent(ExhaustPSC);
WorldInfo.MyEmitterPool.OnParticleSystemFinished(ExhaustPSC);
ExhaustPSC = None;
}
}
}
/** Returns (hardcoded) dialog event ID for when players spots this zed type */
function int GetSpotterDialogID()
{
return 129;//SPOTZ_Scrake
}
/** Returns (hardcoded) dialog event ID for when trader gives advice to player who was killed by this zed type */
static function int GetTraderAdviceID()
{
return 42;//TRAD_AdviceScrake
}
/*********************************************************************************************
* Movement
********************************************************************************************* */
function SetSprinting( bool bNewSprintStatus )
{
if( bEmpDisrupted && bNewSprintStatus && (MyKFAIC == none || !MyKFAIC.bHasDebugCommand) )
{
return;
}
super.SetSprinting( bNewSprintStatus );
}
/*********************************************************************************************
* Notifications
********************************************************************************************* */
/** Interrupt certain moves when bEmpDisrupted is set */
function OnStackingAfflictionChanged(byte Id)
{
Super.OnStackingAfflictionChanged(Id);
if( bEMPDisrupted && bIsSprinting && MyKFAIC != none && IsAliveAndWell() )
{
SetSprinting( false );
}
}
defaultproperties
{
LocalizationKey=KFPawn_ZedScrake
bLargeZed=true
Begin Object Name=KFPawnSkeletalMeshComponent
// Enabling kinematic for physics interaction while alive. (see also MinDistFactorForKinematicUpdate)
bUpdateKinematicBonesFromAnimation=true
End Object
// ---------------------------------------------
// Stats
XPValues(0)=34
XPValues(1)=45
XPValues(2)=60
XPValues(3)=69
// ---------------------------------------------
// Content
MonsterArchPath="ZED_ARCH.ZED_Scrake_Archetype"
PawnAnimInfo=KFPawnAnimInfo'ZED_Scrake_ANIM.Scrake_AnimGroup'
DifficultySettings=class'KFDifficulty_Scrake'
ExhaustTemplate=ParticleSystem'ZED_Scrake_EMIT.FX_Scrake_Smoke_Idle_01'
ExhaustSocketName=FX_Exhaust
// ---------------------------------------------
// Special Moves
Begin Object Name=SpecialMoveHandler_0
SpecialMoveClasses(SM_Taunt)=class'KFGame.KFSM_Zed_Taunt'
SpecialMoveClasses(SM_Evade)=class'KFSM_Evade'
SpecialMoveClasses(SM_Block)=class'KFSM_Block'
End Object
// for reference: Vulnerability=(default, head, legs, arms, special)
IncapSettings(AF_Stun)= (Vulnerability=(0.5, 1.0, 0.5, 0.5, 0.5), Cooldown=5.0, Duration=1.55) //cooldown 10
IncapSettings(AF_Knockdown)=(Vulnerability=(0.4, 0.4, 0.5, 0.4), Cooldown=10) //leg0.4
IncapSettings(AF_Stumble)= (Vulnerability=(0.3), Cooldown=3.5) //2.5
IncapSettings(AF_GunHit)= (Vulnerability=(0.2), Cooldown=1.7)
IncapSettings(AF_MeleeHit)= (Vulnerability=(1.0), Cooldown=1.35)
IncapSettings(AF_Poison)= (Vulnerability=(0.15), Cooldown=20.5, Duration=5.0)
IncapSettings(AF_Microwave)=(Vulnerability=(0.5), Cooldown=10.0, Duration=2.5)
IncapSettings(AF_FirePanic)=(Vulnerability=(0.4), Cooldown=7.0, Duration=3.5)
IncapSettings(AF_EMP)= (Vulnerability=(0.98), Cooldown=10.0, Duration=2.2)
IncapSettings(AF_Freeze)= (Vulnerability=(0.98), Cooldown=6.0, Duration=1.0)
IncapSettings(AF_Snare)= (Vulnerability=(1.0, 2.0, 1.0, 1.0), Cooldown=5.5, Duration=3.0)
IncapSettings(AF_Bleed)= (Vulnerability=(0.75)) //0.5
2022-05-11 15:13:25 +00:00
IncapSettings(AF_Shrink)= (Vulnerability=(1.0)) // Normal Vulnerability
2022-06-14 15:52:40 +00:00
ShrinkEffectModifier = 0.1f
2022-05-11 15:13:25 +00:00
2020-12-13 15:01:13 +00:00
Begin Object Name=Afflictions_0
FireFullyCharredDuration=5
AfflictionClasses(AF_EMP)=class'KFAffliction_EMPDisrupt'
End Object
ParryResistance=4
// ---------------------------------------------
// Gameplay
bCanGrabAttack=false
ZedBumpDamageScale=0.1f
Begin Object Name=MeleeHelper_0
BaseDamage=30.f
MaxHitRange=200.f
MomentumTransfer=45000.f
MyDamageType=class'KFGameContent.KFDT_Slashing_Scrake'
End Object
Health=1100
DoshValue=75
Mass=130.f
// Penetration
PenetrationResistance=4.0
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Submachinegun', DamageScale=(1.0))) //0.5
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_AssaultRifle', DamageScale=(1.0))) //0.7
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Shotgun', DamageScale=(0.9))) //0.8
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Handgun', DamageScale=(0.80))) //0.8
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Rifle', DamageScale=(1.0)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Slashing', DamageScale=(1.0))) //0.75
DamageTypeModifiers.Add((DamageType=class'KFDT_Bludgeon', DamageScale=(1.0))) //0.75
DamageTypeModifiers.Add((DamageType=class'KFDT_Fire', DamageScale=(0.3)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Microwave', DamageScale=(1.1)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Explosive', DamageScale=(0.4)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Piercing', DamageScale=(0.75)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_RPG7Impact', DamageScale=(4.f)))
2022-12-07 20:25:49 +00:00
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_HRG_MedicMissile', DamageScale=(3.f)))
2020-12-13 15:01:13 +00:00
DamageTypeModifiers.Add((DamageType=class'KFDT_Toxic', DamageScale=(0.25)))
//special cases
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_Hemogoblin', DamageScale=(0.75)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Ballistic_HRGTeslauncher', DamageScale=(0.6)))
DamageTypeModifiers.Add((DamageType=class'KFDT_Fire_HRGTeslauncherDoT', DamageScale=(0.6)))
// ---------------------------------------------
// Block Settings
MinBlockFOV=0.1f
// Custom Hit Zones (HeadHealth, SkinTypes, etc...)
HeadlessBleedOutTime=6.f
HitZones[HZI_HEAD]=(ZoneName=head, BoneName=Head, Limb=BP_Head, GoreHealth=600, DmgScale=1.1, SkinID=1)
HitZones[8] =(ZoneName=rforearm, BoneName=RightForearm, Limb=BP_RightArm, GoreHealth=20, DmgScale=0.2, SkinID=2)
HitZones.Add((ZoneName=rchainsaw, BoneName=RightForearm, Limb=BP_RightArm, GoreHealth=20, DmgScale=0.2, SkinID=2))
HitZones.Add((ZoneName=rchainsawblade, BoneName=RightForearm, Limb=BP_RightArm, GoreHealth=20, DmgScale=0.2, SkinID=2))
// ---------------------------------------------
// Movement / Physics
Begin Object Name=CollisionCylinder
CollisionRadius=+0055.000000
End Object
RotationRate=(Pitch=50000,Yaw=50000,Roll=50000)
GroundSpeed=170.f
SprintSpeed=600.f
ReachedEnemyThresholdScale=1.f
PhysRagdollImpulseScale=1.f
KnockdownImpulseScale=2.0f
// ---------------------------------------------
// AI / Navigation
ControllerClass=class'KFAIController_ZedScrake'
BumpDamageType=class'KFDT_NPCBump_Large'
DamageRecoveryTimeHeavy=0.85 //0.2f
DamageRecoveryTimeMedium=0.75 //0.09f //0.85
bCanRage=true
bIsEnraged=false
RageHealthThresholdNormal=0.5
RageHealthThresholdHard=0.75
RageHealthThresholdSuicidal=0.75
RageHealthThresholdHellOnEarth=0.90
// Sound
Begin Object Class=AkComponent name=ChainsawAkComponent0
BoneName=dummy
bStopWhenOwnerDestroyed=true
bForceOcclusionUpdateInterval=true
OcclusionUpdateInterval=0.2f
End Object
ChainsawIdleAkComponent=ChainsawAkComponent0
Components.Add(ChainsawAkComponent0)
PlayChainsawIdleAkEvent=AkEvent'WW_ZED_Scrake_2.ZED_Scrake_SFX_Chainsaw_Idle_LP'
StopChainsawIdleAkEvent=AkEvent'WW_ZED_Scrake_2.ZED_Scrake_SFX_Chainsaw_Idle_LP_Stop'
`if(`notdefined(ShippingPC))
DebugRadarTexture=Texture2D'UI_ZEDRadar_TEX.MapIcon_Scrake';
`endif
// ---------------------------------------------
// Spawning
MinSpawnSquadSizeType=EST_Large
OnDeathAchievementID=KFACHID_HackAndSlash
2021-09-02 21:46:08 +00:00
ZEDCowboyHatAttachName=Hat_Attach
2023-09-21 19:31:11 +00:00
// Only used in Volter Castle for now when the spawn volume has bForceUseMapReplacePawn set to true
// If we need to reuse it more we'll have to connect map to zed here
MapReplacePawnClass.Add(class'KFPawn_ZedHansClot')
2020-12-13 15:01:13 +00:00
}