// 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
       // added Controller check here
       if (Level.NetMode!=NM_Client && !KFGameType(Level.Game).bDidStalkerInvisibleMessage && FRand()<0.25 && Controller != none && 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'
}
