

//***Che: Monstrosities coded by ChebMaster

// This file is an include for Archvile.txt


// vile soul reaver is a weaker version 
// arch trickster has less health than soul reaver but very strong deflector shields he brings up on every blink but lowers when he attacks. In monstersonly he heals himself instead
// arch devil is their big daddy, he can also have weak deflector shields but only if the map scripts give him the token "FBD_CanDeflectPlayersMissiles"


Actor RaiseableArchvile: FBD_Archvile 17694 {
	States{
		Spawn:
			DIAB B 0 NODELAY ACS_NamedExecuteWithResult("FBD_RunMonster", 5) // vile headbox 
			TNT1 A 0 A_GiveInventory("EnemyIsArchvile")
			TNT1 A 0 A_GiveInventory("IAmRaiseable")
			
			DIAB B 1 //7 // slaughtermap init takes 5 tics
			Goto Stand
	}
}

Actor VileSoulReaver: FBD_Archvile 17692 { // NEVER initiates fireball spam on his own, uses regular vile flame unless provoked
	// NEVER raiseable
	// + minion ghost soul
	// + blink
	// + after blink, retaliates with a six-pack of recolored revenant fireballs that inflict fire damage, followed by a regular vile flame

	//$category "FBD Monsters"

	//Shiny red
	Translation "48:50=4:4", "48:67=168:181", "68:79=36:47", "13:15=191:191", "9:12=37:47", "5:8=47:47", "13:15=47:47", "1:2=47:47", "236:239=191:191", "144:151=37:47", "128:143=22:47"
	
	//$Sprite DIBRX1
	
	Tag "$FBD_SUPERVILE_2" // "Vile Soul Reaver"
	Obituary "$FBD_SUPERVILE_2_O" // "%o was incinerated a Vile Soul Reaver."
	
	damagefactor "Avoid", 1.0 // the players rocket launcher fires the alerter when firing
	damagefactor "RailAvoid", 1.0 // one of 2 monsters affected by this are these super viles.
	  // The players railgun fires such a rail attack three times per second
	damagefactor "YouMustDuck", 1.0 // the player's super shotgun. Normally only headboxes are supceptible, but the supervile is such a special snowflake (pointy, deep up yours)...
	PainChance "Avoid", 255 
	PainChance "RailAvoid", 255 
	PainChance "YouMustDuck", 255
	
	damagefactor "Argent", 0.0
	
	PainChance 64 // this actually makes him *more* dangerous because he blinks away on pain
	
	// he has no specific pain state for this, just guarantees he tries teleporting out when he is plummeting
	PainChance "PlummetAaah", 255 // bottomless pits in Chebskies-EDAY
	DamageFactor "PlummetAaah", 1.0	

	Health 1200
	
	MaxTargetRange 4000
	
	States{
		Spawn:
			DIAB B 1 NODELAY ACS_NamedExecuteWithResult("FBD_RunMonster",5)
			TNT1 A 0 A_GiveInventory("EnemyIsArchvile")
			
			DIAB B 1 //7 // slaughtermap init takes 5 tics
			
			// makes regular viles *and* pain elementals raiseable
			// (and pain elementals also respawning on nightmare)
			TNT1 A 0 A_RadiusGive("IAmRaiseable", 200, RGF_MONSTERS | RGF_NOSIGHT, 1)
			Goto Stand
		MaybeFireAGhostSoul:
			TNT1 A 0
			TNT1 A 0 A_TakeInventory("IAmRaiseable", 1) // not raiseable
			TNT1 A 0 A_Jump(128, "FireGhostSoul")
			Goto SeeContinue	
		
		IosChastises: // required by Chebskies-EDAY map 313
			"----" A 0 A_ClearTarget
			"----" A 0 HealThing(100)
			"----" A 0 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 10, 60, 0)		
			Goto Pain
			
		Pain:
			TNT1 A 0
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_TakeInventory("DuckYouFool", 1)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -19, -7, 54)
			DIAB Q 5 A_Pain  
			"----" A 0 A_TakeInventory("BlinkCooldown", 30)
			Goto BlinkAway
		
		Pain.Avoid:
		Pain.RailAvoid:
		Pain.YouMustDuck:
			"----" A 0
			"----" A 0 HealThing(5)
			"----" A 0 A_ChangeFlag("NOPAIN", 1)
			"----" A 0 A_TakeInventory("DuckYouFool", 1)
			"----" A 0 A_SetUserVar("user_sleeping", 0)
			"----" A 0 A_Jump(48, "FireFlameSpam")
			Goto BlinkAway
		BlinkAway:
			"----" A 0
			"----" A 0 A_SetUserVar("user_attacking", 1)
			//"----" A 0 ACS_NamedExecuteAlways("FBD_CustomizeSupervileBlink") // it runs 
				// a map script if the map provided one -- see OnSuperVileBlinkMapScript
			
			"----" A 0 A_JumpIf(CallAcs("FBD_CustomizeSupervileBlink"), "ShieldsUpThenSee")
			
			"----" AAA 0 A_CustomMissile("AoeRaiseInflictorShortRange", 30, 0, Random(0,360), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, Random(-15,15))
			
			"----" A 0 A_TakeInventory("IAmRaiseable", 1) // not raiseable
			"----" A 0 A_JumpIfInventory("BlinkCooldown", 1, "LeapSideways")
			"----" A 1 A_Jump(256, "TryBlink")
		TryBlink:	
			// first, try find a position in open space at a distance of 1000 
			"----" AAAAA 0 A_CustomMissile("SuperVileBlinkPositionFinder1000", 40, 0, random(40,320), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random(0, 45))
			// then, a position in open space at a distance of 600 (+ 2 tics delay)
			"----" AAAAA 0 A_CustomMissile("SuperVileBlinkPositionFinder600", 40, 0, random(40,320), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random(0, 45))
			// then, a long-range scan that succeeds even if it hits a wall (+ 3..4 tics delay)
			"----" AAAAA 0 A_CustomMissile("SuperVileBlinkPositionFinder4000", 40, 0, random(0,359), CMF_AIMDIRECTION | CMF_ABSOLUTEPITCH, random(0, 20))
			// we are getting desperate here. A small room? A tight corridor?
			// fire slow, floor hugging crawlers designed to get us up ledges or through low windows
			// (4..14 tics delay)
			"----" AAAAAAA 0 A_CustomMissile("SuperVileBlinkPositionFinderFallbackUpClose", 0, 0, random(40,320), CMF_AIMDIRECTION, 0)
		LeapSideways:
			// meanwhile, duck
			DIAB Y 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 9, 0, 37) // z from hitbox height - headbox height - 1, not from the sprite!
			DIAB Y 1 A_Jump(256, "LeapLeft", "LeapRight")
			Wait // without this, will leap in a wrong direction clientside half the time instead of sitting and waiting for an update from the server
			
		LeapRight:
			TNT1 A 0 A_SetAngle(angle - 80)
			TNT1 A 0 A_Recoil(8)
			TNT1 A 0 A_SetAngle(angle + 80)
			Goto LeapInProgress
		LeapLeft:
			TNT1 A 0 A_SetAngle(angle + 80)
			TNT1 A 0 A_Recoil(8)
			TNT1 A 0 A_SetAngle(angle - 80)
		LeapInProgress:
			// it is hopefully during *this* phase that the position finders blink us
			
			DIAB Y 4
			DIAB Y 4 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 9, 0, 37)
			DIAB YYYYYYYYYY 2 A_CheckFloor ("LandFromLeap")
		LandFromLeap:	
			TNT1 A 0 A_JumpIfTargetInLOS("FuriousRetaliation")
			TNT1 A 0 A_Jump("BlinkCooldown", 1, "FuriousRetaliationBlindfire") // blink succeeded
			DIAB K 4 BRIGHT ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 21, 6, 41)
			DIAB KLKLKLKL 2 A_JumpIfInventory("BlinkCooldown", 1, "FuriousRetaliationBlindfire") // blink succeeded
			"----" A 1 A_Jump(256, "FuriousRetaliationBlindfire")
			Wait
			
		ShieldsUpThenSee:
			"----" A 0
			Goto See

		FuriousRetaliation:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			
			//TNT1 A 0 A_Jump(128, "Missile","Missile","FireFlameSpam")	
			Goto FireFlameSpam
			//Goto FireGhostSoul
		FuriousRetaliationBlindfire:
			// The ACS script that teleports us turns us to face our former position.
			// Thus by firing at our former position we have a good chance 
			// of our homing missiles catching the sight of player somewhere along the way
			// and targeting.
			// (the advanced revenant fireball only steers if it has a line of sight
			//  to its tracer, flying in a straight line otherwise)
			
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			DIAB K 1 A_Jump(256, "FireGhostPainNoFaceTarget","FireGhostPainNoFaceTarget","BlindFireFlameSpam")
			Wait
		FireGhostSoul:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_PlaySound("DSVILFGS", CHAN_VOICE) // Yoi!
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -8, 0, 60)
			DIBR XX 5 BRIGHT A_CustomMissile("SummoningFlash_1", 50, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, 0)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -20, 0, 60)
			DIBR XX 5 BRIGHT A_CustomMissile("SummoningFlash_2", 50, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, 0)
			
			DIBR Y 10 BRIGHT A_SpawnItem("AttackGhostSoul", 0, 30)
				// distance 0 means the sum of radii will be used!
				
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
			Goto See

		FireGhostPain:
		
			TNT1 A 0
			TNT1 A 0 A_FaceTarget
			
		FireGhostPainNoFaceTarget:	
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -8, 0, 60)
			DIBR YY 4 BRIGHT A_CustomMissile("SummoningFlash_1", 50, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, 0)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -20, 0, 60)
			DIBR YY 4 BRIGHT A_CustomMissile("SummoningFlash_2", 50, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, 0)
			
			DIBR Y 10 BRIGHT A_CustomMissile("GhostPain",25,0,angle, CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH, 0)
				
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
			
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), "See")
			TNT1 A 0 A_JumpIfTargetInLOS("GenericVileFlame")
			
			Goto See
		BlindFireFlameSpam:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_GiveInventory("VileBarrageCount", 6)
			DIAB K 4 BRIGHT ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 21, 6, 41)
			DIAB LMLMLM 2 BRIGHT
			
			//Goto FlameSpamContinue
			"----" A 1 A_Jump(256, "FlameSpamContinue")
			Wait
			
		FireFlameSpam:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 21, 6, 41)
			DIAB K 4 BRIGHT A_FaceTarget
			DIAB LMLMLM 2 BRIGHT 
			"----" A 0 A_GiveInventory("VileBarrageCount", 6)
			
			// respect inheritance (Andariel, for starters)
			"----" A 1 A_Jump(256, "FlameSpamContinue") 
			Wait
			
		FlameSpamContinue:	
		
			TNT1 A 0 A_JumpIfInTargetInventory("IsInATank", 1, "FlameSpamContinueAntitank")
		
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 10, -3, 49)
			DIAB N 3 BRIGHT
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 ACS_NamedExecuteWithResult("FBD_FaceTargetIfCanSeeIt")			
			
			DIAB O 3 BRIGHT A_CustomMissile("VileFireball",41,0,angle + 0.3 * random(-2,2), CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH, 0.1 * random(0,2))
			
			"----" A 0 A_TakeInventory("VileBarrageCount", 1)
			"----" A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			
			"----" A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), "FlameSpamEnd")
			"----" A 0 A_JumpIfTargetInLOS("VileFlameAfterFlameSpam")
			"----" A 1 A_Jump(256, "FlameSpamEnd")
			Wait
			
		FlameSpamContinueAntitank:
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 10, -3, 49)
			DIAB N 3 BRIGHT
			
				//***Che: do NOT adjust aim if target goes out of sight or is invisible
				TNT1 A 0 ACS_NamedExecuteWithResult("FBD_FaceTargetIfCanSeeIt")		
			
			DIAB O 3 BRIGHT A_CustomMissile("VileChaosBall",41,0,angle + 0.3 * random(-2,2), CMF_ABSOLUTEANGLE | CMF_OFFSETPITCH | CMF_SAVEPITCH, 0.1 * random(0,2))
			
			TNT1 A 0 A_TakeInventory("VileBarrageCount", 1)
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			
			Goto FlameSpamEnd
			
		FlameSpamEnd:	
			DIAB P 10 BRIGHT ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 10, -3, 49)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
			Goto See
			
		VileFlameAfterFlameSpam:
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 0)
			DIAB N 3 BRIGHT A_FaceTarget
			DIAB O 3 BRIGHT A_VileStart
			TNT1 A 0 A_FaceTarget
			DIAB N 6 BRIGHT A_VileTarget
			TNT1 A 0 A_FaceTarget
			DIAB O 6 BRIGHT A_VileTarget
			TNT1 A 0 A_FaceTarget
			DIAB N 6 BRIGHT A_VileTarget
			TNT1 A 0 A_FaceTarget
			DIAB O 6 BRIGHT A_VileTarget
			TNT1 A 0 A_FaceTarget
			DIAB N 6 BRIGHT A_VileTarget
			TNT1 A 0 A_FaceTarget
			DIAB O 6 BRIGHT A_VileTarget
			TNT1 A 0 ACS_NamedExecuteWithResult("AdjustHeadboxMkII", 10, -3, 49)
			DIAB P 10 BRIGHT A_VileAttack
			Goto See
			
		Heal: //***Che oooh im *soooo* evil! :)
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_SpawnItem("PentagramSpawner") // spawns *in front* of the vile
				// as per A_SpawnItem with distance of zero
				// (uses vile radius + pentagram radius)
			
			
			//***Che: the frame DIBR X here is radically different from DIBR X in BD21!
			// I frankensteined horns to retouched DIBR X from BD 22 
			//   where he holds his arms out instead of up.
			// The arms up frame is now DIBR Y, only used in derivative archviles
			//   for extra nasty attacks
			//   like a BFG-like AOE mass resurrection
			DIBR X 10 BRIGHT ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -8, 0, 60)
			
			DIBR Y 1 BRIGHT ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -20, 0, 60)
			
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 30, 60, 50)
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 35, 60, 50)
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 40, 60, 50)
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 45, 60, 50)
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 50, 60, 50)
			DIBR Y 3 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 55, 60, 50)
			
			// the TRUE horror, raising *all* standalone corpses in a large radius:
			DIBR YYYYY 0 A_CustomMissile("AoeRaiseInflictorShortRange", 30, 0, Random(0,360), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, Random(-15,15))				
			
			
			// old BD21 frame //ACS_NamedExecuteWithResult("AdjustHeadboxMkII", -15, 0, 50)
			Goto See	
		
		MissileAntiTank:
			"----" A 0 A_JumpIfInventory("BlinkCooldown", 1, "FuriousRetaliation")
			"----" A 1 A_Jump(256, "BlinkAway") 
			Wait
		
			
	}	
}


