Prepare fixtures

This commit is contained in:
dkanus 2026-07-14 20:27:09 +07:00
commit 9c94356263
6021 changed files with 722805 additions and 22 deletions

View file

@ -0,0 +1,54 @@
//2.5 Bile Explosion ✓
class BileExplosionOS extends FleshHitEmitterOS;
//Usage:
//Emitter for when Bloat dies, but not to bleedout
defaultproperties
{
Begin Object Class=SpriteEmitter Name=BileExplosionEmitter
UseCollision=True
UseCollisionPlanes=True
FadeOut=True
RespawnDeadParticles=False
SpawnOnlyInDirectionOfNormal=True
ZTest=False
SpinParticles=True
DampRotation=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
ScaleSizeYByVelocity=True
ScaleSizeZByVelocity=True
BlendBetweenSubdivisions=True
UseRandomSubdivision=True
Acceleration=(Z=-650.000000)
DampingFactorRange=(X=(Min=0.000000,Max=0.000000),Y=(Min=0.000000,Max=0.000000),Z=(Min=0.000000,Max=0.000000))
ColorScale(0)=(Color=(R=255,A=255))
ColorScale(1)=(RelativeTime=1.000000,Color=(R=255,A=255))
ColorMultiplierRange=(Z=(Min=0.670000,Max=2.000000))
MaxParticles=65
StartLocationShape=PTLS_Sphere
SphereRadiusRange=(Max=1.000000)
StartMassRange=(Min=11.000000,Max=11.000000)
AlphaRef=110
UseRotationFrom=PTRS_Normal
SpinCCWorCW=(X=1.000000)
SpinsPerSecondRange=(X=(Min=0.100000,Max=0.520000))
SizeScale(0)=(RelativeTime=1.000000,RelativeSize=3.000000)
StartSizeRange=(X=(Min=1.000000,Max=30.000000),Y=(Min=0.000000,Max=0.000000),Z=(Min=0.000000,Max=0.000000))
ScaleSizeByVelocityMultiplier=(X=0.000000,Y=0.000000,Z=0.000000)
ScaleSizeByVelocityMax=3.000000
ParticlesPerSecond=100.000000
DrawStyle=PTDS_AlphaBlend
Texture=Texture'KFOldSchoolZeds_Textures.Shared.BileSpray'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=1.000000,Max=1.500000)
StartVelocityRange=(X=(Min=-50.000000,Max=50.000000),Y=(Min=-50.000000,Max=50.000000),Z=(Min=-100.000000,Max=400.000000))
MaxAbsVelocity=(X=100.000000,Y=100.000000)
End Object
Emitters(0)=SpriteEmitter'KFOldSchoolZeds.BileExplosionOS.BileExplosionEmitter'
LifeSpan=1.500000
}

View file

@ -0,0 +1,41 @@
//2.5 BileJet ✓
class BileJetOS extends Actor;
//Usage:
//Bile that flies out of a Bloat's stomach when he explodes
function PostBeginPlay()
{
settimer(0.5, true);//settimer(0.1, false);
}
simulated function timer()
{
local vector X,Y,Z, FireStart;
local rotator FireRotation;
GetAxes(Rotation,X,Y,Z);
FireStart = location;
FireRotation = rotation;
Spawn(class'KFVomitJetOS',,,FireStart, FireRotation);
Spawn(class'KFBloatVomitOS',,,FireStart,FireRotation);
FireStart = FireStart - 1.8 * CollisionRadius * Y;
FireRotation.Yaw += 400;
spawn(class'KFBloatVomitOS',,,FireStart, FireRotation);
FireStart = FireStart - 1.8 * CollisionRadius * Z;
FireRotation.Pitch += 400;
spawn(class'KFBloatVomitOS',,,FireStart, FireRotation);
FireStart = FireStart - 1.8 * CollisionRadius * X;
FireRotation.Roll += 400;
spawn(class'KFBloatVomitOS',,,FireStart, FireRotation);
}
defaultproperties
{
bHidden=True
LifeSpan=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 BioDecal ✓
class BioDecalOS extends ProjectedDecal;
//Usage:
//Tiny little green spots that spawn when vomit impacts ground
#exec OBJ LOAD File=KFOldSchool_XEffects.utx
simulated function BeginPlay()
{
if ( !Level.bDropDetail && (FRand() < 0.5) )
ProjTexture = texture'KFOldSchool_XEffects.xbiosplat2';
super.BeginPlay();
}
defaultproperties
{
ProjTexture=Texture'KFOldSchool_XEffects.xbiosplat'
bClipStaticMesh=True
CullDistance=7000.000000
LifeSpan=6.000000
DrawScale=0.650000
}

View file

@ -0,0 +1,12 @@
//2.5 BloodJet ✓
class BloodJetOS extends BloodJet;
//Usage:
//Parent class. Blood Jet.
#exec OBJ LOAD File=KFOldSchoolZeds_Textures.utx
defaultproperties
{
SplatterClass=Class'KFOldSchoolZeds.BloodSplatterOS'
Skins(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodJetc'
}

View file

@ -0,0 +1,28 @@
//2.5 BloodSplatter Decal ✓
class BloodSplatterOS extends ProjectedDecal;
//Usage:
//Blood Decals for when zed corpse impacts the floor
#exec OBJ LOAD FILE=KFOldSchool_XEffects.utx
#exec OBJ LOAD File=KFOldSchoolZeds_Textures.utx
var texture Splats[3];
simulated function PostBeginPlay()
{
ProjTexture = splats[Rand(3)];
super.PostBeginPlay();
}
defaultproperties
{
Splats(0)=Texture'KFOldSchool_XEffects.BloodSplat1'
Splats(1)=Texture'KFOldSchool_XEffects.BloodSplat2'
Splats(2)=Texture'KFOldSchool_XEffects.BloodSplat3'
ProjTexture=Texture'KFOldSchool_XEffects.BloodSplat1'
FOV=6
bClipStaticMesh=True
CullDistance=7000.000000
LifeSpan=5.000000
}

View file

@ -0,0 +1,92 @@
//2.5 BloodSpurt Emitter ✓
class BloodSpurtOS extends xEmitter;
//Usage:
//Decals for when blood impacts a wall
#exec OBJ LOAD FILE=KFOldSchool_XEffects.utx
var class<Actor> BloodDecalClass;
var texture Splats[3];
var vector HitDir;
var bool bMustShow;
replication
{
unreliable if ( bNetInitial && (Role==ROLE_Authority) )
bMustShow,HitDir;
}
simulated function PostNetBeginPlay()
{
if ( Level.NetMode != NM_DedicatedServer )
WallSplat();
else
LifeSpan = 0.2;
}
simulated function WallSplat()
{
local vector WallHit, WallNormal;
local Actor WallActor;
if ( Level.bDropDetail || (!bMustShow && (FRand() > 0.8)) || (BloodDecalClass == none) )
return;
if ( HitDir == vect(0,0,0) )
{
if ( Owner != none )
HitDir = Location - Owner.Location;
else
HitDir.Z = -1;
}
HitDir = Normal(HitDir);
WallActor = Trace(WallHit, WallNormal, Location + 350 * HitDir, Location, false);
if ( WallActor != none )
spawn(BloodDecalClass,,,WallHit + 20 * (WallNormal + VRand()), rotator(-WallNormal));
}
static function PrecacheContent(LevelInfo Level)
{
local int i;
super.PrecacheContent(Level);
if ( default.BloodDecalClass != none )
for ( i=0; i<3; i++ )
Level.AddPrecacheMaterial(default.splats[i]);
}
defaultproperties
{
BloodDecalClass=Class'KFOldSchoolZeds.BloodSplatterOS'
Splats(0)=Texture'KFOldSchool_XEffects.BloodSplat1'
Splats(1)=Texture'KFOldSchool_XEffects.BloodSplat2'
Splats(2)=Texture'KFOldSchool_XEffects.BloodSplat3'
mRegen=False
mStartParticles=13
mMaxParticles=13
mLifeRange(0)=1.000000
mLifeRange(1)=2.000000
mRegenRange(0)=0.000000
mRegenRange(1)=0.000000
mDirDev=(X=0.100000,Y=0.100000,Z=0.100000)
mSpeedRange(0)=0.000000
mSpeedRange(1)=85.000000
mMassRange(0)=0.020000
mMassRange(1)=0.040000
mAirResistance=0.600000
mRandOrient=True
mSizeRange(0)=5.500000
mSizeRange(1)=9.500000
mGrowthRate=3.000000
mRandTextures=True
mNumTileColumns=4
mNumTileRows=4
bOnlyRelevantToOwner=True
RemoteRole=ROLE_SimulatedProxy
LifeSpan=3.500000
Skins(0)=Texture'KFOldSchool_XEffects.pcl_Blooda'
Style=STY_Alpha
}

View file

@ -0,0 +1,9 @@
//2.5 BodySplash ✓
class BodySplashOS extends FleshHitEmitterOS;
//Usage:
//Blood that spawns when zed takes damage
defaultproperties
{
}

View file

@ -0,0 +1,14 @@
//2.5 BossLAWProj ✓
class BossLAWProjOS extends BossLAWProj;
//Usage:
//Boss Projectile. Mainly to play KFMod ExplosionSound and make StaticMesh visible.
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
#exec OBJ LOAD FILE=KillingFloorStatics.usx
defaultproperties
{
ExplosionSound=Sound'KFOldSchoolZeds_Sounds.Shared.TankFire01'
StaticMesh=StaticMesh'KillingFloorStatics.LAWRocket'
DrawScale=0.750000
}

View file

@ -0,0 +1,10 @@
//2.5 BrainSplash ✓
class BrainSplashOS extends FleshHitEmitterOS;
//Usage:
//Blood that spawns when zed takes damage. Longer Lifespan than BodySplash.
defaultproperties
{
LifeSpan=1.200000
}

View file

@ -0,0 +1,15 @@
// Skell KFPro (c) ✓
class ClientExtendedZCollision extends ExtendedZCollision;
//Usage:
//Makes M14EBR Laser appear properly on Zeds
// We definitely don't want simulated proxies calling take damage on zeds.
function TakeDamage( int Damage, Pawn EventInstigator, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
return;
}
defaultproperties
{
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibArm ✓
class ClotGibArmOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.250000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibArm'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibHead ✓
class ClotGibHeadOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.300000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibHead'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibLeg ✓
class ClotGibLegOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.250000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibLeg'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibLowerTorso ✓
class ClotGibLowerTorsoOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.200000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibLowerTorso'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibThigh ✓
class ClotGibThighOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.300000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibThigh'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,23 @@
//2.5 ClotGibTorso ✓
class ClotGibTorsoOS extends KFGibOS;
//Usage:
//Giblet that spawns when Zed takes massive explosive damage.
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.200000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KFOldSchoolStatics.ClotGibTorso'
Skins(0)=Texture'22CharTex.GibletsSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,345 @@
//Controller class for Patriarch ✓
class ControllerBossOS extends KFMonsterControllerOS;
var NavigationPoint HidingSpots;
var float WaitAnimTimeout;
var int AnimWaitChannel;
var name AnimWaitingFor;
var bool bAlreadyFoundEnemy;
function bool CanKillMeYet()
{
return false;
}
function TimedFireWeaponAtEnemy()
{
if ( (Enemy == none) || FireWeaponAt(Enemy) )
SetCombatTimer();
else
SetTimer(0.01, true);
}
function FightEnemy(bool bCanCharge)
{
if( KFM.bShotAnim )
{
GoToState('WaitForAnim');
return;
}
if (KFM.MeleeRange != KFM.default.MeleeRange)
KFM.MeleeRange = KFM.default.MeleeRange;
if ( Enemy == none || Enemy.Health <= 0 )
FindNewEnemy();
if ( (Enemy == FailedHuntEnemy) && (Level.TimeSeconds == FailedHuntTime) )
{
if ( Enemy == FailedHuntEnemy )
{
GoalString = "FAILED HUNT - HANG OUT";
if ( EnemyVisible() )
bCanCharge = false;
}
}
if ( !EnemyVisible() )
{
if( bAlreadyFoundEnemy || ZombieBossOS(Pawn).SneakCount > 2 )
{
bAlreadyFoundEnemy = true;
GoalString = "Hunt";
GotoState('ZombieHunt');
}
else
{
ZombieBossOS(Pawn).SneakCount++;
GoalString = "InitialHunt";
GotoState('InitialHunting');
}
return;
}
Target = Enemy;
GoalString = "Charge";
PathFindState = 2;
DoCharge();
}
state InitialHunting extends Hunting
{
event SeePlayer(Pawn SeenPlayer)
{
super.SeePlayer(SeenPlayer);
bAlreadyFoundEnemy = true;
GoalString = "Hunt";
GotoState('ZombieHunt');
}
function BeginState()
{
local float ZDif;
ZombieBossOS(Pawn).SneakCount++;
if( Pawn.CollisionRadius>27 || Pawn.CollisionHeight>46 )
{
ZDif = Pawn.CollisionHeight-44;
Pawn.SetCollisionSize(24,44);
Pawn.MoveSmooth(vect(0,0,-1)*ZDif);
}
super.BeginState();
}
function EndState()
{
local float ZDif;
if( Pawn.CollisionRadius!=Pawn.default.CollisionRadius || Pawn.CollisionHeight!=Pawn.default.CollisionHeight )
{
ZDif = Pawn.default.CollisionRadius-44;
Pawn.MoveSmooth(vect(0,0,1)*ZDif);
Pawn.SetCollisionSize(Pawn.default.CollisionRadius,Pawn.default.CollisionHeight);
}
super.EndState();
}
}
state ZombieCharge
{
function bool StrafeFromDamage(float Damage, class<DamageType> DamageType, bool bFindDest)
{
return false;
}
function bool TryStrafe(vector sideDir)
{
return false;
}
function Timer()
{
Disable('NotifyBump');
Target = Enemy;
TimedFireWeaponAtEnemy();
}
WaitForAnim:
if ( Monster(Pawn).bShotAnim )
{
Goto('Moving');
}
if ( !FindBestPathToward(Enemy, false,true) )
GotoState('ZombieRestFormation');
Moving:
MoveToward(Enemy);
WhatToDoNext(17);
if ( bSoaking )
SoakStop("STUCK IN CHARGING!");
}
state RunSomewhere
{
Ignores HearNoise,DamageAttitudeTo,Tick,EnemyChanged,Startle;
function BeginState()
{
HidingSpots = none;
Enemy = none;
SetTimer(0.1,true);
}
event SeePlayer(Pawn SeenPlayer)
{
SetEnemy(SeenPlayer);
}
function Timer()
{
if( Enemy==none )
return;
Target = Enemy;
KFM.RangedAttack(Target);
}
Begin:
if( Pawn.Physics==PHYS_Falling )
WaitForLanding();
While( KFM.bShotAnim )
Sleep(0.25);
if( HidingSpots==none )
HidingSpots = FindRandomDest();
if( HidingSpots==none )
ZombieBossOS(Pawn).BeginHealing();
if( ActorReachable(HidingSpots) )
{
MoveTarget = HidingSpots;
HidingSpots = none;
}
else FindBestPathToward(HidingSpots,true,false);
if( MoveTarget==none )
ZombieBossOS(Pawn).BeginHealing();
if( Enemy!=none && VSize(Enemy.Location-Pawn.Location)<100 )
MoveToward(MoveTarget,Enemy,,false);
else MoveToward(MoveTarget,MoveTarget,,false);
if( HidingSpots==none || !PlayerSeesMe() )
ZombieBossOS(Pawn).BeginHealing();
GoTo'Begin';
}
State SyrRetreat
{
Ignores HearNoise,DamageAttitudeTo,Tick,EnemyChanged,Startle;
function BeginState()
{
HidingSpots = none;
Enemy = none;
SetTimer(0.1,true);
}
event SeePlayer(Pawn SeenPlayer)
{
SetEnemy(SeenPlayer);
}
function Timer()
{
if( Enemy==none )
return;
Target = Enemy;
KFM.RangedAttack(Target);
}
function FindHideSpot()
{
local NavigationPoint N,BN;
local float Dist,BDist,MDist;
local vector EnemyDir;
if( Enemy==none )
{
HidingSpots = FindRandomDest();
return;
}
EnemyDir = Normal(Enemy.Location-Pawn.Location);
For( N=Level.NavigationPointList; N!=none; N=N.NextNavigationPoint )
{
MDist = VSize(N.Location-Pawn.Location);
if( MDist<2500 && !FastTrace(N.Location,Enemy.Location) && FindPathToward(N)!=none )
{
Dist = VSize(N.Location-Enemy.Location)/FMax(MDist/800.f,1.5);
if( (EnemyDir Dot Normal(Enemy.Location-N.Location))<0.2 )
Dist/=10;
if( BN==none || BDist<Dist )
{
BN = N;
BDist = Dist;
}
}
}
if( BN==none )
HidingSpots = FindRandomDest();
else HidingSpots = BN;
}
Begin:
if( Pawn.Physics==PHYS_Falling )
WaitForLanding();
While( KFM.bShotAnim )
Sleep(0.25);
if( HidingSpots==none )
FindHideSpot();
if( HidingSpots==none )
ZombieBossOS(Pawn).BeginHealing();
if( ActorReachable(HidingSpots) )
{
MoveTarget = HidingSpots;
HidingSpots = none;
}
else FindBestPathToward(HidingSpots,true,false);
if( MoveTarget==none )
ZombieBossOS(Pawn).BeginHealing();
if( Enemy!=none && VSize(Enemy.Location-Pawn.Location)<100 )
MoveToward(MoveTarget,Enemy,,false);
else MoveToward(MoveTarget,MoveTarget,,false);
if( HidingSpots==none )
ZombieBossOS(Pawn).BeginHealing();
GoTo'Begin';
}
function bool PlayerSeesMe()
{
local Controller C;
For( C=Level.ControllerList; C!=none; C=C.NextController )
{
if( C.bIsPlayer && C.Pawn!=none && C.Pawn!=Pawn && LineOfSightTo(C.Pawn) )
return true;
}
return false;
}
function SetWaitForAnimTimout(float NewWaitAnimTimeout, name AnimToWaitFor)
{
WaitAnimTimeout = NewWaitAnimTimeout;
AnimWaitingFor = AnimToWaitFor;
}
state WaitForAnim
{
Ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump,Startle;
function WaitTimeout()
{
if( bUseFreezeHack )
{
if( Pawn!=none )
{
Pawn.AccelRate = Pawn.default.AccelRate;
Pawn.GroundSpeed = Pawn.default.GroundSpeed;
}
bUseFreezeHack = false;
}
AnimEnd(AnimWaitChannel);
}
event AnimEnd(int Channel)
{
Pawn.AnimEnd(Channel);
if ( !Monster(Pawn).bShotAnim )
WhatToDoNext(99);
}
function Tick( float Delta )
{
Global.Tick(Delta);
if( WaitAnimTimeout > 0 )
{
WaitAnimTimeout -= Delta;
if( WaitAnimTimeout <= 0 )
{
WaitAnimTimeout = 0;
WaitTimeout();
}
}
if( bUseFreezeHack )
{
MoveTarget = none;
MoveTimer = -1;
Pawn.Acceleration = vect(0,0,0);
Pawn.GroundSpeed = 1;
Pawn.AccelRate = 0;
}
}
function EndState()
{
super.EndState();
AnimWaitingFor = '';
}
}
defaultproperties
{
}

View file

@ -0,0 +1,103 @@
//Controller class for Crawler ✓
class ControllerCrawlerOS extends KFMonsterControllerOS;
var float LastPounceTime;
var bool bDoneSpottedCheck;
var bool bEnableOldCrawlerBehaviour;
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedCrawlerMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 18, "");
KFGameType(Level.Game).bDidSpottedCrawlerMessage = true;
}
bDoneSpottedCheck = true;
}
super.SeePlayer(SeenPlayer);
}
}
function bool IsInPounceDist(actor PTarget)
{
local vector DistVec;
local float time;
local float HeightMoved;
local float EndHeight;
DistVec = pawn.location - PTarget.location;
DistVec.Z=0;
time = vsize(DistVec)/ZombieCrawlerOS(pawn).PounceSpeed;
HeightMoved = Pawn.JumpZ*time + 0.5 * pawn.PhysicsVolume.Gravity.z * time * time;
EndHeight = pawn.Location.z +HeightMoved;
if((abs(EndHeight - PTarget.Location.Z) < Pawn.CollisionHeight + PTarget.CollisionHeight) &&
VSize(pawn.Location - PTarget.Location) < KFMonster(pawn).MeleeRange * 5 )
return true;
else
return false;
}
function bool FireWeaponAt(Actor A)
{
local vector aFacing,aToB;
local float RelativeDir;
if ( A == none )
A = Enemy;
if ( (A == none) || (Focus != A) )
return false;
if(CanAttack(A))
{
Target = A;
Monster(Pawn).RangedAttack(Target);
}
else
{
if(LastPounceTime + 1 < Level.TimeSeconds && bEnableOldCrawlerBehaviour ||
LastPounceTime + (4.5 - (FRand() * 3.0)) < Level.TimeSeconds && !bEnableOldCrawlerBehaviour)
{
aFacing=Normal(Vector(Pawn.Rotation));
aToB=A.Location-Pawn.Location;
RelativeDir = aFacing dot aToB;
if ( RelativeDir > 0.85 )
{
if(IsInPounceDist(A) )
{
if(ZombieCrawlerOS(Pawn).DoPounce()==true )
LastPounceTime = Level.TimeSeconds;
}
}
}
}
return false;
}
function bool NotifyLanded(vector HitNormal)
{
if( ZombieCrawlerOS(pawn).bPouncing )
{
GotoState('hunting');
return false;
}
else
return super.NotifyLanded(HitNormal);
}
defaultproperties
{
}

View file

@ -0,0 +1,188 @@
//Controller class for Explosive Gunner Pound ✓
class ControllerExplosivePound extends KFMonsterControllerOS;
var float WaitAnimTimeout;
var int AnimWaitChannel;
var name AnimWaitingFor;
var bool bDoneSpottedCheck;
state DoorBashing
{
ignores EnemyNotVisible,SeeMonster;
function EndState()
{
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieExplosivesPoundOS(Pawn).GetOriginalGroundSpeed();
}
}
}
//Players call out his Chainsaw when he sees them
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedScrakeMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 14, "");
KFGameType(Level.Game).bDidSpottedScrakeMessage = true;
}
bDoneSpottedCheck = true;
}
super.SeePlayer(SeenPlayer);
}
}
function bool FireWeaponAt(Actor A)
{
if ( A == none )
A = Enemy;
if ( (A == none) || (Focus != A) )
return false;
Target = A;
if(ZombieExplosivesPoundOS(Pawn).Health / ZombieExplosivesPoundOS(Pawn).HealthMax < 0.5 )
Monster(Pawn).RangedAttack(Target);
if((VSize(A.Location - Pawn.Location) >= ZombieExplosivesPoundOS(Pawn).MeleeRange + Pawn.CollisionRadius + Target.CollisionRadius) &&
ZombieExplosivesPoundOS(Pawn).LastGLTime - Level.TimeSeconds > 0 )
{
return false;
}
Monster(Pawn).RangedAttack(Target);
return false;
}
function TimedFireWeaponAtEnemy()
{
if ( (Enemy == none) || FireWeaponAt(Enemy) )
SetCombatTimer();
else
SetTimer(0.01, true);
}
state ZombieCharge
{
function GetOutOfTheWayOfShot(vector ShotDirection, vector ShotOrigin){}
function bool StrafeFromDamage(float Damage, class<DamageType> DamageType, bool bFindDest)
{
return false;
}
function bool TryStrafe(vector sideDir)
{
return false;
}
function Timer()
{
Disable('NotifyBump');
Target = Enemy;
TimedFireWeaponAtEnemy();
}
WaitForAnim:
While( Monster(Pawn).bShotAnim )
Sleep(0.25);
if ( !FindBestPathToward(Enemy, false,true) )
GotoState('ZombieRestFormation');
Moving:
MoveToward(Enemy);
WhatToDoNext(17);
if ( bSoaking )
SoakStop("STUCK IN CHARGING!");
}
function SetWaitForAnimTimout(float NewWaitAnimTimeout, name AnimToWaitFor)
{
WaitAnimTimeout = NewWaitAnimTimeout;
AnimWaitingFor = AnimToWaitFor;
}
state WaitForAnim
{
Ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump,Startle;
function WaitTimeout()
{
if( bUseFreezeHack )
{
if( Pawn!=none )
{
Pawn.AccelRate = Pawn.default.AccelRate;
Pawn.GroundSpeed = Pawn.default.GroundSpeed;
}
bUseFreezeHack = false;
}
AnimEnd(AnimWaitChannel);
}
event AnimEnd(int Channel)
{
Pawn.AnimEnd(Channel);
if ( !Monster(Pawn).bShotAnim )
WhatToDoNext(99);
}
function Tick( float Delta )
{
Global.Tick(Delta);
if( WaitAnimTimeout > 0 )
{
WaitAnimTimeout -= Delta;
if( WaitAnimTimeout <= 0 )
{
WaitAnimTimeout = 0;
WaitTimeout();
}
}
if( bUseFreezeHack )
{
MoveTarget = none;
MoveTimer = -1;
Pawn.Acceleration = vect(0,0,0);
Pawn.GroundSpeed = 1;
Pawn.AccelRate = 0;
}
}
function EndState()
{
super.EndState();
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieExplosivesPoundOS(Pawn).GetOriginalGroundSpeed();
}
bUseFreezeHack = False;
AnimWaitingFor = '';
}
}
function float AdjustAimError(float aimerror, float TargetDist, bool bDefendMelee, bool bInstantProj, bool bLeadTargetNow )
{
//Always have the best accuracy, otherwise you aren't a threat
return aimerror*=0;
}
defaultproperties
{
}

