// *** MODIFIED BY CHEBMASTER
// I mark most important places modified by me with //***Che -- unless I forget to.





ACTOR CyberPotpourriChecker: AbstractPotpourriChecker
{
	Radius 45
	Height 94
}

Actor CyberRuntBossCubeSpawner: AbstractBossCubeSpawner
{
	Radius 45
	Height 94
	States
	{
		DoSummon:	
			TNT1 A 0 A_GiveInventory("SummonsCount", 1, AAPTR_TRACER)
			TNT1 A 0 A_SpawnItemEx("BossSizedTeleportFog")
			TNT1 A 1 A_SpawnItemEx("CyberdemonRunt",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION,0,user_stid)
			Stop
	}
}

ACTOR ZandronumCyberdemon 
//***Che copied from Zandronum's PK3 so that our cyberdemon does NOT inherit from anything
//   but is a completely independent entity declared entirely in DECORATE.
{
	Game Doom
	SpawnID 114
	Health 4000
	Radius 40
	Height 110
	Mass 1000
	Speed 16
	PainChance 20
	Monster
	MinMissileChance 160
	+BOSS 
	+MISSILEMORE
	+FLOORCLIP
	+NORADIUSDMG
	+DONTMORPH
	+BOSSDEATH
	SeeSound "cyber/sight"
	PainSound "cyber/pain"
	DeathSound "cyber/death"
	ActiveSound "cyber/active"
	Obituary "$OB_CYBORG"
	States
	{
		Spawn:
			CYBR AB 10 A_Look
			Loop
		See:
			CYBR A 3 A_Hoof
			CYBR ABBCC 3 A_Chase
			CYBR D 3 A_Metal
			CYBR D 3 A_Chase
			Loop
		Missile:
			CYBR E 6 A_FaceTarget
			CYBR F 12 A_CyberAttack
			CYBR E 12 A_FaceTarget
			CYBR F 12 A_CyberAttack
			CYBR E 12 A_FaceTarget
			CYBR F 12 A_CyberAttack
			Goto See
		Pain:
			CYBR G 10 A_Pain
			Goto See
		Death:
			CYBR H 10
			CYBR I 10 A_Scream
			CYBR JKL 10
			CYBR M 10 A_NoBlocking
			CYBR NO 10
			CYBR P 30
			CYBR P -1 A_BossDeath
			Stop
	}
}