Actor ArchTrickster: VileSoulReaver 17897
{
	Health 900
	
	Tag "$FBD_SUPERVILE_2B" // "Arch Trickster"
	Obituary "$FBD_SUPERVILE_2B_O" // "%o was fooled by an Arch Trickster."
	
	// blue
	Translation "51:79=192:207", "13:15=242:242", "9:12=201:207", "5:8=207:207", "13:15=207:207", "1:2=207:207", "236:239=242:242", "48:50=4:4", "128:143=195:207", "144:151=200:207"
	
	var int user_deflector_shield_max;
	var int user_deflector_shield;
	var int user_deflector_shield_recovery; // must be zero - his shields do not recover automatically
	var int user_missile_deflection_spread;	
	
	States {
		Spawn:
			DIAB B 1 NODELAY ACS_NamedExecuteWithResult("FBD_RunMonster",5) 
			TNT1 A 0 A_GiveInventory("EnemyIsArchvile")
			
			"----" A 0 A_GiveInventory("FBD_CanDeflectPlayersMissiles", 1)
			//"----" A 0 A_SetUserVar("user_deflector_shield_recovery", 0) // never auto-recover, only bring it back up after blinking
			"----" A 0 A_SetUserVar("user_deflector_shield_max", 100)
			"----" A 0 A_SetUserVar("user_missile_deflection_spread", 25) // every which way but still dangerous
			
			DIAB B 1
			
			"----" A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp") // do NOT increase his starting health!
			/*
				NOTE: in monstersonly, this script increases monster's current health instead
				-- since the deflecting is implemented player weapons side
				and thus does not exist in monstersonly!
				Thus, the archtrikster heals every time he'd bring his shields up.
			*/
			
			// makes regular viles raiseable
			TNT1 A 0 A_RadiusGive("IAmRaiseable", 200, RGF_MONSTERS | RGF_NOSIGHT, 1)
			Goto Stand
			
		ShieldsUpThenSee:
			"----" A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 1)
			Goto See
			"----" A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 130) // heals 30% = 270 in monstersonly
			Goto See

		FuriousRetaliation:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 2)
			TNT1 A 0 A_Jump(256, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 130) // heals 30% = 270 in monstersonly
			
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			
			//TNT1 A 0 A_Jump(128, "Missile","Missile","FireFlameSpam")	
			Goto FireFlameSpam
			
		FuriousRetaliationBlindfire:
			// The ACS script that teleports us turns us to face our former position.
			// Thus by firing at our former position we have a good chance 
			// of our homing missiles catching the sight of player somewhere along the way
			// and targeting.
			// (the advanced revenant fireball only steers if it has a line of sight
			//  to its tracer, flying in a straight line otherwise)
			
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 2)
			TNT1 A 0 A_Jump(256, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 130) // heals 30% = 270 in monstersonly			
			
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			DIAB K 1 A_Jump(256, "FireGhostPainNoFaceTarget","FireGhostPainNoFaceTarget","BlindFireFlameSpam")
			Wait			
	}
}