View file

@ -0,0 +1,207 @@
//Controller class for Fleshpound ✓
class ControllerFleshpoundOS extends KFMonsterControllerOS;
var float RageAnimTimeout;
var bool bDoneSpottedCheck;
var float RageFrustrationTimer;
var float RageFrustrationThreshhold;
var bool bEnableOldFleshpoundBehavior;
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedFleshpoundMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 12, "");
KFGameType(Level.Game).bDidSpottedFleshpoundMessage = true;
}
bDoneSpottedCheck = true;
}
super.SeePlayer(SeenPlayer);
}
}
function TimedFireWeaponAtEnemy()
{
if ( (Enemy == none) || FireWeaponAt(Enemy) )
SetCombatTimer();
else
SetTimer(0.01, true);
}
state SpinAttack
{
ignores EnemyNotVisible;
function GetOutOfTheWayOfShot(vector ShotDirection, vector ShotOrigin){}
function DoSpinDamage()
{
local Actor A;
foreach CollidingActors(class'actor', A, (ZombieFleshpoundOS(pawn).MeleeRange * 1.5)+pawn.CollisionRadius, pawn.Location)
ZombieFleshpoundOS(pawn).SpinDamage(A);
}
Begin:
WaitForAnim:
While( KFM.bShotAnim )
{
Sleep(0.1);
DoSpinDamage();
}
WhatToDoNext(152);
if ( bSoaking )
SoakStop("STUCK IN SPINATTACK!!!");
}
state ZombieCharge
{
function Tick( float Delta )
{
local ZombieFleshpoundOS ZFP;
Global.Tick(Delta);
if( RageFrustrationTimer < RageFrustrationThreshhold && !bEnableOldFleshpoundBehavior )
{
RageFrustrationTimer += Delta;
if( RageFrustrationTimer >= RageFrustrationThreshhold )
{
ZFP = ZombieFleshpoundOS(Pawn);
if( ZFP != none && !ZFP.bChargingPlayer )
{
ZFP.StartCharging();
ZFP.bFrustrated = true;
}
}
}
}
function bool StrafeFromDamage(float Damage, class<DamageType> DamageType, bool bFindDest)
{
return false;
}
function bool TryStrafe(vector sideDir)
{
return false;
}
function Timer()
{
Disable('NotifyBump');
Target = Enemy;
TimedFireWeaponAtEnemy();
}
function BeginState()
{
super.BeginState();
if(!bEnableOldFleshpoundBehavior)
{
RageFrustrationThreshhold = default.RageFrustrationThreshhold + (Frand() * 5);
RageFrustrationTimer = 0;
}
}
WaitForAnim:
if ( Monster(Pawn).bShotAnim )
{
Goto('Moving');
}
if ( !FindBestPathToward(Enemy, false,true) )
GotoState('ZombieRestFormation');
Moving:
MoveToward(Enemy);
WhatToDoNext(17);
if ( bSoaking )
SoakStop("STUCK IN CHARGING!");
}
function SetPoundRageTimout(float NewRageTimeOut)
{
RageAnimTimeout = NewRageTimeOut;
}
state WaitForAnim
{
Ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump;
function GetOutOfTheWayOfShot(vector ShotDirection, vector ShotOrigin){}
function BeginState()
{
bUseFreezeHack = false;
}
function RageTimeout()
{
if( bUseFreezeHack )
{
if( Pawn!=none )
{
Pawn.AccelRate = Pawn.default.AccelRate;
Pawn.GroundSpeed = Pawn.default.GroundSpeed;
}
bUseFreezeHack = false;
AnimEnd(0);
}
}
function Tick( float Delta )
{
Global.Tick(Delta);
if( RageAnimTimeout > 0 )
{
RageAnimTimeout -= Delta;
if( RageAnimTimeout <= 0 )
{
RageAnimTimeout = 0;
RageTimeout();
}
}
if( bUseFreezeHack )
{
MoveTarget = none;
MoveTimer = -1;
Pawn.Acceleration = vect(0,0,0);
Pawn.GroundSpeed = 1;
Pawn.AccelRate = 0;
}
}
function EndState()
{
if( Pawn!=none )
{
Pawn.AccelRate = Pawn.default.AccelRate;
Pawn.GroundSpeed = Pawn.default.GroundSpeed;
}
bUseFreezeHack = false;
}
Begin:
While( KFM.bShotAnim )
{
Sleep(0.15);
}
WhatToDoNext(99);
}
defaultproperties
{
RageFrustrationThreshhold=10.000000
}

View file

@ -0,0 +1,61 @@
//Controller class for Gorefast ✓
class ControllerGorefastOS extends KFMonsterControllerOS;
var bool bDoneSpottedCheck;
//Fixes slow charge for charging zeds
//Credits:NikC for forum link, aleat0r for the code
state WaitForAnim
{
ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump,Startle;
function EndState()
{
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieGorefastOS(Pawn).GetOriginalGroundSpeed();
}
bUseFreezeHack = False;
}
}
//Ditto
state DoorBashing
{
ignores EnemyNotVisible,SeeMonster;
function EndState()
{
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieGorefastOS(Pawn).GetOriginalGroundSpeed();
}
}
}
//Players that spot a Gorefast will have a 25% chance to call him out
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedGorefastMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 13, "");
KFGameType(Level.Game).bDidSpottedGorefastMessage = true;
}
bDoneSpottedCheck = true;
}
global.SeePlayer(SeenPlayer);
}
}
defaultproperties
{
StrafingAbility=0.500000
}

View file

@ -0,0 +1,139 @@
//Controller class for Gunner Pound ✓
class ControllerRangedPoundOS extends KFMonsterControllerOS;
var float WaitAnimTimeout;
var int AnimWaitChannel;
var name AnimWaitingFor;
function bool FireWeaponAt(Actor A)
{
if ( A == none )
A = Enemy;
if ( (A == none) || (Focus != A) )
return false;
Target = A;
if( (VSize(A.Location - Pawn.Location) >= ZombieRangedPoundOS(Pawn).MeleeRange + Pawn.CollisionRadius + Target.CollisionRadius) &&
ZombieRangedPoundOS(Pawn).LastChainGunTime - Level.TimeSeconds > 0 )
{
return false;
}
Monster(Pawn).RangedAttack(Target);
return false;
}
function TimedFireWeaponAtEnemy()
{
if ( (Enemy == none) || FireWeaponAt(Enemy) )
SetCombatTimer();
else
SetTimer(0.01, true);
}
state ZombieCharge
{
function bool StrafeFromDamage(float Damage, class<DamageType> DamageType, bool bFindDest)
{
return false;
}
function bool TryStrafe(vector sideDir)
{
return false;
}
function Timer()
{
Disable('NotifyBump');
Target = Enemy;
TimedFireWeaponAtEnemy();
}
WaitForAnim:
if ( Monster(Pawn).bShotAnim )
{
Goto('Moving');
}
if ( !FindBestPathToward(Enemy, false,true) )
GotoState('ZombieRestFormation');
Moving:
MoveToward(Enemy);
WhatToDoNext(17);
if ( bSoaking )
SoakStop("STUCK IN CHARGING!");
}
function SetWaitForAnimTimout(float NewWaitAnimTimeout, name AnimToWaitFor)
{
WaitAnimTimeout = NewWaitAnimTimeout;
AnimWaitingFor = AnimToWaitFor;
}
state WaitForAnim
{
Ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump,Startle;
function WaitTimeout()
{
if( bUseFreezeHack )
{
if( Pawn!=none )
{
Pawn.AccelRate = Pawn.default.AccelRate;
Pawn.GroundSpeed = Pawn.default.GroundSpeed;
}
bUseFreezeHack = false;
}
AnimEnd(AnimWaitChannel);
}
event AnimEnd(int Channel)
{
Pawn.AnimEnd(Channel);
if ( !Monster(Pawn).bShotAnim )
WhatToDoNext(99);
}
function Tick( float Delta )
{
Global.Tick(Delta);
if( WaitAnimTimeout > 0 )
{
WaitAnimTimeout -= Delta;
if( WaitAnimTimeout <= 0 )
{
WaitAnimTimeout = 0;
WaitTimeout();
}
}
if( bUseFreezeHack )
{
MoveTarget = none;
MoveTimer = -1;
Pawn.Acceleration = vect(0,0,0);
Pawn.GroundSpeed = 1;
Pawn.AccelRate = 0;
}
}
function EndState()
{
super.EndState();
AnimWaitingFor = '';
}
}
defaultproperties
{
}

View file

@ -0,0 +1,91 @@
// Controller Class for Scrake ✓
class ControllerScrakeOS extends KFMonsterControllerOS;
var bool bDoneSpottedCheck;
//Fixes slow charge for charging zeds
//Credits:NikC for forum link, aleat0r for the code
state WaitForAnim
{
ignores SeePlayer,HearNoise,Timer,EnemyNotVisible,NotifyBump,Startle;
function EndState()
{
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieScrakeOS(Pawn).GetOriginalGroundSpeed();
}
bUseFreezeHack = False;
}
}
//ditto
state DoorBashing
{
ignores EnemyNotVisible,SeeMonster;
function EndState()
{
if (Pawn != None)
{
Pawn.AccelRate = Pawn.Default.AccelRate;
Pawn.GroundSpeed = ZombieScrakeOS(Pawn).GetOriginalGroundSpeed();
}
}
}
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedScrakeMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 14, "");
KFGameType(Level.Game).bDidSpottedScrakeMessage = true;
}
bDoneSpottedCheck = true;
}
super.SeePlayer(SeenPlayer);
}
}
state ZombieCharge
{
function GetOutOfTheWayOfShot(vector ShotDirection, vector ShotOrigin){}
function bool StrafeFromDamage(float Damage, class<DamageType> DamageType, bool bFindDest)
{
return false;
}
function bool TryStrafe(vector sideDir)
{
return false;
}
function Timer()
{
Disable('NotifyBump');
Target = Enemy;
TimedFireWeaponAtEnemy();
}
WaitForAnim:
While( Monster(Pawn).bShotAnim )
Sleep(0.25);
if ( !FindBestPathToward(Enemy, false,true) )
GotoState('ZombieRestFormation');
Moving:
MoveToward(Enemy);
WhatToDoNext(17);
if ( bSoaking )
SoakStop("STUCK IN CHARGING!");
}
defaultproperties
{
}

View file

@ -0,0 +1,27 @@
// Controller class for Siren
class ControllerSirenOS extends KFMonsterControllerOS;
var bool bDoneSpottedCheck;
state ZombieHunt
{
event SeePlayer(Pawn SeenPlayer)
{
if ( !bDoneSpottedCheck && PlayerController(SeenPlayer.Controller) != none )
{
if ( !KFGameType(Level.Game).bDidSpottedSirenMessage && FRand() < 0.25 )
{
PlayerController(SeenPlayer.Controller).Speech('AUTO', 15, "");
KFGameType(Level.Game).bDidSpottedSirenMessage = true;
}
bDoneSpottedCheck = true;
}
super.SeePlayer(SeenPlayer);
}
}
defaultproperties
{
}

View file

@ -0,0 +1,10 @@
class DamTypeVomitOS extends DamTypeVomit
abstract;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
defaultproperties
{
HUDDamageTex=FinalBlend'KFOldSchoolZeds_Textures.HUD.VomitFB'
HUDUberDamageTex=FinalBlend'KFOldSchoolZeds_Textures.HUD.VomitFB'
}

View file

@ -0,0 +1,65 @@
// Code is... borrowed from SkellTestMap's mutator
class DebugHeadHitbox extends Actor;
var KFMonsterOS Zed;
var Vector HeadLocation;
var float headScale;
replication
{
reliable if (Role == ROLE_Authority)
HeadLocation, headScale;
}
simulated event PostBeginPlay()
{
super.PostBeginPlay();
if (Role == ROLE_Authority && Owner != none)
{
SetLocation(Owner.Location);
SetPhysics(PHYS_None);
SetBase(Owner);
Zed = KFMonsterOS(Owner);
}
}
simulated event Tick(float deltaTime)
{
local Coords C;
local bool bAltHeadLoc;
if (Zed == none || Zed.bDecapitated || Zed.HeadBone == '' || Zed.health <= 0)
{
Destroy();
return;
}
// Server hit-boxes
if (Role == ROLE_Authority)
{
if (Level.NetMode == NM_DedicatedServer && Zed.Physics == PHYS_Walking && !Zed.IsAnimating(0) && !Zed.IsAnimating(1) && !Zed.bIsCrouched)
bAltHeadLoc = true;
headScale = Zed.headRadius * Zed.headScale;
if (bAltHeadLoc)
{
HeadLocation = Zed.Location + (Zed.OnlineHeadshotOffset >> Zed.Rotation);
if (Level.NetMode == NM_DedicatedServer)
headScale *= Zed.onlineHeadshotScale;
}
else
{
C = Zed.GetBoneCoords(Zed.HeadBone);
HeadLocation = C.Origin + (Zed.headHeight * Zed.headScale * C.XAxis);
}
}
}
defaultproperties
{
bHidden=True
bSkipActorPropertyReplication=True
RemoteRole=ROLE_SimulatedProxy
NetPriority=2.000000
}

View file

@ -0,0 +1,56 @@
//2.5 FleshHitEmitter ✓
class FleshHitEmitterOS extends KFHitEmitter
abstract
hidedropdown;
//Usage:
//Parent class. Holds information for blood that comes out of zeds.
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
defaultproperties
{
ImpactSounds(0)=Sound'KFOldSchoolZeds_Sounds.Shared.Heavy_FleshImpact1'
ImpactSounds(1)=Sound'KFOldSchoolZeds_Sounds.Shared.Heavy_FleshImpact1'
ImpactSounds(2)=Sound'KFOldSchoolZeds_Sounds.Shared.Heavy_FleshImpact2'
ImpactSounds(3)=Sound'KFOldSchoolZeds_Sounds.Shared.Heavy_FleshImpact3'
Begin Object Class=SpriteEmitter Name=SpriteEmitter0
FadeOut=True
RespawnDeadParticles=False
SpawnOnlyInDirectionOfNormal=True
SpinParticles=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
ScaleSizeYByVelocity=True
ScaleSizeZByVelocity=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
UseRandomSubdivision=True
Acceleration=(Z=-350.000000)
ColorScale(1)=(RelativeTime=0.300000,Color=(B=255,G=255,R=255))
ColorScale(2)=(RelativeTime=0.750000,Color=(B=96,G=160,R=255))
ColorScale(3)=(RelativeTime=1.000000)
ColorMultiplierRange=(Z=(Min=0.670000,Max=2.000000))
FadeOutStartTime=0.300000
StartLocationShape=PTLS_Sphere
SphereRadiusRange=(Max=5.000000)
StartMassRange=(Min=11.000000,Max=11.000000)
UseRotationFrom=PTRS_Normal
SpinsPerSecondRange=(X=(Min=0.100000,Max=0.120000))
SizeScale(0)=(RelativeTime=1.000000,RelativeSize=3.500000)
StartSizeRange=(X=(Min=8.000000,Max=12.000000),Y=(Min=0.000000,Max=0.000000),Z=(Min=0.000000,Max=0.000000))
ScaleSizeByVelocityMultiplier=(X=0.000000,Y=0.000000,Z=0.000000)
ScaleSizeByVelocityMax=3.000000
InitialParticlesPerSecond=100.000000
DrawStyle=PTDS_Modulated
Texture=Texture'KFOldSchoolZeds_Textures.Shared.BloodySpray'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=0.500000,Max=0.750000)
StartVelocityRange=(Z=(Min=120.000000,Max=150.000000))
End Object
Emitters(0)=SpriteEmitter'KFOldSchoolZeds.FleshHitEmitterOS.SpriteEmitter0'
LifeSpan=1.000000
}

View file

@ -0,0 +1,43 @@
// Explosion when zed is obliterated ✓
class GibExplosionOS extends FleshHitEmitterOS;
defaultproperties
{
Begin Object Class=SpriteEmitter Name=SpriteEmitter43
FadeOut=True
RespawnDeadParticles=False
SpawnOnlyInDirectionOfNormal=True
SpinParticles=True
UseSizeScale=True
UseRegularSizeScale=False
UniformSize=True
ScaleSizeYByVelocity=True
ScaleSizeZByVelocity=True
BlendBetweenSubdivisions=True
UseRandomSubdivision=True
Acceleration=(Z=-350.000000)
ColorScale(0)=(Color=(R=255,A=255))
ColorScale(1)=(RelativeTime=1.000000,Color=(R=255,A=255))
ColorMultiplierRange=(Z=(Min=0.670000,Max=2.000000))
FadeOutStartTime=0.126500
MaxParticles=65
StartLocationShape=PTLS_Sphere
SphereRadiusRange=(Max=5.000000)
StartMassRange=(Min=11.000000,Max=11.000000)
UseRotationFrom=PTRS_Normal
SpinsPerSecondRange=(X=(Min=0.100000,Max=0.120000))
SizeScale(0)=(RelativeTime=1.000000,RelativeSize=3.500000)
StartSizeRange=(X=(Min=45.000000,Max=50.000000),Y=(Min=0.000000,Max=0.000000),Z=(Min=0.000000,Max=0.000000))
ScaleSizeByVelocityMultiplier=(X=0.000000,Y=0.000000,Z=0.000000)
ScaleSizeByVelocityMax=3.000000
InitialParticlesPerSecond=100.000000
DrawStyle=PTDS_Modulated
Texture=Texture'KFOldSchoolZeds_Textures.Shared.BloodySpray'
TextureUSubdivisions=4
TextureVSubdivisions=2
LifetimeRange=(Min=0.400000,Max=0.550000)
StartVelocityRange=(X=(Min=-200.000000,Max=200.000000),Y=(Min=-100.000000,Max=100.000000),Z=(Min=300.000000,Max=500.000000))
End Object
Emitters(0)=SpriteEmitter'KFOldSchoolZeds.GibExplosionOS.SpriteEmitter43'
}

View file

@ -0,0 +1,25 @@
// Stump attached to the neck after the head has been destroyed ✓
class GibHeadStumpOS extends KFGibOS;
simulated function PostBeginPlay()
{
SpawnTrail();
}
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DampenFactor=0.300000
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'22Patch.Severed_Head'
RemoteRole=ROLE_SimulatedProxy
NetUpdateFrequency=10.000000
LifeSpan=40.000000
DrawScale=0.600000
Skins(0)=Texture'22CharTex.SeveredSkin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,167 @@
// Projectile for Gunner Class ✓
class GunnerGLProjectile extends SPGrenadeProjectile;
#exec OBJ LOAD FILE=KFOldSchoolStatics.usx
#exec OBJ LOAD FILE=KF_GrenadeSnd.uax
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
#exec OBJ LOAD FILE=KF_IJC_HalloweenSnd.uax
var bool bNerfed;
// Does not work
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ( Monster(instigatedBy) != none || instigatedBy == Instigator )
{
//If were hit by the zed guns, go away
if( damageType == class'DamTypeZEDGun' || DamageType == class 'DamTypeZEDGunMKII')
{
Disintegrate(HitLocation, vect(0,0,1));
}
//If were hit by fire, explode
else if(DamageType == class'DamTypeBurned')
{
Explode(HitLocation, vect(0,0,1));
}
}
}
simulated function PostBeginPlay()
{
local vector Dir;
if ( Level.NetMode != NM_DedicatedServer )
{
if ( !PhysicsVolume.bWaterVolume )
{
SmokeTrail = Spawn(SmokeTrailEmitterClass,self);
}
}
if (Level.Game != none)
{
if(!bNerfed)
{
if( Level.Game.GameDifficulty < 2.0 )
{
Damage = default.Damage * 0.5;
}
else if( Level.Game.GameDifficulty < 4.0 )
{
Damage = default.Damage * 1.0;
}
else if( Level.Game.GameDifficulty < 5.0 )
{
Damage = default.Damage * 1.33;
}
else
{
Damage = default.Damage * 1.66;
}
}
}
OrigLoc = Location;
if( !bKillMomentum )
{
Dir = vector(Rotation);
Velocity = Speed * Dir;
Velocity.Z += TossZ;
}
if (PhysicsVolume.bWaterVolume)
Velocity=0.6*Velocity;
super(Projectile).PostBeginPlay();
SetTimer(ExplodeTimer, false);
}
// override to prevent zeds from taking damage - taken from siren
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('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;
}
simulated function ProcessTouch(Actor Other, Vector HitLocation)
{
if ( Other == none || Other == Instigator || Other.Base == Instigator )
return;
if( KFBulletWhipAttachment(Other) != none )
{
return;
}
if( KFMonster(Other) != none && KFMonsterOS(Other) != none && Instigator != none )
{
return;
}
if( Instigator != none )
{
OrigLoc = Instigator.Location;
}
if( !bKillMomentum )
{
Explode(HitLocation,Normal(HitLocation-Other.Location));
}
}
defaultproperties
{
ExplosionSound=SoundGroup'KF_GrenadeSnd.Nade_Explode_1'
ArmDistSquared=0.000000
ImpactDamage=0
DampenFactor=0.400000
DampenFactorParallel=0.300000
Speed=1.000000
MaxSpeed=2500.000000
Damage=75.000000
MyDamageType=Class'KFMod.DamTypeFrag'
ImpactSound=Sound'KFOldSchoolZeds_Sounds.Shared.Bounce'
LightType=LT_Pulse
LightHue=0
LightSaturation=0
LightBrightness=160.000000
LightRadius=6.000000
LightPeriod=8
StaticMesh=StaticMesh'KFOldSchoolStatics.GunpoundProj'
DrawScale=4.000000
bUnlit=True
}

View file