ACTOR AbstractCyberdemon: ZandronumCyberdemon
{
	// the base for both the nerfed tyrant and the buffed regular cyberdemon
	// not the headbox offsets have been pre-baked with the 1.1 multiplier so the headbox scale used is 100%
	// so the tyrant (back to standard cyberdemon size) uses 83% headbox scale and "Scale 1.0"

    //$category "FBD Bosses"
	//$Sprite CYBRA1
	
	damagefactor "HKFT", 0.05
	damagefactor "HKFT", 0.05
	damagefactor "Decaptate", 5.0
	damagefactor "Avoid", 0.0
	damagefactor "GibRemoving", 0.0
	damagefactor "TeleportRemover", 0.0
	DamageFactor "CauseSplash", 0.0 DamageFactor "CauseObjectsToSplashSlime", 0.0 DamageFactor "CauseObjectsToSplashNukage", 0.0
	DamageFactor "CauseObjectsToSplashBlood", 0.0 DamageFactor "CauseObjectsToSplashLava", 0.0
	+NOICEDEATH
    Health 5000
    damagefactor "Crush", 20.0
	PainSound "CYBPAIN"
	MaxStepHeight 24
	MaxDropOffHeight 32
    Scale 1.2
	
	//***Che cannot make him *bigger* than vanilla! What if monsters get stuck together?
	Radius 40 //45
	
	Height 94
	+MISSILEMORE
	+MISSILEEVENMORE
    +DONTRIP
    +NORADIUSDMG
	+QUICKTORETALIATE
	Speed 16
	FastSpeed 22
	painchance "kick", 255
	painchance "Fire", 60
	painchance 20
	mass 5000
	//damagefactor "fatality", 5000.0
	PainChance "Head", 40
	PainChance "HeadPlasma", 64
	PainChance "Bullet792", 30 // machineguns and snip[er rifles not aimed
	PainChance "SniperBullet", 30 // sniper rifle aimed	
	PainChance "Decaptate", 64
	PainChance "HeadStun", 255 // compensated by going into special attack right after
	PainChance "KillMe", 64
	damagefactor "Killme", 1.0 // AOE inflicted by captured marines
	PainChance "Taunt", 255
	PainChance "Cut", 5
	DropItem "DemonStrengthRune" 25
	Painchance "Fatality", 90
    BloodType "CyberDemon_Blood", "CyberDemon_FBD_SawBlood", "CyberDemon_Blood"
	damagefactor "Blood", 0.0 damagefactor "BlueBlood", 0.0 damagefactor "GreenBlood", 0.0
	
	//Tag "Cyberdemon"
	//***Che
	Tag "$CYBERDEMON"
	
	var int user_head_tid;
	var int user_head_type; // cyberdemon headbox
	var int user_head_rel;
	var int user_head_scale;
	var int user_head_xyzf; /* 
		a packed value: 
		bits 0..7 =x+128, clamped to -128..127
		bits 8..15 =y+128, clamped to -128..127
		bits 16..23 =z, clamped to 1..255
		bit 29 is a command to assume an unique TID, used in monster-on-monster headshotting
		A zero value is a command to terminate
	*/
	
	
	var int user_sleeping;
	var int user_item_no;
	var int user_serverside_sfchk; // on client, always 0. 
	// on server, -1 means command for DECORATE to perform a_radiusGive,
	// 1 decorate replies it had performed A_RadiusGive

	var int user_dont_adjust_aim;
	var int user_bleeding_angle;
	var int user_headshot_stun_limit;
	
	+NOPAIN // initial flag, is cleared when the Spawn state completes
	
	PainChance "Argent", 255
	DamageFactor "Argent", 1.0
	
	Species "Cyberdemons"
	
	PainChance "Ice", 40

	States
	{

		Pain.Ice:
			"----" A 20 A_Pain
			Goto See

/*
		ReplaceVanilla:
			TNT1 A 0
			TNT1 A 0 A_GiveInventory("IAmClassicMonster", 1)
			Goto Stand
*/			
			
/*
			TNT1 A 0 A_JumpIf(x == -1472, "ReplaceForBOSS")
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 A_ChangeFlag("THRUACTORS", 1)
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 0)
			TNT1 A 0 A_SpawnItemEx ("VanillaCyberdemon",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION | SXF_TRANSFERAMBUSHFLAG ,0)
			TNT1 A 100
			TNT1 A 0
			Stop
*/			
			
		ReplaceForBOSS:
			TNT1 A 0
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 ACS_NamedExecuteWithResult("MapEnhancementE2M8")
			TNT1 A 0 A_ChangeFlag("THRUACTORS", 1)
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 0)
			TNT1 A 0 A_SpawnItemEx ("CyberdemonE2M8Boss",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION | SXF_TRANSFERAMBUSHFLAG |SXF_NOCHECKPOSITION | SXF_TRANSFERAMBUSHFLAG | SXF_TRANSFERPOINTERS | SXF_TRANSFERSPECIAL | SXF_CLEARCALLERSPECIAL | SXF_CLEARCALLERTID  ,0, tid)
			TNT1 A 0
			Stop
			
		Pain.Head:
		Pain.HeadPlasma:
		Pain.Decaptate:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_headshot_stun_limit", user_headshot_stun_limit - 1)
			TNT1 A 0 A_JumpIf(user_headshot_stun_limit < 0, "HeadStunAftermath") // *immediate* uniterruptable furious retaliation
			TNT1 A 0 A_JumpIf(user_headshot_stun_limit == 0, "Pain.HeadStun")
			// Just pain
			
		Pain:
			CYBR G 1 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 10, 96)
			CYBR G 4 A_Pain
			CYBR G 4 A_Pain
			Goto See
			
		IosChastises: // required by boss in Chebskies-EDAY map 313
			"----" A 0 A_ClearTarget			
			"----" A 0 HealThing(500)
			"----" A 0 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 40, 90, 0)	
			Goto Pain
			
		Pain.Argent: // inflicted by ghost souls spammed by super archviles
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_headshot_stun_limit", 0)
			TNT1 A 0 HealThing(500)
			TNT1 A 0 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 40, 90, 0)	
			
			CYBR G 1 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 10, 96)
			CYBR G 3 A_Pain
			
			Goto Pain.Taunt // results in furious spraying in a random direction if target is out of sight
			
			
		Pain.HeadStun:
		
			// 25% standard short pain
			// 37.5% one second stun followed by retaliation (33.3%) / furious retaliation(66.6%)
			// 37.5% two seconds stun followed by furious retaliation
		
			TNT1 A 0
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_JumpIf(user_headshot_stun_limit <= 0, "HeadStunAftermath") // *immediate* uniterruptable furious retaliation
			TNT1 A 0 A_SetUserVar("user_headshot_stun_limit", user_headshot_stun_limit - 2)
			TNT1 A 0 A_SetUserVar("user_bleeding_angle", random(-110,110))
			CYBR G 1 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -10, 10, 96)
			TNT1 A 0 A_Pain
			
			TNT1 A 0 A_FaceTarget // *assuming* it was a railgun, we thus lock our firing angle at where the player was before retreating into cover
			
			CYBR GGGG 2 A_CustomMissile ("Brutal_LiquidBlood2", 110, 0, angle + user_bleeding_angle + random (-15, 15), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, random (15, 55))
			TNT1 A 0 A_Jump(64, "See") // just a common short pain, no retaliation
			
			
			// +1 second stun
			TNT1 A 0 A_Pain
			CYBR GGGGGGGGGG 2 A_CustomMissile ("Brutal_LiquidBlood2", 115, 0, angle + user_bleeding_angle + random (-15, 15), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, random (15, 55))
			TNT1 A 0 A_Pain
			CYBR GGGG 4 A_CustomMissile ("Brutal_LiquidBlood2", 115, 0, angle + user_bleeding_angle + random (-15, 15), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, random (15, 55))
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 1)
			TNT1 A 0 A_Jump(127, "Missile", "SpecialAttack", "SpecialAttack")
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 0)
			
			
			// + one more second stun followed by furious retaliation
			TNT1 A 0 A_Pain
			CYBR GGGGGGGGGG 2 A_CustomMissile ("Brutal_LiquidBlood2", 115, 0, angle + user_bleeding_angle + random (-15, 15), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, random (15, 55))
			TNT1 A 0 A_Pain
			CYBR GGGG 4 A_CustomMissile ("Brutal_LiquidBlood2", 115, 0, angle + user_bleeding_angle + random (-15, 15), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, random (15, 55))
			
		HeadStunAftermath:	
			TNT1 A 0
			TNT1 A 0 A_PlaySound("cyber/sight", CHAN_VOICE)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 1) // fire in the direction that caused pain, first. 
			// Will adjust aim during firing, if player in LOS. If no LOS, will keep laying down suppressive fire past player's cover.
			
			CYBR G 1 A_Jump(256, "SpecialAttack")
			Wait // Zandronum multiplayer client will repeat the last frame 
				// waiting for a state update from the server
				// Otherwise (GZDoom or singleplayer) this frame never shows because of action functions execute *before* the frame
		
		PotPourriSwap:
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 0)
			TNT1 A 0 A_ChangeFlag("SHOOTABLE", 0)
		PotPourriWait:			
			KYPP C 5 A_JumpIf(CallAcs("FBD_GetMapRandomizerReady"), 1) // a two-second delay to allow re-randomizing on loading an auto-save
			Loop			
			TNT1 A 0 A_Jumpif(!CallAcs("GetPotPourriChance", 75), "PotPourriNoSwap") // bosses have 75% replacement probability instead of normal 33%
			
			TNT1 A 0 A_ChangeFlag("SOLID", 0)
			TNT1 A 0 A_ChangeFlag("THRUACTORS", 1)
			TNT1 A 0 A_SpawnItemEx ("CyberPotpourriSwapper",0,0,0, 0,0,0, 0,SXF_NOCHECKPOSITION | SXF_TRANSFERAMBUSHFLAG | SXF_TRANSFERPOINTERS | SXF_TRANSFERSPECIAL | SXF_CLEARCALLERSPECIAL | SXF_CLEARCALLERTID  ,0, tid)
			TNT1 A 30
			Stop
		PotPourriNoSwap:
			TNT1 A 0 A_ChangeFlag("SHOOTABLE", 1)
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 1)
			Goto PotPourriCancel		
		Spawn:
			CYBR D 0 NODELAY
			//***Che: a nice pitfall, the jump functions won't execute on the first frame,
			//  NODELAY doesn't help. And you get NO error message, nothing. It just doesn't work.
			
			//***Che: unlike vanilla BD, *both* coordinates must match. 
			//    I had accidents happen to unrelated maps (EDAY13) due to this.
			
			//***TODO: harden map detection using ACS
			//  because false positives happen :(
			//P.S. This check is only present in TheCyberdemon
			//TNT1 A 0 A_JumpIf(x == -1472 && y == 576, "ReplaceForBOSS")
			
			TNT1 A 0 A_JumpIf(CallAcs("GetPotPourri"), "PotPourriSwap")
		PotPourriCancel:
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_RunMonster", 1) // cyberdemon headbox, 1.0 default scale (using pre-baked 1.2 scale)
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 0)
			TNT1 A 0 A_SetUserVar("user_headshot_stun_limit", 8) // prevents permanent stunlock
			TNT1 A 0 A_GiveInventory("TargetIsACyberdemon")
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
		Idle: // without this, the game engine puts him into his Spawn state when he loses target 
				//-- and that wrecks havok with the init scripts!
		Stand:	
			
			TNT1 A 0
			//TNT1 A 0 A_JumpIf(user_serverside_sfchk >= 4, 2) // extreme slaughtermap optimization
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 2, 96)
			CYBR Z 10 A_Look
			CYBR D 10 A_Look
			"----" A 0 A_JumpIf(!user_head_tid, "StandSfest")
			Loop
			
		StandSfest:
			CYBR ZD 10 A_Look
			Loop			

		See:
			
			TNT1 A 0 
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
//			TNT1 A 0 A_JumpIfInventory("IAmClassicMonster", 1, "SeeVanilla")
			
