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)
}