Actor ArchDevil: ArchTrickster 17693 {
	// NEVER raiseable
	// + the six-pack of recolored revenant fireballs is his normal modus operandi
	// + has a small chance to fire the ghost pain as his regular attack
	// + higher flinch chance, blinks more readily
	// + AOE mass raise attack by firing a ghost pain that spams ghost souls -- after blink 66% or as his regular attack 25%

	//Dark green with shiny purple highlights
	Translation "48:50=4:4", "51:56=169:172", "57:67=250:254", "68:79=123:127", "128:135=250:254", "208:213=168:171", "214:223=250:254", "136:143=123:127", "13:15=127:127", "9:12=125:127", "5:8=0:0", "13:15=127:127", "1:2=0:0", "236:239=127:127", "144:151=123:127"
	
	//$Sprite DIBRY1
	
	Tag "$FBD_SUPERVILE_3" // "Arch Devil"
	Obituary "$FBD_SUPERVILE_3_O" // "%o was massacred by an Arch Devil."
	
	
	MaxTargetRange 8000
	
	Health 1800
	
	PainChance 128 // this actually makes him *more* dangerous because he blinks away on pain
	
	States{
		Spawn:
			DIAB B 1 NODELAY ACS_NamedExecuteWithResult("FBD_RunMonster", 5)
			TNT1 A 0 A_GiveInventory("EnemyIsArchvile")

			// does NOT get the token but can be added by map scripts
			"----" A 0 A_SetUserVar("user_deflector_shield_max", 50) // one rocket or 3 plasma shots
			//"----" A 0 A_SetUserVar("user_deflector_shield_recovery", 0) // never auto-recover, only bring it back up after blinking
			"----" A 0 A_SetUserVar("user_missile_deflection_spread", 1) // in your face!			
			
			DIAB B 1 //7 // slaughtermap init takes 5 tics
			
			// makes regular viles *and* pain elementals raiseable
			// (and pain elementals also respawning on nightmare)
			TNT1 A 0 A_RadiusGive("IAmRaiseable", 700, RGF_MONSTERS | RGF_NOSIGHT, 1)
			Goto Stand
		MaybeFireAGhostSoul:
			TNT1 A 0
			Goto FireGhostSoul
		Pain.Avoid:
		Pain.RailAvoid:
		Pain.YouMustDuck:
			TNT1 A 0
			TNT1 A 0 HealThing(5)
			TNT1 A 0 A_SetUserVar("user_sleeping", 0)
			Goto BlinkAway
		FuriousRetaliation:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("NOPAIN", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 2)
			TNT1 A 0 A_Jump(256, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 110) // only heals 10% in monstersonly... Which is 180!
			
			DIAB B 1 A_Jump(256, "FireGhostPain", "FireGhostPain", "FireFlameSpam")
			Wait // Zandronum clientside trickery
		Missile:
			TNT1 A 0
			TNT1 A 0 A_TakeInventory("IAmRaiseable", 1) // not raiseable
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			
			TNT1 A 0 A_JumpIfInTargetInventory("IsInATank", 1, "MissileAntiTank")
			
			//***Che: attack bruisers and bosses by headshotting them
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_TryReAggroAtHead",1,1,TIDtoHate)
			
			TNT1 A 0 A_Jump(64, "FireGhostPain")
			Goto FireFlameSpam
		ShieldsUpThenSee:
			"----" A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 1)
			Goto See
			"----" A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 110) // only heals 10% in monstersonly... Which is 180!
			Goto See
		FuriousRetaliationBlindfire:
			// The ACS script that teleports us turns us to face our former position.
			// Thus by firing at our former position we have a good chance 
			// of our homing missiles catching the sight of player somewhere along the way
			// and targeting.
			// (the advanced revenant fireball only steers if it has a line of sight
			//  to its tracer, flying in a straight line otherwise)
			
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_attacking", 1)
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 0)
			TNT1 A 0 A_ChangeFlag("MISSILEEVENMORE", 0)
			
			TNT1 A 0 A_JumpIfInventory("FBD_CanDeflectPlayersMissiles", 1, 2)
			TNT1 A 0 A_Jump(256, 2)
			TNT1 A 0 ACS_NamedExecuteWithResult("DeflectorShieldsUp", 110)  // only heals 10% in monstersonly... Which is 180!	
			
			TNT1 A 0 A_JumpIfInventory("VileBarrageCount", 1, "FlameSpamContinue")
			DIAB K 1 A_Jump(256, "FireGhostPainNoFaceTarget","FireGhostPainNoFaceTarget","BlindFireFlameSpam")
			Wait				
	}	
}