/*
			// slaughtermap manage
			TNT1 A 0 A_JumpIf(!user_sleeping, 3) // forgo the expensive sight check if already awake
			TNT1 A 0 A_CheckSight(2) // do not consider ourselves awake if none of the players can see us
			TNT1 A 0 A_SetUserVar("user_sleeping", 0)
			TNT1 A 0 A_JumpIf(user_serverside_sfchk != -1, 3) // -1 means ACS commands us to do the radiusgive
			// A_RadiusGive is:
			//  1. serverside-only: the call is skipped on the client; only if a player is involved, a network command to update his item count is sent, otherwise the item count only increases on the server
			//  2. iterates over all actors in an infinitely tall square column checking their flags and coordinates
			//  3. performs expensive precision radius calculation (using a square root) unless RGF_CUBE is given (which results in cheaper delta per-coordinate comparison)
			//  4. performs expensive sight check, for each thing that passes flag and radius checks, unless RGF_NOSIGHT is given
			TNT1 A 0 A_RadiusGive("SfestCounterServerside", 500, RGF_MONSTERS | RGF_CUBE | RGF_NOSIGHT, 1)			
			TNT1 A 0 A_SetUserVar("user_serverside_sfchk", 1) // reply that we did the deed
*/			
			
			
		ChaseTheTarget:	

			// 34 tics
			// 12 A_Chase calls
			
			//***Che: commented this crap out. It inflicts 900 damage in a radius of 10 
			//   while cyberdemon's radius is 40!
			//  Meaning it only has effect if that cyberdemon lands ob your head.
			//TNT1 A 0 A_SpawnItem("HeavyFootSteps32")
			
			//***Che also replaced these with A_JumpIfTargetInLOS because wasn't checking LOS:
			//TNT1 A 0 A_JumpIf(CallACS("GetCyberdemonCanStompTarget", 120), "Stomp")
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			
			CYBR A 6
			TNT1 A 0 A_JumpIfTargetInLOS("Missile", 60, JLOSF_DEADNOJUMP, 120)
			"----" A 0 A_Metal // plays DSMETAL which is 0.73s (25 tics) long
			
			CYBR AA 2 A_Chase
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 2, 96)
			CYBR BBBB 2 A_Chase
			//TNT1 A 0 A_SpawnItem("HeavyFootSteps32")
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			CYBR C 4 A_PlaySound("KYBHOOF1")  
			TNT1 A 0 A_JumpIfTargetInLOS("Missile", 60, JLOSF_DEADNOJUMP, 120)
			CYBR CC 2 A_Chase
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 2, 96)
			CYBR DDDD 2 A_Chase
			Loop
