ACTOR IsSwimmingZombie : Boolean {}
ACTOR HasSpawnedHead : Boolean {}
ACTOR IgnoreHeadshot : Boolean {}
ACTOR WasSetup : Boolean {}
ACTOR HasDied : Boolean {}
ACTOR HasTarget : Boolean {}
ACTOR DidHeadshot : Boolean {}

// Are we actually on fire? SERVER
ACTOR Burning : Boolean {}
// Check to spawn flame effects - CLIENT
// 0: No effects
// 1: Effects until death
// 2: Effects until destroyed
ACTOR BurnFX : Inventory { Inventory.MaxAmount 2 }
ACTOR DoTDamage : Inventory { Inventory.MaxAmount 9999 }
ACTOR DoTReset : Boolean {}

// Spawned from a floor vent / hole
ACTOR Spawned_Complete : Boolean {}
ACTOR Spawned_Floor : Boolean {}

// This is used for lengthy see states
ACTOR ChaseState : Inventory { Inventory.MaxAmount 4 }

// HACK used for headshots
ACTOR RealHeight : Inventory { Inventory.MaxAmount 999 }

// This is only used if a shot killed us during headshot
// We need a way to detect LATER if we were headshotted
ACTOR IsDecapitated : Boolean {}

// These might not even be used
ACTOR Forgotten : Inventory { Inventory.MaxAmount 18 }
ACTOR FlameCounter : Inventory { Inventory.MaxAmount 7 }
ACTOR CorpseDecayTime : Inventory { Inventory.MaxAmount 999 }

// Types of kills
ACTOR Kill_Blunt : Boolean {}
ACTOR Kill_Headshot : Boolean {}
ACTOR Kill_Gib : Boolean {}

//--==--==--==--==--==--==--==--==--==--==--==--==--==
// C O R E   Z O M B I E   C L A S S 
// All zombies inherit from this class
//--==--==--==--==--==--==--==--==--==--==--==--==--==
ACTOR ZTZombieNew
{
	Monster
	Health 60
	Radius 20
	Height 56
	Speed 2
	PainChance 128
	MaxDropOffHeight 512
	Mass 200
	
	// Melee attacks ALWAYS go to pain
	PainChance "QuickMelee", 255
	PainChance "MeleeLeft", 255
	PainChance "MeleeRight", 255
	
	DamageFactor "ItemExplode", 0.00
	
	// Weak legs
	DamageFactor "Cripple", 1.5
	
	// Normal HUMAN head
	DamageFactor "head", 1.0
	DamageFactor "Decapitate", 1.0
	DamageFactor "Head_Shotgun", 1.15
	
	// We have frail little bones
	DamageFactor "MeleeLeft", 2.5
	DamageFactor "MeleeRight", 2.5
	DamageFactor "MeleeVert", 2.5
	
	+FLOORCLIP
	+NOTARGET
	+NOINFIGHTING
}