Actor VileBarrageCount: Inventory
{
	inventory.maxamount 30
}

Actor GhostSoulExpiration: Inventory
{
	inventory.maxamount 100 
}


Actor GhostSoul {
	
	//Red Doom PR Beta skull
	Translation "168:191=0:0", "25:47=0:0", "80:111=168:191", "112:127=168:184", "192:207=170:178", "48:79=168:191", "128:143=175:191", "144:151=168:191", "160:167=168:179", "152:159=29:41"
	
	// there is no tag because this monster is a ghost and not selectable via monster name picker
	Obituary "$FBD_GHOSTSOUL_O" // "%o was zapped by a Ghost Soul."
	
	RenderStyle Add
	Alpha 0.6
	
	+MISSILE
	+SEEKERMISSILE // we cheat by using this flag temporarily to acquire our master's target.
		// we then clear it and set the ISMONSTER flag 
		
	+THRUACTORS
	+GHOST
	+THRUGHOST
	+FLOORCLIP
	+FLOAT
	+NOGRAVITY
	-SHOOTABLE
	+NOTARGET
	+BRIGHT
	
	AttackSound "skull/melee"
	PainSound "skull/pain"
	//DeathSound "skull/death"
	DeathSound "LSOD"
	ActiveSound "skull/active"
	
	DamageFactor "Argent", 0.0
	
	Speed 12
	Radius 16
	Height 32

	States {
		Spawn:
			// Set the tracer (our spawner's target) as our target and our spawner as out master 
			YKUL A 0 NODELAY A_RearrangePointers(AAPTR_TRACER, AAPTR_TARGET, AAPTR_NULL, PTROP_NOSAFEGUARDS)
			TNT1 A 0 A_ChangeFlag("MISSILE", 0)
			TNT1 A 0 A_ChangeFlag("SEEKERMISSILE", 0)
			TNT1 A 0 A_ChangeFlag("ISMONSTER", 1)
			TNT1 A 0 A_PlaySound("skull/active", CHAN_VOICE)
		Idle:
			YKUL AAA 3 A_Wander
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			TNT1 A 0 A_SetAngle(angle + random(-30,30))
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 1)
			TNT1 A 0 A_JumpIfInventory("GhostSoulExpiration", 10, "Death")
			YKUL A 3 A_VileChase // jumps straight to Idle if no target
		See:	
			YKUL AAA 3 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL AAA 3 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			TNT1 A 0 A_SetAngle(angle + random(-30,30))
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 1)
			TNT1 A 0 A_JumpIfInventory("GhostSoulExpiration", 20, "Death")
			Loop
		Missile:
			TNT1 A 0
			TNT1 A 0 A_PlaySound("skull/melee", CHAN_VOICE)
			YKUL A 1 A_FaceTarget
		MissileContinue:
			TNT1 A 0 A_JumpIfCloser(110, "LastLunge") // it goes *through* its target in a straight line
			YKUL AAA 1 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL AAA 1 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL ABC 1 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL DEF 1 A_VileChase
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 1)
			TNT1 A 0 A_JumpIfInventory("GhostSoulExpiration", 13, "Death")
			TNT1 A 0 A_Jump(96, "Retarget")
			TNT1 A 0 A_JumpIfTargetinLOS("MissileContinue")
			TNT1 A 0 A_PlaySound("skull/pain", CHAN_VOICE)
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 4)
			Goto Idle
		Retarget:
			TNT1 A 0
			TNT1 A 0 A_ClearTarget
			Goto Idle
		LastLunge:
			TNT1 A 0
			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), 1)
			TNT1 A 0 A_FaceTarget
			TNT1 A 0 A_PlaySound("skull/melee", CHAN_VOICE)
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 100)
			YKUL AB 1 A_Recoil(-1)
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL CD 1 A_Recoil(-1)
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			YKUL EF 1 A_Recoil(-1)
			TNT1 A 0 A_CustomMissile("GhostSoulAttack", 1, 0, angle, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -45)
			Goto Death
		Crush:	
		Death:
		XDeath:
			TNT1 A 0
			TNT1 A 0 A_Scream
			YKUL GHIJKLMNOP 2 A_FadeOut(0.05)
			Stop
		Heal:
		
			// collapse into a vertical line while accelerating downwards: an illusion of diving into the corpse
			TNT1 A 0 A_PlaySound("skull/death", CHAN_VOICE)
			
			YKUL G 2 ThrustThingZ(0,5,1,0)
			TNT1 A 0 A_SetScale(0.9, 1.0)
			YKUL H 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.85, 1.0)
			YKUL I 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.8, 1.0)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL J 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.75, 1.1)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL K 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.7, 1.2)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL L 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.6, 1.3)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL M 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.5, 1.35)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL N 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.4, 1.3)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL O 2 A_FadeOut(0.02)
			TNT1 A 0 A_SetScale(0.3, 1.2)
			TNT1 A 0 ThrustThingZ(0,5,1,1)
			YKUL P 2 A_FadeOut(0.02)
			TNT1 A 0 ThrustThingZ(0,40,1,1)
			TNT1 A 3
			TNT1 A 50 ACS_NamedExecuteWithResult("DisplayArgentDischarge", 40, 15, 8) // a flat ring
			Stop
	}
}