/*		
		SeeVanilla:
			
			TNT1 A 0
			
			// slaughtermap manage
			TNT1 A 0 A_JumpIf(!user_sleeping, 3) // forgo the expensive sight check if already awake
			TNT1 A 0 A_CheckSight(2) // do not consider ourselves awake if none of the players can see us
			TNT1 A 0 A_SetUserVar("user_sleeping", 0)
			TNT1 A 0 A_JumpIf(user_serverside_sfchk != -1, 3) // -1 means ACS commands us to do the radiusgive
			// A_RadiusGive is:
			//  1. serverside-only: the call is skipped on the client; only if a player is involved, a network command to update his item count is sent, otherwise the item count only increases on the server
			//  2. iterates over all actors in an infinitely tall square column checking their flags and coordinates
			//  3. performs expensive precision radius calculation (using a square root) unless RGF_CUBE is given (which results in cheaper delta per-coordinate comparison)
			//  4. performs expensive sight check, for each thing that passes flag and radius checks, unless RGF_NOSIGHT is given
			TNT1 A 0 A_RadiusGive("SfestCounterServerside", 500, RGF_MONSTERS | RGF_CUBE | RGF_NOSIGHT, 1)			
			TNT1 A 0 A_SetUserVar("user_serverside_sfchk", 1) // reply that we did the deed
		
			
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			CYBR A 3 A_Hoof
			CYBR A 3 A_Chase
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 2, 96)
			CYBR BB 3 A_Chase
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			CYBR CC 3 A_Chase
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 2, 96)
			CYBR D 3 A_Metal
			CYBR D 3 A_Chase
			Loop
		MissileVanilla:
			TNT1 A 0
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -12, -6, 96)
			TNT1 A 0 A_JumpIfTargetInLOS(2)
			TNT1 A 0 A_JumpIf(user_dont_adjust_aim, 2)
			TNT1 A 0 A_FaceTarget
			CYBR E 6 
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 0)
			CYBR F 12 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0) //VanillaCyberRocket
			CYBR E 12 A_FaceTarget
			CYBR F 12 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			CYBR E 12 A_FaceTarget
			CYBR F 12 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			Goto See			
*/
		Missile:
			TNT1 A 0
			
			//TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			TNT1 A 0 A_JumpIf(CallACS("GetCyberdemonCanStompTarget", 180), "Stomp")
			
			// slaughtermap manage - warming the headbox up
			TNT1 A 0 A_JumpIf(!user_sleeping, 4) // forgo the expensive sight check if already awake
			TNT1 A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 2) // bypass the sight check 
			TNT1 A 0 A_CheckSight(2) // out of sight of any player, AND attacking another monster, keep slumbering
			TNT1 A 0 A_SetUserVar("user_sleeping", 0)

			TNT1 A 0 A_JumpIfInTargetInventory("IsInATank", 1, "SpecialAttack")

			// Kinslayer check:	
			TNT1 A 0 A_JumpIfInTargetInventory("TargetIsACyberdemon", 1, 2)
			TNT1 A 0 A_JumpIf(true, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_InfightFriendlyFireOn")	

			
			//TNT1 A 0 A_JumpIfInventory("IAmClassicMonster", 1, "MissileVanilla")
			//TNT1 A 0 A_JumpIf(!CallACS("GetIsZDeltaToTargetInRange", -40, 40), 2)
			//TNT1 A 0 A_JumpIfCloser(180, "Stomp")
			TNT1 A 0 A_JumpIf(CallACS("GetCyberdemonCanStompTarget", 180), "Stomp")
			TNT1 A 0 A_JumpIfInventory("Enraged", 1, "SpecialAttack")
			
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -12, -6, 96)
			
			TNT1 A 0 A_JumpIfTargetInLOS(2)
			TNT1 A 0 A_JumpIf(user_dont_adjust_aim, 2)
			TNT1 A 0 A_FaceTarget
			CYBR E 8
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 0)

			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			
			//TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			TNT1 A 0 A_JumpIf(CallACS("GetCyberdemonCanStompTarget", 180), "Stomp")
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget

				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget
			
			

			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle - 7, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,-7,0)

			
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget

				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget

			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle + 7, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,7,0)		

			
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget

				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget
			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			
			
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget

				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			CYBR E 6 //A_FaceTarget
			
			CYBR E 12
			Goto See
		
		Melee:
			TNT1 A 0 A_JumpIf(!CallACS("GetIsZDeltaToTargetInRange", -40, 40) || CallACS("GetIsTargetUnStompeable"), "Missile")
		Stomp:
			TNT1 A 0
			
			//***Che this stomp is only used by the tyrant, all other cyberdemons override it with a leap-stomp
			// slaughtermap manage - warming the headbox up
			TNT1 A 0 A_JumpIf(!user_sleeping, 4) // forgo the expensive sight check if already awake
			TNT1 A 0 A_JumpIfInTargetInventory("IsPlayer", 1, 2) // bypass the sight check 
			TNT1 A 0 A_CheckSight(2) // out of sight of any player, AND attacking another monster, keep slumbering
			TNT1 A 0 A_SetUserVar("user_sleeping", 0)			
			
			TNT1 A 0 A_JumpIfInTargetInventory("IsInATank", 1, "SpecialAttack")
			
			// Kinslayer check:	
			TNT1 A 0 A_JumpIfInTargetInventory("TargetIsACyberdemon", 1, 2)
			TNT1 A 0 A_JumpIf(true, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_InfightFriendlyFireOn")	
			
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 2, 0, 96)
			
			//TNT1 A 0 A_CustomMissile("FBD_CheckIfTargetIsAbove40")
			//TNT1 A 0 A_CustomMissile("FBD_CheckIfTargetIsBelow40")
			
			//***Che adding a windup sound
			TNT1 A 0 A_Hoof // doom legacy DSHOOF
			TNT1 A 0 A_PlaySound("KYBWHRR", CHAN_BODY)
			
			CYBR Z 4 A_FaceTarget
			
			//TNT1 A 0 A_JumpIfInventory("TargetIsAbove", 1, "NoStomp")
			//TNT1 A 0 A_JumpIfInventory("TargetIsBelow", 1, "NoStomp")
			
			CYBR Z 1
			
			TNT1 A 0 A_Recoil(-5)
			
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 9, -12, 96)
			
			CYMA A 7 A_FaceTarget
			
			TNT1 A 0 A_CustomMissile("CyberStomp",10,0,0,0)
			CYMA B 7
			
			CYMA B 7
			
			Goto See
		Death:
			CYBR H 0
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			CYBR H 0 A_Scream
			CYBR H 10
			CYBR I 4
			CYBR J 4
			TNT1 AAAAAA 0 A_CustomMissile ("HighExplosiveFlames2", random (40, 90)* 0.0000152587890625 * user_head_scale, 0, random (0, 360), 2, random (0, 360))
			CYBR J 4
			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonHead", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonHead", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-5,5),random(-5,5),random(3,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			Goto Death_Explosion


		XDeath:
		Death.Telefrag:	
		XDeath.Telefrag:
			TNT1 A 0
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 A_Scream
			TNT1 A 0 A_CustomMissile("ExplosionSplashSpawner") // liquid splash causer
			TNT1 A 0 Radius_Quake (6, 100, 0, 22, 0)
			TNT1 AAAA 0 A_CustomMissile ("ExplosionSpawner", 90.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 AAAAAA 0 A_CustomMissile ("ExplosionSpawner", 90.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 AAAA 0 A_CustomMissile ("UltraGoreSPawner", 90.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 AAAAAA 0 A_CustomMissile ("UltraGoreSpawner", 90.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 A 0 A_CustomMissile ("CyberXDeath", 0, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 160))
			CYBR IJKLMNOP 1
			CYBR P 120
			CYBR P 1 A_Jump(256, "CheckIfBoss")
			Wait // Zandronum client will skip the jump and keep repeating the last frame until receives status change from the server
				
				
		Death.Head:
			//***Che: Decaptate damage is now relayed directly by the headbox
			//TNT1 A 0
			//TNT1 A 0 A_JumpIfInTargetInventory("HasCutingWeapon", 1, "Death.Decaptate")
		Death.HeadPlasma:
		Death.HeadStun:	
			TNT1 A 0
			TNT1 A 0 A_StopSound(CHAN_VOICE)
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			TNT1 AAA 0 A_CustomMissile ("Brains6Big", 120.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 160))
			TNT1 AAA 0 A_CustomMissile ("Brains7Big", 210.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 160))
			TNT1 AAAAA 0 A_CustomMissile ("XDeath3b", 120.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (50, 90))
			TNT1 AAAAA 0 A_CustomMissile ("XDeath2b", 120.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (50, 90))
			TNT1 AA 0 A_CustomMissile ("MeatDeath", 120.0 * 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (50, 90))
			Goto Death_Beheaded

		Death.Decaptate:
			TNT1 A 0
			TNT1 A 0 A_StopSound(CHAN_VOICE) 
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			//***Che scalability and palette-swappability:
			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonHead", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonHead", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-5,5),random(-5,5),random(3,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			TNT1 AAAAAAAAA 0 A_CustomMissile ("XDeath1", 120.0* 0.0000152587890625 * user_head_scale, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			Goto Death_Beheaded
			
		Death_Beheaded:	
			CYBB AAAA 6 A_SpawnItem("MuchBlood3", 0, 120.0 * 0.0000152587890625 * user_head_scale)
			CYBB ABCABCB 8 A_SpawnItem("MuchBlood", 0, 120.0 * 0.0000152587890625 * user_head_scale)
			Goto Death_Explosion
			
		Death_Explosion:
			EXPL A 0 Radius_Quake (6, 50, 0, 22, 0)
			TNT1 A 0 A_CustomMissile("ExplosionSplashSpawner") // liquid splash causer
			TNT1 AA 0 A_SpawnItemEx ("DetectFloorCrater",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION,0)
			
			TNT1 A 0 A_NoBlocking

			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonArm", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonGun", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonPiece", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			//TNT1 A 0 A_CustomMissile ("XDeathCyberdemonTorso", 120, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 180))
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonArm", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-7,7),random(-7,7),random(0,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonGun", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-7,7),random(-7,7),random(0,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonPiece", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-7,7),random(-7,7),random(0,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			TNT1 A 0 A_SpawnItemEx ("XDeathCyberdemonTorso", 0,0,120.0 * 0.0000152587890625 * user_head_scale, random(-7,7),random(-7,7),random(0,5), 0,SXF_TRANSFERTRANSLATION | SXF_TRANSFERSCALE,0)
			TNT1 AAA 0 A_CustomMissile ("BDExplosionparticles3", 74, 0, random (0, 360), CMF_AIMDIRECTION, random (40, 90))
			TNT1 AAA 0 A_CustomMissile ("BDExplosionparticles4", 76, 0, random (0, 360), CMF_AIMDIRECTION, random (40, 90))
			TNT1 AA 0 A_CustomMissile ("ExplosionSpawner", 40, 0, random (0, 360), CMF_AIMDIRECTION, random (10, 90))
			EXPL AA 0 A_CustomMissile ("BigBlackSmokeLarger", 40, 0, random (0, 360), CMF_AIMDIRECTION, random (10, 90))
			TNT1 A 0 A_CustomMissile ("CyberXDeath", 0, 0, random (0, 360), CMF_AIMDIRECTION, random (0, 160))
			CYBR MNOP 5
			CYBR P 120
			CYBR P 1 A_Jump(256, "CheckIfBoss")
			Wait // Zandronum client will skip the jump and keep repeating the last frame until receives status update from the server		
			
		CheckIfBoss:
			"----" A 1
			"----" A -1 A_BossDeath
			Stop
		Crush:
			TNT1 A 0
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			TNT1 AAAA 0 A_SpawnItemEx ("BodyRemovalThing",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION,0)
			TNT1 A 1 A_XScream
			TNT1 A 30 A_ChangeFlag("CORPSE", 0) // without a *large* margin scripts run ownerless
			Stop
		
		Pain.Taunt:
			TNT1 A 0
			TNT1 A 0 HealThing(1)
			TNT1 A 0 A_JumpIfInventory("Enraged", 1, "SpecialAttack")
			SPOS B 0 A_Pain
			TNT1 A 0 A_ChangeFlag("FASTER", 1)
			TNT1 A 0 A_ChangeFlag("MISSILEMORE", 1)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 1)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_PlaySound("demon/pain", CHAN_VOICE)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			CYBT A 1 A_FaceTarget
			CYBT ABCCBADE 4
			TNT1 A 0 A_PlaySound("CYBTAT", 1)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, 0, 85)
			CYBT FGHGFGHGFGHGFGHG 3
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 0, -7, 96)
			CYBT EDA 4
			"----" A 0 A_GiveInventory("Enraged", 1)
			//Goto Missile
			"----" A 1 A_Jump(256, "Missile")
			Wait
		
		Pain.Killme:
			"----" A 0
			"----" A 0 HealThing(1)
			//Goto Missile
			"----" A 1 A_Jump(256, "Missile")
			Wait

		
		SpecialAttack:
			
			TNT1 A 0 
			TNT1 A 0 A_JumpIfTargetInLOS(2)
			TNT1 A 0 A_JumpIf(user_dont_adjust_aim, 2)
			TNT1 A 0 A_FaceTarget
			CYBR E 6
			TNT1 A 0 A_SetUserVar("user_dont_adjust_aim", 0)
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			
			TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			
			CYBR EE 4 //A_FaceTarget
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle - 7, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,-7,0)
			
			TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			
			CYBR EE 4 //A_FaceTarget
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget

			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle + 7, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,7,0)
			
			TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			
			CYBR EE 4 //A_FaceTarget
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			
			TNT1 A 0 A_JumpIf(CallACS("GetDistanceToTarget", 999) <= 180 && CallACS("GetIsZDeltaToTargetInRange", -40, 40) && !CallACS("GetIsTargetUnStompeable"), "Stomp")
			
			CYBR EE 4 //A_FaceTarget
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			

			CYBR EE 4 //A_FaceTarget
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 4)
				TNT1 A 0 A_JumpIfTargetInLOS(2)
				TNT1 A 0 A_Jump(256, 2)
				TNT1 A 0 A_FaceTarget
			
			
			
			// MUST use auto-aiming at visible targets, otherwise misses at close range due to projectile's origin offset
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 2)
			TNT1 A 0 A_JumpIfTargetInLOS(3)
			// the version with auto-aim disabled:		
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH)
			TNT1 A 0 A_Jump(256, 2)
			// the auto-aimed version:
			CYBR F 3 BRIGHT A_CustomMissile("CyberBalls",60,-25,0,0)
			TNT1 A 0 // a dummy frame for A_Jump

			Goto See
			
		Death.Deletus:
			TNT1 A 0
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 0)
			TNT1 A 0 A_NoBlocking
			TNT1 A 30 A_ChangeFlag("CORPSE", 0) // without a *large* margin scripts run ownerless
			Stop
			
		Death.Fatality:
			TNT1 A 0
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			TNT1 A 0 A_Pain
			TNT1 A 0 A_NoBlocking
			TNT1 A 0 A_JumpIfIntargetInventory("IsPlayer", 1, 1)
			Goto Death
			TNT1 A 0
			TNT1 A 0 A_FaceTarget
			//TNT1 AAAAAA 0 A_SpawnItemEx("HealthPlusFatalityBonus", 0,0,20, random (-1, 1),random (-1, 1),8, 0, SXF_ABSOLUTEVELOCITY | SXF_NOCHECKPOSITION)
			//TNT1 AAAAAA 0 A_SpawnItemEx("ArmorShardFatalityBonus", 0,0,20, random (-1, 1),random (-1, 1),8, 0, SXF_ABSOLUTEVELOCITY | SXF_NOCHECKPOSITION)
			//TNT1 A 0 A_Jump(128, "Death.Fatality2")
			TNT1 A 0 A_GiveToTarget("GoFatality", 1)
			TNT1 A 0 A_GiveToTarget("CyberdemonFatality", 1)
			TNT1 A 30
			TNT1 A 0 ACS_NamedExecuteAlways("DropFatalityBonuses", 0, 30, 30, 0) // 0, health, armor, 0 -- rounded down to nearest 2
			TNT1 A 470
			TNT1 A 1 A_Jump(256, "CheckIfBoss")
			Wait // Zandronum client will skip the jump and keep repeating the last frame until receives status change from the server
			Stop	
