diff --git a/sources/Weapons/NiceBullet.uc b/sources/Weapons/NiceBullet.uc index 8e03861..216ee99 100644 --- a/sources/Weapons/NiceBullet.uc +++ b/sources/Weapons/NiceBullet.uc @@ -710,7 +710,7 @@ function Stick(Actor target, Vector hitLocation) { expData.affectedByScream = charAffectedByScream; if (!target.IsA('NiceMonster')) { - hitLocation -= target.location; + hitLocation = (hitLocation - target.location) << target.rotation; boneStick = 'None'; resultTarget = target; } else { diff --git a/sources/Weapons/NiceProjectileSpawner.uc b/sources/Weapons/NiceProjectileSpawner.uc index 5334af4..a8ee953 100644 --- a/sources/Weapons/NiceProjectileSpawner.uc +++ b/sources/Weapons/NiceProjectileSpawner.uc @@ -259,6 +259,7 @@ static function SpawnStuckProjectile( } else { spawnedBullet.SetBase(base); spawnedBullet.SetRelativeLocation(shift); + spawnedBullet.SetRelativeRotation(direction - base.rotation); } } diff --git a/sources/Zeds/Mean/MeanZombieHusk.uc b/sources/Zeds/Mean/MeanZombieHusk.uc index b0ada50..efbb5fb 100644 --- a/sources/Zeds/Mean/MeanZombieHusk.uc +++ b/sources/Zeds/Mean/MeanZombieHusk.uc @@ -37,7 +37,7 @@ function RangedAttack(Actor A) { //Increment the number of consecutive shtos taken and apply the cool down if needed totalShots ++; consecutiveShots ++; - if(consecutiveShots < 3 && totalShots > maxNormalShots) + if(consecutiveShots < 3 && totalShots > maxNormalShots && VSize(a.location - location) <= 900) NextFireProjectileTime = Level.TimeSeconds; else{ NextFireProjectileTime = Level.TimeSeconds + ProjectileFireInterval + (FRand() * 2.0); diff --git a/sources/Zeds/Nice/NiceZombieClot.uc b/sources/Zeds/Nice/NiceZombieClot.uc index 57875e8..71f8939 100644 --- a/sources/Zeds/Nice/NiceZombieClot.uc +++ b/sources/Zeds/Nice/NiceZombieClot.uc @@ -5,6 +5,8 @@ class NiceZombieClot extends NiceZombieClotBase; #exec OBJ LOAD FILE=KF_Specimens_Trip_T.utx #exec OBJ LOAD FILE=MeanZedSkins.utx +var float sirenBoostTimeout; + function ClawDamageTarget() { local vector PushDir; @@ -109,9 +111,33 @@ simulated function int DoAnimAction( name AnimName ) } return super.DoAnimAction( AnimName ); } +function DealDecapDamage( int damage, + Pawn instigatedBy, + Vector hitLocation, + Vector momentum, + class damageType, + float headshotLevel, + KFPlayerReplicationInfo KFPRI, + optional float lockonTime) { + if (sirenBoostTimeout > 0) { + RemoveHead(); + } else { + super.DealDecapDamage(damage, instigatedBy, hitLocation, momentum, + damageType, headshotLevel, KFPRI, lockonTime); + } +} +simulated function UpdateGroundSpeed() { + super.UpdateGroundSpeed(); + if (sirenBoostTimeout > 0) { + groundSpeed *= 1.5; + } +} simulated function Tick(float DeltaTime) { super.Tick(DeltaTime); + if (sirenBoostTimeout >= 0) { + sirenBoostTimeout -= deltaTime; + } if( bShotAnim && Role == ROLE_Authority ) { if( LookTarget!=none ) diff --git a/sources/Zeds/Nice/NiceZombieShiver.uc b/sources/Zeds/Nice/NiceZombieShiver.uc index 72c110e..a28b0d1 100644 --- a/sources/Zeds/Nice/NiceZombieShiver.uc +++ b/sources/Zeds/Nice/NiceZombieShiver.uc @@ -3,6 +3,7 @@ class NiceZombieShiver extends NiceZombieShiverBase; var float TeleportBlockTime; var float HeadOffsetY; var transient bool bRunning, bClientRunning; +var float teleportAttackCooldownEndTime; replication { reliable if ( Role == ROLE_Authority) @@ -38,6 +39,39 @@ simulated function PostBeginPlay() } } } + +function bool CanAttack(Actor target) { + if (level.timeSeconds < teleportAttackCooldownEndTime) + return false; + return super.CanAttack(target); +} + +simulated event SetAnimAction(name NewAction) { + local int meleeAnimIndex; + + if (bFrozenZed) return; + if (newAction == '') return; + + if (newAction == 'Claw') { + meleeAnimIndex = Rand(2); // Shivers only have two animations now + newAction = meleeAnims[meleeAnimIndex]; + currentDamtype = zombieDamType[meleeAnimIndex]; + } else if(newAction == 'DoorBash') { + currentDamtype = zombieDamType[Rand(3)]; + } + 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 Destroyed() { if (Level.NetMode != NM_DedicatedServer && MatAlphaSkin != none) @@ -281,7 +315,7 @@ simulated function Tick(float Delta) { SetCollision(true, true); FlashTeleport(); - SetCollision(false, false); + SetCollision(true, false); FadeStage = 2; } } @@ -322,7 +356,7 @@ function StartTeleport() { FadeStage = 1; AlphaFader = 255; - SetCollision(false, false); + SetCollision(true, false); bFlashTeleporting = true; } function FlashTeleport() @@ -380,6 +414,7 @@ function FlashTeleport() Teleported: bFlashTeleporting = false; LastFlashTime = Level.TimeSeconds; + teleportAttackCooldownEndTime = level.timeSeconds + 0.5; } function Died(Controller Killer, class damageType, vector HitLocation) { @@ -429,10 +464,16 @@ simulated function int DoAnimAction( name AnimName ) } defaultproperties { - HeadOffsetY=-3.000000 + headOffsetY=-3.000000 idleInsertFrame=0.468000 - OnlineHeadshotOffset=(X=19.000000,Z=39.000000) - ScoringValue=15 - HeadRadius=8.000000 - HeadHeight=3.000000 + onlineHeadshotOffset=(X=19.000000,Z=39.000000) + scoringValue=15 + headRadius=8.000000 + headHeight=3.000000 + // Override third animation just in case. + // However it shouldn't be required since we've already changed + // `SetAnimAction` function to only use first two animations + meleeAnims(0)="Claw" + meleeAnims(1)="Claw2" + meleeAnims(2)="Claw" } diff --git a/sources/Zeds/Nice/NiceZombieSiren.uc b/sources/Zeds/Nice/NiceZombieSiren.uc index 6f13cf4..aa15090 100644 --- a/sources/Zeds/Nice/NiceZombieSiren.uc +++ b/sources/Zeds/Nice/NiceZombieSiren.uc @@ -226,6 +226,7 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class niceVet; + local NiceZombieClot niceClot; if (bHurtEntry || Health <= 0 || HeadHealth <= 0 || bIsStunned) return; @@ -243,6 +244,10 @@ simulated function HurtRadius(float DamageAmount, float DamageRadius, class