Actor HotLaunchGhostSoul: GhostSoul { // ghost pain spams this
	// accelerate immediately 
	States {
		Spawn:
			// Set the tracer (our spawner's target) as our target and our spawner as out master 
			YKUL A 0 NODELAY A_RearrangePointers(AAPTR_TRACER, AAPTR_TARGET, AAPTR_NULL, PTROP_NOSAFEGUARDS)
			TNT1 A 0 A_ChangeFlag("MISSILE", 0)
			TNT1 A 0 A_ChangeFlag("SEEKERMISSILE", 0)
			TNT1 A 0 A_ChangeFlag("ISMONSTER", 1)
			TNT1 A 0 ThrustThing(angle*256/360, 15, 0, 0) // give it a kick to start moving
			YKUL AAA 3
			TNT1 A 0 A_Jump (85, "Coward") // 33% chance of it moving *away* from target, to cover a bigger area with the swarm!
			Goto Idle
		Coward:
			TNT1 A 0
			TNT1 A 0 A_ChangeFlag("FRIGHTENED", 1)
			Goto Idle
	}
}



Actor AttackGhostSoul: GhostSoul {
	// attack immediately if target in sight
	States {
		Spawn:
			// Set the tracer (our spawner's target) as our target and our spawner as out master 
			YKUL A 0 NODELAY A_RearrangePointers(AAPTR_TRACER, AAPTR_TARGET, AAPTR_NULL, PTROP_NOSAFEGUARDS)
			TNT1 A 0 A_ChangeFlag("MISSILE", 0)
			TNT1 A 0 A_ChangeFlag("SEEKERMISSILE", 0)
			TNT1 A 0 A_ChangeFlag("ISMONSTER", 1)
			TNT1 A 0 ThrustThing(angle*256/360, 15, 0, 0) // give it a kick to start moving
			YKUL AAA 3
			TNT1 A 0 A_JumpIfTargetinLOS("Missile")
			Goto See
		Retarget:
			TNT1 A 0
			TNT1 A 0 A_JumpIfTargetinLOS("MissileContinue")
			TNT1 A 0 A_ClearTarget
			Goto Idle	
	}
}






Actor GhostSoulAttack {
	+MISSILE
	Speed 10 // inflicts boo boo every frame, meaning 2 to 3 times per a small monster with a diameter of 32
	// note that this missile is *slower* than the ghost soul who fires it
	Damage (random(2,2))
	Radius 16
	Height 30
	+THRUGHOST
	+THRUACTORS
	+NOGRAVITY
	
	Damagetype "Argent" // monsters have a pain state that heals and enrages them
	
	States {
		Spawn:
			TNT1 AAA 1 A_Explode(5, 40)
		Death:
			TNT1 A 0 // presumably, we hit a wall
			Stop
	} 
}



