rott/kf_sources/KFOldSchoolZeds/Classes/ZombieClotOS.uc
2026-07-14 20:27:09 +07:00

205 lines
6.0 KiB
Ucode

class ZombieClotOS extends KFMonsterOS;
//TODO: Break grapple immediately on death
var KFPawn DisabledPawn; // The pawn that has been disabled by this zombie's grapple
var bool bGrappling; // This zombie is grappling someone
var float GrappleEndTime; // When the current grapple should be over
var() float GrappleDuration; // How long a grapple by this zombie should last
var float ClotGrabMessageDelay; // Amount of time between a player saying "I've been grabbed" message
replication
{
reliable if(bNetDirty && Role == ROLE_Authority)
bGrappling;
}
function BreakGrapple()
{
if( DisabledPawn != none )
{
DisabledPawn.bMovementDisabled = false;
DisabledPawn = none;
}
}
function ClawDamageTarget()
{
local vector PushDir;
local KFPawn KFP;
local float UsedMeleeDamage;
if( MeleeDamage > 1 )
UsedMeleeDamage = (MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1));
else
UsedMeleeDamage = MeleeDamage;
if ( MeleeDamageTarget( UsedMeleeDamage, PushDir))
{
KFP = KFPawn(Controller.Target);
if( !bDecapitated && KFP != none )
{
if ( KFPlayerReplicationInfo(KFP.PlayerReplicationInfo).ClientVeteranSkill != class'KFVetBerserker')
{
if( DisabledPawn != none )
DisabledPawn.bMovementDisabled = false;
KFP.DisableMovement(GrappleDuration);
DisabledPawn = KFP;
}
}
}
}
function DoorAttack(Actor A)
{
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( CanAttack(A) )
{
bShotAnim = true;
SetAnimAction('Claw2');
PlaySound(sound'Claw2s', SLOT_None);
return;
}
}
function RangedAttack(Actor A)
{
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( CanAttack(A) )
{
bShotAnim = true;
SetAnimAction('Claw');
Acceleration = Normal(A.Location-Location)*600;
Controller.GoToState('WaitForAnim');
Controller.MoveTarget = A;
Controller.MoveTimer = 1.5;
}
}
simulated event SetAnimAction(name NewAction)
{
local int meleeAnimIndex;
if( NewAction=='' )
return;
if(NewAction == 'Claw')
{
meleeAnimIndex = Rand(3);
NewAction = meleeAnims[2];
CurrentDamtype = ZombieDamType[meleeAnimIndex];
}
ExpectingChannel = DoAnimAction(NewAction);
if( AnimNeedsWait(NewAction) )
bWaitForAnim = true;
else
bWaitForAnim = false;
if( Level.NetMode!=NM_Client )
{
AnimAction = NewAction;
bResetAnimAct = true;
ResetAnimActTime = Level.TimeSeconds+0.3;
}
}
simulated function int DoAnimAction( name AnimName )
{
if( AnimName=='ClotGrapple' )
{
if ( FRand() < 0.10 && LookTarget != none && KFPlayerController(LookTarget.Controller) != none &&
VSizeSquared(Location - LookTarget.Location) < 2500 &&
Level.TimeSeconds - KFPlayerController(LookTarget.Controller).LastClotGrabMessageTime > ClotGrabMessageDelay &&
KFPlayerController(LookTarget.Controller).SelectedVeterancy != class'KFVetBerserker' )
{
PlayerController(LookTarget.Controller).Speech('AUTO', 11, "");
KFPlayerController(LookTarget.Controller).LastClotGrabMessageTime = Level.TimeSeconds;
}
}
return super.DoAnimAction( AnimName );
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
super.takeDamage(Damage, instigatedBy, hitLocation, momentum, damageType);
//Fixed log spam
if( (Health < 0 || Damage > Health) && DisabledPawn != None)
DisabledPawn.bMovementDisabled = false;
}
function RemoveHead()
{
Super.RemoveHead();
MeleeAnims[0] = 'Claw';
MeleeAnims[1] = 'Claw';
MeleeAnims[2] = 'Claw2';
MeleeDamage *= 2;
MeleeRange *= 2;
if( DisabledPawn != none )
{
DisabledPawn.bMovementDisabled = false;
DisabledPawn = none;
}
}
static simulated function PreCacheStaticMeshes(LevelInfo myLevel)
{
super.PreCacheStaticMeshes(myLevel);
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Clot.ClotSkin');
}
defaultproperties
{
GrappleDuration=1.000000
ClotGrabMessageDelay=12.000000
MeleeAnims(2)="ClotGrapple"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.clot.Clot_Speech'
bCannibal=True
MeleeDamage=6
damageForce=5000
KFRagdollName="ClotRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
CrispUpThreshhold=9
PuntAnim="ClotPunt"
AdditionalWalkAnims(0)="ClotWalk"
Intelligence=BRAINS_Mammal
bUseExtendedCollision=True
ColOffset=(Z=48.000000)
ColRadius=25.000000
ColHeight=5.000000
OnlineHeadshotOffset=(X=21.000000,Y=-7.000000,Z=43.000000)
OnlineHeadshotScale=1.200000
MotionDetectorThreat=0.340000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=7
MeleeRange=20.000000
GroundSpeed=105.000000
WaterSpeed=105.000000
JumpZ=340.000000
HealthMax=130.000000
Health=130
HeadHeight=5.000000
MenuName="Clot 2.5"
MovementAnims(0)="ClotWalk"
WalkAnims(0)="ClotWalk"
WalkAnims(1)="ClotWalk"
WalkAnims(2)="ClotWalk"
WalkAnims(3)="ClotWalk"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieBreath'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.InfectedWhiteMale1'
Skins(0)=Texture'KFOldSchoolZeds_Textures.clot.ClotSkin'
RotationRate=(Yaw=45000,Roll=0)
}