freeslot(
"MT_SHADOW",
"S_SHADOWBOSS_STND1",
"S_SHADOWBOSS_STND2",
"S_SHADOWBOSS_STND3",
"S_SHADOWBOSS_LOOK",
"S_SHADOWBOSS_LOOK1",
"S_SHADOWBOSS_LOOK2",
"S_SHADOWBOSS_LOOK3",
"S_SHADOWBOSS_LOOK4",
"S_SHADOWBOSS_LOOK5",
"S_SHADOWBOSS_LOOK6",
"S_SHADOWBOSS_LOOK7",
"S_SHADOWBOSS_HOP1",
"S_SHADOWBOSS_HOP2",
"S_SHADOWBOSS_HOP3",
"S_SHADOWBOSS_HOP4",
"S_SHADOWBOSS_HOP5",
"S_SHADOWBOSS_HOP6",
"S_SHADOWBOSS_HOP7",
"S_SHADOWBOSS_HOP8",
"S_SHADOWBOSS_HOP9",
"S_SHADOWBOSS_HOP10",
"S_SHADOWBOSS_HOP11",
"S_SHADOWBOSS_HOP122",
"S_SHADOWBOSS_HOP12",
"S_SHADOWBOSS_BACKHOP1",
"S_SHADOWBOSS_BACKHOP2",
"S_SHADOWBOSS_BACKHOP3",
"S_SHADOWBOSS_BACKHOP4",
"S_SHADOWBOSS_BACKHOP44",
"S_SHADOWBOSS_BACKHOP55",
"S_SHADOWBOSS_BACKHOP5",
"S_SHADOWBOSS_BACKHOP6",
"S_SHADOWBOSS_BACKHOP7",
"S_SHADOWBOSS_BACKHOP8",
"S_SHADOWBOSS_BACKHOP9",
"S_SHADOWBOSS_BACKHOP10",
"S_SHADOWBOSS_BACKHOP11",
"S_SHADOWBOSS_LOOK3",
"S_SHADOWBOSS_LOOK4",
"S_SHADOWBOSS_LOOK5",
"S_SHADOWSPIN1",
"S_SHADOWSPIN2",
"S_SHADOWSPIN3",
"S_SHADOWSPIN4",
"S_SHADOWSPIN5",
"S_SHADOWSPIN6",
"S_SHADOWSPIN7",
"S_SHADOWSPIN8",
"S_SHADOWDASH1",
"S_SHADOWDASH2",
"S_SHADOWDASH3",
"S_SHADOWDASH4",
"S_SHADOWDASH5",
"S_SHADOWDASH6",
"S_SHADOWDASH7",
"S_SHADOWDASH8",
"S_SHADOWDASH9",
"S_SHADOWDASH10",
"S_SHADOWDASH11",
"S_SHADOWDASH12",
"S_SHADOWBOSS_MELEECHOOSE",
"S_SHADOWBOSS_SAPR1",
"S_SHADOWBOSS_SAPR2",
"S_SHADOWBOSS_SAPR22",
"S_SHADOWBOSS_SAPR3",
"S_SHADOWBOSS_SAPR33",
"S_SHADOWBOSS_SAPR333",
"S_SHADOWBOSS_SAPR4",
"S_SHADOWBOSS_SAPR44",
"S_SHADOWBOSS_SAPR444",
"S_SHADOWBOSS_SAPR5",
"S_SHADOWBOSS_SAPR55",
"S_SHADOWBOSS_SAPR555",
"S_SHADOWBOSS_SAPR6",
"S_SHADOWBOSS_SAPR66",
"S_SHADOWBOSS_SAPR666",
"S_SHADOWBOSS_SAPR7",
"S_SHADOWBOSS_SAPR77",
"S_SHADOWBOSS_SAPR777",
"S_SHADOWBOSS_SAPR8",
"S_SHADOWBOSS_SAPR88",
"S_SHADOWBOSS_SAPR888",
"S_SHADOWBOSS_SAPR9",
"S_SHADOWBOSS_SAPR10",
"S_SHADOWBOSS_SAPR11",
"S_SHADOWBOSS_SAPR12",
"S_SHADOWBOSS_CHAOS11",
"S_SHADOWBOSS_CHAOS1",
"S_SHADOWBOSS_CHAOS2",
"S_SHADOWBOSS_CHAOS22",
"S_SHADOWBOSS_CHAOS222",
"S_SHADOWBOSS_CHAOS2222",
"S_SHADOWBOSS_CHAOS3",
"S_SHADOWBOSS_CHAOS4",
"S_SHADOWBOSS_CHAOS5",
"S_SHADOWBOSS_CHAOS6",
"S_SHADOWBOSS_CHAOS66",
"S_SHADOWBOSS_CHAOS666",
"S_SHADOWBOSS_CHAOS7",
"S_SHADOWBOSS_CHAOS8",
"S_SHADOWBOSS_BLAST1",
"S_SHADOWBOSS_BLAST2",
"S_SHADOWBOSS_BLAST3",
"S_SHADOWBOSS_BLAST4",
"S_SHADOWBOSS_BLAST5",
"S_SHADOWBOSS_BLAST55",
"S_SHADOWBOSS_BLAST6",
"S_SHADOWBOSS_PAIN1",
"S_SHADOWBOSS_PAIN2",
"S_SHADOWBOSS_PAIN3",
"S_SHADOWBOSS_PAIN4",
"S_SHADOWBOSS_PAIN5",
"S_SHADOWBOSS_DEAD1",
"S_SHADOWBOSS_DEAD2",
"S_SHADOWBOSS_DEAD3",
"S_SHADOWBOSS_DEAD4",
"S_SHADOWBOSS_DEAD5",
"S_SHADOWBOSS_DEAD6",
"S_SHADOWBOSS_JUMP",
"S_SHADOWBOSS_HOMING",
"S_SHADOWBOSS_HOMINGSTOP",
"MT_CHAOSSPEAR",
"S_CHAOSSPEARSTATE1",
"S_CHAOSSPEARSTATE2",
"S_CHAOSSPEARSTATE3",
"MT_EXPLODINGCHAOSSPEAR",
"S_EXPLODINGCHAOSSPEAR1",
"S_EXPLODINGCHAOSSPEAR2",
"S_EXPLODINGCHAOSSPEAR3",
"S_EXPLODINGCHAOSSPEAR4",
"SPR_CHSP",
"SPR_F993",
"SPR_SHDW",
"SPR_SHSP",
"SPR_CTRL",
"SPR_SHDH",
"SPR_SSPN",
"SPR_CSOB",
"SPR_SHSB",
"SPR_SHWK",
"sfx_skateb",
"sfx_shdwh",
"sfx_shdwd",
"sfx_shdwt",
"sfx_chgecs",
"sfx_chaoss",
"sfx_chaosc",
"sfx_chaosb",
"sfx_cspear",
"sfx_cssfx1"
)