Actor GhostPain: FBD_RevenantBall {

	/* 
		//***Che This is based on my *old* advanced revenant fireball code.
		Such a complete clone I just leave it as is, only commenting out the declumping code
	*/

	Damage (random(0,0))
	SeeSound None
	DeathSound None
	+GHOST
	+THRUACTORS
	+THRUGHOST
	+NOGRAVITY
	+BRIGHT
	
	Radius 20
	Height 30
	
	SeeSound "pain/sight"
	DeathSound None
	
	// Red pain elemental
	Translation "128:151=173:191", "163:167=168:191", "56:79=168:191", "13:15=186:191", "236:239=186:191", "47:47=239:239", "91:111=168:184", "208:223=168:191", "224:231=168:177", "232:235=183:183"
	
	// there is no tag because this thing is not a monster
	// there is no obituary because it does no damage
	
	RenderStyle Add
	Alpha 0.8
	
	var int user_aoe_cd;
	
	// removed these from my new fireball, adding here:
	var int user_wobble_pitch;
	var int user_wobble_angle;
	
	States {
		Spawn:
			
			PAIN D 4 // leave the spawner before spamming
			
		
			//TNT1 A 0 ACS_NamedExecuteAlways("RFDeclumpManageServerside", 0) // runs until we disappear
			Goto Fly
		RestorePointersAndFly:
			TNT1 A 0
			// move target from master to its rightful place
			TNT1 A 0 A_RearrangePointers (AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS)
		Fly:	
			//TNT1 AA 2
			
			// give it a vertical kick. It will give the forward kick to itself.
			
			PAIN F 8 A_SpawnItemEx("HotLaunchGhostSoul", 0,0,20, 0,0,0.1 * Random(-5,5), Random(90,270),0,0)
			
			TNT1 A 0 A_SetUserVar("user_aoe_cd", user_aoe_cd + 1)
			TNT1 A 0 A_JumpIf(user_aoe_cd < 5, 3)
			TNT1 A 0 A_SetUserVar("user_aoe_cd", 0)
			TNT1 A 0 A_CustomMissile("AoeRaiseInflictor", 16, 0, Random(0,360), CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, Random(-90, -75))
			
			
			TNT1 A 0 A_GiveInventory("GhostSoulExpiration", 1)
			TNT1 A 0 A_JumpIfInventory("GhostSoulExpiration", 40, "Death")
			
			// the behavior

			// overwrite target with tracer, allows checking LOS and inventory on tracer - while saving the target in master
			TNT1 A 0 A_RearrangePointers (AAPTR_TRACER, AAPTR_DEFAULT, AAPTR_TARGET, PTROP_NOSAFEGUARDS) //*very* fast unless you forgot the nosafeguards

			TNT1 A 0 A_JumpIf(CallAcs("FBD_TargetIsInvisible"), "HomeAtInvisible")			
			TNT1 A 0 A_CheckFlag("SOLID", "HomeAdvanced", AAPTR_TRACER) // if we *did* acquire a target, switch to advanced 
			// move target from master to its rightful place
			TNT1 A 0 A_RearrangePointers (AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS)
			TNT1 A 0 A_SeekerMissile (4,8, SMF_LOOK | SMF_PRECISE) // can acqire a tracer
			Loop

/*			
		CheckDeClump:	
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_declump_commanded", 0) // is set to 1 by a serverside-only ACS scrpt, according the load balancer
			// 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 BRIGHT A_RadiusGive("RFDeClumpCountServerside", 32, RGF_OBJECTS | RGF_MISSILES | RGF_MONSTERS | RGF_CUBE | RGF_NOSIGHT, 1)	
		
			Goto RestorePointersAndFly			
		PerformDeclump:
			TNT1 A 0
			TNT1 A 0 A_SetUserVar("user_steering_commanded", 0)
			// move target from master to its rightful place
			TNT1 A 0 A_RearrangePointers (AAPTR_MASTER, AAPTR_DEFAULT, AAPTR_DEFAULT, PTROP_NOSAFEGUARDS)
			
			// change direction, then fly in a straight line for one second
			TNT1 A 0 A_SetAngle(angle + 1.0 * user_wobble_angle)
			TNT1 A 0 A_ChangeVelocity(momx, momy, momz + 0.1 * user_wobble_pitch, CVF_REPLACE)
			PAIN FFFF 8 A_SpawnItem("GhostSoul", 0, 20)
			TNT1 A 0 A_SetUserVar("user_wobble_angle", 0)
			TNT1 A 0 A_SetUserVar("user_wobble_pitch", 0)
			Goto Fly
*/			
		HomeAtInvisible:	
			TNT1 A 0
			TNT1 A 0 A_Jump(192, "Wobble")
			//TNT1 A 0 A_SetUserVar("user_wobble_angle", 0)
			TNT1 A 0 A_SetUserVar("user_wobble_pitch", user_wobble_pitch / 2)
			TNT1 A 0 A_SeekerMissile (4,8, SMF_LOOK | SMF_PRECISE)
			Goto RestorePointersAndFly
		Wobble:
			// all those max, min, sin -- they are gzdoom only. Zandronum crashes at startup.
			TNT1 A 0 A_SetUserVar("user_wobble_angle", user_wobble_angle + Random(-3, 3))
			TNT1 A 0 A_SetUserVar("user_wobble_pitch", user_wobble_pitch + Random(-3, 3))
			
			// diminishes slowly approaching zero, to avoid runaway effect
			TNT1 A 0 A_JumpIf(user_wobble_pitch < 1, 2)
			TNT1 A 0 A_SetUserVar("user_wobble_pitch", user_wobble_pitch - 1)
			TNT1 A 0 A_JumpIf(user_wobble_pitch > -1, 2)
			TNT1 A 0 A_SetUserVar("user_wobble_pitch", user_wobble_pitch + 1)
			
			TNT1 A 0 A_SetAngle(angle + user_wobble_angle)
			//TNT1 A 0 A_SetPitch(pitch + user_wobble_pitch)
			TNT1 A 0 A_ChangeVelocity(momx, momy, momz + 0.1 * user_wobble_pitch, CVF_REPLACE)
			Goto RestorePointersAndFly	
		HomeAdvanced:
			TNT1 A 0
			TNT1 A 0 A_JumpIfTargetInLOS(1)
			Goto RestorePointersAndFly // fly straight, only home when in sight
			TNT1 A 0 A_SeekerMissile (4,8, SMF_PRECISE)
			//TNT1 A 0 A_JumpIf(user_steering_commanded, "PerformDeclump")
			//TNT1 A 0 A_JumpIf(user_declump_commanded, "CheckDeClump")
			Goto RestorePointersAndFly			

		Crash:
		Xdeath:	
		Death:
			TNT1 A 0
			TNT1 A 0 A_Stop
			TNT1 A 0 A_PlaySound("pain/death", CHAN_VOICE)
			TNT1 A 0 A_CustomMissile("AoeRaiseInflictor", 16, 0, 0, CMF_ABSOLUTEANGLE | CMF_ABSOLUTEPITCH, -90)
			PAIN IIIIIIIIIIIIII 5 A_FadeOut(0.065)
			Stop
	}
}