@ -0,0 +1,368 @@
// Mutator that replaces zeds with their 2.5 counterpart
// GitHub: https://github.com/theengineertcr/KFOldSchoolZeds
class KF25OSMut extends Mutator
config(KFOldSchoolZeds);
// Load all relevant texture, sound, and other packages
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
#exec OBJ LOAD FILE=KFPatch2.utx
#exec OBJ LOAD FILE=KillingFloorLabTextures.utx
#exec OBJ LOAD FILE=KFCharacterModelsOldSchool.ukx
#exec OBJ LOAD FILE=KFBossOld.ukx
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
#exec OBJ LOAD FILE=KF_M79Snd.uax
// We've taken this code from CssHDMut:
// https://github.com/InsultingPros/CsHDMut/blob/02a0cdd2b79de8e1c7ea26f12370b115c038e542/sources/CsHDMut.uc#L20
var config bool bEnableRangedPound; // Fleshpound Chaingunners replace Husks
var config bool bDisableIncendiaryRounds; // Fleshpound Chaingunner does not use incendiary rounds
var config bool bDisableIncendiaryResistance; // Fleshpound Chaingunner no longer has resistance to burned damagetype
var config bool bEnableExplosivesPound; // Explosive Fleshpound Gunners spawn alongside Fleshpounds
var config bool bNerfEP; // Explosive Pound is nerfed.
var config bool bEnableOldBloatPuke; // Bloat uses 2.5 puke behavior
var config bool bEnableOldCrawlerBehaviour; // Crawler uses 2.5 leaping behavior
var config bool bEnableSirenNadeBoom; // Swaps Siren Scream Damage type, causing explosives to explode
var config bool bEnableOldScrakeBehavior; // Use 2.5 Scrake behavior: No rage charging.
var config bool bEnableOldFleshpoundBehavior; // Use 2.5 Fleshpound behavior: No LoS rage and 10 second long rage.
//var config bool bEnableOldHeadshotBehavior; // Use 2.5 Headshot behavior. No head health/bleedout. Damage Vs. Health / HealthMax * Multiplier determines if big zed loses head.
//var config bool bDisableHealthScaling; // Disables Health Scaling, similar to the mod version of the game
var config bool bEnableRandomSkins; // Zeds use a random skin from other zeds
var private array< class<KFMonsterOS> > ZedList;
var bool bShowHeadHitbox;
const STEAMID1="76561198044316328"; // nikc
const STEAMID2="76561197993557589"; // bofa
replication
{
reliable if (Role == ROLE_Authority)
bShowHeadHitbox;
}
//=======================================
// PostBeginPlay
//=======================================
event PostBeginPlay()
{
local int i;
local KFGameType KF;
super.PostBeginPlay();
KF = KFGameType(Level.Game);
if (KF == none)
{
log("KFGameType not found, terminating!", self.name);
Destroy();
return;
}
if (KF.MonsterCollection == class'KFGameType'.default.MonsterCollection)
{
KF.MonsterCollection = class'KFMonstersCollectionOS';
}
for (i = 0; i < KF.SpecialEventMonsterCollections.Length; i++)
{
KF.SpecialEventMonsterCollections[i] = KF.MonsterCollection;
}
if(bEnableRangedPound && KF.MonsterCollection.default.MonsterClasses[8].MClassName != "")
{
if(bEnableRangedPound)
KF.MonsterCollection.default.MonsterClasses[8].MClassName = string(class'ZombieRangedPoundOS');
}
else
KF.MonsterCollection.default.MonsterClasses[8].MClassName = "";
if(bEnableExplosivesPound)
{
// Replace 2/3 Scrake Squad Spawns(temporary)
// He's supposed to be as rare as a Fleshpound, but
// This is fine for now. People will learn to fear him :)
KF.StandardMonsterSquads[13]="2A1J";
KF.MonsterSquad[13]="2A1J";
KF.StandardMonsterSquads[14]="2A3C1J";
KF.MonsterSquad[14]="2A3C1J";
if(bNerfEP)
{
class'ZombieExplosivesPoundOS'.default.bNerfed = true;
class'GunnerGLProjectile'.default.bNerfed = true;
}
}
if(bEnableSirenNadeBoom)
class'ZombieSirenOS'.default.bEnableSirenNadeBoom = true;
if(bEnableOldScrakeBehavior)
class'ZombieScrakeOS'.default.bEnableOldScrakeBehavior = true;
if(bEnableOldCrawlerBehaviour)
class'ControllerCrawlerOS'.default.bEnableOldCrawlerBehaviour = true;
if(bEnableOldFleshpoundBehavior)
{
class'ZombieFleshPoundOS'.default.bEnableOldFleshpoundBehavior = true;
class'ControllerFleshpoundOS'.default.bEnableOldFleshpoundBehavior = true;
}
if(bEnableOldBloatPuke)
class'ZombieBloatOS'.default.bEnableOldBloatPuke = true;
if(bDisableIncendiaryRounds)
class'ZombieRangedPoundOS'.default.bDisableIncendiaryRounds = true;
if(bDisableIncendiaryResistance)
class'ZombieRangedPoundOS'.default.bDisableIncendiaryResistance = true;
}
// precache materials
function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
{
// catch the PRI, most likely player is 'alive' at this point
if (PlayerReplicationInfo(Other) != none)
{
PreCacheMaterials(PlayerController(PlayerReplicationInfo(other).owner));
}
return super.CheckReplacement(Other, bSuperRelevant);
}
// parse zed list and load their assets to avoid lags on their first appearance
final private function PreCacheMaterials(PlayerController pc)
{
local int i;
// just in case
if (Level.NetMode != NM_DedicatedServer || pc == none)
return;
for (i = 0; i < ZedList.length; i++)
{
ZedList[i].static.PreCacheMaterials(Level);
}
}
// add our interaction
simulated function Tick(float DeltaTime)
{
local PlayerController PC;
local Interaction KFOSInt;
PC = Level.GetLocalPlayerController();
if (PC != None)
{
KFOSInt = PC.Player.InteractionMaster.AddInteraction(string(class'KFOSInteraction'), PC.Player);
KFOSInteraction(KFOSInt).Mut = Self;
}
Disable('Tick');
}
// fancy, colored Mutate system
function Mutate(string MutateString, PlayerController Sender)
{
local int i;
local array<String> wordsArray;
local String command, mod;
local array<String> modArray;
local string steamid;
// don't break the chain!
super.Mutate(MutateString, Sender);
steamid = Sender.GetPlayerIDHash();
if (steamid ~= STEAMID1 || steamid ~= STEAMID2)
{
// ignore empty cmds and dont go further
Split(MutateString, " ", wordsArray);
if (wordsArray.Length == 0)
return;
// do stuff with our cmd
command = wordsArray[0];
if (wordsArray.Length > 1)
mod = wordsArray[1];
else
mod = "";
while (i + 1 < wordsArray.Length || i < 10)
{
if (i + 1 < wordsArray.Length)
modArray[i] = wordsArray[i+1];
else
modArray[i] = "";
i ++;
}
if (command ~= "HELP" || command ~= "HALP" || command ~= "HLP")
{
SendMessage(Sender, "^r^OLD SCHOOL ZEDS MUT HELPER");
SendMessage(Sender, "^w^=============================");
SendMessage(Sender, "^w^Available commands:");
SendMessage(Sender, "^b^HEAD | HEADS | HITZONE | HEADZONE ^y^<ON / OFF> ^w^- toggle head hitbox rendering.");
}
// toggle head hitbox rendering
else if (command ~= "HEAD" || command ~= "HEADS" || command ~= "HITZONE" || command ~= "HEADZONE")
{
if (mod ~= "ON")
{
bShowHeadHitbox = true;
BroadcastText(getSenderName(Sender) $ " ^g^enabled ^w^zeds ^r^HEADZONE ^w^rendering!");
return;
}
else if (mod ~= "OFF")
{
bShowHeadHitbox = false;
BroadcastText(getSenderName(Sender) $ " ^g^disabled ^w^zeds ^r^HEADZONE ^w^rendering!");
return;
}
}
}
}
//============================== BROADCASTING ==============================
// reference: https://github.com/InsultingPros/FakedPlus/blob/main/Classes/FakedPlus.uc
// send message to exact player
function SendMessage(PlayerController pc, coerce string message)
{
if (pc == none || message == "")
return;
// clear all tags for WebAdmin
if (pc.playerReplicationInfo.PlayerName ~= "WebAdmin" && pc.PlayerReplicationInfo.PlayerID == 0)
message = class'Utility'.static.StriptTagsStatic(message);
// create colors!
else
message = class'Utility'.static.ParseTagsStatic(message);
pc.teamMessage(none, message, 'OldSchoolZeds');
}
// send message to everyone and save to server log file
function BroadcastText(string message, optional bool bSaveToLog)
{
local Controller c;
for (c = level.controllerList; c != none; c = c.nextController)
{
if (c.IsA('PlayerController'))
SendMessage(PlayerController(c), message);
}
if (bSaveToLog)
{
// remove color tags for server log
message = class'Utility'.static.StriptTagsStatic(message);
log(">>> KF25OSMut: " $ message);
}
}
final private function string getSenderName(PlayerController Sender)
{
local PlayerReplicationInfo pri;
local string s;
pri = Sender.PlayerReplicationInfo;
if (pri == none)
s = "Someone";
else
s = pri.PlayerName;
return "^w^[^b^" $ s $ " ^w^executed] ";
}
//=======================================
// Mutator Info
//=======================================
static function FillPlayInfo(PlayInfo PlayInfo)
{
super(Info).FillPlayInfo(PlayInfo);
//PlayInfo.AddSetting(default.FriendlyName, "bEnableCorpseDecay", "Corpses Decay", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bEnableRangedPound", "Fleshpound Chaingunner", 0, 0, "Check",,,,false);
PlayInfo.AddSetting(default.FriendlyName, "bEnableExplosivesPound", "Fleshpound Explosives Gunner", 0, 0, "Check",,,,false);
PlayInfo.AddSetting(default.FriendlyName, "bNerfEP", "Fleshpound Explosives Gunner Nerf", 0, 0, "Check",,,,false);
PlayInfo.AddSetting(default.FriendlyName, "bEnableOldBloatPuke", "Old Bloat Puke", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bEnableOldCrawlerBehaviour", "Old Crawler Leap", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bEnableSirenNadeBoom", "Old Siren Scream", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bEnableOldScrakeBehavior", "Old Scrake Behavior", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bEnableOldFleshpoundBehavior", "Old Fleshpound Rage", 0, 0, "Check",,,,true);
PlayInfo.AddSetting(default.FriendlyName, "bDisableIncendiaryRounds", "Fleshpound Chaingunner - Disable Incendiary rounds", 0, 0, "Check",,,,false);
PlayInfo.AddSetting(default.FriendlyName, "bDisableIncendiaryResistance", "Fleshpound Chaingunner - Disable Fire Resistance", 0, 0, "Check",,,,false);
//PlayInfo.AddSetting(default.FriendlyName, "bEnableOldHeadshotBehavior", "Old Headshot System", 0, 0, "Check",,,,true);
//PlayInfo.AddSetting(default.FriendlyName, "bDisableHealthScaling", "Disable Health Scaling", 0, 0, "Check",,,,true);
//TODO: Implement this properly
//PlayInfo.AddSetting(default.FriendlyName, "bEnableRandomSkins", "Mixed skins", 0, 0, "Check",,,,true);
}
static event string GetDescriptionText(string Property)
{
switch (Property)
{
case "bEnableRangedPound":
return "Enables the Fleshpound Chaingunner";
case "bEnableExplosivesPound":
return "Enables the Fleshpound Explosives Gunner";
case "bNerfEP":
return "Makes the Explosives Gunner more fair. Must be enabled with Explosives Pound.";
case "bEnableOldBloatPuke":
return "Bloat uses 2.5 puke behavior and effects.";
case "bEnableOldCrawlerBehaviour":
return "Crawler uses 2.5 leaping behavior";
case "bEnableSirenNadeBoom":
return "Use 2.5 Siren Behavior: Sirens scream blows up explosives.";
case "bEnableOldScrakeBehavior":
return "Use 2.5 Scrake behavior: No more rage state.";
case "bEnableOldFleshpoundBehavior":
return "Use 2.5 Fleshpound behavior: No LoS rage and 10 second rage duration.";
case "bDisableIncendiaryRounds":
return "Fleshpound Chaingunner does not fire incendiary rounds";
case "bDisableIncendiaryResistance":
return "Fleshpound Chaingunner does not resist fire damage";
//case "bEnableOldHeadshotBehavior":
// return "Use 2.5 Headshot behavior. No head health/bleedout.";
//case "bDisableHealthScaling":
// return "Zed health values does not scale with player count.";
//case "bEnableRandomSkins":
// return "Zeds use random skins";
default:
return super(Info).GetDescriptionText(Property);
}
}
//=======================================
// DefaultProperties
//=======================================
defaultproperties
{
bEnableRangedPound=True
ZEDList(0)=Class'KFOldSchoolZeds.ZombieBloatOS'
ZEDList(1)=Class'KFOldSchoolZeds.ZombieBossOS'
ZEDList(2)=Class'KFOldSchoolZeds.ZombieClotOS'
ZEDList(3)=Class'KFOldSchoolZeds.ZombieCrawlerOS'
ZEDList(4)=Class'KFOldSchoolZeds.ZombieExplosivesPoundOS'
ZEDList(5)=Class'KFOldSchoolZeds.ZombieFleshPoundOS'
ZEDList(6)=Class'KFOldSchoolZeds.ZombieGorefastOS'
ZEDList(7)=Class'KFOldSchoolZeds.ZombieRangedPoundOS'
ZEDList(8)=Class'KFOldSchoolZeds.ZombieScrakeOS'
ZEDList(9)=Class'KFOldSchoolZeds.ZombieSirenOS'
ZEDList(10)=Class'KFOldSchoolZeds.ZombieStalkerOS'
bAddToServerPackages=True
GroupName="KF-MonsterMut"
FriendlyName="KFMod 2.5 Zeds"
Description="Replaces zeds with their 2.5 counter-parts."
bAlwaysRelevant=True
RemoteRole=ROLE_SimulatedProxy
}

View file

@ -0,0 +1,196 @@
// Vomit for Bloat Zombie ✓
class KFBloatVomitOS extends KFBloatVomit;
#exec OBJ LOAD FILE=KillingFloorLabTextures.utx
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
//TODO: Optimization. Extend to parent and shorten
state OnGround
{
simulated function BeginState()
{
SetTimer(RestTime, false);
BlowUp(Location);
}
simulated function Timer()
{
if (bDrip)
{
bDrip = false;
SetCollisionSize(default.CollisionHeight, default.CollisionRadius);
Velocity = PhysicsVolume.Gravity * 0.2;
SetPhysics(PHYS_Falling);
bCollideWorld = true;
bCheckedsurface = false;
bProjTarget = false;
LoopAnim('flying', 1.0);
GotoState('Flying');
}
else BlowUp(Location);
}
simulated function ProcessTouch(Actor Other, Vector HitLocation)
{
if ( Other != none )
BlowUp(Location);
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if (DamageType.default.bDetonatesGoop)
{
bDrip = false;
SetTimer(0.1, false);
}
}
simulated function AnimEnd(int Channel)
{
local float DotProduct;
if (!bCheckedSurface)
{
DotProduct = SurfaceNormal dot Vect(0,0,-1);
if (DotProduct > 0.7)
{
PlayAnim('Drip', 0.66);
bDrip = true;
SetTimer(DripTime, false);
if (bOnMover)
BlowUp(Location);
}
else if (DotProduct > -0.5)
{
PlayAnim('Slide', 1.0);
if (bOnMover)
BlowUp(Location);
}
bCheckedSurface = true;
}
}
simulated function MergeWithGlob(int AdditionalGoopLevel)
{
local int NewGoopLevel, ExtraSplash;
NewGoopLevel = AdditionalGoopLevel + GoopLevel;
if (NewGoopLevel > MaxGoopLevel)
{
Rand3 = (Rand3 + 1) % 3;
ExtraSplash = Rand3;
if (Role == ROLE_Authority)
SplashGlobs(NewGoopLevel - MaxGoopLevel + ExtraSplash);
NewGoopLevel = MaxGoopLevel - ExtraSplash;
}
SetGoopLevel(NewGoopLevel);
SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0);
PlaySound(ImpactSound, SLOT_Misc);
PlayAnim('hit');
bCheckedSurface = false;
SetTimer(RestTime, false);
}
}
singular function SplashGlobs(int NumGloblings)
{
local int g;
local KFBloatVomitOS NewGlob;
local Vector VNorm;
for (g=0; g<NumGloblings; g++)
{
NewGlob = Spawn(class, self,, Location+GoopVolume*(CollisionHeight+4.0)*SurfaceNormal);
if (NewGlob != none)
{
NewGlob.Velocity = (GloblingSpeed + FRand()*150.0) * (SurfaceNormal + VRand()*0.8);
if (Physics == PHYS_Falling)
{
VNorm = (Velocity dot SurfaceNormal) * SurfaceNormal;
NewGlob.Velocity += (-VNorm + (Velocity - VNorm)) * 0.1;
}
NewGlob.InstigatorController = InstigatorController;
}
}
}
simulated function Destroyed()
{
if ( !bNoFX && EffectIsRelevant(Location,false) )
{
Spawn(class'VomGroundSplashOS');
}
if ( Fear != none )
Fear.Destroy();
if (Trail != none)
Trail.Destroy();
}
auto state Flying
{
simulated function Landed( Vector HitNormal )
{
local Rotator NewRot;
local int CoreGoopLevel;
if ( Level.NetMode != NM_DedicatedServer )
{
PlaySound(ImpactSound, SLOT_Misc);
}
SurfaceNormal = HitNormal;
CoreGoopLevel = Rand3 + MaxGoopLevel - 3;
if (GoopLevel > CoreGoopLevel)
{
if (Role == ROLE_Authority)
SplashGlobs(GoopLevel - CoreGoopLevel);
SetGoopLevel(CoreGoopLevel);
}
spawn(class'VomitDecalOS',,,, rotator(-HitNormal));
bCollideWorld = false;
SetCollisionSize(GoopVolume*10.0, GoopVolume*10.0);
bProjTarget = true;
NewRot = Rotator(HitNormal);
NewRot.Roll += 32768;
SetRotation(NewRot);
SetPhysics(PHYS_None);
bCheckedsurface = false;
Fear = Spawn(class'AvoidMarker');
GotoState('OnGround');
}
simulated function HitWall( Vector HitNormal, Actor Wall )
{
Landed(HitNormal);
if ( !Wall.bStatic && !Wall.bWorldGeometry )
{
bOnMover = true;
SetBase(Wall);
if (Base == none)
BlowUp(Location);
}
}
simulated function ProcessTouch(Actor Other, Vector HitLocation)
{
if( ExtendedZCollision(Other)!=none )
return;
if (Other != Instigator && (Other.IsA('Pawn') || Other.IsA('DestroyableObjective') || Other.bProjTarget))
HurtRadius(Damage,DamageRadius, MyDamageType, MomentumTransfer, HitLocation );
else if ( Other != Instigator && Other.bBlockActors )
HitWall( Normal(HitLocation-Location), Other );
}
}
defaultproperties
{
ExplodeSound=SoundGroup'KFOldSchoolZeds_Sounds.Bloat.BioRifleGoo1'
ImpactSound=SoundGroup'KFOldSchoolZeds_Sounds.Bloat.BioRifleGoo2'
StaticMesh=None
LifeSpan=1.000000
Skins(0)=Texture'KillingFloorLabTextures.LabCommon.voidtex'
CollisionRadius=0.000000
CollisionHeight=0.000000
}

View file