/*			
		Death.Fatality2:
			TNT1 A 0
			TNT1 A 0 A_StopSound(CHAN_VOICE) 
			TNT1 A 0 ACS_NamedExecuteWithResult("DeleteHeadboxMkII")
			TNT1 A 0 A_GiveToTarget("GoFatality", 1)
			TNT1 A 0 A_GiveToTarget("CyberdemonFatality", 1)
			TNT1 A 500
			TNT1 A 1 A_Jump(256, "CheckIfBoss")
			Wait // Zandronum client will skip the jump and keep repeating the last frame until receives status change from the server	
*/	
	}
}



ACTOR CyberdemonLegsFatality 17003
{
	Health 200
	Radius 16
	Height 56
	Mass 500
	Speed 12
	PainChance 0
	+BOSS
	+FLOORCLIP
	+DONTMORPH
	+BOSSDEATH
	+SOLID
	+SHOOTABLE
	+THRUACTORS
	DeathSound "world/barrelx"
	Obituary "$OB_CYBORG"
	Tag "Cyberdemon's roaming legs"
	States
	{
		Spawn:
			PATA AABBCCDD 3 A_Wander
			TNT1 A 0 A_ChangeFlag("THRUACTORS", 0)
		See:
			PATA AABBCCDD 3 A_Wander
			Loop
		Death:
			PATA H 10 
			TNT1 AA 0 A_SpawnItem("MeatDeath", 0, 32)
			TNT1 AA 0 A_SpawnItem("RipGuts", 0, 32)
			TNT1 A 0 A_SpawnItem("MuchBlood2", 0, 42)
			PATA I 3
			PATA JKL 3 A_Scream
			PATA M 3 A_NoBlocking
			PATA NO 3
			PATA P 3
			PATA P -1 A_BossDeath
			Stop
	}
}




