298 lines
9.6 KiB
Ucode
298 lines
9.6 KiB
Ucode
// Zombie Monster for KF Invasion gametype
|
|
class NiceZombieStalker extends NiceZombieStalkerBase;
|
|
#exec OBJ LOAD FILE=KFX.utx
|
|
#exec OBJ LOAD FILE=KF_BaseStalker.uax
|
|
//----------------------------------------------------------------------------
|
|
// NOTE: All Variables are declared in the base class to eliminate hitching
|
|
//----------------------------------------------------------------------------
|
|
simulated function PostBeginPlay()
|
|
{
|
|
CloakStalker();
|
|
super.PostBeginPlay();
|
|
}
|
|
simulated function PostNetBeginPlay()
|
|
{
|
|
local PlayerController PC;
|
|
super.PostNetBeginPlay();
|
|
if( Level.NetMode!=NM_DedicatedServer )
|
|
{
|
|
PC = Level.GetLocalPlayerController();
|
|
if( PC != none && PC.Pawn != none )
|
|
{
|
|
LocalKFHumanPawn = KFHumanPawn(PC.Pawn);
|
|
}
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
Super.Tick(DeltaTime);
|
|
if( Level.NetMode==NM_DedicatedServer )
|
|
Return; // Servers aren't intrested in this info.
|
|
if( bZapped )
|
|
{
|
|
// Make sure we check if we need to be cloaked as soon as the zap wears off
|
|
NextCheckTime = Level.TimeSeconds;
|
|
}
|
|
else if( Level.TimeSeconds > NextCheckTime && Health > 0 )
|
|
{
|
|
NextCheckTime = Level.TimeSeconds + 0.5;
|
|
|
|
if( LocalKFHumanPawn != none && LocalKFHumanPawn.Health > 0 && LocalKFHumanPawn.ShowStalkers() &&
|
|
VSizeSquared(Location - LocalKFHumanPawn.Location) < LocalKFHumanPawn.GetStalkerViewDistanceMulti() * 640000.0 ) // 640000 = 800 Units
|
|
{
|
|
bSpotted = True;
|
|
}
|
|
else
|
|
{
|
|
bSpotted = false;
|
|
}
|
|
|
|
if ( !bSpotted && !bCloaked && Skins[0] != Combiner'KF_Specimens_Trip_T.stalker_cmb' )
|
|
{
|
|
UncloakStalker();
|
|
}
|
|
else if ( Level.TimeSeconds - LastUncloakTime > 1.2 )
|
|
{
|
|
// if we're uberbrite, turn down the light
|
|
if( bSpotted && Skins[0] != Finalblend'KFX.StalkerGlow' )
|
|
{
|
|
bUnlit = false;
|
|
CloakStalker();
|
|
}
|
|
else if ( Skins[0] != Shader'KF_Specimens_Trip_T.stalker_invisible' )
|
|
{
|
|
CloakStalker();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Cloak Functions ( called from animation notifies to save Gibby trouble ;) )
|
|
simulated function CloakStalker()
|
|
{
|
|
// No cloaking if zapped
|
|
if( bZapped )
|
|
{
|
|
return;
|
|
}
|
|
if ( bSpotted )
|
|
{
|
|
if( Level.NetMode == NM_DedicatedServer )
|
|
return;
|
|
|
|
Skins[0] = Finalblend'KFX.StalkerGlow';
|
|
Skins[1] = Finalblend'KFX.StalkerGlow';
|
|
bUnlit = true;
|
|
return;
|
|
}
|
|
if ( !bDecapitated && !bCrispified ) // No head, no cloak, honey. updated : Being charred means no cloak either :D
|
|
{
|
|
Visibility = 1;
|
|
bCloaked = true;
|
|
|
|
if( Level.NetMode == NM_DedicatedServer )
|
|
Return;
|
|
|
|
Skins[0] = Shader'KF_Specimens_Trip_T.stalker_invisible';
|
|
Skins[1] = Shader'KF_Specimens_Trip_T.stalker_invisible';
|
|
|
|
// Invisible - no shadow
|
|
if(PlayerShadow != none)
|
|
PlayerShadow.bShadowActive = false;
|
|
if(RealTimeShadow != none)
|
|
RealTimeShadow.Destroy();
|
|
|
|
// Remove/disallow projectors on invisible people
|
|
Projectors.Remove(0, Projectors.Length);
|
|
bAcceptsProjectors = false;
|
|
SetOverlayMaterial(Material'KFX.FBDecloakShader', 0.25, true);
|
|
}
|
|
}
|
|
simulated function UnCloakStalker()
|
|
{
|
|
if( bZapped )
|
|
{
|
|
return;
|
|
}
|
|
if( !bCrispified )
|
|
{
|
|
LastUncloakTime = Level.TimeSeconds;
|
|
|
|
Visibility = default.Visibility;
|
|
bCloaked = false;
|
|
bUnlit = false;
|
|
|
|
// 25% chance of our Enemy saying something about us being invisible
|
|
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;
|
|
|
|
if ( Skins[0] != Combiner'KF_Specimens_Trip_T.stalker_cmb' )
|
|
{
|
|
Skins[1] = FinalBlend'KF_Specimens_Trip_T.stalker_fb';
|
|
Skins[0] = Combiner'KF_Specimens_Trip_T.stalker_cmb';
|
|
|
|
if (PlayerShadow != none)
|
|
PlayerShadow.bShadowActive = true;
|
|
|
|
bAcceptsProjectors = true;
|
|
|
|
SetOverlayMaterial(Material'KFX.FBDecloakShader', 0.25, true);
|
|
}
|
|
}
|
|
}
|
|
// Set the zed to the zapped behavior
|
|
simulated function SetZappedBehavior()
|
|
{
|
|
super.SetZappedBehavior();
|
|
bUnlit = false;
|
|
// Handle setting the zed to uncloaked so the zapped overlay works properly
|
|
if( Level.Netmode != NM_DedicatedServer )
|
|
{
|
|
Skins[1] = FinalBlend'KF_Specimens_Trip_T.stalker_fb';
|
|
Skins[0] = Combiner'KF_Specimens_Trip_T.stalker_cmb';
|
|
|
|
if (PlayerShadow != none)
|
|
PlayerShadow.bShadowActive = true;
|
|
|
|
bAcceptsProjectors = true;
|
|
SetOverlayMaterial(Material'KFZED_FX_T.Energy.ZED_overlay_Hit_Shdr', 999, true);
|
|
}
|
|
}
|
|
// Turn off the zapped behavior
|
|
simulated function UnSetZappedBehavior()
|
|
{
|
|
super.UnSetZappedBehavior();
|
|
// Handle getting the zed back cloaked if need be
|
|
if( Level.Netmode != NM_DedicatedServer )
|
|
{
|
|
NextCheckTime = Level.TimeSeconds;
|
|
SetOverlayMaterial(none, 0.0f, true);
|
|
}
|
|
}
|
|
// Overridden because we need to handle the overlays differently for zombies that can cloak
|
|
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'KF_Specimens_Trip_T.stalker_fb';
|
|
Skins[0] = Combiner'KF_Specimens_Trip_T.stalker_cmb';
|
|
}
|
|
}
|
|
simulated function PlayDying(class<DamageType> DamageType, vector HitLoc)
|
|
{
|
|
Super(NiceMonster).PlayDying(DamageType,HitLoc);
|
|
if(bUnlit)
|
|
bUnlit=!bUnlit;
|
|
LocalKFHumanPawn = none;
|
|
if (!bCrispified)
|
|
{
|
|
Skins[1] = FinalBlend'KF_Specimens_Trip_T.stalker_fb';
|
|
Skins[0] = Combiner'KF_Specimens_Trip_T.stalker_cmb';
|
|
}
|
|
}
|
|
// Give her the ability to spring.
|
|
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)
|
|
MakeNoise(1.0);
|
|
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)
|
|
{//should be derived and used.
|
|
myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.stalker_cmb');
|
|
myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.stalker_env_cmb');
|
|
myLevel.AddPrecacheMaterial(Texture'KF_Specimens_Trip_T.stalker_diff');
|
|
myLevel.AddPrecacheMaterial(Texture'KF_Specimens_Trip_T.stalker_spec');
|
|
myLevel.AddPrecacheMaterial(Material'KF_Specimens_Trip_T.stalker_invisible');
|
|
myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.StalkerCloakOpacity_cmb');
|
|
myLevel.AddPrecacheMaterial(Material'KF_Specimens_Trip_T.StalkerCloakEnv_rot');
|
|
myLevel.AddPrecacheMaterial(Material'KF_Specimens_Trip_T.stalker_opacity_osc');
|
|
myLevel.AddPrecacheMaterial(Material'KFCharacters.StalkerSkin');
|
|
}
|
|
defaultproperties
|
|
{
|
|
stunLoopStart=0.250000
|
|
stunLoopEnd=0.890000
|
|
idleInsertFrame=0.950000
|
|
EventClasses(0)="NicePack.NiceZombieStalker"
|
|
MoanVoice=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Talk'
|
|
MeleeAttackHitSound=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_HitPlayer'
|
|
JumpSound=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Jump'
|
|
DetachedArmClass=Class'KFChar.SeveredArmStalker'
|
|
DetachedLegClass=Class'KFChar.SeveredLegStalker'
|
|
DetachedHeadClass=Class'KFChar.SeveredHeadStalker'
|
|
HitSound(0)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Pain'
|
|
DeathSound(0)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Death'
|
|
ChallengeSound(0)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Challenge'
|
|
ChallengeSound(1)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Challenge'
|
|
ChallengeSound(2)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Challenge'
|
|
ChallengeSound(3)=SoundGroup'KF_EnemiesFinalSnd.Stalker.Stalker_Challenge'
|
|
AmbientSound=Sound'KF_BaseStalker.Stalker_IdleLoop'
|
|
Mesh=SkeletalMesh'KF_Freaks_Trip.Stalker_Freak'
|
|
Skins(0)=Shader'KF_Specimens_Trip_T.stalker_invisible'
|
|
Skins(1)=Shader'KF_Specimens_Trip_T.stalker_invisible'
|
|
}
|