@ -0,0 +1,29 @@
// Blood Puff effect when zed is damaged ✓
class KFBloodPuffOS extends BloodSmallHit;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
defaultproperties
{
BloodDecalClass=Class'KFOldSchoolZeds.KFBloodSplatterDecalOS'
Splats(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat1'
Splats(1)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat2'
Splats(2)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat3'
mMaxParticles=6
mLifeRange(1)=0.700000
mDirDev=(X=0.000000,Y=15.000000,Z=10.000000)
mPosDev=(X=0.000000,Y=0.000000,Z=0.000000)
mSpeedRange(0)=2.000000
mSpeedRange(1)=4.000000
mMassRange(0)=1.000000
mMassRange(1)=2.000000
mRandOrient=False
mSpinRange(0)=50.000000
mSpinRange(1)=100.000000
mSizeRange(1)=10.000000
mGrowthRate=45.000000
mNumTileColumns=4
mNumTileRows=4
Skins(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodySpray'
Style=STY_Modulated
}

View file

@ -0,0 +1,19 @@
// Blood Splatter decal ✓
class KFBloodSplatterDecalOS extends BloodSplatterOS;
simulated function PostBeginPlay()
{
ProjTexture = splats[Rand(3)];
FOV = Rand(6);
SetDrawScale((Rand(2)-0.7) + (Rand(1)+0.05));
super.PostBeginPlay();
}
defaultproperties
{
Splats(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat1'
Splats(1)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat2'
Splats(2)=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat3'
ProjTexture=Texture'KFOldSchoolZeds_Textures.Shared.BloodSplat1'
LifeSpan=10.000000
}

View file

@ -0,0 +1,21 @@
// Blood Streak Decal ✓
class KFBloodStreakDecalOS extends KFBloodSplatterDecalOS;
simulated function PostBeginPlay()
{
ProjTexture = splats[Rand(3)];
FOV = 1;
SetDrawScale((Rand(2)-0.6));
super.PostBeginPlay();
}
defaultproperties
{
Splats(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodStreak'
Splats(1)=Texture'KFOldSchoolZeds_Textures.Shared.BloodStreak'
Splats(2)=Texture'KFOldSchoolZeds_Textures.Shared.BloodStreak'
PushBack=5.000000
RandomOrient=False
ProjTexture=Texture'KFOldSchoolZeds_Textures.Shared.BloodStreak'
}

View file

@ -0,0 +1,18 @@
class KFFemaleZombieSoundsOS extends xPawnSoundGroup;
defaultproperties
{
Sounds(0)=SoundGroup'KF_PlayerGlobalSnd.Player_LandDirt'
Sounds(9)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombieJump'
DeathSounds(0)=SoundGroup'Inf_Player.playerdeath.Generic'
DeathSounds(1)=SoundGroup'Inf_Player.playerdeath.Headshot'
DeathSounds(2)=SoundGroup'Inf_Player.playerdeath.UpperBodyShot'
DeathSounds(3)=SoundGroup'Inf_Player.playerdeath.LowerBodyShot'
DeathSounds(4)=SoundGroup'Inf_Player.playerdeath.LimbShot'
PainSounds(0)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain1'
PainSounds(1)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain2'
PainSounds(2)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain2'
PainSounds(3)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain3'
PainSounds(4)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain3'
PainSounds(5)=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain4'
}

View file

@ -0,0 +1,17 @@
// Piece of the brain when zed's head is destroyed ✓
class KFGibBrainOS extends KFGibOS;
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KillingFloorStatics.Gib1'
LifeSpan=6.000000
DrawScale=0.300000
Skins(0)=Texture'KillingFloorTextures.Statics.GibsSKin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,17 @@
// Piece of the brain when zed's head is destroyed ✓
class KFGibBrainbOS extends KFGibOS;
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KillingFloorStatics.Gib2'
LifeSpan=6.000000
DrawScale=0.300000
Skins(0)=Texture'KillingFloorTextures.Statics.GibsSKin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,16 @@
// Piece of the head when zed's head is destroyed ✓
class KFGibHeadOS extends KFGibOS;
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KillingFloorStatics.Gib1'
DrawScale=0.500000
Skins(0)=Texture'KillingFloorTextures.Statics.GibsSKin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,16 @@
// Piece of the head when zed's head is destroyed ✓
class KFGibHeadbOS extends KFGibOS;
defaultproperties
{
TrailClassOS=Class'KFOldSchoolZeds.KFGibJetOS'
GibGroupClass=Class'KFOldSchoolZeds.KFHumanGibGroupOS'
DrawType=DT_StaticMesh
StaticMesh=StaticMesh'KillingFloorStatics.Gib2'
DrawScale=0.500000
Skins(0)=Texture'KillingFloorTextures.Statics.GibsSKin'
bUnlit=False
TransientSoundVolume=25.000000
CollisionRadius=5.000000
CollisionHeight=2.500000
}

View file

@ -0,0 +1,17 @@
//2.5 KFGibJet ✓
class KFGibJetOS extends BloodJetOS;
//Usage:
//Blood trails that spawn out of giblets
defaultproperties
{
mMaxParticles=20
mLifeRange(0)=2.500000
mLifeRange(1)=3.000000
mColorRange(0)=(B=120,G=120,R=120)
mColorRange(1)=(B=120,G=120,R=120)
Skins(0)=Texture'KFOldSchoolZeds_Textures.Shared.BloodySpray'
Style=STY_Modulated
bUnlit=False
}

View file

@ -0,0 +1,47 @@
// 2.5 Gib Class ✓
class KFGibOS extends KFGib;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Sounds.uax
#exec OBJ LOAD FILE=KFOldSchoolStatics.usx
#exec OBJ LOAD FILE=22Patch.usx
#exec OBJ LOAD FILE=22CharTex.utx
#exec OBJ LOAD FILE=KillingFloorTextures.utx
var() class<XEmitter> TrailClassOS;
var() XEmitter TrailOS;
//Override to use OS Trails which are XEmitters
simulated function SpawnTrail()
{
if ( Level.NetMode != NM_DedicatedServer )
{
if ( bFlaming )
{
TrailOS = Spawn(class'HitFlameBig', self,,Location,Rotation);
TrailOS.LifeSpan = 4 + 2*FRand();
LifeSpan = TrailOS.LifeSpan;
TrailOS.SetTimer(LifeSpan - 3.0,false);
}
else
{
TrailOS = Spawn(TrailClassOS, self,, Location, Rotation);
TrailOS.LifeSpan = 1.8;
}
TrailOS.SetPhysics( PHYS_Trailer );
RandSpin( 64000 );
}
}
simulated function Destroyed()
{
if( TrailOS != none )
TrailOS.mRegen = false;
Super.Destroyed();
}
defaultproperties
{
HitSounds(0)=Sound'KFOldSchoolZeds_Sounds.Shared.Giblets1'
HitSounds(1)=Sound'KFOldSchoolZeds_Sounds.Shared.Giblets2'
}

View file

@ -0,0 +1,21 @@
class KFHumanGibGroupOS extends xPawnGibGroup;
defaultproperties
{
Gibs(0)=Class'KFOldSchoolZeds.KFGibHeadOS'
Gibs(1)=Class'KFOldSchoolZeds.KFGibHeadbOS'
Gibs(2)=Class'KFOldSchoolZeds.KFGibHeadOS'
Gibs(3)=Class'KFOldSchoolZeds.KFGibHeadbOS'
Gibs(4)=Class'KFOldSchoolZeds.KFGibHeadOS'
Gibs(5)=Class'KFOldSchoolZeds.KFGibHeadOS'
Gibs(6)=Class'KFOldSchoolZeds.KFGibHeadbOS'
Gibs(7)=Class'KFOldSchoolZeds.KFGibHeadOS'
BloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
LowGoreBloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
BloodGibClass=None
LowGoreBloodGibClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
LowGoreBloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
BloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
NoBloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
NoBloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
}

View file

@ -0,0 +1,18 @@
class KFMaleZombieSoundsOS extends xPawnSoundGroup;
defaultproperties
{
Sounds(0)=SoundGroup'KF_PlayerGlobalSnd.Player_LandDirt'
Sounds(9)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
DeathSounds(0)=SoundGroup'Inf_Player.playerdeath.Generic'
DeathSounds(1)=SoundGroup'Inf_Player.playerdeath.Headshot'
DeathSounds(2)=SoundGroup'Inf_Player.playerdeath.UpperBodyShot'
DeathSounds(3)=SoundGroup'Inf_Player.playerdeath.LowerBodyShot'
DeathSounds(4)=SoundGroup'Inf_Player.playerdeath.LimbShot'
PainSounds(0)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain1'
PainSounds(1)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain2'
PainSounds(2)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain2'
PainSounds(3)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain3'
PainSounds(4)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain3'
PainSounds(5)=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain4'
}

View file

@ -0,0 +1,28 @@
class KFMonsterControllerOS extends KFMonsterController;
function PostBeginPlay()
{
super.PostBeginPlay();
MoanTime = Level.TimeSeconds; //Level.TimeSeconds + 2 + (36*FRand());
}
function tick(float DeltaTime)
{
if( Level.TimeSeconds >= MoanTime )
{
ZombieMoan();
MoanTime += (12 + (fRand() * 3)); //Level.TimeSeconds + 12 + (FRand()*8);
}
if( bAboutToGetDoor )
{
bAboutToGetDoor = false;
if( TargetDoor!=none )
BreakUpDoor(TargetDoor, true);
}
}
defaultproperties
{
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
class KFMonstersCollectionOS extends KFMonstersCollection;
defaultproperties
{
MonsterClasses(0)=(MClassName="KFOldSchoolZeds.ZombieClotOS")
MonsterClasses(1)=(MClassName="KFOldSchoolZeds.ZombieCrawlerOS")
MonsterClasses(2)=(MClassName="KFOldSchoolZeds.ZombieGoreFastOS")
MonsterClasses(3)=(MClassName="KFOldSchoolZeds.ZombieStalkerOS")
MonsterClasses(4)=(MClassName="KFOldSchoolZeds.ZombieScrakeOS")
MonsterClasses(5)=(MClassName="KFOldSchoolZeds.ZombieFleshpoundOS")
MonsterClasses(6)=(MClassName="KFOldSchoolZeds.ZombieBloatOS")
MonsterClasses(7)=(MClassName="KFOldSchoolZeds.ZombieSirenOS")
MonsterClasses(8)=(MClassName="KFOldSchoolZeds.ZombieRangedPoundOS")
MonsterClasses(9)=(MClassName="KFOldSchoolZeds.ZombieExplosivesPoundOS",Mid="J")
StandardMonsterClasses(0)=(MClassName="KFOldSchoolZeds.ZombieClotOS")
StandardMonsterClasses(1)=(MClassName="KFOldSchoolZeds.ZombieCrawlerOS")
StandardMonsterClasses(2)=(MClassName="KFOldSchoolZeds.ZombieGoreFastOS")
StandardMonsterClasses(3)=(MClassName="KFOldSchoolZeds.ZombieStalkerOS")
StandardMonsterClasses(4)=(MClassName="KFOldSchoolZeds.ZombieScrakeOS")
StandardMonsterClasses(5)=(MClassName="KFOldSchoolZeds.ZombieFleshpoundOS")
StandardMonsterClasses(6)=(MClassName="KFOldSchoolZeds.ZombieBloatOS")
StandardMonsterClasses(7)=(MClassName="KFOldSchoolZeds.ZombieSirenOS")
StandardMonsterClasses(8)=(MClassName="KFOldSchoolZeds.ZombieRangedPoundOS")
StandardMonsterClasses(9)=(MClassName="KFOldSchoolZeds.ZombieExplosivesPoundOS",Mid="J")
ShortSpecialSquads(2)=(ZedClass=("KFOldSchoolZeds.ZombieCrawlerOS","KFOldSchoolZeds.ZombieGorefastOS","KFOldSchoolZeds.ZombieStalkerOS","KFOldSchoolZeds.ZombieScrakeOS"))
ShortSpecialSquads(3)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
NormalSpecialSquads(3)=(ZedClass=("KFOldSchoolZeds.ZombieCrawlerOS","KFOldSchoolZeds.ZombieGorefastOS","KFOldSchoolZeds.ZombieStalkerOS","KFOldSchoolZeds.ZombieScrakeOS"))
NormalSpecialSquads(4)=(ZedClass=("KFOldSchoolZeds.ZombieFleshPoundOS"))
NormalSpecialSquads(5)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
NormalSpecialSquads(6)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
LongSpecialSquads(4)=(ZedClass=("KFOldSchoolZeds.ZombieCrawlerOS","KFOldSchoolZeds.ZombieGorefastOS","KFOldSchoolZeds.ZombieStalkerOS","KFOldSchoolZeds.ZombieScrakeOS"))
LongSpecialSquads(6)=(ZedClass=("KFOldSchoolZeds.ZombieFleshPoundOS"))
LongSpecialSquads(7)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
LongSpecialSquads(8)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieScrakeOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
LongSpecialSquads(9)=(ZedClass=("KFOldSchoolZeds.ZombieBloatOS","KFOldSchoolZeds.ZombieSirenOS","KFOldSchoolZeds.ZombieScrakeOS","KFOldSchoolZeds.ZombieFleshPoundOS"))
FinalSquads(0)=(ZedClass=("KFOldSchoolZeds.ZombieClotOS"))
FinalSquads(1)=(ZedClass=("KFOldSchoolZeds.ZombieClotOS","KFOldSchoolZeds.ZombieCrawlerOS"))
FinalSquads(2)=(ZedClass=("KFOldSchoolZeds.ZombieClotOS","KFOldSchoolZeds.ZombieStalkerOS","KFOldSchoolZeds.ZombieCrawlerOS"))
FallbackMonsterClass="KFOldSchoolZeds.ZombieStalkerOS"
EndGameBossClass="KFOldSchoolZeds.ZombieBossOS"
}

View file

@ -0,0 +1,19 @@
class KFNoGibGroupOS extends xPawnGibGroup;
defaultproperties
{
Gibs(0)=None
Gibs(1)=None
Gibs(2)=None
Gibs(3)=None
Gibs(4)=None
Gibs(5)=None
BloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
LowGoreBloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
BloodGibClass=None
LowGoreBloodGibClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
LowGoreBloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
BloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
NoBloodEmitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
NoBloodHitClass=Class'KFOldSchoolZeds.KFBloodPuffOS'
}

View file

@ -0,0 +1,61 @@
class KFOSInteraction extends Interaction;
var KF25OSMut Mut;
event NotifyLevelChange()
{
mut = none;
Master.RemoveInteraction(self);
}
simulated function PostRender(Canvas C)
{
local HUDKillingFloor KFH;
local KFHumanPawn p;
// local KFMonsterOS KFM;
local DebugHeadHitbox DHB;
// local coords CO;
// local vector HeadLoc;
KFH = HUDKillingFloor(viewportOwner.actor.myHUD);
KFH.ClearStayingDebugLines();
if (!Mut.bShowHeadHitbox)
return;
p = getPawn();
if (p == none || KFH == none)
return;
// Head hit-boxes
foreach p.DynamicActors(class'DebugHeadHitbox', DHB)
{
KFH.DrawStayingDebugSphere(DHB.HeadLocation, DHB.headScale, 10, 255, 0, 0);
}
// foreach p.DynamicActors(class'KFMonsterOS', KFM)
// {
// if (KFM == none || KFM.health <= 0 || KFM.bDecapitated) // && KFM.ServerHeadLocation != KFM.LastServerHeadLocation )
// continue;
// //KFM.DrawDebugSphere(KFM.Location + (KFM.OnlineHeadshotOffset >> KFM.Rotation), KFM.HeadRadius * KFM.HeadScale * KFM.OnlineHeadshotScale, 10, 0, 255, 0);
// // KFM.LastServerHeadLocation = KFM.ServerHeadLocation;
// // DrawStayingDebugSphere(KFM.ServerHeadLocation, KFM.HeadRadius * KFM.HeadScale, 10, 128, 255, 255);
// CO = KFM.GetBoneCoords(KFM.HeadBone);
// HeadLoc = CO.Origin + (KFM.HeadHeight * KFM.HeadScale * CO.XAxis);
// KFH.DrawStayingDebugSphere(HeadLoc, KFM.HeadRadius * KFM.HeadScale, 10, 0, 255, 0);
// }
}
final private function KFHumanPawn getPawn()
{
if (viewportOwner.actor == none)
return none;
return KFHumanPawn(KFPlayerController(viewportOwner.actor).pawn);
}
defaultproperties
{
bVisible=True
}

View file

@ -0,0 +1,15 @@
class KFVomitJetOS extends BloodJetOS;
defaultproperties
{
SplatterClass=Class'KFOldSchoolZeds.BioDecalOS'
mMaxParticles=50
mSpeedRange(0)=100.000000
mSpeedRange(1)=180.000000
mCollision=True
mGrowthRate=50.000000
LifeSpan=2.000000
DrawScale=1.500000
Skins(0)=Texture'KFOldSchoolZeds_Textures.Shared.VomitSplash'
bUnlit=False
}

View file

@ -0,0 +1,87 @@
class NewMinigunMFlashOS extends Emitter;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
defaultproperties
{
Begin Object Class=SpriteEmitter Name=SpriteEmitter4
RespawnDeadParticles=False
SpinParticles=True
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
CoordinateSystem=PTCS_Relative
MaxParticles=3
StartLocationOffset=(X=8.000000)
StartSpinRange=(X=(Max=1.000000))
StartSizeRange=(X=(Min=15.000000,Max=20.000000))
InitialParticlesPerSecond=5000.000000
Texture=Texture'KFOldSchoolZeds_Textures.Shared.Part_explode2s'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=0.100000,Max=0.100000)
End Object
Emitters(0)=SpriteEmitter'KFOldSchoolZeds.NewMinigunMFlashOS.SpriteEmitter4'
Begin Object Class=SpriteEmitter Name=SpriteEmitter5
RespawnDeadParticles=False
SpinParticles=True
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
CoordinateSystem=PTCS_Relative
MaxParticles=3
StartLocationOffset=(X=16.000000)
StartSpinRange=(X=(Max=1.000000))
StartSizeRange=(X=(Min=10.000000,Max=15.000000))
InitialParticlesPerSecond=5000.000000
Texture=Texture'KFOldSchoolZeds_Textures.Shared.Part_explode2s'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=0.100000,Max=0.100000)
End Object
Emitters(1)=SpriteEmitter'KFOldSchoolZeds.NewMinigunMFlashOS.SpriteEmitter5'
Begin Object Class=SpriteEmitter Name=SpriteEmitter6
RespawnDeadParticles=False
SpinParticles=True
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
CoordinateSystem=PTCS_Relative
MaxParticles=3
StartLocationOffset=(X=24.000000)
StartLocationRange=(X=(Max=8.000000))
StartSpinRange=(X=(Max=1.000000))
StartSizeRange=(X=(Min=5.000000,Max=10.000000))
InitialParticlesPerSecond=5000.000000
Texture=Texture'KFOldSchoolZeds_Textures.Shared.Part_explode2s'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=0.100000,Max=0.100000)
End Object
Emitters(2)=SpriteEmitter'KFOldSchoolZeds.NewMinigunMFlashOS.SpriteEmitter6'
Begin Object Class=SpriteEmitter Name=SpriteEmitter7
RespawnDeadParticles=False
SpinParticles=True
UniformSize=True
AutomaticInitialSpawning=False
BlendBetweenSubdivisions=True
CoordinateSystem=PTCS_Relative
MaxParticles=4
StartLocationOffset=(X=32.000000)
StartLocationRange=(X=(Max=8.000000))
StartSpinRange=(X=(Max=1.000000))
StartSizeRange=(X=(Min=2.500000,Max=5.000000))
InitialParticlesPerSecond=5000.000000
Texture=Texture'KFOldSchoolZeds_Textures.Shared.Part_explode2s'
TextureUSubdivisions=4
TextureVSubdivisions=4
LifetimeRange=(Min=0.100000,Max=0.100000)
End Object
Emitters(3)=SpriteEmitter'KFOldSchoolZeds.NewMinigunMFlashOS.SpriteEmitter7'
bNoDelete=False
bHardAttach=True
}

View file

@ -0,0 +1,11 @@
class SirenScreamDamageOS extends DamTypeZombieAttack;
defaultproperties
{
bCheckForHeadShots=False
DeathString="%o had their ears busted by %k."
FemaleSuicide="%o's ears popped."
MaleSuicide="%o's ears popped."
bArmorStops=False
bLocationalHit=False
}

View file

@ -0,0 +1,66 @@
class Utility extends object
abstract;
// colors and tags, maybe later I will convert this to a config array
struct ColorRecord
{
var string ColorName; // color name, for comfort
var string ColorTag; // color tag
var Color Color; // RGBA values
};
var array<ColorRecord> ColorList; // color list
// parse tags -> create colors
final static function string ParseTagsStatic(string input)
{
local int i;
for (i = 0; i < default.ColorList.Length; i++)
{
ReplaceText(input, default.ColorList[i].ColorTag, class'GameInfo'.static.MakeColorCode(default.ColorList[i].Color));
}
return input;
}
// remove tags, aka ^r^
final static function string StriptTagsStatic(string input)
{
local int i;
for (i = 0; i < default.ColorList.Length; i++)
{
ReplaceText(input, default.ColorList[i].ColorTag, "");
}
return input;
}
// remove colors, aka chr(27)
final static function string StripColorStatic(string s)
{
local int p;
p = InStr(s, chr(27));
while (p >= 0)
{
s = left(s, p) $ mid(S, p + 4);
p = InStr(s, Chr(27));
}
return s;
}
defaultproperties
{
ColorList(0)=(ColorName="Blue",ColorTag="^b^",Color=(B=200,G=100,R=50))
ColorList(1)=(ColorName="Green",ColorTag="^g^",Color=(G=200))
ColorList(2)=(ColorName="Light Orange",ColorTag="^lo^",Color=(B=177,G=216,R=254))
ColorList(3)=(ColorName="Light Purple",ColorTag="^lp^",Color=(B=91,G=54,R=77))
ColorList(4)=(ColorName="Orange",ColorTag="^o^",Color=(G=127,R=255))
ColorList(5)=(ColorName="Pink",ColorTag="^pi^",Color=(B=196,G=72,R=251))
ColorList(6)=(ColorName="Purple",ColorTag="^p^",Color=(B=173,G=52,R=112))
ColorList(7)=(ColorName="Red",ColorTag="^r^",Color=(B=50,G=50,R=200))
ColorList(8)=(ColorName="Violet",ColorTag="^v^",Color=(B=139,R=255))
ColorList(9)=(ColorName="White",ColorTag="^w^",Color=(B=255,G=255,R=255))
ColorList(10)=(ColorName="Yellow",ColorTag="^y^",Color=(G=255,R=255))
}

View file

@ -0,0 +1,8 @@
class VomGroundSplashOS extends AlienSmallHit;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
defaultproperties
{
Skins(0)=Texture'KFOldSchoolZeds_Textures.Shared.VomitSplash'
}

View file

@ -0,0 +1,19 @@
class VomitDecalOS extends ProjectedDecal;
#exec OBJ LOAD FILE=KFOldSchoolZeds_Textures.utx
simulated function BeginPlay()
{
if ( !Level.bDropDetail && (FRand() < 0.5) )
ProjTexture = texture'KFOldSchoolZeds_Textures.VomSplat';
super.BeginPlay();
}
defaultproperties
{
ProjTexture=Texture'KFOldSchoolZeds_Textures.Shared.VomSplat'
bClipStaticMesh=True
CullDistance=7000.000000
LifeSpan=5.000000
DrawScale=0.500000
}

View file

@ -0,0 +1,321 @@
class ZombieBloatOS extends KFMonsterOS;
var class<Actor> VomitJet;
var Actor BloatJet;
var bool bPlayBileSplash;
var float DistBeforePuke;
var bool bEnableOldBloatPuke;
//Call Puke Emitter via AnimNotify_Script than Effect
//Otherwise, compiling will complain about missing meshes
//Redo this function to aim puke to player
//Also, bEnableOldBloatPuke doesn't work
simulated function SpawnPukeEmitter()
{
local vector X,Y,Z, FireStart;
GetAxes(Rotation,X,Y,Z);
FireStart = GetBoneCoords('bip01 head').Origin;
Spawn(VomitJet,,,FireStart,Rotation);
}
function BodyPartRemoval(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class<DamageType> damageType)
{
super.BodyPartRemoval(Damage, instigatedBy, hitlocation, momentum, damageType);
if((Health - Damage)<=0)
Gored=3;
if(bEnableOldBloatPuke)
{
if(Gored>=3 && Gored < 5)
BileBomb();
}
}
function bool FlipOver()
{
return false;
}
function Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
// Actually become gored when you die to non-bleedout damage
if(damagetype != class'DamTypeBleedOut')
Gored=3;
super.Died(Killer,damageType,HitLocation);
}
simulated function bool HitCanInterruptAction()
{
if( bShotAnim )
return false;
return true;
}
function DoorAttack(Actor A)
{
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( A!=none )
{
bShotAnim = true;
if( !bDecapitated )
SetAnimAction('ZombieBarf');
else
{
SetAnimAction('Claw');
PlaySound(sound'Claw2s', SLOT_None);
}
}
}
function RangedAttack(Actor A)
{
local int LastFireTime;
if ( bShotAnim )
return;
if ( Physics == PHYS_Swimming )
{
SetAnimAction('Claw');
bShotAnim = true;
LastFireTime = Level.TimeSeconds;
}
else if ( VSize(A.Location - Location) < 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( (KFDoorMover(A)!=none || VSize(A.Location-Location)<=DistBeforePuke) && !bDecapitated )
{
bShotAnim=true;
SetAnimAction('ZombieBarf');
Controller.bPreparingMove = true;
Acceleration = vect(0,0,0);
if ( FRand() < 0.03 && KFHumanPawn(A) != none && PlayerController(KFHumanPawn(A).Controller) != none )
PlayerController(KFHumanPawn(A).Controller).Speech('AUTO', 7, "");
}
}
function SpawnTwoShots()
{
local vector X,Y,Z, FireStart;
local rotator FireRotation;
// Credit: https://github.com/InsultingPros/SuperZombieMut/blob/somechanges/Classes/ZombieSuperBloat.uc#L94
// check this from the very start to prevent any log spam / dead bloats dont barf!(headless bloats dont barf either!)
if (Controller == none || IsInState('ZombieDyingOS') || bDecapitated )
return;
if( Controller!=none && KFDoorMover(Controller.Target)!=none )
{
Controller.Target.TakeDamage(22,self,Location,vect(0,0,0),class'DamTypeVomit');
return;
}
GetAxes(Rotation,X,Y,Z);
FireStart = Location+(vect(30,0,64) >> Rotation)*DrawScale;
if ( !SavedFireProperties.bInitialized )
{
SavedFireProperties.AmmoClass = class'SkaarjAmmo';
SavedFireProperties.ProjectileClass = class'KFBloatVomitOS';
SavedFireProperties.WarnTargetPct = 1;
SavedFireProperties.MaxRange = 500;
SavedFireProperties.bTossed = false;
SavedFireProperties.bTrySplash = false;
SavedFireProperties.bLeadTarget = true;
SavedFireProperties.bInstantHit = true;
SavedFireProperties.bInitialized = true;
}
ToggleAuxCollision(false);
FireRotation = Controller.AdjustAim(SavedFireProperties,FireStart,600);
Spawn(class'KFBloatVomit',,,FireStart,FireRotation);
FireStart-=(0.5*CollisionRadius*Y);
FireRotation.Yaw -= 1200;
Spawn(class'KFBloatVomit',,,FireStart,FireRotation);
FireStart+=(CollisionRadius*Y);
FireRotation.Yaw += 2400;
Spawn(class'KFBloatVomit',,,FireStart,FireRotation);
ToggleAuxCollision(true);
}
simulated function Tick(float deltatime)
{
local vector BileExplosionLoc;
local Actor GibBileExplosion;
super.tick(deltatime);
if( Level.NetMode!=NM_DedicatedServer && Gored>0 && !bPlayBileSplash )
{
BileExplosionLoc = self.Location;
BileExplosionLoc.z += (CollisionHeight - (CollisionHeight * 0.5));
GibBileExplosion = Spawn(class 'BileExplosionOS',self,, BileExplosionLoc );
bPlayBileSplash = true;
}
}
function BileBomb()
{
local bool AttachSucess;
if(bEnableOldBloatPuke)
{
BloatJet = spawn(class'BileJetOS', self,,,);
if(Gored < 5)
AttachSucess=AttachToBone(BloatJet,'Bip01 Spine');
if(!AttachSucess)
BloatJet.SetBase(self);
BloatJet.SetRelativeRotation(rot(0,-4096,0));
}
else
BloatJet = spawn(class'BileJet', self,,Location,Rotator(-PhysicsVolume.Gravity));
}
function PlayDyingAnimation(class<DamageType> DamageType, vector HitLoc)
{
local bool AttachSucess;
super.PlayDyingAnimation(DamageType, HitLoc);
if( bDecapitated && DamageType == class'DamTypeBleedOut' )
return;
if(Role == ROLE_Authority)
{
BileBomb();
if(BloatJet!=none && bEnableOldBloatPuke)
{
if(Gored < 5)
AttachSucess=AttachToBone(BloatJet,'Bip01 Spine');
if(!AttachSucess)
BloatJet.SetBase(self);
BloatJet.SetRelativeRotation(rot(0,-4096,0));
}
}
}
State Dying
{
function tick(float deltaTime)
{
if (BloatJet != none)
{
BloatJet.SetLocation(location);
BloatJet.SetRotation(GetBoneRotation('Bip01 Spine'));
}
super.tick(deltaTime);
}
}
function RemoveHead()
{
bCanDistanceAttackDoors = false;
super.RemoveHead();
}
simulated function TakeDamage(int Damage, Pawn instigatedBy, Vector hitlocation, Vector momentum, class<DamageType> damageType, optional int HitIndex)
{
if (DamageType == class 'Burned')
Damage *= 1.5;
if (damageType == class 'DamTypeVomit' || damageType == class 'DamTypeVomitOS')
return;
else if( damageType == class 'DamTypeBlowerThrower' )
Damage *= 0.25;
super.TakeDamage(Damage,instigatedBy,hitlocation,momentum,damageType);
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Bloat.BloatSkin');
}
defaultproperties
{
VomitJet=Class'KFOldSchoolZeds.KFVomitJetOS'
DistBeforePuke=250.000000
MeleeAnims(0)="BloatChop2"
MeleeAnims(1)="BloatChop2"
MeleeAnims(2)="BloatChop2"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Bloat.Bloat_Speech'
BleedOutDuration=6.000000
bCannibal=True
ZapThreshold=0.500000
ZappedDamageMod=1.500000
bHarpoonToBodyStuns=False
ZombieFlag=1
MeleeDamage=14
damageForce=70000
bFatAss=True
KFRagdollName="BloatRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
PuntAnim="BloatPunt"
Intelligence=BRAINS_Stupid
bCanDistanceAttackDoors=True
bUseExtendedCollision=True
ColOffset=(Z=60.000000)
ColRadius=27.000000
ColHeight=22.000000
PlayerCountHealthScale=0.250000
OnlineHeadshotOffset=(X=10.000000,Y=-5.000000,Z=69.000000)
OnlineHeadshotScale=1.200000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
AmmunitionClass=Class'KFMod.BZombieAmmo'
ScoringValue=17
IdleHeavyAnim="BloatIdle"
IdleRifleAnim="BloatIdle"
MeleeRange=30.000000
GroundSpeed=75.000000
WaterSpeed=102.000000
HealthMax=525.000000
Health=525
HeadRadius=8.000000
HeadHeight=5.500000
MenuName="Bloat 2.5"
MovementAnims(0)="WalkBloat"
MovementAnims(1)="WalkBloat"
WalkAnims(0)="WalkBloat"
WalkAnims(1)="WalkBloat"
WalkAnims(2)="WalkBloat"
WalkAnims(3)="WalkBloat"
IdleCrouchAnim="BloatIdle"
IdleWeaponAnim="BloatIdle"
IdleRestAnim="BloatIdle"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieBreath'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.Bloat'
PrePivot=(Z=8.000000)
Skins(0)=Texture'KFOldSchoolZeds_Textures.Bloat.BloatSkin'
Mass=400.000000
RotationRate=(Yaw=45000,Roll=0)
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,204 @@
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)
}

View file

@ -0,0 +1,146 @@
class ZombieCrawlerOS extends KFMonsterOS;
var() float PounceSpeed;
var bool bPouncing;
simulated function ZombieCrispUp()
{
super.ZombieCrispUp();
Skins[1]=default.Skins[1];
}
function bool DoPounce()
{
if ( bZapped || bIsCrouched || bWantsToCrouch || (Physics != PHYS_Walking) || VSize(Location - Controller.Target.Location) > (MeleeRange * 5) )
return false;
Velocity = Normal(Controller.Target.Location-Location)*PounceSpeed;
Velocity.Z = JumpZ;
SetPhysics(PHYS_Falling);
ZombieSpringAnim();
bPouncing=true;
return true;
}
simulated function ZombieSpringAnim()
{
SetAnimAction('ZombieSpring');
}
event Landed(vector HitNormal)
{
bPouncing=false;
super.Landed(HitNormal);
}
event Bump(actor Other)
{
if(bPouncing && KFHumanPawn(Other)!=none )
{
KFHumanPawn(Other).TakeDamage(((MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1))), self ,self.Location,self.velocity, class 'KFmod.ZombieMeleeDamage');
if (KFHumanPawn(Other).Health <=0)
KFHumanPawn(Other).SpawnGibs(self.rotation, 1);
bPouncing=false;
}
}
simulated event SetAnimAction(name NewAction)
{
super.SetAnimAction(NewAction);
if ( AnimAction == 'ZombieLeapAttack' || AnimAction == 'LeapAttack3' || AnimAction == 'ZombieLeapAttack')
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
}
function bool FlipOver()
{
return false;
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Crawler.CrawlerSkin');
myLevel.AddPrecacheMaterial(FinalBlend'KFOldSchoolZeds_Textures.Crawler.CrawlerHairFB');
}
defaultproperties
{
PounceSpeed=330.000000
MeleeAnims(0)="ZombieLeapAttack"
MeleeAnims(1)="ZombieLeapAttack"
MeleeAnims(2)="LeapAttack3"
HitAnims(0)=
HitAnims(1)=
HitAnims(2)=
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Crawler.Crawler_Speech'
KFHitFront=
KFHitBack=
KFHitLeft=
KFHitRight=
bStunImmune=True
bCannibal=True
ZombieFlag=2
MeleeDamage=6
damageForce=5000
KFRagdollName="CrawlerRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
CrispUpThreshhold=10
Intelligence=BRAINS_Mammal
OnlineHeadshotOffset=(X=20.000000,Y=-5.000000,Z=-7.000000)
OnlineHeadshotScale=1.100000
MotionDetectorThreat=0.340000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=10
IdleHeavyAnim="ZombieLeapIdle"
IdleRifleAnim="ZombieLeapIdle"
bCrawler=True
GroundSpeed=140.000000
WaterSpeed=130.000000
JumpZ=350.000000
HealthMax=70.000000
Health=70
HeadRadius=10.000000
HeadHeight=1.000000
MenuName="Crawler 2.5"
ControllerClass=Class'KFOldSchoolZeds.ControllerCrawlerOS'
bDoTorsoTwist=False
MovementAnims(0)="ZombieScuttle"
MovementAnims(1)="ZombieScuttle"
MovementAnims(2)="ZombieScuttle"
MovementAnims(3)="ZombieScuttle"
TurnLeftAnim="ZombieScuttle"
TurnRightAnim="ZombieScuttle"
WalkAnims(0)="ZombieLeap"
WalkAnims(1)="ZombieLeap"
WalkAnims(2)="ZombieLeap"
WalkAnims(3)="ZombieLeap"
AirAnims(0)="ZombieSpring"
AirAnims(3)="ZombieSpring"
TakeoffAnims(0)="ZombieSpring"
TakeoffAnims(1)="ZombieSpring"
TakeoffAnims(2)="ZombieSpring"
TakeoffAnims(3)="ZombieSpring"
LandAnims(0)="ZombieScuttle"
LandAnims(1)="ZombieScuttle"
LandAnims(2)="ZombieScuttle"
LandAnims(3)="ZombieScuttle"
AirStillAnim="ZombieSpring"
TakeoffStillAnim="ZombieLeap"
IdleCrouchAnim="ZombieLeapIdle"
IdleWeaponAnim="ZombieLeapIdle"
IdleRestAnim="ZombieLeapIdle"
SpineBone1=
bOrientOnSlope=True
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieBreath'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.Shade'
Skins(0)=Texture'KFOldSchoolZeds_Textures.Crawler.CrawlerSkin'
Skins(1)=FinalBlend'KFOldSchoolZeds_Textures.Crawler.CrawlerHairFB'
CollisionHeight=25.000000
}