ACTOR CyberStomp
{
	Radius 12
	Height 8
	+MISSILE
	Speed 15
    Damage 50
	renderstyle translucent
	alpha 0.9
	DamageType Stomp
    Gravity 1.0
    Decal "Cracks"
    -NOGRAVITY
    +EXTREMEDEATH
	+NOTELEPORT
	+THRUACTORS
	//***Che these obituaries never work, the game engine uses monster's obituary
	Obituary "%o was stepped on by a Cyberdemon."
	HitObituary "%o was stepped on by a Cyberdemon."
	States
	{
		Spawn:
			TNT1 A 1
			TNT1 A 0 ThrustThingZ(0, -35, 0, 0)
			TNT1 A 10
			Stop
		Death:
			MARN A 0 A_SpawnItemEx("FootStepStrong", 0, 0, 8, 0, 0)
			TNT1 A 0 A_PlaySound("CLAP", 1)
			EXPL AAAA 0 A_CustomMissile ("ExplosionSmoke", 0, 0, random (0, 360), 2, random (10, 12))
			TNT1 A 0 Radius_Quake(4, 15, 0, 25, 0)
			TNT1 A 0 Radius_Quake(2, 15, 0, 45, 0)
			EXPL A 0 A_Explode
			SM8K BDFHJLNPRTVXZ 1
			Stop
	}
}