Actor VileFireball: FBD_RevenantBall {

	//Translation "176:191=160:167", "168:175=224:231", "38:47=164:167", "128:143=176:184", "144:151=176:183", "58:79=176:191", "13:15=184:186", "16:47=208:223"
	// bright red
	Translation "176:191=172:191", "168:175=168:171", "38:47=174:184", "128:143=172:183", "144:151=172:183", "58:79=172:191", "13:15=179:186", "16:47=168:191", "208:223=168:180", "160:167=168:179", "232:235=177:184"
	DamageType "Fire"
	Damage (Random(1,1))
	States {
		Death:
		XDeath:
		Crash:
			TNT1 A 0
			TNT1 A 0 A_SetDamageType("Burn")
			TNT1 A 0 A_Explode(7, 120, 1)
			
			TNT1 A 0 A_CustomMissile("FlamethrowerBurningStuffNoSelfHarm", random (-32, 0), random (-32, 32), random (-32, 32), 2 | CMF_TRACKOWNER, random (-32, 32))
			
			TNT1 A 0 A_RearrangePointers (AAPTR_DEFAULT, AAPTR_NULL, AAPTR_DEFAULT, 0) // clear the master field
			TNT1 A 0 A_SpawnItemEx ("ExplosionFlareSpawner",0,0,0,0,0,0,0,SXF_NOCHECKPOSITION,0)
			TNT1 A 0 A_CustomMissile ("BDExplosionparticles", 0, 0, random (0, 360), 2, random (40, 90))
			TNT1 A 0 A_CustomMissile ("BDExplosionparticles2", 0, 0, random (0, 360), 2, random (40, 90))
			TNT1 A 0 A_CustomMissile ("BDExplosionparticles3", 10, 0, random (0, 360), 2, random (40, 90))
			EXPL A 0 A_CustomMissile ("FlamethrowerFireParticles", 6, 0, random (0, 360), 2, random (0, 90))
			Stop

	}
}

// moved to supercyberdemons due to load order
//Actor VileGoldenIgniter: GoldenIgniter


Actor VileChaosBall: FBD_RevenantBall 
{
	DamageType "Desintegrate" // triple damage to player tank
	Damage (Random(50,50)) // no splash but spawns igniters
	Translation "176:191=160:167", "168:175=224:231", "38:47=160:164", "128:143=160:165", "144:151=160:167", "58:79=160:167", "13:15=163:164", "16:24=224:231", "25:47=160:167", "208:216=224:231", "217:223=160:163", "160:167=160:163", "232:235=161:164"
	Species "Vile"
	+DONTHARMSPECIES
	States {
		Death:
		XDeath:
		Crash:
			TNT1 A 0
			TNT1 AAA 0 A_CustomMissile("VileGoldenIgniter", 24.0, 0.0, Random(-180,180), CMF_AIMDIRECTION | CMF_TRACKOWNER | CMF_SAVEPITCH, Random(5, 70))
			TNT1 AAAAAAAAA 0 A_CustomMissile ("GoldenExplosionFire", 2, 0, random (0, 360), 2, random (0, 360))
			EXPL AA 0 A_CustomMissile ("BigNeoSmoke", 0, 0, random (0, 360), 2, random (0, 360))
			TNT1 A 30
			Stop
	}
}


Actor SuperVileBlinkPositionFinder4000: FastProjectile 
// this one finds a position along a wall
{
	+SERVERSIDEONLY
	Radius 20
	Height 2
	Speed 2000
	FastSpeed 2000
	+GHOST
	+THRUACTORS
	+THRUGHOST
	-SKYEXPLODE
	-NOBLOCKMAP
	Scale 0.3
	
	States {
		Spawn:
			TNT1 AA 1
		Death:
			TNT1 A 0 
			TNT1 A 0 A_JumpIfCloser(300, "NoDeal")
			TNT1 A 0 A_JumpIfInTargetInventory("BlinkCooldown", 1, "NoDeal")
			TNT1 A 0 A_Stop
			TNT1 A 3 // 3 tics delay
			TNT1 A 30 ACS_NamedExecuteAlways("BlinkSuperVile", 0,0,0,0)
			Stop
		NoDeal:	
			TNT1 A 1 A_Stop
			Stop
		XDeath:
		Crash:
			// should not happen
			TNT1 A 1
			Stop
	}	
}

Actor SuperVileBlinkPositionFinder1000: SuperVileBlinkPositionFinder4000 
// this one only finds positions in open space, hitting a wall is considered failure
{
	Speed 1000
	FastSpeed 1000
	States {
		Spawn:
			TNT1 A 1
			TNT1 A 0 A_JumpIfCloser(300, "NoDeal")
			TNT1 A 0 A_JumpIfInTargetInventory("BlinkCooldown", 1, "NoDeal")
			TNT1 A 0 A_Stop
			TNT1 A 30 ACS_NamedExecuteAlways("BlinkSuperVile", 0,0,0,0)
			Stop
		Death:
			TNT1 A 0
			Goto NoDeal
	}
}


Actor SuperVileBlinkPositionFinder600: SuperVileBlinkPositionFinder1000 
// likewise
{
	Speed 600
	FastSpeed 600
	States {
		Spawn:
			TNT1 A 1
			TNT1 A 0 A_JumpIfCloser(300, "NoDeal")
			TNT1 A 0 A_JumpIfInTargetInventory("BlinkCooldown", 1, "NoDeal")
			TNT1 A 0 A_Stop
			TNT1 A 2 // 2 tics delay 
			TNT1 A 30 ACS_NamedExecuteAlways("BlinkSuperVile", 0,0,0,0)
			Stop
		Death:
			TNT1 A 0
			Goto NoDeal
	}
}

Actor SuperVileBlinkPositionFinderFallbackUpClose {
	+SERVERSIDEONLY
	Radius 20
	Height 2
	+MISSILE
	+GHOST
	+THRUACTORS
	+THRUGHOST
	-SKYEXPLODE
	+FLOORHUGGER // designed to seep through windows and other slits
	-NOBLOCKMAP
	Speed 18
	FastSpeed 18
	
	Scale 0.3
	
	States {
		Spawn:
			TNT1 AAAAAAAAAA 1
		Death:
			TNT1 A 0 
			TNT1 A 0 A_JumpIfInTargetInventory("BlinkCooldown", 1, "NoDeal")
			TNT1 A 0 A_JumpIfCloser(300, "NoDeal")
			TNT1 A 0 A_Stop
			TNT1 A 4 // 4 tics delay
			TNT1 A 30 ACS_NamedExecuteAlways("BlinkSuperVile", 0,0,0,0)
			Stop
		NoDeal:	
			TNT1 A 1 A_Stop
			Stop
		XDeath:
		Crash:
			// should not happen
			TNT1 A 1
			Stop
	}
}




/*

Actor UnholyBuff {
	// attaches to monsters (just like the headbox) surrounding them with a hissing super sayan aura,
	// healing them over time and buffing them with ALWAYSFAST
	
	
}

*/

Actor SuperVileBlinkProbe {
	+SERVERSIDEONLY
	+ISMONSTER
	+SHOOTABLE
	+THRUGHOST
	+THRUACTORS
	+NOBLOOD
	-NOGRAVITY
	Radius 20
	Height 2
	Health 10
	States {
		Spawn:
			TNT1 A 10
			Stop
		Death:
			TNT1 A 10
			Stop
	}
}