View file

@ -0,0 +1,860 @@
class ZombieExplosivesPoundOS extends KFMonsterOS;
var class<Projectile> GunnerProjClass;
var bool bClientGLing;
var int GLFireCounter;
var bool bFireAtWill,bGLing;
var float LastGLTime;
var vector TraceHitPos;
var Emitter mTracer,mMuzzleFlash;
var() float GLFireRate;
var() int GLFireBurst;
var() float GLFireInterval;
var bool bCharging;
var float DistBeforeSaw;
var bool bHasRaged;
var bool bNerfed;
replication
{
reliable if( Role==ROLE_Authority )
TraceHitPos,bGLing,bCharging;
}
function vector ComputeTrajectoryByTime( vector StartPosition, vector EndPosition, float fTimeEnd )
{
local vector NewVelocity;
NewVelocity = super.ComputeTrajectoryByTime( StartPosition, EndPosition, fTimeEnd );
if( PhysicsVolume.IsA( 'KFPhysicsVolume' ) && StartPosition.Z < EndPosition.Z )
{
if( PhysicsVolume.Gravity.Z < class'PhysicsVolume'.default.Gravity.Z )
{
if( Mass > 900 )
{
NewVelocity.Z += 90;
}
}
}
return NewVelocity;
}
simulated function PostBeginPlay()
{
if( Role < ROLE_Authority )
return;
if (Level.Game != none)
{
if(!bNerfed)
{
if( Level.Game.GameDifficulty < 2.0 )
{
GLFireBurst = default.GLFireBurst * 0.5;
GLFireRate = default.GLFireRate * 1.66;
}
else if( Level.Game.GameDifficulty < 4.0 )
{
GLFireBurst = default.GLFireBurst * 1.0;
GLFireRate = default.GLFireRate * 1.0;
}
else if( Level.Game.GameDifficulty < 5.0 )
{
GLFireBurst = default.GLFireBurst * 1.5;
GLFireRate = default.GLFireRate * 0.8;
}
else
{
GLFireBurst = default.GLFireBurst * 2.0;
GLFireRate = default.GLFireRate * 0.5;
}
}
else
{
GLFireInterval = default.GLFireInterval * 0.6;
GLFireBurst = default.GLFireBurst * 0.5;
GLFireRate = default.GLFireRate;
}
}
super.PostBeginPlay();
}
simulated Function PostNetBeginPlay()
{
EnableChannelNotify ( 1,1);
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
super.PostNetBeginPlay();
TraceHitPos = vect(0,0,0);
bNetNotify = true;
}
simulated function PostNetReceive()
{
if (bCharging)
MovementAnims[0]='PoundRun';
else if(!(bCrispified && bBurnified))
MovementAnims[0]=default.MovementAnims[0];
if(bClientGLing != bGLing)
{
bClientGLing = bGLing;
if( bGLing )
{
IdleHeavyAnim='RangedFireMG';
IdleRifleAnim='RangedFireMG';
IdleCrouchAnim='RangedFireMG';
IdleWeaponAnim='RangedFireMG';
IdleRestAnim='RangedFireMG';
}
else
{
IdleHeavyAnim='RangedIdle';
IdleRifleAnim='RangedIdle';
IdleCrouchAnim='RangedIdle';
IdleWeaponAnim='RangedIdle';
IdleRestAnim='RangedIdle';
}
}
if( TraceHitPos!=vect(0,0,0) )
{
AddTraceHitFX(TraceHitPos);
TraceHitPos = vect(0,0,0);
}
}
// This zed has been taken control of. Boost its health and speed
function SetMindControlled(bool bNewMindControlled)
{
if( bNewMindControlled )
{
NumZCDHits++;
// if we hit him a couple of times, make him rage!
if( NumZCDHits > 1 )
{
if( !IsInState('ChargeToMarker') )
{
GotoState('ChargeToMarker');
}
else
{
NumZCDHits = 1;
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
}
else
{
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
}
else
{
NumZCDHits=0;
}
bZedUnderControl = bNewMindControlled;
}
// Handle the zed being commanded to move to a new location
function GivenNewMarker()
{
if( bCharging && NumZCDHits > 1 )
{
GotoState('RunningToMarker');
}
else
{
GotoState('');
}
}
simulated function SetBurningBehavior()
{
if( Role == Role_Authority && IsInState('RunningState') )
{
super.SetBurningBehavior();
GotoState('');
}
super.SetBurningBehavior();
}
function bool FlipOver()
{
if( Physics==PHYS_Falling )
{
SetPhysics(PHYS_Walking);
}
bShotAnim = true;
//Explosive Pound has a unique animation for getting stunned
GoToState('');
SetAnimAction('StunState');
HandleWaitForAnim('StunState');
Acceleration = vect(0, 0, 0);
Velocity.X = 0;
Velocity.Y = 0;
KFMonsterController(Controller).Focus = none;
KFMonsterController(Controller).FocalPoint = KFMonsterController(Controller).LastSeenPos;
Controller.GoToState('WaitForAnim');
KFMonsterController(Controller).bUseFreezeHack = true;
return true;
}
function StartCharging()
{
GoToState('');
SetAnimAction('PoundRage');
HandleWaitForAnim('PoundRage');
Acceleration = vect(0,0,0);
Velocity.X = 0;
Velocity.Y = 0;
bShotAnim = true;
Controller.GoToState('WaitForAnim');
KFMonsterController(Controller).bUseFreezeHack = True;
bHasRaged = true;
}
simulated function bool HitCanInterruptAction()
{
if( bShotAnim )
{
return false;
}
return true;
}
simulated function Destroyed()
{
if( mTracer!=none )
mTracer.Destroy();
if( mMuzzleFlash!=none )
mMuzzleFlash.Destroy();
super.Destroyed();
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(Controller.Target.Location-Location);
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < (MeleeRange - DistBeforeSaw + CollisionRadius + A.CollisionRadius) && CanAttack(A) )
{
bShotAnim = true;
SetAnimAction('Claw');
PlaySound(sound'Claw2s', SLOT_Interact);
}
if( !bShotAnim && !bDecapitated )
{
if ( float(Health)/HealthMax < 0.5 )
{
GoToState('RunningState');
if(!bHasRaged)
StartCharging();
}
}
if ( !bWaitForAnim && !bShotAnim && !bDecapitated && LastGLTime<Level.TimeSeconds && Dist < 5000 && !bCharging)
{
LastGLTime = Level.TimeSeconds + GLFireInterval + (FRand() *2.0);
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedPreFireMG');
HandleWaitForAnim('RangedPreFireMG');
GLFireCounter = GLFireBurst;
GoToState('FireGrenades');
}
}
state RunningState
{
//Fixes slow charge for charging zeds
//Credits:NikC for forum link, aleat0r for the code
simulated function float GetOriginalGroundSpeed()
{
return 3.0 * OriginalGroundSpeed;
}
simulated function SetZappedBehavior()
{
Global.SetZappedBehavior();
GoToState('');
}
function bool CanSpeedAdjust()
{
return false;
}
function BeginState()
{
if( bZapped )
{
GoToState('');
}
else
{
SetGroundSpeed(OriginalGroundSpeed * 3.0);
bCharging = true;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset.Z = 51;
OnlineHeadshotOffset.X = 38;
OnlineHeadshotOffset.Y = -5;
NetUpdateTime = Level.TimeSeconds - 1;
}
}
function EndState()
{
if( !bZapped )
{
SetGroundSpeed(GetOriginalGroundSpeed());
}
bCharging = false;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
}
function RemoveHead()
{
GoToState('');
Global.RemoveHead();
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
DistBeforeSaw = 20.0;
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < (MeleeRange - DistBeforeSaw + CollisionRadius + A.CollisionRadius) && CanAttack(A) )
{
if(FRand() < 0.05 )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedPreFireMG');
HandleWaitForAnim('RangedPreFireMG');
GLFireCounter = 2;
GoToState('FireGrenades');
}
else
{
if(Level.Game.GameDifficulty < 5.0)
SetAnimAction(MeleeAnims[Rand(2)]);
else
SetAnimAction(MeleeAnims[1]);
bShotAnim = true;
PlaySound(sound'Claw2s', SLOT_Interact);
GoToState('');
}
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
}
}
function Tick( float Delta )
{
if( Role == ROLE_Authority && bShotAnim)
{
if( LookTarget!=None )
{
Acceleration = 10000 * Normal(LookTarget.Location - Location);
}
}
global.Tick(Delta);
}
}
state RunningToMarker extends RunningState{}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
local bool bIsHeadShot;
bIsHeadShot = IsHeadShot(Hitlocation, normal(Momentum), 1.0);
if ( Level.Game.GameDifficulty >= 5.0 && bIsHeadshot && (class<DamTypeCrossbow>(damageType) != none || class<DamTypeCrossbowHeadShot>(damageType) != none) )
{
Damage *= 0.5; // Half Damage from Crossbow HS
}
if(DamageType == class 'DamTypeFrag' || DamageType == class 'DamTypePipeBomb' || DamageType == class 'DamTypeM79Grenade' ||
DamageType == class 'DamTypeM32Grenade' || DamageType == class 'DamTypeM203Grenade' || DamageType == class 'DamTypeSPGrenade' ||
DamageType == class 'DamTypeSealSquealExplosion' || DamageType == class 'DamTypeSeekerSixRocket')
Damage *= 0.5; // Half damage from explosives
Super.takeDamage(Damage, instigatedBy, hitLocation, momentum, damageType, HitIndex);
}
simulated function AddTraceHitFX( vector HitPos )
{
local vector Start,SpawnVel,SpawnDir;
local float hitDist;
Start = GetBoneCoords('FireBone').Origin;
if( mTracer==none )
mTracer = Spawn(class'KFMod.KFNewTracer',,,Start);
else mTracer.SetLocation(Start);
if( mMuzzleFlash==none )
{
mMuzzleFlash = Spawn(class'NewMinigunMFlashOS');
AttachToBone(mMuzzleFlash, 'FireBone');
}
else mMuzzleFlash.SpawnParticle(1);
hitDist = VSize(HitPos - Start) - 50.f;
if( hitDist>10 )
{
SpawnDir = Normal(HitPos - Start);
SpawnVel = SpawnDir * 10000.f;
mTracer.Emitters[0].StartVelocityRange.X.Min = SpawnVel.X;
mTracer.Emitters[0].StartVelocityRange.X.Max = SpawnVel.X;
mTracer.Emitters[0].StartVelocityRange.Y.Min = SpawnVel.Y;
mTracer.Emitters[0].StartVelocityRange.Y.Max = SpawnVel.Y;
mTracer.Emitters[0].StartVelocityRange.Z.Min = SpawnVel.Z;
mTracer.Emitters[0].StartVelocityRange.Z.Max = SpawnVel.Z;
mTracer.Emitters[0].LifetimeRange.Min = hitDist / 10000.f;
mTracer.Emitters[0].LifetimeRange.Max = mTracer.Emitters[0].LifetimeRange.Min;
mTracer.SpawnParticle(1);
}
Instigator = self;
if( HitPos != vect(0,0,0) )
{
Spawn(class'ROBulletHitEffect',,, HitPos, Rotator(Normal(HitPos - Start)));
}
}
function FireGLShot()
{
local vector X,Y,Z, FireStart;
local rotator FireRotation;
local float Dist;
//Log spam prevention(?)
if(Controller.Target != None)
{
Controller.Target = Controller.Target;
}
Dist = VSize(Controller.Target.Location-Location);
GLFireCounter--;
//Randomness in leading target
if(FRand() > 0.5 && !bNerfed)
SavedFireProperties.bLeadTarget = true;
else
SavedFireProperties.bLeadTarget = false;
if( Controller!=none && KFDoorMover(Controller.Target)!=none )
{
Controller.Target.TakeDamage(22,self,Location,vect(0,0,0),class'DamTypeVomit');
return;
}
GetAxes(Rotation,X,Y,Z);
FireStart = GetBoneCoords('FireBone').Origin;
if ( !SavedFireProperties.bInitialized )
{
SavedFireProperties.AmmoClass = class'SkaarjAmmo';
SavedFireProperties.ProjectileClass = GunnerProjClass;
SavedFireProperties.WarnTargetPct = 1;
SavedFireProperties.MaxRange = 65535;
SavedFireProperties.bTossed = false;
SavedFireProperties.bTrySplash = true;
SavedFireProperties.bLeadTarget = false;
SavedFireProperties.bInstantHit = false;
SavedFireProperties.bInitialized = true;
}
ToggleAuxCollision(false);
FireRotation = Controller.AdjustAim(SavedFireProperties,FireStart,600);
Spawn(GunnerProjClass,,,FireStart,FireRotation);
PlaySound(sound'KF_M79Snd.M79_Fire',SLOT_Misc,2,,1400,0.9+FRand()*0.2);
ToggleAuxCollision(true);
}
simulated function AnimEnd( int Channel )
{
local name Sequence;
local float Frame, Rate;
if( Level.NetMode==NM_Client && bGLing )
{
GetAnimParams( Channel, Sequence, Frame, Rate );
if( Sequence != 'RangedPreFireMG' && Sequence != 'RangedFireMG' )
{
super.AnimEnd(Channel);
return;
}
PlayAnim('RangedFireMG');
bWaitForAnim = true;
bShotAnim = true;
IdleTime = Level.TimeSeconds;
}
else super.AnimEnd(Channel);
}
state FireGrenades
{
function RangedAttack(Actor A)
{
//Log spam prevention(?)
if(Controller.Target != None)
{
Controller.Target = A;
Controller.Focus = A;
}
}
simulated function Tick(float DeltaTime)
{
local float Dist;
local float Speed, Timer, TossZ;
local float AdditionalSpeed;
local float TimerDivizor;
//Log spam prevention
if(Controller.Target != None)
{
Dist = VSize(Controller.Target.Location-Location);
TossZ = Controller.Target.Location.Z - Location.Z;
}
AdditionalSpeed = 250;
TimerDivizor = 1250;
Speed = Dist + AdditionalSpeed;
Timer = Dist / TimerDivizor;
if(TossZ >= 200)
TossZ = 200;
else if(TossZ <=100)
TossZ = 100;
class'GunnerGLProjectile'.default.Speed = Speed;
class'GunnerGLProjectile'.default.ExplodeTimer = 1 + (FRand() - 0.5) + Timer;
class'GunnerGLProjectile'.default.TossZ = TossZ;
if(class'GunnerGLProjectile'.default.ExplodeTimer >= 1.75)
class'GunnerGLProjectile'.default.ExplodeTimer = 1.75;
if(bNerfed)
class'GunnerGLProjectile'.default.ExplodeTimer = 1.5;
if(Dist < 500)
{
SavedFireProperties.bLeadTarget = true;
AdditionalSpeed = 700;
}
if(Dist > 3500 )
AdditionalSpeed = 0;
if(float(Health)/HealthMax < 0.5 && !bHasRaged )
{
StartCharging();
}
super.Tick(DeltaTime);
}
function EndState()
{
TraceHitPos = vect(0,0,0);
bGLing = false;
SoundVolume=default.SoundVolume;
SoundRadius=default.SoundRadius;
GLFireCounter=0;
LastGLTime = Level.TimeSeconds + GLFireInterval + (FRand() *2.0);
}
function BeginState()
{
bFireAtWill = false;
Acceleration = vect(0,0,0);
bGLing = true;
}
function AnimEnd( int Channel )
{
if( GLFireCounter <= 0 )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMGEnd');
HandleWaitForAnim('RangedFireMGEnd');
GoToState('');
}
else
{
if ( Controller.Enemy != none )
{
if ( Controller.LineOfSightTo(Controller.Enemy) && FastTrace(GetBoneCoords('FireBone').Origin,Controller.Enemy.Location))
{
Controller.Focus = Controller.Enemy;
Controller.FocalPoint = Controller.Enemy.Location;
}
Controller.Target = Controller.Enemy;
}
bFireAtWill = true;
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMG');
bWaitForAnim = true;
}
}
function bool NeedToTurnFor( rotator targ )
{
local int YawErr;
targ.Yaw = DesiredRotation.Yaw & 65535;
YawErr = (targ.Yaw - (Rotation.Yaw & 65535)) & 65535;
return !((YawErr < 2000) || (YawErr > 64535));
}
Begin:
While( true )
{
Acceleration = vect(0,0,0);
if( GLFireCounter <= 0 )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMGEnd');
HandleWaitForAnim('RangedFireMGEnd');
GoToState('');
}
if( bFireAtWill )
FireGLShot();
Sleep(GLFireRate);
}
}
simulated function int DoAnimAction( name AnimName )
{
if(AnimName=='GoreAttack2' || AnimName=='GoreAttack1' ||AnimName=='RangedHitF' )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(AnimName,, 0.0, 1);
return 1;
}
return super.DoAnimAction(AnimName);
}
simulated event SetAnimAction(name NewAction)
{
local int meleeAnimIndex;
if( NewAction=='' )
return;
if(NewAction == 'Claw')
{
meleeAnimIndex = Rand(3);
NewAction = meleeAnims[meleeAnimIndex];
CurrentDamtype = ZombieDamType[meleeAnimIndex];
}
ExpectingChannel = DoAnimAction(NewAction);
if( Controller != none )
{
ControllerExplosivePound(Controller).AnimWaitChannel = ExpectingChannel;
}
if( AnimNeedsWait(NewAction) )
{
bWaitForAnim = true;
}
if( Level.NetMode!=NM_Client )
{
AnimAction = NewAction;
bResetAnimAct = true;
ResetAnimActTime = Level.TimeSeconds+0.3;
}
}
simulated function HandleWaitForAnim( name NewAnim )
{
local float RageAnimDur;
Controller.GoToState('WaitForAnim');
RageAnimDur = GetAnimDuration(NewAnim);
ControllerExplosivePound(Controller).SetWaitForAnimTimout(RageAnimDur,NewAnim);
}
simulated function bool AnimNeedsWait(name TestAnim)
{
if( TestAnim == 'RangedFireMG' || TestAnim == 'RangedPreFireMG' || TestAnim == 'RangedFireMGEnd'
|| TestAnim == 'StunState' || TestAnim == 'PoundRage')
{
return true;
}
return false;
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.GunPound.AutoTurretGunTex');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.GunPound.GunPoundSkin');
}
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex)
{
if(LastGLTime<Level.TimeSeconds + 1)
return;
else
super.OldPlayHit(Damage,InstigatedBy,HitLocation,damageType,Momentum,HitIndex);
}
defaultproperties
{
GunnerProjClass=Class'KFOldSchoolZeds.GunnerGLProjectile'
GLFireRate=0.750000
GLFireBurst=2
GLFireInterval=5.500000
MeleeAnims(0)="GoreAttack2"
MeleeAnims(1)="GoreAttack1"
MeleeAnims(2)="GoreAttack2"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Fleshpound.Fleshpound_Speech'
BleedOutDuration=6.000000
ZapThreshold=1.250000
ZappedDamageMod=1.250000
bHarpoonToBodyStuns=False
ZombieFlag=1
MeleeDamage=20
damageForce=-200000
bFatAss=True
KFRagdollName="FleshPoundRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
Intelligence=BRAINS_Mammal
bUseExtendedCollision=True
ColOffset=(Z=65.000000)
ColRadius=27.000000
ColHeight=25.000000
PlayerCountHealthScale=0.100000
BurningWalkFAnims(0)="RangedWalkF"
BurningWalkFAnims(1)="RangedWalkF"
BurningWalkFAnims(2)="RangedWalkF"
BurningWalkAnims(0)="RangedWalkF"
BurningWalkAnims(1)="RangedWalkF"
BurningWalkAnims(2)="RangedWalkF"
OnlineHeadshotOffset=(X=-8.000000,Y=7.000000,Z=77.000000)
OnlineHeadshotScale=1.200000
HeadHealth=650.000000
PlayerNumHeadHealthScale=0.050000
MotionDetectorThreat=2.000000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
AmmunitionClass=Class'KFMod.BZombieAmmo'
ScoringValue=125
IdleHeavyAnim="RangedIdle"
IdleRifleAnim="RangedIdle"
MeleeRange=65.000000
GroundSpeed=80.000000
WaterSpeed=75.000000
HealthMax=1250.000000
Health=1250
HeadRadius=8.750000
HeadHeight=11.000000
AmbientSoundScaling=5.000000
MenuName="Flesh Pound Explosives Gunner"
ControllerClass=Class'KFOldSchoolZeds.ControllerExplosivePound'
MovementAnims(0)="RangedWalkF"
MovementAnims(1)="RangedWalkF"
MovementAnims(2)="RangedWalkF"
MovementAnims(3)="RangedWalkF"
TurnLeftAnim="RangedBossHitF"
TurnRightAnim="RangedBossHitF"
WalkAnims(0)="RangedWalkF"
WalkAnims(1)="RangedWalkF"
WalkAnims(2)="RangedWalkF"
WalkAnims(3)="RangedWalkF"
AirAnims(0)="RangedJumpInAir"
AirAnims(1)="RangedJumpInAir"
AirAnims(2)="RangedJumpInAir"
AirAnims(3)="RangedJumpInAir"
TakeoffAnims(0)="RangedJumpTakeOff"
TakeoffAnims(1)="RangedJumpTakeOff"
TakeoffAnims(2)="RangedJumpTakeOff"
TakeoffAnims(3)="RangedJumpTakeOff"
LandAnims(0)="RangedJumpLanded"
LandAnims(1)="RangedJumpLanded"
LandAnims(2)="RangedJumpLanded"
LandAnims(3)="RangedJumpLanded"
AirStillAnim="RangedJumpInAir"
TakeoffStillAnim="RangedJumpTakeOff"
IdleCrouchAnim="RangedIdle"
IdleWeaponAnim="RangedIdle"
IdleRestAnim="RangedIdle"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Scrake.Saw_Idle'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.ExplosivesPound'
PrePivot=(Z=2.000000)
Skins(0)=Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader'
Skins(1)=TexOscillator'KillingFloorWeapons.Chainsaw.SAWCHAIN'
Skins(2)=Texture'KFPatch2.BossGun'
Skins(3)=Shader'KFPatch2.LaserShader'
Skins(4)=Shader'KFCharacters.PoundBitsShader'
Skins(5)=Texture'KFOldSchoolZeds_Textures.clot.ClotSkinVariant2'
Skins(6)=Texture'KillingFloorWeapons.Chainsaw.ChainSawSkin3PZombie'
SoundRadius=200.000000
Mass=400.000000
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,797 @@
class ZombieFleshpoundOS extends KFMonsterOS;
var bool bChargingPlayer,bClientCharge;
var int TwoSecondDamageTotal;
var float LastDamagedTime,RageEndTime;
var() vector RotMag;
var() vector RotRate;
var() float RotTime;
var() vector OffsetMag;
var() vector OffsetRate;
var() float OffsetTime;
var name ChargingAnim;
var () int RageDamageThreshold;
var FleshPoundAvoidArea AvoidArea;
var bool bFrustrated;
var bool bEnableOldFleshpoundBehavior;
replication
{
reliable if(Role == ROLE_Authority)
bChargingPlayer, bFrustrated;
}
simulated function PostNetBeginPlay()
{
//TODO: Make Avoid Area spawn if Fleshy is charging
//Also, extend AvoidArea box more forward so zeds
//In front have chance to move away once Zeds notice
//That he's pissed off. Or, just remove it entirely.
//if (AvoidArea == none && bChargingPlayer )
// AvoidArea = Spawn(class'FleshPoundAvoidArea',self);
//if (AvoidArea != none)
// AvoidArea.InitFor(self);
EnableChannelNotify ( 1,1);
AnimBlendParams(1, 1.0, 0.0,, SpineBone1);
super.PostNetBeginPlay();
}
simulated function PostBeginPlay()
{
if( Role < ROLE_Authority )
{
return;
}
if (Level.Game != none)
{
if( Level.Game.GameDifficulty < 2.0 )
{
SpinDamConst = default.SpinDamConst * 0.5;
}
else if( Level.Game.GameDifficulty < 4.0 )
{
SpinDamConst = default.SpinDamConst * 1.0;
}
else if( Level.Game.GameDifficulty < 5.0 )
{
SpinDamConst = default.SpinDamConst * 1.2;
}
else // Hardest difficulty
{
SpinDamConst = default.SpinDamConst * 1.6;
}
}
super.PostBeginPlay();
}
// This zed has been taken control of. Boost its health and speed
function SetMindControlled(bool bNewMindControlled)
{
if( bNewMindControlled )
{
NumZCDHits++;
// if we hit him a couple of times, make him rage!
if( NumZCDHits > 1 )
{
if( !IsInState('ChargeToMarker') )
{
GotoState('ChargeToMarker');
}
else
{
NumZCDHits = 1;
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
}
else
{
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
}
else
{
NumZCDHits=0;
}
bZedUnderControl = bNewMindControlled;
}
// Handle the zed being commanded to move to a new location
function GivenNewMarker()
{
if( bChargingPlayer && NumZCDHits > 1 )
{
GotoState('ChargeToMarker');
}
else
{
GotoState('');
}
}
function PlayTakeHit(vector HitLocation, int Damage, class<DamageType> DamageType)
{
if( Level.TimeSeconds - LastPainAnim < MinTimeBetweenPainAnims )
return;
if( !Controller.IsInState('WaitForAnim') && Damage >= 10 )
PlayDirectionalHit(HitLocation);
LastPainAnim = Level.TimeSeconds;
if( Level.TimeSeconds - LastPainSound < MinTimeBetweenPainSounds )
return;
LastPainSound = Level.TimeSeconds;
PlaySound(HitSound[0], SLOT_Pain,1.25,,400);
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
local int OldHealth;
local Vector X,Y,Z, Dir;
local bool bIsHeadShot;
local float HeadShotCheckScale;
GetAxes(Rotation, X,Y,Z);
if( LastDamagedTime<Level.TimeSeconds )
TwoSecondDamageTotal = 0;
LastDamagedTime = Level.TimeSeconds+2;
OldHealth = Health;
HeadShotCheckScale = 1.0;
if( class<DamTypeMelee>(damageType) != none )
HeadShotCheckScale *= 1.25;
bIsHeadShot = IsHeadShot(Hitlocation, normal(Momentum), 1.0);
if ( DamageType != class 'DamTypeFrag' && DamageType != class 'DamTypeLaw' && DamageType != class 'DamTypePipeBomb'
&& DamageType != class 'DamTypeM79Grenade' && DamageType != class 'DamTypeM32Grenade'
&& DamageType != class 'DamTypeM203Grenade' && DamageType != class 'DamTypeMedicNade'
&& DamageType != class 'DamTypeSPGrenade' && DamageType != class 'DamTypeSealSquealExplosion'
&& DamageType != class 'DamTypeSeekerSixRocket' )
{
if(bIsHeadShot && class<KFWeaponDamageType>(damageType)!=none &&
class<KFWeaponDamageType>(damageType).default.HeadShotDamageMult >= 1.5)
Damage *= 0.75;
else if ( Level.Game.GameDifficulty >= 5.0 && bIsHeadshot && (class<DamTypeCrossbow>(damageType) != none || class<DamTypeCrossbowHeadShot>(damageType) != none) )
Damage *= 0.35;
else
Damage *= 0.5;
}
else if (DamageType == class 'DamTypeFrag' || DamageType == class 'DamTypePipeBomb' || DamageType == class 'DamTypeMedicNade' )
Damage *= 2.0;
else if( DamageType == class 'DamTypeM79Grenade' || DamageType == class 'DamTypeM32Grenade'
|| DamageType == class 'DamTypeM203Grenade' || DamageType == class 'DamTypeSPGrenade'
|| DamageType == class 'DamTypeSealSquealExplosion' || DamageType == class 'DamTypeSeekerSixRocket')
Damage *= 1.25;
if (Damage >= Health)
PostNetReceive();
Dir = -Normal(Location - hitlocation);
if (damageType == class 'DamTypeVomit')
Damage = 0;
else if( damageType == class 'DamTypeBlowerThrower' )
Damage *= 0.25;
super.takeDamage(Damage, instigatedBy, hitLocation, momentum, damageType,HitIndex) ;
TwoSecondDamageTotal += OldHealth - Health;
if (!bDecapitated && TwoSecondDamageTotal > RageDamageThreshold && !bChargingPlayer &&
!bZapped && (!(bCrispified && bBurnified) || bFrustrated) )
StartCharging();
}
simulated function DeviceGoRed()
{
Skins[1]=FinalBlend'KFOldSchoolZeds_Textures.Fleshpound.RedPoundMeter';
Skins[2]=Shader'KFOldSchoolZeds_Textures.Fleshpound.FPDeviceBloomRedShader';
}
simulated function DeviceGoNormal()
{
Skins[1]=FinalBlend'KFOldSchoolZeds_Textures.Fleshpound.AmberPoundMeter';
Skins[2]=Shader'KFOldSchoolZeds_Textures.Fleshpound.FPDeviceBloomAmberShader';
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < MeleeRange + CollisionRadius + A.CollisionRadius || CanAttack(A))
{
bShotAnim = true;
SetAnimAction('Claw');
PlaySound(sound'Claw2s', SLOT_None);
damageForce=default.damageForce;
return;
}
}
function StartCharging()
{
local float RageAnimDur;
if( Health <= 0 )
return;
SetAnimAction('PoundRage');
Acceleration = vect(0,0,0);
bShotAnim = true;
Velocity.X = 0;
Velocity.Y = 0;
Controller.GoToState('WaitForAnim');
KFMonsterControllerOS(Controller).bUseFreezeHack = true;
RageAnimDur = GetAnimDuration('PoundRage');
ControllerFleshpoundOS(Controller).SetPoundRageTimout(RageAnimDur);
GoToState('BeginRaging');
}
state BeginRaging
{
Ignores StartCharging;
simulated function SetZappedBehavior()
{
Global.SetZappedBehavior();
GoToState('');
}
function Tick( float Delta )
{
Acceleration = vect(0,0,0);
global.Tick(Delta);
}
Begin:
Sleep(GetAnimDuration('PoundRage'));
GotoState('RageCharging');
}
simulated function SetBurningBehavior()
{
if( bFrustrated || bChargingPlayer )
return;
super.SetBurningBehavior();
}
state RageCharging
{
Ignores StartCharging;
simulated function SetZappedBehavior()
{
Global.SetZappedBehavior();
GoToState('');
}
function PlayDirectionalHit(Vector HitLoc)
{
if( !bShotAnim )
super.PlayDirectionalHit(HitLoc);
}
function bool CanSpeedAdjust()
{
return false;
}
//Dont play hit anims while charging so people don't complain about broken head hitboxes :)
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex){}
function BeginState()
{
local float DifficultyModifier;
if( bZapped )
{
GoToState('');
}
else
{
bChargingPlayer = true;
if( Level.NetMode!=NM_DedicatedServer )
ClientChargingAnims();
if( Level.Game.GameDifficulty < 2.0 )
{
DifficultyModifier = 0.85;
}
else if( Level.Game.GameDifficulty < 4.0 )
{
DifficultyModifier = 1.0;
}
else if( Level.Game.GameDifficulty < 5.0 )
{
DifficultyModifier = 1.25;
}
else
{
DifficultyModifier = 3.0;
}
OnlineHeadshotOffset.Z=50;
OnlineHeadshotOffset.X=44;
OnlineHeadshotOffset.Y=-4;
if(!bEnableOldFleshpoundBehavior)
RageEndTime = (Level.TimeSeconds + 5 * DifficultyModifier) + (FRand() * 6 * DifficultyModifier);
else
RageEndTime = Level.TimeSeconds + 10;
NetUpdateTime = Level.TimeSeconds - 1;
}
}
function EndState()
{
bChargingPlayer = false;
bFrustrated = false;
ControllerFleshpoundOS(Controller).RageFrustrationTimer = 0;
if( Health>0 && !bZapped )
SetGroundSpeed(GetOriginalGroundSpeed());
if( Level.NetMode!=NM_DedicatedServer )
ClientChargingAnims();
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
NetUpdateTime = Level.TimeSeconds - 1;
}
function Tick( float Delta )
{
if( !bShotAnim )
{
SetGroundSpeed(OriginalGroundSpeed * 2.3);
if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime )
GoToState('');
}
if( Role == ROLE_Authority && bShotAnim)
{
if( LookTarget!=None )
Acceleration = AccelRate * Normal(LookTarget.Location - Location);
}
global.Tick(Delta);
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < MeleeRange + CollisionRadius + A.CollisionRadius )
{
bShotAnim = true;
SetAnimAction('FPRageAttack'); // ACTUALLY do your rage attack when raged
damageForce=-20000; // Your rage attack looks like it pulls players, so actually pull them
PlaySound(sound'Claw2s', SLOT_None);
return;
}
}
function Bump( Actor Other )
{
local float RageBumpDamage;
local KFMonster KFMonst;
KFMonst = KFMonster(Other);
if( !bShotAnim && KFMonst!=none && ZombieFleshPound(Other)==none && ZombieFleshPoundOS(Other)==none && Pawn(Other).Health>0 )
{
if( FRand() < 0.4 )
RageBumpDamage = 501;
else
RageBumpDamage = 450;
RageBumpDamage *= KFMonst.PoundRageBumpDamScale;
Other.TakeDamage(RageBumpDamage, self, Other.Location, Velocity * Other.Mass, class'DamTypePoundCrushed');
}
else Global.Bump(Other);
}
function bool MeleeDamageTarget(int hitdamage, vector pushdir)
{
local bool RetVal,bWasEnemy;
bWasEnemy = (Controller.Target==Controller.Enemy);
RetVal = super.MeleeDamageTarget(hitdamage*1.75, pushdir*3);
if( RetVal && bWasEnemy )
GoToState('');
return RetVal;
}
}
state ChargeToMarker extends RageCharging
{
Ignores StartCharging;
function Tick( float Delta )
{
if( !bShotAnim )
{
SetGroundSpeed(OriginalGroundSpeed * 2.3);
if( !bFrustrated && !bZedUnderControl && Level.TimeSeconds>RageEndTime )
GoToState('');
}
global.Tick(Delta);
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < MeleeRange + CollisionRadius + A.CollisionRadius )
{
bShotAnim = true;
SetAnimAction('Claw');
PlaySound(sound'Claw2s', SLOT_None);
return;
}
}
}
simulated function PostNetReceive()
{
if( bClientCharge!=bChargingPlayer && !bZapped )
{
bClientCharge = bChargingPlayer;
if (bChargingPlayer)
{
MovementAnims[0]=ChargingAnim;
MeleeAnims[0]='FPRageAttack';
MeleeAnims[1]='FPRageAttack';
MeleeAnims[2]='FPRageAttack';
DeviceGoRed();
}
else
{
MovementAnims[0]=default.MovementAnims[0];
MeleeAnims[0]=default.MeleeAnims[0];
MeleeAnims[1]=default.MeleeAnims[1];
MeleeAnims[2]=default.MeleeAnims[2];
DeviceGoNormal();
}
}
}
simulated function PlayDyingAnimation(class<DamageType> DamageType, vector HitLoc)
{
super.PlayDyingAnimation(DamageType,HitLoc);
if( Level.NetMode!=NM_DedicatedServer )
DeviceGoNormal();
}
simulated function ClientChargingAnims()
{
PostNetReceive();
}
function ClawDamageTarget()
{
local vector PushDir;
local KFHumanPawn HumanTarget;
local KFPlayerController HumanTargetController;
local float UsedMeleeDamage;
local name Sequence;
local float Frame, Rate;
GetAnimParams( ExpectingChannel, Sequence, Frame, Rate );
if( MeleeDamage > 1 )
UsedMeleeDamage = (MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1));
else
UsedMeleeDamage = MeleeDamage;
if( Sequence == 'PoundAttack1' )
UsedMeleeDamage *= 0.5;
else if( Sequence == 'PoundAttack2' )
UsedMeleeDamage *= 0.25;
if(Controller!=none && Controller.Target!=none)
PushDir = (damageForce * Normal(Controller.Target.Location - Location));
else
PushDir = damageForce * vector(Rotation);
if (MeleeDamageTarget(UsedMeleeDamage,PushDir))
{
HumanTarget = KFHumanPawn(Controller.Target);
if( HumanTarget!=none )
HumanTargetController = KFPlayerController(HumanTarget.Controller);
if( HumanTargetController!=none )
HumanTargetController.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
PlayZombieAttackHitSound();
}
}
function SpinDamage(actor Target)
{
local vector HitLocation;
local Name TearBone;
local Float dummy;
local float DamageAmount;
local vector PushDir;
local KFHumanPawn HumanTarget;
if(target==none)
return;
PushDir = (damageForce * Normal(Target.Location - Location));
damageamount = (SpinDamConst);
if (Target.IsA('KFHumanPawn') && Pawn(Target).Health <= DamageAmount)
{
KFHumanPawn(Target).RagDeathVel *= 3;
KFHumanPawn(Target).RagDeathUpKick *= 1.5;
}
if (Target !=none && Target.IsA('KFDoorMover'))
{
Target.TakeDamage(DamageAmount,self,HitLocation,pushdir,class'KFmod.ZombieMeleeDamage');
PlayZombieAttackHitSound();
}
if (KFHumanPawn(Target)!=none)
{
HumanTarget = KFHumanPawn(Target);
if (HumanTarget.Controller != none)
HumanTarget.Controller.ShakeView(RotMag, RotRate, RotTime, OffsetMag, OffsetRate, OffsetTime);
KFHumanPawn(Target).TakeDamage(DamageAmount,self,HitLocation,pushdir,class'KFmod.ZombieMeleeDamage');
if (KFHumanPawn(Target).Health <=0)
{
KFHumanPawn(Target).SpawnGibs(rotator(pushdir), 1);
TearBone=KFPawn(Target).GetClosestBone(HitLocation,Velocity,dummy);
KFHumanPawn(Controller.Target).HideBone(TearBone);
}
}
}
simulated function int DoAnimAction( name AnimName )
{
if( AnimName=='PoundAttack1' || AnimName=='PoundAttack2' || AnimName=='FPRageAttack' || AnimName=='ZombieFireGun' )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(AnimName,, 0.0, 1);
return 1;
}
return super.DoAnimAction(AnimName);
}
simulated event SetAnimAction(name NewAction)
{
local int meleeAnimIndex;
if (!bWaitForAnim)
{
AnimAction = NewAction;
if ( AnimAction == KFHitFront )
{
AnimBlendParams(1, 1.0, 0.0,,'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == KFHitBack )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == KFHitRight )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == KFHitLeft )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == 'PoundRage' )
PlayAnim(NewAction);
else if ( AnimAction == 'PoundAttack1' )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == 'PoundAttack2' )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if ( AnimAction == 'FPRageAttack' )
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(NewAction,, 0.0, 1);
}
else if(AnimAction == 'Claw')
{
meleeAnimIndex = Rand(3);
AnimAction=meleeAnims[Rand(3)];
CurrentDamtype = ZombieDamType[meleeAnimIndex];
SetAnimAction(AnimAction);
return;
}
//Maybe the reason this attack animation doesn't play online is because of it not being in AnimNeedsWait like Scrake's?
if( AnimAction=='PoundAttack3' && Controller!=none )
Controller.GotoState('spinattack');
else if(NewAction == 'ZombieFeed')
{
AnimAction = NewAction;
LoopAnim(AnimAction,,0.1);
}
else AnimAction = NewAction;
if (PlayAnim(AnimAction,,0.1) && AnimAction != KFHitFront && AnimAction != KFHitBack && AnimAction != KFHitLeft &&
AnimAction != KFHitRight && AnimAction != 'PoundAttack1' && AnimAction != 'PoundAttack2' && AnimAction != 'FPRageAttack')
{
if ( Physics != PHYS_None )
bWaitForAnim = true;
}
}
}
simulated function bool AnimNeedsWait(name TestAnim)
{
if( TestAnim == 'PoundAttack3')
return true;
return false;
}
function bool FlipOver()
{
return false;
}
function bool SameSpeciesAs(Pawn P)
{
return (ZombieFleshPound(P)!=none || ZombieFleshPoundOS(P)!=none);
}
simulated function Destroyed()
{
if( AvoidArea!=none )
AvoidArea.Destroy();
super.Destroyed();
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(FinalBlend'KFOldSchoolZeds_Textures.Fleshpound.RedPoundMeter');
myLevel.AddPrecacheMaterial(FinalBlend'KFOldSchoolZeds_Textures.Fleshpound.AmberPoundMeter');
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.Fleshpound.FPDeviceBloomRedShader');
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.Fleshpound.FPDeviceBloomAmberShader');
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Fleshpound.PoundSkin');
}
defaultproperties
{
RotMag=(X=500.000000,Y=500.000000,Z=600.000000)
RotRate=(X=12500.000000,Y=12500.000000,Z=12500.000000)
RotTime=6.000000
OffsetMag=(X=5.000000,Y=10.000000,Z=5.000000)
OffsetRate=(X=300.000000,Y=300.000000,Z=300.000000)
OffsetTime=3.500000
ChargingAnim="PoundRun"
RageDamageThreshold=360
MeleeAnims(0)="PoundAttack1"
MeleeAnims(1)="PoundAttack2"
MeleeAnims(2)="PoundAttack3"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Fleshpound.Fleshpound_Speech'
BleedOutDuration=7.000000
ZapThreshold=1.750000
ZappedDamageMod=1.250000
bHarpoonToBodyStuns=False
DamageToMonsterScale=5.000000
ZombieFlag=3
MeleeDamage=35
damageForce=15000
bFatAss=True
KFRagdollName="FleshPoundRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
SpinDamConst=5.000000
bMeleeStunImmune=True
Intelligence=BRAINS_Mammal
bUseExtendedCollision=True
ColOffset=(Z=52.000000)
ColRadius=36.000000
ColHeight=35.000000
PlayerCountHealthScale=0.250000
OnlineHeadshotOffset=(X=-9.000000,Y=-6.000000,Z=69.000000)
OnlineHeadshotScale=1.200000
HeadHealth=700.000000
PlayerNumHeadHealthScale=0.300000
MotionDetectorThreat=5.000000
bBoss=True
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=200
IdleHeavyAnim="PoundIdle"
IdleRifleAnim="PoundIdle"
RagDeathVel=100.000000
RagDeathUpKick=100.000000
MeleeRange=55.000000
GroundSpeed=130.000000
WaterSpeed=120.000000
HealthMax=1500.000000
Health=1500
HeadRadius=8.200000
HeadHeight=9.000000
MenuName="Flesh Pound 2.5"
ControllerClass=Class'KFOldSchoolZeds.ControllerFleshpoundOS'
MovementAnims(0)="PoundWalk"
MovementAnims(1)="PoundWalk"
MovementAnims(2)="PoundWalk"
MovementAnims(3)="PoundWalk"
WalkAnims(0)="PoundWalk"
WalkAnims(1)="PoundWalk"
WalkAnims(2)="PoundWalk"
WalkAnims(3)="PoundWalk"
IdleCrouchAnim="PoundIdle"
IdleWeaponAnim="PoundIdle"
IdleRestAnim="PoundIdle"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieBreath'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.ZombieBoss'
PrePivot=(Z=0.000000)
Skins(0)=Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader'
Skins(1)=FinalBlend'KFOldSchoolZeds_Textures.Fleshpound.AmberPoundMeter'
Skins(2)=Shader'KFOldSchoolZeds_Textures.Fleshpound.FPDeviceBloomAmberShader'
Skins(3)=Texture'KFOldSchoolZeds_Textures.Fleshpound.PoundSkin'
Mass=600.000000
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,260 @@
class ZombieGoreFastOS extends KFMonsterOS;
var bool bRunning;
replication
{
reliable if(Role == ROLE_Authority)
bRunning;
}
simulated function PostNetReceive()
{
if( !bZapped )
{
if (bRunning)
MovementAnims[0]='ZombieRun';
else
MovementAnims[0]=default.MovementAnims[0];
}
}
// This zed has been taken control of. Boost its health and speed
function SetMindControlled(bool bNewMindControlled)
{
if( bNewMindControlled )
{
NumZCDHits++;
// if we hit him a couple of times, make him rage!
if( NumZCDHits > 1 )
{
if( !IsInState('ChargeToMarker') )
{
GotoState('ChargeToMarker');
}
else
{
NumZCDHits = 1;
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
}
else
{
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
}
else
{
NumZCDHits=0;
}
bZedUnderControl = bNewMindControlled;
}
// Handle the zed being commanded to move to a new location
function GivenNewMarker()
{
if( bRunning && NumZCDHits > 1 )
{
GotoState('ChargeToMarker');
}
else
{
GotoState('');
}
}
function PlayZombieAttackHitSound()
{
local int MeleeAttackSounds;
MeleeAttackSounds = rand(3);
switch(MeleeAttackSounds)
{
case 0:
PlaySound(sound'KFOldSchoolZeds_Sounds.Stab_Hit1', SLOT_Interact);
break;
case 1:
PlaySound(sound'KFOldSchoolZeds_Sounds.Stab_Hit2', SLOT_Interact);
break;
case 2:
PlaySound(sound'KFOldSchoolZeds_Sounds.Stab_Hit3', SLOT_Interact);
}
}
function RangedAttack(Actor A)
{
super.RangedAttack(A);
if( !bShotAnim && !bDecapitated && VSize(A.Location-Location)<=700 )
GoToState('RunningState');
}
state RunningState
{
//Fixes slow charge for charging zeds
//Credits:NikC for forum link, aleat0r for the code
simulated function float GetOriginalGroundSpeed()
{
return 1.875 * OriginalGroundSpeed;
}
simulated function SetZappedBehavior()
{
Global.SetZappedBehavior();
GoToState('');
}
function bool CanSpeedAdjust()
{
return false;
}
//Dont play hit anims while charging so people don't complain about broken head hitboxes :)
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex){}
function BeginState()
{
if( bZapped )
GoToState('');
else
{
SetGroundSpeed(OriginalGroundSpeed * 1.875);
bRunning = true;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset.Z = 32;
OnlineHeadshotOffset.X = 32;
NetUpdateTime = Level.TimeSeconds - 1;
}
}
function EndState()
{
if( !bZapped )
SetGroundSpeed(GetOriginalGroundSpeed());
bRunning = false;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
NetUpdateTime = Level.TimeSeconds - 1;
}
function RemoveHead()
{
GoToState('');
Global.RemoveHead();
}
function RangedAttack(Actor A)
{
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( CanAttack(A) )
{
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
bShotAnim = true;
SetAnimAction('Claw');
Controller.bPreparingMove = true;
Acceleration = vect(0,0,0);
GoToState('');
return;
}
}
Begin:
GoTo('CheckCharge');
CheckCharge:
if( Controller!=none && Controller.Target!=none && VSize(Controller.Target.Location-Location)<700 )
{
Sleep(0.5+ FRand() * 0.5);
GoTo('CheckCharge');
}
else
GoToState('');
}
state RunningToMarker extends RunningState
{
Begin:
GoTo('CheckCharge');
CheckCharge:
if( bZedUnderControl || (Controller!=none && Controller.Target!=none && VSize(Controller.Target.Location-Location)<700) )
{
Sleep(0.5+ FRand() * 0.5);
GoTo('CheckCharge');
}
else
GoToState('');
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Gorefast.GorefastSkin');
}
defaultproperties
{
MeleeAnims(0)="GoreAttack1"
MeleeAnims(1)="GoreAttack2"
MeleeAnims(2)="GoreAttack1"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.GoreFast.GoreFast_Speech'
bCannibal=True
MeleeDamage=15
damageForce=5000
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
CrispUpThreshhold=8
bUseExtendedCollision=True
ColOffset=(Z=52.000000)
ColRadius=25.000000
ColHeight=10.000000
PlayerCountHealthScale=0.150000
OnlineHeadshotOffset=(X=16.000000,Y=-8.000000,Z=38.000000)
OnlineHeadshotScale=1.200000
MotionDetectorThreat=0.500000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=12
IdleHeavyAnim="GoreIdle"
IdleRifleAnim="GoreIdle"
MeleeRange=45.000000
GroundSpeed=120.000000
WaterSpeed=140.000000
HealthMax=250.000000
Health=250
HeadRadius=8.000000
HeadHeight=5.000000
MenuName="Gorefast 2.5"
ControllerClass=Class'KFOldSchoolZeds.ControllerGorefastOS'
MovementAnims(0)="GoreWalk"
WalkAnims(0)="GoreWalk"
WalkAnims(1)="GoreWalk"
WalkAnims(2)="GoreWalk"
WalkAnims(3)="GoreWalk"
IdleCrouchAnim="GoreIdle"
IdleWeaponAnim="GoreIdle"
IdleRestAnim="GoreIdle"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieBreath'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.GoreFast'
Skins(0)=Texture'KFOldSchoolZeds_Textures.GoreFast.GorefastSkin'
Mass=350.000000
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,632 @@
class ZombieRangedPoundOS extends KFMonsterOS;
var bool bFireAtWill,bMinigunning;
var float LastChainGunTime;
var vector TraceHitPos;
var Emitter mTracer,mMuzzleFlash;
var int MGFireCounter;
var bool bClientMiniGunning;
var float MGLostSightTimeout;
var() float MGDamage;
var() float MGAccuracy;
var() float MGFireRate;
var() int MGFireBurst;
var() float BurnDamageScale;
var() float MGFireInterval;
var bool bDisableIncendiaryRounds;
var bool bDisableIncendiaryResistance;
var () class <DamageType> MGDamageType;
replication
{
reliable if( Role==ROLE_Authority )
TraceHitPos,bMinigunning;
}
function vector ComputeTrajectoryByTime( vector StartPosition, vector EndPosition, float fTimeEnd )
{
local vector NewVelocity;
NewVelocity = super.ComputeTrajectoryByTime( StartPosition, EndPosition, fTimeEnd );
if( PhysicsVolume.IsA( 'KFPhysicsVolume' ) && StartPosition.Z < EndPosition.Z )
{
if( PhysicsVolume.Gravity.Z < class'PhysicsVolume'.default.Gravity.Z )
{
if( Mass > 900 )
{
NewVelocity.Z += 90;
}
}
}
return NewVelocity;
}
function bool CanGetOutOfWay()
{
return false;
}
function bool FlipOver()
{
if( Physics==PHYS_Falling )
{
SetPhysics(PHYS_Walking);
}
bShotAnim = true;
GoToState('');
SetAnimAction('RangedKnockDown');
HandleWaitForAnim('RangedKnockDown');
Acceleration = vect(0, 0, 0);
Velocity.X = 0;
Velocity.Y = 0;
KFMonsterController(Controller).Focus = none;
KFMonsterController(Controller).FocalPoint = KFMonsterController(Controller).LastSeenPos;
Controller.GoToState('WaitForAnim');
KFMonsterController(Controller).bUseFreezeHack = true;
return true;
}
simulated function PostBeginPlay()
{
if( Role < ROLE_Authority )
{
return;
}
if (Level.Game != none)
{
if( Level.Game.GameDifficulty < 2.0 )
{
BurnDamageScale = default.BurnDamageScale * 2.0;
MGFireInterval = default.MGFireInterval * 1.25;
MGDamage = default.MGDamage * 0.5;
MGAccuracy = default.MGAccuracy * 1.25;
MGFireBurst = default.MGFireBurst * 0.7;
MGFireRate = default.MGFireRate * 1.5;
}
else if( Level.Game.GameDifficulty < 4.0 )
{
BurnDamageScale = default.BurnDamageScale * 1.0;
MGFireInterval = default.MGFireInterval * 1;
MGDamage = default.MGDamage * 1.0;
MGAccuracy = default.MGAccuracy * 1.0;
MGFireBurst = default.MGFireBurst * 1.0;
MGFireRate = default.MGFireRate * 1.0;
}
else if( Level.Game.GameDifficulty < 5.0 )
{
BurnDamageScale = default.BurnDamageScale * 0.75;
MGFireInterval = default.MGFireInterval * 0.75;
MGDamage = default.MGDamage * 1.0;
MGAccuracy = default.MGAccuracy * 0.9;
MGFireBurst = default.MGFireBurst * 1.33;
MGFireRate = default.MGFireRate * 0.833333;
}
else
{
BurnDamageScale = default.BurnDamageScale * 0.5;
MGFireInterval = default.MGFireInterval * 0.6;
MGDamage = default.MGDamage * 1.0;
MGAccuracy = default.MGAccuracy * 0.80;
MGFireBurst = default.MGFireBurst * 1.67;
MGFireRate = default.MGFireRate * 0.68;
}
}
if(bDisableIncendiaryRounds)
MGDamageType=class'ZombieMeleeDamage';
super.PostBeginPlay();
}
simulated function bool HitCanInterruptAction()
{
if( bShotAnim )
{
return false;
}
return true;
}
simulated function Destroyed()
{
if( mTracer!=none )
mTracer.Destroy();
if( mMuzzleFlash!=none )
mMuzzleFlash.Destroy();
super.Destroyed();
}
simulated Function PostNetBeginPlay()
{
EnableChannelNotify ( 1,1);
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
super.PostNetBeginPlay();
TraceHitPos = vect(0,0,0);
bNetNotify = true;
}
function RangedAttack(Actor A)
{
local float Dist;
local int LastFireTime;
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 ( !bWaitForAnim && !bShotAnim && !bDecapitated && LastChainGunTime<Level.TimeSeconds )
{
if (!Controller.LineOfSightTo(A))
{
//Maybe lower this further?
LastChainGunTime = Level.TimeSeconds + MGFireInterval + (FRand() *1.0);
return;
}
LastChainGunTime = Level.TimeSeconds + MGFireInterval + (FRand() *2.0);
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedPreFireMG');
HandleWaitForAnim('RangedPreFireMG');
MGFireCounter = MGFireBurst;
GoToState('FireChaingun');
}
}
simulated function AddTraceHitFX( vector HitPos )
{
local vector Start,SpawnVel,SpawnDir;
local float hitDist;
PlaySound(sound'KFOldSchoolZeds_Sounds.MinigunFire',SLOT_Misc,2,,1400,0.9+FRand()*0.2);
Start = GetBoneCoords('FireBone').Origin;
if( mTracer==none )
mTracer = Spawn(class'KFMod.KFNewTracer',,,Start);
else mTracer.SetLocation(Start);
if( mMuzzleFlash==none )
{
mMuzzleFlash = Spawn(class'NewMinigunMFlashOS');
AttachToBone(mMuzzleFlash, 'FireBone');
}
else mMuzzleFlash.SpawnParticle(1);
hitDist = VSize(HitPos - Start) - 50.f;
if( hitDist>10 )
{
SpawnDir = Normal(HitPos - Start);
SpawnVel = SpawnDir * 10000.f;
mTracer.Emitters[0].StartVelocityRange.X.Min = SpawnVel.X;
mTracer.Emitters[0].StartVelocityRange.X.Max = SpawnVel.X;
mTracer.Emitters[0].StartVelocityRange.Y.Min = SpawnVel.Y;
mTracer.Emitters[0].StartVelocityRange.Y.Max = SpawnVel.Y;
mTracer.Emitters[0].StartVelocityRange.Z.Min = SpawnVel.Z;
mTracer.Emitters[0].StartVelocityRange.Z.Max = SpawnVel.Z;
mTracer.Emitters[0].LifetimeRange.Min = hitDist / 10000.f;
mTracer.Emitters[0].LifetimeRange.Max = mTracer.Emitters[0].LifetimeRange.Min;
mTracer.SpawnParticle(1);
}
Instigator = self;
if( HitPos != vect(0,0,0) )
{
Spawn(class'ROBulletHitEffect',,, HitPos, Rotator(Normal(HitPos - Start)));
}
}
simulated function AnimEnd( int Channel )
{
local name Sequence;
local float Frame, Rate;
if( Level.NetMode==NM_Client && bMinigunning )
{
GetAnimParams( Channel, Sequence, Frame, Rate );
if( Sequence != 'RangedPreFireMG' && Sequence != 'RangedFireMG' )
{
super.AnimEnd(Channel);
return;
}
PlayAnim('RangedFireMG');
bWaitForAnim = true;
bShotAnim = true;
IdleTime = Level.TimeSeconds;
}
else super.AnimEnd(Channel);
}
state FireChaingun
{
function RangedAttack(Actor A)
{
Controller.Target = A;
Controller.Focus = A;
}
function EndState()
{
TraceHitPos = vect(0,0,0);
bMinigunning = false;
AmbientSound = default.AmbientSound;
SoundVolume=default.SoundVolume;
SoundRadius=default.SoundRadius;
MGFireCounter=0;
LastChainGunTime = Level.TimeSeconds + MGFireInterval + (FRand() *2.0);
}
function BeginState()
{
bFireAtWill = false;
Acceleration = vect(0,0,0);
MGLostSightTimeout = 0.0;
bMinigunning = true;
}
function AnimEnd( int Channel )
{
if( MGFireCounter <= 0 )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMGEnd');
HandleWaitForAnim('RangedFireMGEnd');
GoToState('');
}
else
{
if ( Controller.Enemy != none )
{
if ( Controller.LineOfSightTo(Controller.Enemy) && FastTrace(GetBoneCoords('FireBone').Origin,Controller.Enemy.Location))
{
MGLostSightTimeout = 0.0;
Controller.Focus = Controller.Enemy;
Controller.FocalPoint = Controller.Enemy.Location;
}
else
{
MGLostSightTimeout = Level.TimeSeconds + (0.25 + FRand() * 0.35);
Controller.Focus = none;
}
Controller.Target = Controller.Enemy;
}
else
{
MGLostSightTimeout = Level.TimeSeconds + (0.25 + FRand() * 0.35);
Controller.Focus = none;
}
if ( FRand() < 0.03 && Controller.Enemy != none && PlayerController(Controller.Enemy.Controller) != none )
{
PlayerController(Controller.Enemy.Controller).Speech('AUTO', 9, "");
}
bFireAtWill = true;
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMG');
bWaitForAnim = true;
}
}
function FireMGShot()
{
local vector Start,End,HL,HN,Dir;
local rotator R;
local Actor A;
local KFPawn KFP;
local float Dist;
KFP = KFPawn(Controller.Target);
Dist = VSize(Controller.Target.Location-Location);
MGFireCounter--;
Start = GetBoneCoords('FireBone').Origin;
if( Controller.Focus!=none )
R = rotator(Controller.Focus.Location-Start);
else R = rotator(Controller.FocalPoint-Start);
if( NeedToTurnFor(R) )
R = Rotation;
Dir = Normal(vector(R)+VRand()*MGAccuracy);
End = Start+Dir*10000;
bBlockHitPointTraces = false;
A = Trace(HL,HN,End,Start,true);
bBlockHitPointTraces = true;
if( A==none )
return;
TraceHitPos = HL;
if( Level.NetMode!=NM_DedicatedServer )
AddTraceHitFX(HL);
if( A!=Level && ( A == KFPawn(A) || A == KFGlassMover(A) || A == KFDoorMover(A)) )
{
// This spams server logs with "Accessed None PlayerReplicationInfo"
if(KFPlayerReplicationInfo(KFP.PlayerReplicationInfo).ClientVeteranSkill != class'KFVetBerserker')
A.TakeDamage(MGDamage,self,HL,Dir*500,MGDamageType);
else
A.TakeDamage((MGDamage + 1),self,HL,Dir*500,MGDamageType);
}
else return;
}
function bool NeedToTurnFor( rotator targ )
{
local int YawErr;
targ.Yaw = DesiredRotation.Yaw & 65535;
YawErr = (targ.Yaw - (Rotation.Yaw & 65535)) & 65535;
return !((YawErr < 2000) || (YawErr > 64535));
}
Begin:
While( true )
{
Acceleration = vect(0,0,0);
if( MGLostSightTimeout > 0 && Level.TimeSeconds > MGLostSightTimeout )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMGEnd');
HandleWaitForAnim('RangedFireMGEnd');
GoToState('');
}
if( MGFireCounter <= 0 )
{
bShotAnim = true;
Acceleration = vect(0,0,0);
SetAnimAction('RangedFireMGEnd');
HandleWaitForAnim('RangedFireMGEnd');
GoToState('');
}
if( bFireAtWill )
FireMGShot();
Sleep(MGFireRate);
}
}
simulated function PostNetReceive()
{
if( bClientMiniGunning != bMinigunning )
{
bClientMiniGunning = bMinigunning;
if( bMinigunning )
{
IdleHeavyAnim='RangedFireMG';
IdleRifleAnim='RangedFireMG';
IdleCrouchAnim='RangedFireMG';
IdleWeaponAnim='RangedFireMG';
IdleRestAnim='RangedFireMG';
}
else
{
IdleHeavyAnim='RangedIdle';
IdleRifleAnim='RangedIdle';
IdleCrouchAnim='RangedIdle';
IdleWeaponAnim='RangedIdle';
IdleRestAnim='RangedIdle';
}
}
if( TraceHitPos!=vect(0,0,0) )
{
AddTraceHitFX(TraceHitPos);
TraceHitPos = vect(0,0,0);
}
}
simulated function int DoAnimAction( name AnimName )
{
if(AnimName=='PoundPunch2' || AnimName=='RangedHitF')
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(AnimName,, 0.0, 1);
return 1;
}
return super.DoAnimAction(AnimName);
}
simulated event SetAnimAction(name NewAction)
{
local int meleeAnimIndex;
if( NewAction=='' )
return;
if(NewAction == 'Claw')
{
meleeAnimIndex = Rand(3);
NewAction = meleeAnims[meleeAnimIndex];
CurrentDamtype = ZombieDamType[meleeAnimIndex];
}
ExpectingChannel = DoAnimAction(NewAction);
if( Controller != none )
{
ControllerRangedPoundOS(Controller).AnimWaitChannel = ExpectingChannel;
}
if( AnimNeedsWait(NewAction) )
{
bWaitForAnim = true;
}
else
{
bWaitForAnim = false;
}
if( Level.NetMode!=NM_Client )
{
AnimAction = NewAction;
bResetAnimAct = true;
ResetAnimActTime = Level.TimeSeconds+0.3;
}
}
simulated function HandleWaitForAnim( name NewAnim )
{
local float RageAnimDur;
Controller.GoToState('WaitForAnim');
RageAnimDur = GetAnimDuration(NewAnim);
ControllerRangedPoundOS(Controller).SetWaitForAnimTimout(RageAnimDur,NewAnim);
}
simulated function bool AnimNeedsWait(name TestAnim)
{
if( TestAnim == 'RangedFireMG' || TestAnim == 'RangedPreFireMG' || TestAnim == 'RangedFireMGEnd' || TestAnim == 'RangedKnockDown')
{
return true;
}
return false;
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
if ((DamageType == class 'DamTypeBurned' || DamageType == class 'DamTypeFlamethrower') && !bDisableIncendiaryResistance)
{
Damage *= BurnDamageScale;
}
super.TakeDamage(Damage,instigatedBy,hitlocation,momentum,damageType,HitIndex);
}
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex)
{
if(LastChainGunTime<Level.TimeSeconds + 1)
return;
else
super.OldPlayHit(Damage,InstigatedBy,HitLocation,damageType,Momentum,HitIndex);
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.GunPound.AutoTurretGunTex');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.GunPound.GunPoundSkin');
}
defaultproperties
{
MGDamage=2.000000
MGAccuracy=0.040000
MGFireRate=0.060000
MGFireBurst=15
BurnDamageScale=0.250000
MGFireInterval=5.500000
MGDamageType=Class'KFMod.DamTypeBurned'
MeleeAnims(0)="PoundPunch2"
MeleeAnims(1)="PoundPunch2"
MeleeAnims(2)="PoundPunch2"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Fleshpound.Fleshpound_Speech'
BleedOutDuration=6.000000
ZapThreshold=0.750000
bHarpoonToBodyStuns=False
ZombieFlag=1
MeleeDamage=15
damageForce=70000
bFatAss=True
KFRagdollName="FleshPoundRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
Intelligence=BRAINS_Mammal
bUseExtendedCollision=True
ColOffset=(Z=65.000000)
ColRadius=27.000000
ColHeight=25.000000
PlayerCountHealthScale=0.100000
BurningWalkFAnims(0)="RangedWalkF"
BurningWalkFAnims(1)="RangedWalkF"
BurningWalkFAnims(2)="RangedWalkF"
BurningWalkAnims(0)="RangedWalkF"
BurningWalkAnims(1)="RangedWalkF"
BurningWalkAnims(2)="RangedWalkF"
OnlineHeadshotOffset=(X=5.000000,Y=7.000000,Z=71.000000)
OnlineHeadshotScale=1.200000
HeadHealth=200.000000
PlayerNumHeadHealthScale=0.050000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=17
IdleHeavyAnim="RangedIdle"
IdleRifleAnim="RangedIdle"
MeleeRange=30.000000
GroundSpeed=115.000000
WaterSpeed=102.000000
HealthMax=600.000000
Health=600
HeadRadius=8.750000
HeadHeight=11.000000
MenuName="Flesh Pound Chaingunner"
ControllerClass=Class'KFOldSchoolZeds.ControllerRangedPoundOS'
MovementAnims(0)="RangedWalkF"
MovementAnims(1)="RangedWalkF"
MovementAnims(2)="RangedWalkF"
MovementAnims(3)="RangedWalkF"
TurnLeftAnim="RangedBossHitF"
TurnRightAnim="RangedBossHitF"
WalkAnims(0)="RangedWalkF"
WalkAnims(1)="RangedWalkF"
WalkAnims(2)="RangedWalkF"
WalkAnims(3)="RangedWalkF"
AirAnims(0)="RangedJumpInAir"
AirAnims(1)="RangedJumpInAir"
AirAnims(2)="RangedJumpInAir"
AirAnims(3)="RangedJumpInAir"
TakeoffAnims(0)="RangedJumpTakeOff"
TakeoffAnims(1)="RangedJumpTakeOff"
TakeoffAnims(2)="RangedJumpTakeOff"
TakeoffAnims(3)="RangedJumpTakeOff"
LandAnims(0)="RangedJumpLanded"
LandAnims(1)="RangedJumpLanded"
LandAnims(2)="RangedJumpLanded"
LandAnims(3)="RangedJumpLanded"
AirStillAnim="RangedJumpInAir"
TakeoffStillAnim="RangedJumpTakeOff"
IdleCrouchAnim="RangedIdle"
IdleWeaponAnim="RangedIdle"
IdleRestAnim="RangedIdle"
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.RangedPound'
PrePivot=(Z=0.000000)
Skins(0)=Shader'KFOldSchoolZeds_Textures.Fleshpound.PoundBitsShader'
Skins(1)=Texture'KFOldSchoolZeds_Textures.Gunpound.AutoTurretGunTex'
Skins(2)=Texture'KFOldSchoolZeds_Textures.Gunpound.GunPoundSkin'
Mass=400.000000
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,409 @@
class ZombieScrakeOS extends KFMonsterOS;
var bool bCharging;
var float DistBeforeSaw;
var bool bEnableOldScrakeBehavior;
replication
{
reliable if(Role == ROLE_Authority)
bCharging;
}
simulated function PostNetBeginPlay()
{
EnableChannelNotify ( 1,1);
AnimBlendParams(1, 1.0, 0.0,, SpineBone1);
super.PostNetBeginPlay();
}
simulated function PostNetReceive()
{
if (bCharging)
MovementAnims[0]='ZombieRun';
else if( !(bCrispified && bBurnified) )
MovementAnims[0]=default.MovementAnims[0];
}
// This zed has been taken control of. Boost its health and speed
function SetMindControlled(bool bNewMindControlled)
{
if( bNewMindControlled )
{
NumZCDHits++;
// if we hit him a couple of times, make him rage!
if( NumZCDHits > 1 )
{
if( !IsInState('ChargeToMarker') )
{
GotoState('ChargeToMarker');
}
else
{
NumZCDHits = 1;
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
}
else
{
if( IsInState('ChargeToMarker') )
{
GotoState('');
}
}
if( bNewMindControlled != bZedUnderControl )
{
SetGroundSpeed(OriginalGroundSpeed * 1.25);
Health *= 1.25;
HealthMax *= 1.25;
}
}
else
{
NumZCDHits=0;
}
bZedUnderControl = bNewMindControlled;
}
// Handle the zed being commanded to move to a new location
function GivenNewMarker()
{
if( bCharging && NumZCDHits > 1 )
{
GotoState('ChargeToMarker');
}
else
{
GotoState('');
}
}
simulated function SetBurningBehavior()
{
if( Role == Role_Authority && IsInState('RunningState') )
{
super.SetBurningBehavior();
GotoState('');
}
super.SetBurningBehavior();
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < (MeleeRange - DistBeforeSaw + CollisionRadius + A.CollisionRadius) && CanAttack(A) )
{
//Reset to default when you swing
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
bShotAnim = true;
SetAnimAction(MeleeAnims[Rand(2)]);
CurrentDamType = ZombieDamType[0];
PlaySound(sound'Claw2s', SLOT_None);
GoToState('SawingLoop');
}
if(AnimAction == MeleeAnims[0])
MeleeDamage = Max( (DifficultyDamageModifer() * default.MeleeDamage * 0.85), 1 );
else if(AnimAction == MeleeAnims[1])
MeleeDamage = Max( (DifficultyDamageModifer() * default.MeleeDamage * 1.15), 1 );
if( !bShotAnim && !bDecapitated && !bEnableOldScrakeBehavior )
{
if ( Level.Game.GameDifficulty < 5.0 )
{
if ( float(Health)/HealthMax < 0.5 )
GoToState('RunningState');
}
else
{
if ( float(Health)/HealthMax < 0.75 )
GoToState('RunningState');
}
}
}
state RunningState
{
//Fixes slow charge for charging zeds
//Credits:NikC for forum link, aleat0r for the code
simulated function float GetOriginalGroundSpeed()
{
return 3.5 * OriginalGroundSpeed;
}
simulated function SetZappedBehavior()
{
Global.SetZappedBehavior();
GoToState('');
}
function bool CanSpeedAdjust()
{
return false;
}
//Dont play hit anims while charging so people don't complain about broken head hitboxes :)
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex){}
function BeginState()
{
if( bZapped )
GoToState('');
else
{
SetGroundSpeed(OriginalGroundSpeed * 3.5);
bCharging = true;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset.Z = 41;
OnlineHeadshotOffset.X = 30;
OnlineHeadshotOffset.Y = -10;
NetUpdateTime = Level.TimeSeconds - 1;
}
}
function EndState()
{
if( !bZapped )
SetGroundSpeed(GetOriginalGroundSpeed());
bCharging = false;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
}
function RemoveHead()
{
GoToState('');
Global.RemoveHead();
}
function RangedAttack(Actor A)
{
local float Dist;
Dist = VSize(A.Location - Location);
DistBeforeSaw = 20.0;
if ( bShotAnim || Physics == PHYS_Swimming)
return;
else if ( Dist < (MeleeRange - DistBeforeSaw + CollisionRadius + A.CollisionRadius) && CanAttack(A) )
{
bShotAnim = true;
if(Level.Game.GameDifficulty < 5.0)
SetAnimAction(MeleeAnims[Rand(2)]);
else
SetAnimAction(MeleeAnims[0]);
CurrentDamType = ZombieDamType[0];
GoToState('SawingLoop');
OnlineHeadshotOffset = default.OnlineHeadshotOffset;
}
}
}
state RunningToMarker extends RunningState
{
}
State SawingLoop
{
function bool CanSpeedAdjust()
{
return false;
}
function RangedAttack(Actor A)
{
if ( bShotAnim )
return;
else if ( CanAttack(A) )
{
Acceleration = vect(0,0,0);
bShotAnim = true;
MeleeDamage = default.MeleeDamage*0.6;
SetAnimAction('SawImpaleLoop');
CurrentDamType = ZombieDamType[0];
}
else GoToState('');
}
function AnimEnd( int Channel )
{
super.AnimEnd(Channel);
if( Controller!=none && Controller.Enemy!=none )
RangedAttack(Controller.Enemy);
}
function EndState()
{
MeleeDamage = Max( DifficultyDamageModifer() * default.MeleeDamage, 1 );
SetGroundSpeed(GetOriginalGroundSpeed());
bCharging = false;
if( Level.NetMode!=NM_DedicatedServer )
PostNetReceive();
}
}
function TakeDamage( int Damage, Pawn InstigatedBy, Vector Hitlocation, Vector Momentum, class<DamageType> damageType, optional int HitIndex)
{
local bool bIsHeadShot;
bIsHeadShot = IsHeadShot(Hitlocation, normal(Momentum), 1.0);
if ( Level.Game.GameDifficulty >= 5.0 && bIsHeadshot && (class<DamTypeCrossbow>(damageType) != none || class<DamTypeCrossbowHeadShot>(damageType) != none) )
{
Damage *= 0.5;
}
super.takeDamage(Damage, instigatedBy, hitLocation, momentum, damageType, HitIndex);
if ( Level.Game.GameDifficulty >= 5.0 && !IsInState('SawingLoop') && !IsInState('RunningState') && float(Health) / HealthMax < 0.75 )
RangedAttack(InstigatedBy);
}
function PlayTakeHit(vector HitLocation, int Damage, class<DamageType> DamageType)
{
super(ZombieScrake).PlayTakeHit(HitLocation,Damage,DamageType);
}
simulated function int DoAnimAction( name AnimName )
{
if( AnimName=='SawZombieAttack1' || AnimName=='SawZombieAttack2' /*|| AnimName=='SawImpaleLoop' */)
{
AnimBlendParams(1, 1.0, 0.0,, 'Bip01 Spine1');
PlayAnim(AnimName,, 0.0, 1);
return 1;
}
return super.DoAnimAction(AnimName);
}
simulated event SetAnimAction(name NewAction)
{
local int meleeAnimIndex;
if( NewAction=='' )
return;
if(NewAction == 'Claw')
{
meleeAnimIndex = Rand(3);
NewAction = meleeAnims[meleeAnimIndex];
CurrentDamtype = ZombieDamType[meleeAnimIndex];
}
ExpectingChannel = DoAnimAction(NewAction);
if( AnimNeedsWait(NewAction) )
bWaitForAnim = true;
if( Level.NetMode!=NM_Client )
{
AnimAction = NewAction;
bResetAnimAct = true;
ResetAnimActTime = Level.TimeSeconds+0.3;
}
}
simulated function bool AnimNeedsWait(name TestAnim)
{
if( TestAnim == 'SawImpaleLoop' || TestAnim == 'DoorBash' || TestAnim == 'KnockDown' )
return true;
return false;
}
simulated function SpawnGibs(Rotator HitRotation, float ChunkPerterbation)
{
super.SpawnGibs(HitRotation,ChunkPerterbation);
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeSkin');
myLevel.AddPrecacheMaterial(TexOscillator'KFOldSchoolZeds_Textures.Scrake.SawChainOSC');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeFrockSkin');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeSawSkin');
}
defaultproperties
{
MeleeAnims(0)="SawZombieAttack1"
MeleeAnims(1)="SawZombieAttack2"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Scrake.Scrake_Speech'
BleedOutDuration=6.000000
bCannibal=True
ZapThreshold=1.250000
ZappedDamageMod=1.250000
bHarpoonToBodyStuns=False
DamageToMonsterScale=8.000000
ZombieFlag=3
MeleeDamage=20
damageForce=-100000
bFatAss=True
KFRagdollName="FleshPoundRag"
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Male_ZombieJump'
bMeleeStunImmune=True
Intelligence=BRAINS_Mammal
bUseExtendedCollision=True
ColOffset=(Z=55.000000)
ColRadius=29.000000
ColHeight=18.000000
PlayerCountHealthScale=0.500000
PoundRageBumpDamScale=0.010000
OnlineHeadshotOffset=(X=10.000000,Y=-7.000000,Z=58.000000)
OnlineHeadshotScale=1.200000
HeadHealth=650.000000
PlayerNumHeadHealthScale=0.300000
MotionDetectorThreat=3.000000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombiePain'
DeathSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Male_ZombieDeath'
ScoringValue=75
IdleHeavyAnim="SawZombieIdle"
IdleRifleAnim="SawZombieIdle"
MeleeRange=60.000000
GroundSpeed=85.000000
WaterSpeed=75.000000
HealthMax=1000.000000
Health=1000
HeadRadius=8.000000
HeadHeight=6.000000
AmbientSoundScaling=5.000000
MenuName="Scrake 2.5"
ControllerClass=Class'KFOldSchoolZeds.ControllerScrakeOS'
MovementAnims(0)="SawZombieWalk"
MovementAnims(1)="SawZombieWalk"
MovementAnims(2)="SawZombieWalk"
MovementAnims(3)="SawZombieWalk"
WalkAnims(0)="SawZombieWalk"
WalkAnims(1)="SawZombieWalk"
WalkAnims(2)="SawZombieWalk"
WalkAnims(3)="SawZombieWalk"
IdleCrouchAnim="SawZombieIdle"
IdleWeaponAnim="SawZombieIdle"
IdleRestAnim="SawZombieIdle"
AmbientSound=Sound'KFOldSchoolZeds_Sounds.Scrake.Saw_Idle'
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.SawZombie'
PrePivot=(Z=0.000000)
Skins(0)=Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeSkin'
Skins(1)=TexOscillator'KFOldSchoolZeds_Textures.Scrake.SawChainOSC'
Skins(2)=Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeFrockSkin'
Skins(3)=Texture'KFOldSchoolZeds_Textures.Scrake.ScrakeSawSkin'
SoundRadius=200.000000
Mass=500.000000
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,303 @@
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)
}