ACTOR CyberStompMedium: Cyberstomp
{
	Scale 1.5
	States
	{
		Death:
			MARN A 0 A_SpawnItemEx("FootStepStrong", 0, 0, 8, 0, 0)
			//***Che a mightier, more metallic sound
			TNT1 A 0 A_PlaySound("KYBSTMP1", 1)
			EXPL AAAA 0 A_CustomMissile ("ExplosionSmoke", 0, 0, random (0, 360), 2, random (10, 12))
			TNT1 A 0 Radius_Quake(4, 15, 0, 25, 0)
			TNT1 A 0 Radius_Quake(2, 15, 0, 45, 0)
			EXPL A 0 A_Explode(150, 150)
			SM8K ABCDEFGHIJKLMNOPQRSTUWVXYZ 1
			Stop
	}
}

ACTOR CyberStompBig: Cyberstomp
{
	Scale 2.0
	States
	{
		Death:
			MARN A 0 A_SpawnItemEx("FootStepStrong", 0, 0, 8, 0, 0)
			TNT1 A 0 A_PlaySound("KYBSTMP1", 1)
			EXPL AAAA 0 A_CustomMissile ("ExplosionSmoke", 0, 0, random (0, 360), 2, random (10, 12))
			TNT1 A 0 Radius_Quake(4, 15, 0, 25, 0)
			TNT1 A 0 Radius_Quake(2, 15, 0, 45, 0)
			EXPL A 0 A_Explode(300, 300)
			SM8K ABCDEFGHIJKLMNOPQRSTUWVXYZ 1
			Stop
	}
}

#include Cyber_Regular.txt

#include Cyber_Tyrant.txt

#include Cyber_Chad.txt

#include Cyber_Devastator.txt