addHook("MobjThinker", function(shadow)
     if shadow.valid
	 if shadow.aura == nil
	 shadow.aura = 0
	 end
	 if shadow.aura > 0
	 shadow.aura = $1 - 1
	 P_SpawnGhostMobj(shadow)
	 end
	 if shadow.state == S_SHADOWSPIN1
	 shadow.aura = 40
	 end
	 end
end, MT_SHADOW)

addHook("MobjThinker", function(shadow)
     if shadow.valid
	 P_SpawnGhostMobj(shadow)
	 end
end, MT_CHAOSSPEAR)
	
addHook("MobjThinker", function(boss)
	//print(boss.reactiontime)
	if boss.state == S_SHADOWBOSS_LOOK
		A_Chase(boss, 3, 3)
		if boss.tics == 39
			boss.reactiontime = 32
		end
		if boss.reactiontime == 1
			if R_PointToDist2(boss.x, boss.y, boss.target.x, boss.target.y) < RING_DIST*2
				boss.state = S_SHADOWBOSS_MELEECHOOSE
			else
				boss.state = S_SHADOWBOSS_HOP1
			end
		end
	end
	if boss.state == S_SHADOWBOSS_JUMP
		if boss.tics == 34			
			A_BunnyHop(boss, 10, 0)
			S_StartSound(boss, sfx_jump)
		end
		if boss.tics == 15
			P_BossTargetPlayer(boss, true)
		end
	end
	if boss.state == S_SHADOWBOSS_HOMING
		if boss.tics == 104
			S_StartSound(boss, sfx_shdwt)
		end
		A_HomingChase(boss, 35*FRACUNIT, 0)
		local thok = P_SpawnMobj(boss.x, boss.y, boss.z, MT_THOK)
		thok.color = SKINCOLOR_YELLOW
		boss.flags = $1|MF_NOGRAVITY
	end
	/*if boss.state == S_SHADOWBOSS_HOMING
	and P_PlayerInPain(boss.target.player)		
		boss.state = S_SHADOWBOSS_HOMINGSTOP
	end*/
	if boss.state == S_SHADOWBOSS_HOMING
		if boss.tics > 0
		
			boss.flags = $1|MF_PAIN
		else
			boss.flags = $1 & ~MF_PAIN
		end
	end
	if boss.state == S_SHADOWBOSS_HOMINGSTOP
		boss.flags = $1 & ~MF_NOGRAVITY
		if P_IsObjectOnGround(boss)
			boss.state = S_SHADOWBOSS_STND1
			A_ForceStop(boss)
		end
	end
end, MT_SHADOW)