View file

@ -0,0 +1,315 @@
class ZombieStalkerOS extends KFMonsterOS;
var bool bCloaking;
var float NextCheckTime;
simulated event SetAnimAction(name NewAction)
{
if ( NewAction == 'Claw' || NewAction == MeleeAnims[0] || NewAction == MeleeAnims[1] || NewAction == MeleeAnims[2] )
{
UncloakStalker();
}
super.SetAnimAction(NewAction);
}
simulated function Tick(float DeltaTime)
{
Local KFHumanPawn HP;
super.Tick(DeltaTime);
if( Level.NetMode==NM_DedicatedServer )
return;
if( bZapped )
{
NextCheckTime = Level.TimeSeconds;
}
else if( Level.TimeSeconds > NextCheckTime && Health > 0 )
{
NextCheckTime = Level.TimeSeconds + 0.8;
//We need GetStalkerViewDistanceMulti here later
ForEach VisibleCollidingActors(class'KFHumanPawn',HP,800,Location)
{
if( HP.Health<=0 || !HP.ShowStalkers() )
continue;
if( !bSpotted )
{
bSpotted = true;
Skins[0] = Finalblend 'KFOldSchoolZeds_Textures.StalkerGlowFB';
Skins[1] = Finalblend 'KFOldSchoolZeds_Textures.StalkerGlowFB';
}
return;
}
if( bSpotted )
{
bSpotted = false;
bUnlit = false;
CloakStalker();
}
}
}
// You can have this because you're invisible and annoying to headshot
function OldPlayHit(float Damage, Pawn InstigatedBy, vector HitLocation, class<DamageType> damageType, vector Momentum, optional int HitIndex)
{
if(!bShotAnim)
return;
else
super.OldPlayHit(Damage,InstigatedBy,hitlocation,damageType,momentum,HitIndex);
}
simulated function CloakStalker()
{
if( bZapped )
{
return;
}
if ( bSpotted && !bDecapitated )
{
if( Level.NetMode == NM_DedicatedServer )
return;
Skins[0] = Finalblend 'KFOldSchoolZeds_Textures.StalkerGlowFB';
Skins[1] = Finalblend 'KFOldSchoolZeds_Textures.StalkerGlowFB';
bUnlit = true;
return;
}
if ( !bDecapitated && !bCrispified && !bCloaked)
{
Visibility = 1;
bCloaked = true;
if( Level.NetMode == NM_DedicatedServer )
return;
Skins[0] = Shader 'KFOldSchoolZeds_Textures.StalkerHairShader';
Skins[1] = Shader 'KFOldSchoolZeds_Textures.StalkerCloakShader';
if(PlayerShadow != none)
PlayerShadow.bShadowActive = false;
if(RealTimeShadow != none)
RealTimeShadow.Destroy();
Projectors.Remove(0, Projectors.Length);
bAcceptsProjectors = false;
SetOverlayMaterial(Material'KFOldSchoolZeds_Textures.StalkerDeCloakfb', 0.25, true);
}
}
simulated function UnCloakStalker()
{
if( bZapped )
{
return;
}
if( !bCrispified )
{
Visibility = default.Visibility;
bCloaked = false;
bUnlit = false;
if( Level.NetMode!=NM_Client && !KFGameType(Level.Game).bDidStalkerInvisibleMessage && FRand()<0.25 && Controller.Enemy!=none &&
PlayerController(Controller.Enemy.Controller)!=none )
{
PlayerController(Controller.Enemy.Controller).Speech('AUTO', 17, "");
KFGameType(Level.Game).bDidStalkerInvisibleMessage = true;
}
if( Level.NetMode == NM_DedicatedServer )
return;
Skins[1] = FinalBlend'KFOldSchoolZeds_Textures.StalkerHairFB';
Skins[0] = Texture'KFOldSchoolZeds_Textures.StalkerSkin';
if (PlayerShadow != none)
PlayerShadow.bShadowActive = true;
bAcceptsProjectors = true;
SetOverlayMaterial(Material'KFOldSchoolZeds_Textures.StalkerDeCloakfb', 0.25, true);
}
}
simulated function SetZappedBehavior()
{
super.SetZappedBehavior();
bUnlit = false;
if( Level.Netmode != NM_DedicatedServer )
{
Skins[1] = FinalBlend'KFOldSchoolZeds_Textures.StalkerHairFB';
Skins[0] = Texture'KFOldSchoolZeds_Textures.StalkerSkin';
if (PlayerShadow != none)
PlayerShadow.bShadowActive = true;
bAcceptsProjectors = true;
SetOverlayMaterial(Material'KFZED_FX_T.Energy.ZED_overlay_Hit_Shdr', 999, true);
}
}
simulated function UnSetZappedBehavior()
{
super.UnSetZappedBehavior();
if( Level.Netmode != NM_DedicatedServer )
{
NextCheckTime = Level.TimeSeconds;
SetOverlayMaterial(none, 0.0f, true);
}
}
function SetZapped(float ZapAmount, Pawn Instigator)
{
LastZapTime = Level.TimeSeconds;
if( bZapped )
{
TotalZap = ZapThreshold;
RemainingZap = ZapDuration;
}
else
{
TotalZap += ZapAmount;
if( TotalZap >= ZapThreshold )
{
RemainingZap = ZapDuration;
bZapped = true;
}
}
ZappedBy = Instigator;
}
function RemoveHead()
{
super.RemoveHead();
if (!bCrispified)
{
Skins[1] = FinalBlend'KFOldSchoolZeds_Textures.StalkerHairFB';
Skins[0] = Texture'KFOldSchoolZeds_Textures.StalkerSkin';
}
}
simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
{
super.PlayDying(DamageType,HitLoc);
if(bUnlit)
bUnlit=!bUnlit;
if (!bCrispified)
{
Skins[1] = FinalBlend'KFOldSchoolZeds_Textures.StalkerHairFB';
Skins[0] = Texture'KFOldSchoolZeds_Textures.StalkerSkin';
}
}
function bool DoJump( bool bUpdating )
{
if ( !bIsCrouched && !bWantsToCrouch && ((Physics == PHYS_Walking) || (Physics == PHYS_Ladder) || (Physics == PHYS_Spider)) )
{
if ( Role == ROLE_Authority )
{
if ( (Level.Game != none) && (Level.Game.GameDifficulty > 2) )
MakeNoise(0.1 * Level.Game.GameDifficulty);
if ( bCountJumps && (Inventory != none) )
Inventory.OwnerEvent('Jumped');
}
if ( Physics == PHYS_Spider )
Velocity = JumpZ * Floor;
else if ( Physics == PHYS_Ladder )
Velocity.Z = 0;
else if ( bIsWalking )
{
Velocity.Z = default.JumpZ;
Velocity.X = (default.JumpZ * 0.6);
}
else
{
Velocity.Z = JumpZ;
Velocity.X = (JumpZ * 0.6);
}
if ( (Base != none) && !Base.bWorldGeometry )
{
Velocity.Z += Base.Velocity.Z;
Velocity.X += Base.Velocity.X;
}
SetPhysics(PHYS_Falling);
return true;
}
return false;
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.StalkerHairShader');
myLevel.AddPrecacheMaterial(Shader'KFOldSchoolZeds_Textures.StalkerCloakShader');
myLevel.AddPrecacheMaterial(Finalblend 'KFOldSchoolZeds_Textures.StalkerGlowFB');
myLevel.AddPrecacheMaterial(Material'KFOldSchoolZeds_Textures.StalkerDeCloakfb');
myLevel.AddPrecacheMaterial(Texture'KFOldSchoolZeds_Textures.StalkerSkin');
myLevel.AddPrecacheMaterial(FinalBlend 'KFOldSchoolZeds_Textures.StalkerHairFB');
}
defaultproperties
{
MeleeAnims(0)="StalkerSpinAttack"
MeleeAnims(1)="StalkerAttack1"
MeleeAnims(2)="JumpAttack"
MoanVoice=SoundGroup'KFOldSchoolZeds_Sounds.Stalker.Stalker_Speech'
bCannibal=True
MeleeDamage=9
damageForce=5000
ZombieDamType(0)=Class'KFMod.DamTypeSlashingAttack'
ZombieDamType(1)=Class'KFMod.DamTypeSlashingAttack'
ZombieDamType(2)=Class'KFMod.DamTypeSlashingAttack'
JumpSound=Sound'KFOldSchoolZeds_Sounds.Shared.Female_ZombieJump'
CrispUpThreshhold=10
PuntAnim="ClotPunt"
bUseExtendedCollision=True
ColOffset=(Z=48.000000)
ColRadius=25.000000
ColHeight=5.000000
OnlineHeadshotOffset=(X=19.000000,Y=-7.000000,Z=25.000000)
OnlineHeadshotScale=1.200000
MotionDetectorThreat=0.250000
HitSound(0)=SoundGroup'KFOldSchoolZeds_Sounds.Shared.Female_ZombiePain'
DeathSound(0)=Sound'KFOldSchoolZeds_Sounds.Stalker.Stalker_Death'
ScoringValue=15
SoundGroupClass=Class'KFOldSchoolZeds.KFFemaleZombieSoundsOS'
IdleHeavyAnim="StalkerIdle"
IdleRifleAnim="StalkerIdle"
MeleeRange=30.000000
GroundSpeed=200.000000
WaterSpeed=180.000000
JumpZ=350.000000
Health=100
MenuName="Stalker 2.5"
MovementAnims(0)="ZombieRun"
MovementAnims(1)="ZombieRun"
MovementAnims(2)="ZombieRun"
MovementAnims(3)="ZombieRun"
WalkAnims(0)="ZombieRun"
WalkAnims(1)="ZombieRun"
WalkAnims(2)="ZombieRun"
WalkAnims(3)="ZombieRun"
IdleCrouchAnim="StalkerIdle"
IdleWeaponAnim="StalkerIdle"
IdleRestAnim="StalkerIdle"
Mesh=SkeletalMesh'KFCharacterModelsOldSchool.InfectedWhiteFemale'
Skins(0)=Shader'KFOldSchoolZeds_Textures.Stalker.StalkerHairShader'
Skins(1)=Shader'KFOldSchoolZeds_Textures.Stalker.StalkerCloakShader'
RotationRate=(Yaw=45000,Roll=0)
}