// Compatibility
ACTOR ZTZombie : ZTZombieNew
{
	
	
	// Time to get into the nitty gritty
	States
	{
		// - - - - - - - - - - - - - - - -
		
		// Spawn
		// Zombies will likely try to go here once everyone dies
		Spawn:
			BSZM A 0
			BSZM A 0 A_TakeInventory("HasTarget", 1)
			BSZM A 0 A_JumpIfInventory("WasSetup",1,"Wandering")
			BSZM A 0 ACS_NamedExecuteAlways("ZombieSetup",0,0,0,0)
			Goto Main
			
		// Main
		// This is our MAIN state for base checks, things of the sort
		Main:
			"####" "#" 0 A_JumpIfInventory("HasTarget",1,"Chasing")
			"####" "#" 0 A_LookEx(0,0,2048,2048,100)
			"####" "#" -1 A_Jump(256,"Wandering")
			Goto Wandering
			
		// Wandering
		// Zombie is roaming around WITHOUT a target
		Wandering:
			TROO ABCD 4 A_Wander
			Goto Main
		
		// - - - - - - - - - - - - - - - -
		
		// See
		// Native code jumps to this, DO NOT USE
		See:
			"####" "#" 0 A_GiveInventory("HasTarget", 1)
			Goto Main
		
		// Chasing
		// We are actively pursuing a player
		Chasing:
			TROO ABCD 4 A_Chase
			Goto Main
		
		// - - - - - - - - - - - - - - - -
		
		// DEATH TYPE: INCENDIARY
		Death.Fire:
		Death.Dragon:
		FireDeath:
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,4)
			"####" "#" 1
			"####" "#" 0 A_UnsetShootable
			"####" "#" 0 A_NoBlocking
			"####" "#" -1 A_Jump(256, "Ignite")
			Goto Ignite
			
		// Ignite
		// This is used for spawning a flaming copy
		Ignite:
			TNT1 A 0 A_SpawnItemEx("Flaming_BaseZombie",0,0,0)
			TNT1 A -1 A_Jump(256, "Ignited")
			Goto Ignited
			
		// Ignited
		// Required for the death script to work
		Ignited:
			TNT1 A 4
			Stop
		
		// - - - - - - - - - - - - - - - -
		
		Pain:
			"####" "#" -1 A_Jump(256,"PainAnim")
			Goto PainAnim
		
		// Quick melee attacks push us back on purpose
		Pain.QuickMelee:
			"####" "#" 0 A_FaceTarget
			"####" "#" 0 A_Recoil(20)
			"####" "#" -1 A_Jump(256,"PainAnim")
			Goto PainAnim
			
		// - - - - - - - - - - - - - - - -
		
		// DEATH TYPE: BLUNT
		Death.Blunt:
			"####" "#" 0 A_GiveInventory("Kill_Blunt", 1)
			Goto Death
		
		// DEATH TYPE: NORMAL
		Death:
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0)
			"####" "#" -1 A_Jump(256,"DeathAnim")
			Wait
			
		// Override this with YOUR animation
		DeathAnim:
			"####" "#" 1
			Stop
		
		// - - - - - - - - - - - - - - - -
			
		// DEATH TYPE: HEADSHOT
		Death.Decapitate:
		Death.head:
		Death.minorhead:
		Death.Head_Shotgun:
			"####" "#" 0 A_GiveInventory("Kill_Headshot", 1)
			"####" "#" 0 A_StopSound(CHAN_VOICE)
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,2)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" -1 A_Jump(256,"Decapitated")
			Goto Decapitated
			
		// Override this with YOUR animation
		Decapitated:
			TNT1 A 0 A_SpawnItemEx("HeadChunkSpawner",0,0,44)
			"####" "#" -1 A_Jump(256, "DeathAnim")
			Goto DeathAnim
			
		// DEATH TYPE: HEAD CUT OFF
		// (Not used for the moment)
		Death.MeleeDecap:
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,1)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" -1 A_Jump(256,"DecapitatedMelee")
			Goto DecapitatedMelee
			
		// Override this with YOUR animation
		DecapitatedMelee:
			"####" "#" -1 A_Jump(256,"Decapitated")
			Goto Decapitated
			
		// - - - - - - - - - - - - - - - -
		
		// DEATH TYPE: CRIPPLED
		Death.Cripple:
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,3)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" -1 A_Jump(256,"Crippled")
			Goto Crippled
			
		// Override this with YOUR animation
		Crippled:
			"####" "#" -1 A_Jump(256,"DeathAnim")
			Goto DeathAnim
			
		// - - - - - - - - - - - - - - - -
		
		// DEATH TYPE: COOKED
		Death.Microwave:
			"####" "#" 0 A_GiveInventory("Kill_Gib", 1)
			"####" "#" 0 A_UnsetShootable
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,2)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" -1 A_Jump(256,"Puffy")
			Goto Puffy
			
		// Override this with YOUR animation
		Puffy:
			"####" "#" -1 A_Jump(256,"DeathAnim")
			Goto DeathAnim
			
		// - - - - - - - - - - - - - - - -
			
		// DEATH TYPE: EXPLOSIVE
		Death.PointBlank:
		Death.ExplosiveDamage:
		Death.PulverizerBoom:
			"####" "#" 0 A_GiveInventory("Kill_Gib", 1)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1,2)
			"####" "#" -1 A_Jump(256,"Obliterate")
			Goto Obliterate
			
		// Override this with YOUR animation
		Obliterate:
			"####" "#" -1 A_Jump(256,"DeathAnim")
			Goto DeathAnim
			
		// Go back to this after we gibbed
		// This is required for our death script to process properly
		Obliterated:
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 A_UnsetShootable
			TNT1 A 10
			Stop
			
		// - - - - - - - - - - - - - - - -
		
		// DEATH TYPE: SIDEWAYS SLICE
		Death.MeleeLeft:
		Death.MeleeRight:
			"####" "#" 0 ACS_NamedExecuteAlways("ZombieDeath",0,1)
			"####" "#" 0 A_GiveInventory("IgnoreHeadshot", 1)
			"####" "#" -1 A_Jump(256,"Halved")
			Goto Halved
			
		// Override this with YOUR animation
		Halved:
			"####" "#" 0 A_UnsetShootable
			"####" "#" -1 A_Jump(256,"DeathAnim")
			Goto DeathAnim
	}
}

