// Zombie Monster for KF Invasion gametype
class NiceZombieClot extends NiceZombieClotBase;

#exec OBJ LOAD FILE=KF_Freaks_Trip.ukx
#exec OBJ LOAD FILE=KF_Specimens_Trip_T.utx
#exec OBJ LOAD FILE=MeanZedSkins.utx

var float sirenBoostTimeout;

function ClawDamageTarget()
{
    local vector PushDir;
    local KFPawn KFP;
    local float UsedMeleeDamage;

    // TODO Controller fix
    if( MeleeDamage > 1 )
    {
      UsedMeleeDamage = (MeleeDamage - (MeleeDamage * 0.05)) + (MeleeDamage * (FRand() * 0.1));
    }
    else
    {
      UsedMeleeDamage = MeleeDamage;
    }
    // If zombie has latched onto us...
    if ( MeleeDamageTarget( UsedMeleeDamage, PushDir))
    {
       KFP = KFPawn(Controller.Target);

       PlaySound(MeleeAttackHitSound, SLOT_Interact, 2.0);

       if( !bDecapitated && KFP != none )
       {
           if( KFPlayerReplicationInfo(KFP.PlayerReplicationInfo) == none ||
               KFP.GetVeteran().static.CanBeGrabbed(KFPlayerReplicationInfo(KFP.PlayerReplicationInfo), self))
           {
               if( DisabledPawn != none )
               {
                    DisabledPawn.bMovementDisabled = false;
               }

               KFP.DisableMovement(GrappleDuration);
               DisabledPawn = KFP;
           }
       }
    }
}

function RangedAttack(Actor A)
{
    if ( bShotAnim || Physics == PHYS_Swimming)
       return;
    else if ( CanAttack(A) )
    {
       bShotAnim = true;
       SetAnimAction('Claw');
       return;
    }
}
simulated event SetAnimAction(name NewAction)
{
    local int meleeAnimIndex;
    if( NewAction=='' )
       Return;
    if(NewAction == 'Claw')
    {
       meleeAnimIndex = Rand(3);
       NewAction = meleeAnims[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 == 'KnockDown' || TestAnim == 'DoorBash' )
    {
       return true;
    }
    return false;
}
simulated function int DoAnimAction( name AnimName )
{
    if( AnimName=='ClotGrapple' || AnimName=='ClotGrappleTwo' || AnimName=='ClotGrappleThree' )
    {
       AnimBlendParams(1, 1.0, 0.1,, FireRootBone);
       PlayAnim(AnimName,, 0.1, 1);

       // Randomly send out a message about Clot grabbing you(10% chance)
       if ( FRand() < 0.10 && LookTarget != none && KFPlayerController(LookTarget.Controller) != none &&
            VSizeSquared(Location - LookTarget.Location) < 2500 /* (MeleeRange + 20)^2 */ &&
            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;
       }

       bGrappling = true;
       GrappleEndTime = Level.TimeSeconds + GrappleDuration;

       return 1;
    }
    return super.DoAnimAction( AnimName );
}
function DealDecapDamage(  int damage,
                           Pawn instigatedBy,
                           Vector hitLocation,
                           Vector momentum,
                           class<NiceWeaponDamageType> damageType,
                           float headshotLevel,
                           KFPlayerReplicationInfo KFPRI,
                           optional float lockonTime) {
    if (sirenBoostTimeout > 0) {
        RemoveHead();
    } else {
        super.DealDecapDamage(damage, instigatedBy, hitLocation, momentum,
            damageType, headshotLevel, KFPRI, lockonTime);
    }
}
simulated function UpdateGroundSpeed() {
    super.UpdateGroundSpeed();
    if (sirenBoostTimeout > 0) {
        groundSpeed *= 1.5;
    }
}
simulated function Tick(float DeltaTime)
{
    super.Tick(DeltaTime);
    if (sirenBoostTimeout >= 0) {
        sirenBoostTimeout -= deltaTime;
    }
    if( bShotAnim && Role == ROLE_Authority )
    {
       if( LookTarget!=none )
       {
           Acceleration = AccelRate * Normal(LookTarget.Location - Location);
       }
    }
    if( Role == ROLE_Authority && bGrappling )
    {
       if( Level.TimeSeconds > GrappleEndTime )
       {
           bGrappling = false;
       }
    }
    // if we move out of melee range, stop doing the grapple animation
    if( bGrappling && LookTarget != none )
    {
       if( VSize(LookTarget.Location - Location) > MeleeRange + CollisionRadius + LookTarget.CollisionRadius )
       {
           bGrappling = false;
           AnimEnd(1);
       }
    }
}
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;
    }
}
function Died(Controller Killer, class<DamageType> damageType, vector HitLocation)
{
    if( DisabledPawn != none )
    {
        DisabledPawn.bMovementDisabled = false;
        DisabledPawn = none;
    }
    super.Died(Killer, damageType, HitLocation);
}
simulated function Destroyed()
{
    super.Destroyed();
    if( DisabledPawn != none )
    {
        DisabledPawn.bMovementDisabled = false;
        DisabledPawn = none;
    }
}
static simulated function PreCacheStaticMeshes(LevelInfo myLevel)
{//should be derived and used.
    Super.PreCacheStaticMeshes(myLevel);
/*
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_1');
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_2');
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_3');
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_4');
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_5');
    myLevel.AddPrecacheStaticMesh(StaticMesh'kf_gore_trip_sm.clot.clothead_piece_6');
*/
}
static simulated function PreCacheMaterials(LevelInfo myLevel)
{//should be derived and used.
    myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.clot_cmb');
    myLevel.AddPrecacheMaterial(Combiner'KF_Specimens_Trip_T.clot_env_cmb');
    myLevel.AddPrecacheMaterial(Texture'KF_Specimens_Trip_T.clot_diffuse');
    myLevel.AddPrecacheMaterial(Texture'KF_Specimens_Trip_T.clot_spec');
}
defaultproperties
{
    idleInsertFrame=0.468000
    EventClasses(0)="NicePack.NiceZombieClot"
    MoanVoice=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Talk'
    MeleeAttackHitSound=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_HitPlayer'
    JumpSound=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Jump'
    DetachedArmClass=Class'KFChar.SeveredArmClot'
    DetachedLegClass=Class'KFChar.SeveredLegClot'
    DetachedHeadClass=Class'KFChar.SeveredHeadClot'
    HitSound(0)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Pain'
    DeathSound(0)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Death'
    ChallengeSound(0)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Challenge'
    ChallengeSound(1)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Challenge'
    ChallengeSound(2)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Challenge'
    ChallengeSound(3)=SoundGroup'KF_EnemiesFinalSnd.clot.Clot_Challenge'
    AmbientSound=Sound'KF_BaseClot.Clot_Idle1Loop'
    Mesh=SkeletalMesh'KF_Freaks_Trip.CLOT_Freak'
    Skins(0)=Combiner'KF_Specimens_Trip_T.clot_cmb'
}