addHook("MobjMoveCollide", function(boss, target)
	if boss.state == S_SHADOWBOSS_HOMING
	and target.type == MT_PLAYER
		P_DamageMobj(target)
		A_ZThrust(boss, 10, 0)
		//A_Thrust(boss, -8, 1)
		boss.state = S_SHADOWBOSS_HOMINGSTOP	
		return true
	end
end, MT_SHADOW)

function A_ChaosBlast(actor)
	local maxcbdistance = FixedMul(1536*FRACUNIT, actor.scale)
	for mobj in mobjs.iterate()
	local cbdistance = R_PointToDist2(actor.x, actor.y, mobj.x, mobj.y)					
					
		if not (mobj == actor)
		and (cbdistance <= maxcbdistance)
		and (mobj.z <= actor.z+(maxcbdistance))
		and (mobj.z >= actor.z-(maxcbdistance))					
		and ((mobj.flags & (MF_ENEMY|MF_BOSS)) or (mobj.type == MT_PLAYER)) then
					
			if (mobj.valid)
			and (mobj.flags & (MF_ENEMY|MF_BOSS)) then
				local cborb = P_SpawnMobj(mobj.x, mobj.y, mobj.z + mobj.height, MT_CBORB)
				cborb.target = actor
				cborb.flags2 = $1|MF2_DONTDRAW
				cborb.color = SKINCOLOR_RED
				cborb.scale = actor.scale*5
			end
						
			if (mobj.valid)
			and (mobj.type == MT_PLAYER)
			and not G_GametypeHasTeams()
				local cborb = P_SpawnMobj(mobj.x, mobj.y, mobj.z + mobj.height, MT_CBORB)
				cborb.target = actor
				cborb.flags2 = $1|MF2_DONTDRAW
				cborb.color = SKINCOLOR_RED
				cborb.scale = actor.scale*5
			end
						
			if (mobj.valid)
			and (mobj.type == MT_PLAYER)
			and (G_RingSlingerGametype() or G_GametypeHasTeams())
			and (mobj.player.ctfteam ~= actor.player.ctfteam)
				local cborb = P_SpawnMobj(mobj.x, mobj.y, mobj.z + mobj.height, MT_CBORB)
				cborb.target = actor
				cborb.flags2 = $1|MF2_DONTDRAW
				cborb.color = SKINCOLOR_RED
				cborb.scale = actor.scale*5
			end
			
			if (actor and actor.valid)
				local cborb = P_SpawnMobj(actor.x, actor.y, actor.z + actor.height, MT_CBORB)
				cborb.target = actor
				//cborb.color = SKINCOLOR_RED
				cborb.tics = 2
				cborb.scale = actor.scale*5
				S_StartSound(nil, sfx_bkpoof)
				P_FlashPal(actor.target.player, PAL_NUKE, 10)
				P_StartQuake(100*FRACUNIT, TICRATE)
			end						
		end
		actor.shadowscbready = 0
	end
end

local function blockbusters(mo,bustsec)
	for rover in bustsec.ffloors() // search through FOFs in sector
		if not (rover.flags & FF_EXISTS) continue end // FOF does not "exist" in sector!
		if not (rover.flags & FF_BUSTUP) continue end // FOF is not bustable, ignore it

		//if rover.flags & FF_ONLYKNUX continue end // you're not knux, so ....ignore it I guess

		/*if mo.z >= rover.topheight // too high
			continue
		end

		if mo.z+mo.momz+mo.height < rover.bottomheight // too low
			continue
		end*/

		EV_CrumbleChain(bustsec, rover) // DESTROY IT
	end
end

local function rocketbuster(mo)
	//fof busting stuff
	local checksec = R_PointInSubsector(mo.x, mo.y).sector
	blockbusters(mo, checksec) // check sector you're in
	if R_PointInSubsector(mo.x+(mo.momx/2), mo.y + (mo.momy/2)).sector != checksec
		checksec = R_PointInSubsector(mo.x+(mo.momx/2), mo.y + (mo.momy/2)).sector
		blockbusters(mo, checksec) // sector half-way to next
	end
	if R_PointInSubsector(mo.x+(mo.momx), mo.y + (mo.momy)).sector != checksec
		checksec = R_PointInSubsector(mo.x+(mo.momx), mo.y + (mo.momy)).sector
		blockbusters(mo, checksec) // sector at next frame
	end
	if R_PointInSubsector(mo.x+(mo.momx*2), mo.y + (mo.momy*2)).sector != checksec
		checksec = R_PointInSubsector(mo.x+(mo.momx*2), mo.y + (mo.momy*2)).sector
		blockbusters(mo, checksec) // sector at frame after
	end
end

addHook("MobjThinker", rocketbuster, MT_CHAOSSPEAR)