//--==--==--==--==--==--==--==--==--==--==--==--==--==
// G R O U N D   Z O M B I E
// Used for zombies that are choking, or suffering
//--==--==--==--==--==--==--==--==--==--==--==--==--==
ACTOR ZombieOnGround
{
    Radius 19
    Height 40
	Mass 300
	Monster
	Health 70
	DamageFactor "Head", 0.0
	DamageFactor "PointBlank", 2.0
	DamageFactor "Explosive", 2.0
	DamageFactor "PulverizerBoom", 2.0
    +SHOOTABLE
    -SOLID
    +NOTELEPORT
	+FLOORCLIP
    +MOVEWITHSECTOR
	+NOTARGET
	PainChance 0
	Speed 0
    States
    {
    Spawn:
		TNT1 A 0
		Stop
    }
}

//--==--==--==--==--==--==--==--==--==--==--==--==--==
// Z O M B I E   C O R P S E
// Actual dead body on the ground, can be shot and blown up
//--==--==--==--==--==--==--==--==--==--==--==--==--==
ACTOR ZombieCorpse
{
	// +THRUACTORS
	+SHOOTABLE
	+MOVEWITHSECTOR
	-NOBLOOD
	-SOLID
	// +FLOORCLIP
	+CORPSE
	+NOTELEPORT
	+CANPASS
	Health 150
	Mass 300000000
	Radius 22
	Height 4
	PainChance 255
	
	// Anything flame-related will instantly burn us
	DamageFactor "Fire", 50.0
	DamageFactor "Dragon", 50.0
	States
	{
		Spawn:
			TNT1 A 0
			TNT1 A -1 A_Jump(256,"SetSprite")
			Wait
			
		// Override THIS STATE for your visual sprite
		SetSprite:
			TNT1 A 1
			Goto Main
			
		// This state checks if we should disappear
		Main:
			"####" "#" 0 A_CheckSight("Disappear")
			"####" "#" -1 A_Jump(256,"Dead")
			Wait
			
		// Go away
		Disappear:
			TNT1 A 1
			Stop
			
		// We are on the ground
		Dead:
			"####" "#" 300
			Goto Main
			
		// Default pain doesn't do anything
		Pain:
			"####" "#" 0
			Goto Dead
			
		// - - - - - - - - - - - - - - - -
		
		// Fire can burn us very easily
		Pain.Fire:
		Pain.Dragon:
		Death.Fire:
		Death.Dragon:
			"####" "#" 0
			"####" "#" -1 A_Jump(256,"Burnt")
			Wait
		
		// Override THIS STATE if you want your corpse to burn
		Burnt:
			"####" "#" 0
			Stop
			
		// - - - - - - - - - - - - - - - -
		
		// Explosives can blow this body up
		Pain.PointBlank:
		Death.PointBlank:
		Death.ExplosiveDamage:
		Death.PulverizerBoom:
			"####" "#" 0
			"####" "#" -1 A_Jump(256,"Gibbed")
			Wait
			
		// Override THIS STATE if you don't want your corpse to explode
		Gibbed:
			"####" "#" 0 A_SpawnItemEx("ZombieGibber",0,0,10)
			Stop
	}
}