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

304 lines
9.1 KiB
Ucode

class ZombieSirenOS extends KFMonsterOS;
var float DistBeforeScream;
var () int ScreamRadius;
var () class <DamageType> ScreamDamageType;
var () int ScreamForce;
var(Shake) rotator RotMag;
var(Shake) float RotRate;
var(Shake) vector OffsetMag;
var(Shake) float OffsetRate;
var(Shake) float ShakeTime;
var(Shake) float ShakeFadeTime;
var(Shake) float ShakeEffectScalar;
var(Shake) float MinShakeEffectScale;
var(Shake) float ScreamBlurScale;
var bool bAboutToDie;
var float DeathTimer;
var bool bEnableSirenNadeBoom;
// Fixes credit: https://github.com/Shtoyan/KF1066/blob/main/docs/VeryAnnoying/ZedIssues.md
simulated function PostBeginPlay()
{
super.PostBeginPlay();
if(bEnableSirenNadeBoom)
ScreamDamageType=class'SirenScreamDamageOS';
}
function bool FlipOver()
{
return false;
}
function DoorAttack(Actor A)
{
if ( bShotAnim || Physics == PHYS_Swimming || bDecapitated || A==none )
return;
bShotAnim = true;
SetAnimAction('Siren_Scream');
}
function RangedAttack(Actor A)
{
local int LastFireTime;
local float Dist;
if ( bShotAnim )
return;
Dist = VSize(A.Location - Location);
if ( Physics == PHYS_Swimming )
{
SetAnimAction('Claw');
bShotAnim = true;
LastFireTime = Level.TimeSeconds;
}
else if ( Dist < MeleeRange + CollisionRadius + A.CollisionRadius )
{
bShotAnim = true;
LastFireTime = Level.TimeSeconds;
SetAnimAction('Claw');
PlaySound(sound'Claw2s', SLOT_Interact);
Controller.bPreparingMove = true;
Acceleration = vect(0,0,0);
}
else if( Dist <= (ScreamRadius - DistBeforeScream) && !bDecapitated && !bZapped )
{
bShotAnim=true;
SetAnimAction('Siren_Scream');
Controller.bPreparingMove = true;
Acceleration = vect(0,0,0);
}
}
simulated function SpawnTwoShots()
{
if( bZapped || bDecapitated)
{
return;
}
DoShakeEffect();
if( Level.NetMode!=NM_Client )
{
if( Controller!=none && KFDoorMover(Controller.Target)!=none )
Controller.Target.TakeDamage(ScreamDamage*0.6,self,Location,vect(0,0,0),ScreamDamageType);
else
HurtRadius(ScreamDamage ,ScreamRadius, ScreamDamageType, ScreamForce, Location);
}
}
simulated function DoShakeEffect()
{
local PlayerController PC;
local float Dist, scale, BlurScale;
if (Level.NetMode != NM_DedicatedServer)
{
PC = Level.GetLocalPlayerController();
if (PC != none && PC.ViewTarget != none)
{
Dist = VSize(Location - PC.ViewTarget.Location);
if (Dist < ScreamRadius )
{
scale = (ScreamRadius - Dist) / (ScreamRadius);
scale *= ShakeEffectScalar;
BlurScale = scale;
if( !FastTrace(PC.ViewTarget.Location,Location) )
{
scale *= 0.25;
BlurScale = scale;
}
else
{
scale = Lerp(scale,MinShakeEffectScale,1.0);
}
PC.SetAmbientShake(Level.TimeSeconds + ShakeFadeTime, ShakeTime, OffsetMag * Scale, OffsetRate, RotMag * Scale, RotRate);
if( KFHumanPawn(PC.ViewTarget) != none )
{
KFHumanPawn(PC.ViewTarget).AddBlur(ShakeTime, BlurScale * ScreamBlurScale);
}
if ( Level != none && Level.Game != none && !KFGameType(Level.Game).bDidSirenScreamMessage && FRand() < 0.10 )
{
PC.Speech('AUTO', 16, "");
KFGameType(Level.Game).bDidSirenScreamMessage = true;
}
}
}
}
}
simulated function HurtRadius( float DamageAmount, float DamageRadius, class<DamageType> DamageType, float Momentum, vector HitLocation )
{
local actor Victims;
local float damageScale, dist;
local vector dir;
local float UsedDamageAmount;
if( bHurtEntry )
return;
bHurtEntry = true;
foreach VisibleCollidingActors( class 'Actor', Victims, DamageRadius, HitLocation )
{
if( (Victims != self) && !Victims.IsA('FluidSurfaceInfo') && !Victims.IsA('KFMonster') && !Victims.IsA('ExtendedZCollision') )
{
dir = Victims.Location - HitLocation;
dist = FMax(1,VSize(dir));
dir = dir/dist;
damageScale = 1 - FMax(0,(dist - Victims.CollisionRadius)/DamageRadius);
if (!Victims.IsA('KFHumanPawn'))
Momentum = 0;
if (Victims.IsA('KFGlassMover'))
{
UsedDamageAmount = 100000;
}
else
{
UsedDamageAmount = DamageAmount;
}
Victims.TakeDamage(damageScale * UsedDamageAmount,Instigator, Victims.Location - 0.5 * (Victims.CollisionHeight + Victims.CollisionRadius) * dir,(damageScale * Momentum * dir),DamageType);
if (Instigator != none && Vehicle(Victims) != none && Vehicle(Victims).Health > 0)
Vehicle(Victims).DriverRadiusDamage(UsedDamageAmount, DamageRadius, Instigator.Controller, DamageType, Momentum, HitLocation);
}
}
bHurtEntry = false;
}
function RemoveHead()
{
super.RemoveHead();
if( FRand()<0.5 )
KilledBy(LastDamagedBy);
else
{
bAboutToDie = true;
MeleeRange = -500;
DeathTimer = Level.TimeSeconds+10*FRand();
}
}
State ZombieDyingOS
{
ignores AnimEnd, Trigger, Bump, HitWall, HeadVolumeChange, PhysicsVolumeChange, Falling, BreathTimer, Died, RangedAttack, SpawnTwoShots;
}
simulated function Tick( float Delta )
{
super.Tick(Delta);
if( bAboutToDie && Level.TimeSeconds>DeathTimer )
{
if( Health>0 && Level.NetMode!=NM_Client )
KilledBy(LastDamagedBy);
bAboutToDie = false;
}
}
function PlayDyingSound()
{
if( !bAboutToDie )
super.PlayDyingSound();
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Siren.SirenSkin');
myLevel.AddPrecacheMaterial(FinalBlend'KFOldSchoolZeds_Textures.Siren.SirenHairFB');
}
defaultproperties
{
DistBeforeScream=200.000000
ScreamRadius=900
ScreamDamageType=Class'KFMod.SirenScreamDamage'
ScreamForce=-150000
RotMag=(Pitch=150,Yaw=150,Roll=150)
RotRate=500.000000
OffsetMag=(Y=5.000000,Z=1.000000)
OffsetRate=500.000000
ShakeTime=2.000000
ShakeFadeTime=0.250000
ShakeEffectScalar=1.000000
MinShakeEffectScale=0.600000
ScreamBlurScale=0.850000
MeleeAnims(0)="Siren_Bite"
MeleeAnims(1)="Siren_Bite"
MeleeAnims(2)="Siren_Bite"
HitAnims(0)="HitReactionF"
HitAnims(1)="HitReactionF"
HitAnims(2)="HitReactionF"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.siren.Siren_Speech'
ZapThreshold=0.500000
ZappedDamageMod=1.500000
ZombieFlag=1
MeleeDamage=13
damageForce=5000
KFRagdollName="SirenRag"
ZombieDamType(0)=Class'KFMod.DamTypeSlashingAttack'
ZombieDamType(1)=Class'KFMod.DamTypeSlashingAttack'
ZombieDamType(2)=Class'KFMod.DamTypeSlashingAttack'
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombieJump'
ScreamDamage=8
CrispUpThreshhold=7
bCanDistanceAttackDoors=True
bUseExtendedCollision=True
ColOffset=(Z=48.000000)
ColRadius=25.000000
ColHeight=5.000000
PlayerCountHealthScale=0.100000
OnlineHeadshotOffset=(X=12.000000,Y=-3.000000,Z=44.000000)
OnlineHeadshotScale=1.200000
HeadHealth=200.000000
PlayerNumHeadHealthScale=0.050000
MotionDetectorThreat=2.000000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain'
DeathSound(0)=Sound'KFOldSchoolZeds_Sounds.siren.Siren_Die'
ScoringValue=25
SoundGroupClass=Class'KFOldSchoolZeds.KFFemaleZombieSoundsOS'
IdleHeavyAnim="Siren_Idle"
IdleRifleAnim="Siren_Idle"
MeleeRange=45.000000
GroundSpeed=100.000000
WaterSpeed=80.000000
HealthMax=300.000000
Health=300
HeadRadius=6.000000
HeadHeight=4.500000
MenuName="Siren 2.5"
ControllerClass=Class'KFOldSchoolZeds.ControllerSirenOS'
MovementAnims(0)="Siren_Walk"
MovementAnims(1)="Siren_Walk"
MovementAnims(2)="Siren_Walk"
MovementAnims(3)="Siren_Walk"
WalkAnims(0)="Siren_Walk"
WalkAnims(1)="Siren_Walk"
WalkAnims(2)="Siren_Walk"
WalkAnims(3)="Siren_Walk"
IdleCrouchAnim="Siren_Idle"
IdleWeaponAnim="Siren_Idle"
IdleRestAnim="Siren_Idle"
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.InfectedWhiteMale2'
PrePivot=(Z=-8.000000)
Skins(0)=Texture'KFOldSchoolZeds_Textures.siren.SirenSkin'
Skins(1)=FinalBlend'KFOldSchoolZeds_Textures.siren.SirenHairFB'
RotationRate=(Yaw=45000,Roll=0)
}