Actor AoeRaiseInflictor: FastProjectile {
	+SERVERSIDEONLY
	Speed 5000
	FastSpeed 5000
	Radius 16
	Height 32
	//Damagetype "AoeRaise"
	Damage (Random(0,0))
	+PAINLESS
	+THRUACTORS
	+THRUGHOST
	States
	{
		Spawn:
			TNT1 A 1
		Death:
			//TNT1 A 1 A_Explode(2,255,XF_NOTMISSILE,0,250)
			// XF_NOTMISSILE : count the missile itself as inflictor, thus applying 
			//   its PAINLESS flag (cannot give that to the archie himself)
			TNT1 A 1 A_Warp(AAPTR_Default,0,0,40) // leap upwards like a leaping mine, to get corpses obscured by stairs
			TNT1 A 1 A_RadiusGive("AOERaiseApplier", 250, RGF_CORPSES | RGF_MONSTERS | RGF_OBJECTS, 1)
			
			// NOTE: A_RadiusGive's flags are *screwy*. It is *not* an OR but rather
			//  a spagetti of if()s where failing to match *any* of the actor's flags results in it being disregarded.
			// You need RGF_CORPSES for actors that can have the CORPSE flag
			// You need RGF_MONSTERS for actors that can have the ISMONSTER flag
			// You need RGF_OBJECTS for actors that don't have the ISMONSTER flag but have SHOOTABLE or VULNERABLE
			// You need RGF_MISSILES for actors that don't have the ISMONSTER, SHOOTABLE nor VULNERABLE flags but do have the MISSILE flag.
			
			Stop
	}
}


ACTOR AOERaiseApplier: CustomInventory 
{
	+INVENTORY.AUTOACTIVATE
	+INVENTORY.ALWAYSPICKUP
	inventory.maxamount 1
    States
    {
		Pickup:
			// inventory item's states execute in the context of the actor that item is in the inventory of
			TNT1 A 0
			// due to A_RadiusGive being the strange bird it is, regular monsters will also receive this! As will shootable decorations.
			TNT1 A 0 A_CheckFlag("CORPSE", "DoRaise", AAPTR_Default)
			TNT1 A 0 A_RailWait // set the internal action result variable to true, otherwise fails if FBD_RunElectricDmg returns false
			Stop
			
		DoRaise:	
			TNT1 A 0 A_ChangeFlag("CORPSE", 0)
			TNT1 A 0 A_ChangeFlag("COUNTKILL", 0) // for original monsters
			TNT1 A 0 ACS_NamedExecuteWithResult("FBD_RaiseThisCorpse")	
			TNT1 A 0 A_RailWait // set the internal action result variable to true, otherwise fails if FBD_RunElectricDmg returns false
			Stop
    }
}

Actor AoeRaiseInflictorShortRange: AoeRaiseInflictor
{
	Speed 230
	FastSpeed 230
}



Actor DeflectorShieldBreakingEffect
{
	Radius 20
	+NOGRAVITY
	+NOINTERACTION
	States {
		Spawn:
			TNT1 A 0
			TNT1 A 0 A_PlaySound("shields/shatter")
			TNT1 AAAAAAAAAAAAAAAAAAAAAAA 0 A_CustomMissile("DeflectorShieldBreakingParticle", 0, 0, Random(0,360),CMF_AIMDIRECTION,Random(-50, 50))
			TNT1 A 60
			Stop
	
	}
}

Actor DeflectorShieldRestoringEffect
{
	Projectile
	Speed 0
	Radius 1
	Height 1
	Renderstyle Add
	Alpha 0.9
	
	+NOGRAVITY
	+NOINTERACTION
	+BRIGHT
	States {
		Spawn:
			TNT1 A 0
			TNT1 A 0 A_PlaySound("shields/up")
			LEYS BRBRBRBRBRBRBRBRBRBRBRBRBRBR 1 A_FadeOut(0.05)
			TNT1 A 60
			Stop
	
	}
}

Actor DeflectorShieldReflectingEffect
{
	Projectile
	Speed 0
	Radius 1
	Height 1
	Renderstyle Add
	Alpha 0.9
	
	+NOGRAVITY
	+NOINTERACTION
	+BRIGHT
	States {
		Spawn:
			TNT1 A 0
			TNT1 A 0 A_PlaySound("shields/reflect")
			KYSH ABCDEABCDEABCDEABCDEABCDEABCDE 1 A_FadeOut(0.05)
			TNT1 A 60
			Stop
	
	}
}


Actor DeflectorShieldParticle
{
	+NOGRAVITY
	+NOINTERACTION // exclude from physics completely
	+CLIENTSIDEONLY
	+BRIGHT
	Renderstyle Add
	Alpha 0.5
	Radius 1
	Height 1
	Translation "80:111=[255,0,255]:[74,0,74]", "5:8=[70,0,70]:[0,0,0]", "3:3=[102,0,102]:[255,255,255]"
	States {
		Spawn:
			TNT1 A 0 NODELAY A_SetScale(Random(0, 1) ? -1.0 : 1.0, Random(0, 1) ? -1.0 : 1.0)
		Fly:
			PUF2 ACEIMQUY 1 BRIGHT
			PUF3 AC 1 BRIGHT
			Stop
	}
}

Actor DeflectorShieldBreakingParticle
{
	Projectile
	+NOGRAVITY
	+THRUACTORS
	+NOBLOCKMAP
	+CLIENTSIDEONLY
	+BRIGHT

	// GLSP have a unique non-doom palette.
	Translation "0:27=[74,0,74]:[255,0,255]"
	
	RenderStyle Add
	Alpha 0.8
	Radius 1
	Height 1
	Speed 5
	FastSpeed 5
	
	States
    {
		Spawn:
			TNT1 A 0 NODELAY A_SetScale(0.1 * (Random(0, 1) ? Random(-30, -10) : Random(10, 30)), 0.1 * (Random(0, 1) ? Random(-30, -10) : Random(10, 30)))
			TNT1 A 0 A_Jump (256, "Fly5", "Fly3", "Fly4")
		Fly5:
			GLSP ABCDEFGH 5 A_FadeOut(0.038)
			Loop
		Fly3:
			GLSP ABCDEFGH 3 A_FadeOut(0.0228)
			Loop
		Fly4:
			GLSP ABCDEFGH 4 A_FadeOut(0.0308)
			Loop	
		Death:
			"----" AAAAAAAAAAAAA 1 A_FadeOut(0.1)
			Stop
    }
}
	