View file

@ -0,0 +1,72 @@
<html>
<head><title>Index of /kf_sources/KFOldSchoolZeds/Classes/</title></head>
<body>
<h1>Index of /kf_sources/KFOldSchoolZeds/Classes/</h1><hr><pre><a href="../">../</a>
<a href="BileExplosionOS.uc">BileExplosionOS.uc</a> 10-Sep-2022 21:09 2257
<a href="BileJetOS.uc">BileJetOS.uc</a> 10-Sep-2022 21:09 1042
<a href="BioDecalOS.uc">BioDecalOS.uc</a> 10-Sep-2022 21:09 557
<a href="BloodJetOS.uc">BloodJetOS.uc</a> 10-Sep-2022 21:09 298
<a href="BloodSplatterOS.uc">BloodSplatterOS.uc</a> 10-Sep-2022 21:09 731
<a href="BloodSpurtOS.uc">BloodSpurtOS.uc</a> 10-Sep-2022 21:09 2412
<a href="BodySplashOS.uc">BodySplashOS.uc</a> 10-Sep-2022 21:09 151
<a href="BossLAWProjOS.uc">BossLAWProjOS.uc</a> 10-Sep-2022 21:09 435
<a href="BrainSplashOS.uc">BrainSplashOS.uc</a> 10-Sep-2022 21:09 211
<a href="ClientExtendedZCollision.uc">ClientExtendedZCollision.uc</a> 10-Sep-2022 21:09 412
<a href="ClotGibArmOS.uc">ClotGibArmOS.uc</a> 10-Sep-2022 21:09 616
<a href="ClotGibHeadOS.uc">ClotGibHeadOS.uc</a> 10-Sep-2022 21:09 619
<a href="ClotGibLegOS.uc">ClotGibLegOS.uc</a> 10-Sep-2022 21:09 616
<a href="ClotGibLowerTorsoOS.uc">ClotGibLowerTorsoOS.uc</a> 10-Sep-2022 21:09 637
<a href="ClotGibThighOS.uc">ClotGibThighOS.uc</a> 10-Sep-2022 21:09 622
<a href="ClotGibTorsoOS.uc">ClotGibTorsoOS.uc</a> 10-Sep-2022 21:09 622
<a href="ControllerBossOS.uc">ControllerBossOS.uc</a> 10-Sep-2022 21:09 8524
<a href="ControllerCrawlerOS.uc">ControllerCrawlerOS.uc</a> 10-Sep-2022 21:09 2703
<a href="ControllerExplosivePound.uc">ControllerExplosivePound.uc</a> 10-Sep-2022 21:09 4566
<a href="ControllerFleshpoundOS.uc">ControllerFleshpoundOS.uc</a> 10-Sep-2022 21:09 4792
<a href="ControllerGorefastOS.uc">ControllerGorefastOS.uc</a> 10-Sep-2022 21:09 1559
<a href="ControllerRangedPoundOS.uc">ControllerRangedPoundOS.uc</a> 10-Sep-2022 21:09 2990
<a href="ControllerScrakeOS.uc">ControllerScrakeOS.uc</a> 10-Sep-2022 21:09 2186
<a href="ControllerSirenOS.uc">ControllerSirenOS.uc</a> 10-Sep-2022 21:09 695
<a href="DamTypeVomitOS.uc">DamTypeVomitOS.uc</a> 10-Sep-2022 21:09 277
<a href="DebugHeadHitbox.uc">DebugHeadHitbox.uc</a> 10-Sep-2022 21:09 1630
<a href="FleshHitEmitterOS.uc">FleshHitEmitterOS.uc</a> 10-Sep-2022 21:09 2433
<a href="GibExplosionOS.uc">GibExplosionOS.uc</a> 10-Sep-2022 21:09 1877
<a href="GibHeadStumpOS.uc">GibHeadStumpOS.uc</a> 10-Sep-2022 21:09 704
<a href="GunnerGLProjectile.uc">GunnerGLProjectile.uc</a> 10-Sep-2022 21:09 4836
<a href="KF25OSMut.uc">KF25OSMut.uc</a> 10-Sep-2022 21:09 14200
<a href="KFBloatVomitOS.uc">KFBloatVomitOS.uc</a> 10-Sep-2022 21:09 5819
<a href="KFBloodPuffOS.uc">KFBloodPuffOS.uc</a> 10-Sep-2022 21:09 995
<a href="KFBloodSplatterDecalOS.uc">KFBloodSplatterDecalOS.uc</a> 10-Sep-2022 21:09 593
<a href="KFBloodStreakDecalOS.uc">KFBloodStreakDecalOS.uc</a> 10-Sep-2022 21:09 599
<a href="KFFemaleZombieSoundsOS.uc">KFFemaleZombieSoundsOS.uc</a> 10-Sep-2022 21:09 1006
<a href="KFGibBrainOS.uc">KFGibBrainOS.uc</a> 10-Sep-2022 21:09 546
<a href="KFGibBrainbOS.uc">KFGibBrainbOS.uc</a> 10-Sep-2022 21:09 547
<a href="KFGibHeadOS.uc">KFGibHeadOS.uc</a> 10-Sep-2022 21:09 520
<a href="KFGibHeadbOS.uc">KFGibHeadbOS.uc</a> 10-Sep-2022 21:09 521
<a href="KFGibJetOS.uc">KFGibJetOS.uc</a> 10-Sep-2022 21:09 415
<a href="KFGibOS.uc">KFGibOS.uc</a> 10-Sep-2022 21:09 1240
<a href="KFHumanGibGroupOS.uc">KFHumanGibGroupOS.uc</a> 10-Sep-2022 21:09 922
<a href="KFMaleZombieSoundsOS.uc">KFMaleZombieSoundsOS.uc</a> 10-Sep-2022 21:09 990
<a href="KFMonsterControllerOS.uc">KFMonsterControllerOS.uc</a> 10-Sep-2022 21:09 578
<a href="KFMonsterOS.uc">KFMonsterOS.uc</a> 10-Sep-2022 21:09 51538
<a href="KFMonstersCollectionOS.uc">KFMonstersCollectionOS.uc</a> 10-Sep-2022 21:09 3635
<a href="KFNoGibGroupOS.uc">KFNoGibGroupOS.uc</a> 10-Sep-2022 21:09 638
<a href="KFOSInteraction.uc">KFOSInteraction.uc</a> 10-Sep-2022 21:09 1822
<a href="KFVomitJetOS.uc">KFVomitJetOS.uc</a> 10-Sep-2022 21:09 394
<a href="NewMinigunMFlashOS.uc">NewMinigunMFlashOS.uc</a> 10-Sep-2022 21:09 3411
<a href="SirenScreamDamageOS.uc">SirenScreamDamageOS.uc</a> 10-Sep-2022 21:09 295
<a href="Utility.uc">Utility.uc</a> 10-Sep-2022 21:09 2116
<a href="VomGroundSplashOS.uc">VomGroundSplashOS.uc</a> 10-Sep-2022 21:09 195
<a href="VomitDecalOS.uc">VomitDecalOS.uc</a> 10-Sep-2022 21:09 479
<a href="ZombieBloatOS.uc">ZombieBloatOS.uc</a> 10-Sep-2022 21:09 9158
<a href="ZombieBossOS.uc">ZombieBossOS.uc</a> 10-Sep-2022 21:09 46832
<a href="ZombieClotOS.uc">ZombieClotOS.uc</a> 10-Sep-2022 21:09 6145
<a href="ZombieCrawlerOS.uc">ZombieCrawlerOS.uc</a> 10-Sep-2022 21:09 4386
<a href="ZombieExplosivesPoundOS.uc">ZombieExplosivesPoundOS.uc</a> 10-Sep-2022 21:09 24357
<a href="ZombieFleshPoundOS.uc">ZombieFleshPoundOS.uc</a> 10-Sep-2022 21:09 23858
<a href="ZombieGorefastOS.uc">ZombieGorefastOS.uc</a> 10-Sep-2022 21:09 6821
<a href="ZombieRangedPoundOS.uc">ZombieRangedPoundOS.uc</a> 10-Sep-2022 21:09 19035
<a href="ZombieScrakeOS.uc">ZombieScrakeOS.uc</a> 10-Sep-2022 21:09 11733
<a href="ZombieSirenOS.uc">ZombieSirenOS.uc</a> 10-Sep-2022 21:09 9307
<a href="ZombieStalkerOS.uc">ZombieStalkerOS.uc</a> 10-Sep-2022 21:09 9282
</pre><hr></body>
</html>