--=================================DARK PZ BOSS=============================================
--ACZ4's boss! The mastermind who brought the Metroids and turns the Black Rock's goo into Phazon!
--They are referred to as DarkPZ alot in the code, but that doesn't mean it's spoiler-free.
--==========================================================================================

local function DoPZGhost(s, color) --PZ version of P_SpawnGhostMobj
if not color
color = SKINCOLOR_SUPERSKY3
end
		s.ghs = P_SpawnGhostMobj(s)
		if s.ghs and s.ghs.valid
			s.ghs.rollangle = s.rollangle
			s.ghs.tics = 12
			s.ghs.blendmode = AST_ADD
			s.ghs.scalespeed = $*P_RandomRange(1,3)
			s.ghs.destscale = $*5
			s.ghs.color = color
			s.ghs.colorized = true
		end
end
local function DoPZBarrier(s, color, tics, stomp, rotatedist) --PZ Barrier!
if not color	
color = SKINCOLOR_SUPERSKY3
end
if not tics
tics = 12
end
if not rotatedist
rotatedist = 45
end
	if stomp and stomp == "special" --Reflector variant.
		for d = 0,5
			local cal = (ANG60*d)
			s.stomp = P_SpawnMobj(s.x+FixedMul(30*cos(s.angle+cal), s.scale), s.y+FixedMul(30*sin(s.angle+cal), s.scale), s.z, MT_THOK)
			s.stomp.scale = FRACUNIT
			s.stomp.momz = FRACUNIT*P_RandomRange(5,40)
			s.stomp.tics = tics*P_RandomRange(2,4)
			s.stomp.destscale = FRACUNIT*30
			s.stomp.blendmode = AST_ADD
			s.stomp.sprite = SPR_PHAZ
			
			if d < 3
				s.stomp.frame = J|TR_TRANS20
				s.stomp.color = SKINCOLOR_SUPERSKY3			
			else
				if (leveltime % 2 == 0)
				s.stomp.frame = J|TR_TRANS30
				s.stomp.color = SKINCOLOR_COBALT
				else
				s.stomp.color = SKINCOLOR_BLACK
				s.stomp.frame = J|TR_TRANS50
				end
			end
			
			P_InstaThrust(s.stomp, ANGLE_45*d, P_RandomRange(4,6)*FRACUNIT)
		end	
			
	
	elseif stomp --Stomp variant.
		for d = 0,5
			local cal = (ANG60*d)
			s.stomp = P_SpawnMobj(s.x+FixedMul(rotatedist*cos(s.angle+cal), s.scale), s.y+FixedMul(rotatedist*sin(s.angle+cal), s.scale), s.z, MT_THOK)
			s.stomp.scale = 3*FRACUNIT
			s.stomp.momz = FRACUNIT*10
			s.stomp.tics = tics*2
			s.stomp.destscale = FRACUNIT*30
			s.stomp.sprite = SPR_PHAZ
			if (leveltime % 2 == 0)
			s.stomp.frame = J|TR_TRANS30
			s.stomp.color = color
			else
			s.stomp.color = SKINCOLOR_WHITE
			s.stomp.frame = J|TR_TRANS50
			end
		//	P_InstaThrust(s.stomp, R_PointToAngle2(s.stomp.x, s.stomp.y, s.x, s.y), -20*FRACUNIT)
			P_InstaThrust(s.stomp, ANGLE_45*d, P_RandomRange(8,12)*FRACUNIT)
		end	
		
	else
		s.ghs = P_SpawnMobj(s.x, s.y, s.z, MT_THOK)
			s.ghs.scale = P_RandomRange(9,12)*FRACUNIT
			s.ghs.sprite = SPR_PHAZ
			s.ghs.color = color
			s.ghs.colorized = true			
				if P_RandomRange(0,1)
				s.ghs.frame = J|TR_TRANS50
				s.ghs.tics = tics
				s.ghs.color = color
				else
				s.ghs.tics = tics
				s.ghs.frame = J|TR_TRANS70
					if P_RandomRange(0,1)
					s.ghs.color = color
					else
					s.ghs.color = SKINCOLOR_JET
					end
				end	
			s.ghs.scalespeed = $*2/P_RandomRange(1,7)
			s.ghs.destscale = s.scalespeed+1
			s.ghs.momz = (P_RandomRange(38,54))*FRACUNIT			
	end
end


addHook("MobjThinker", function(s)
	if s.valid
		if not s.setup --Similar size to Samus
		s.scale = 110000
		s.setup = true
		s.superstrongfoe = true
		end
	--These flashing frames don't take massive priority exactly.
		if s.painfred --Flash pain colors.
			if (s.painfred % 2 == 0)
				s.color = SKINCOLOR_RED
				s.colorized = true
			else
				s.colorized = false
				s.color = SKINCOLOR_NONE
			end
		s.painfred = $-1			
		elseif s.painfyellow
			if (s.painfyellow % 2 == 0)
				s.color = SKINCOLOR_YELLOW
				s.colorized = true
			else
				s.colorized = false
				s.color = SKINCOLOR_NONE
			end
		s.painfyellow = $-1			
		end		
	--DYING....DRAMATICALLY.	
		if s.pzdeathanim
			s.flags = $|MF_NOCLIPHEIGHT & ~MF_PAIN & ~MF_SHOOTABLE
			if s.pzclone or (leveltime % 8 == 0) --Clones don't get a dramatic death.
					
					for d = 1,12
						s.ghs = P_SpawnMobj(s.x+P_RandomRange(200,200)*FRACUNIT, s.y+P_RandomRange(200,200)*FRACUNIT, s.z+P_RandomRange(1,80)*FRACUNIT, MT_THOK)
						s.ghs.tics = 24
						s.ghs.momx = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momy = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momz = P_RandomRange(-10,10)*FRACUNIT						
						s.ghs.sprite = SPR_MPR1
						s.ghs.color = SKINCOLOR_RED
						s.ghs.blendmode = AST_ADD
						s.ghs.colorized = true
							if P_RandomRange(0,1)
							s.ghs.frame = Q|FF_FULLBRIGHT|TR_TRANS30
							else
							s.ghs.frame = P|FF_FULLBRIGHT|TR_TRANS20					
							end
					end
					if s.pzclone
					s.ghs = P_SpawnGhostMobj(s)
					s.ghs.scale = $*3
					s.ghs.destscale = s.ghs.scalespeed+1
					s.ghs.tics = 35
					s.ghs.colorized = true
					s.ghs.color = SKINCOLOR_RED
					S_StartSound(s.ghs, sfx_pztele)
						if s.target and s.target.player
						and (s.target.player.sammissiles != nil and (s.target.player.sammissiles < 6))
						P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_MPKU) 
						end
						if s.valid
						s.state = S_NULL
						return
						end
					else
					local ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SAMUSZAP)
						if ghs.valid
						ghs.scale = s.scale*2
						ghs.momx = s.momx
						ghs.momy = s.momy
						ghs.momz = s.momz
						ghs.eflags = s.eflags
						ghs.blendmode = AST_ADD
						ghs.color = P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5)
						ghs.morning = 4
							if ghs.valid
								LeafSpawn(s, nil, true, 90)
								LeafSpawn(s, nil, true, 300)
								ghs = P_SpawnMobj(s.x, s.y, s.z+((s.height/6)*P_MobjFlip(s)), MT_SAMUSZAP)
								ghs.color = P_RandomRange(SKINCOLOR_SUPERRED1, SKINCOLOR_SUPERRED5)
								ghs.morning = 4
							end
						end
					end
					
			end
			
			if not s.pzclone --Commence dramatic doom.
				if (s.pzdeathanim == 139)
				A_FaceTarget(s)
				s.scalespeed = $/4
				s.destscale = s.scale*3
				P_MoveOrigin(s, s.x+FixedMul(255*FRACUNIT, cos(s.angle)), s.y+FixedMul(255*FRACUNIT, sin(s.angle)), s.floorz+50*FRACUNIT)
					for z in players.iterate
						if z.mo and z.mo.valid
						z.mo.crystalflashtune = 0
							if z.mo.crystalflashtime
							z.mo.nocftunechange = true
							end
						end
					P_SamFP(z, PAL_RECYCLE, 12)
					end
				P_LinedefExecute(11111) --Stop the music.
				end
				
				s.state = S_PZ_PAIN
				s.pzdeathanim = $-1
				s.momx = 0 s.momy = 0 s.momz = FRACUNIT
				
				if s.pzdeathanim % 4 == 0
				DoPZGhost(s)
				S_StartSound(s, sfx_mtrdb)
				s.bmb = P_SpawnMobj(s.x+P_RandomRange(-250,250)*FRACUNIT, s.y+P_RandomRange(-250, 250)*FRACUNIT, s.z+P_RandomRange(-150, 150)*FRACUNIT, MT_THOK)
				s.bmb.scale = FRACUNIT*P_RandomRange(3,5)
				s.bmb.state = S_MINIEXP1
				s.bmb.color = SKINCOLOR_FLAME
				s.bmb.blendmode = AST_ADD
				end
				
				if (s.pzdeathanim < 40)
					if (s.pzdeathanim < 18)
					s.sprite = SPR_PHAZ
					s.frame = I|TR_TRANS80
					else
					s.sprite = SPR_PHAZ
					s.frame = I|TR_TRANS40
					end
					
					if (s.pzdeathanim == 1)
					
						DoPZBarrier(s, nil, nil, true, 40)
						DoPZBarrier(s, P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERSILVER5))
						
						for d = 1,30
						LeafSpawn(s, nil, true, 350)
						s.ghs = P_SpawnMobj(s.x+P_RandomRange(-100,100)*FRACUNIT, s.y+P_RandomRange(-100,100)*FRACUNIT, s.z+P_RandomRange(1,80)*FRACUNIT, MT_THOK)
						s.ghs.tics = 105
						s.ghs.momx = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momy = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momz = P_RandomRange(-10,30)*FRACUNIT						
						s.ghs.sprite = SPR_MPR1
							if P_RandomRange(0,1)
							s.ghs.color = SKINCOLOR_COBALT
							s.ghs.colorized = true
							end
							if P_RandomRange(0,1)
							s.ghs.frame = Q|FF_FULLBRIGHT|TR_TRANS30
							else
							s.ghs.frame = P|FF_FULLBRIGHT|TR_TRANS20					
							end						
						end
					s.plexpand = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_PBEXPAND)
						if s.plexpand
						s.plexpand.blendmode = AST_ADD
						s.plexpand.frame = $|TR_TRANS50
						s.plexpand.scale = FRACUNIT*7
						s.plexpand.scalespeed = $*10
						s.plexpand.destscale = $*40
						end	
						P_LinedefExecute(11112)
						P_LinedefExecute(11113)
						P_LinedefExecute(111)
						S_StartSound(nil, sfx_mtrdd)
					
						for d = 1,5
							s.itemrng = P_RandomRange(1,8)
							if s.itemrng == 1
							s.item = MT_PBOM
							elseif s.itemrng == 2
							s.item = MT_BMPKU
							elseif s.itemrng < 5
							s.item = MT_NRGB
							elseif s.item == 6
							s.item = MT_NRGD
							else
							s.item = MT_SPKU
							end
							P_SpawnMobj(s.x+P_RandomRange(-450,450)*FRACUNIT, s.y+P_RandomRange(-450,450)*FRACUNIT, s.z+P_RandomRange(0,100)*FRACUNIT, s.item)
						end
					end
				end
				
			end
	-- Ambush sequence				
		elseif s.pzambush
			s.pzambush = $-1
			if (s.pzambush > 100)
				if s.pzambush == 101
					for z in players.iterate
						if z.mo
						z.mo.rdeathmsg = true 
						end
					end
				end
			s.frame = A|TR_TRANS70
			elseif (s.pzambush > 25)
			s.momz = 2*FRACUNIT
				if (s.pzambush > 60)
				s.flags2 = $ & ~MF2_DONTDRAW
				s.frame = A|TR_TRANS60|FF_FULLBRIGHT
				elseif (s.pzambush > 50)
				s.frame = D|TR_TRANS40|FF_FULLBRIGHT
					if (s.pzambush == 60)
					S_StartSound(s, sfx_pzlaug)
					end
				elseif (s.pzambush == 50)
				S_StartSound(s, sfx_cmcha)
				s.frame = D|FF_FULLBRIGHT
					if s.target
					local t = s.target
					t.omegarushpanic = 30
					s.pzreticule2 = P_SpawnMobj(t.x, t.y, t.z+t.height*2, MT_PZTARGET)
						if s.pzreticule2 and s.pzreticule2.valid
						s.pzreticule2.target = t
						s.pzreticule2.fuse = 51
						end
					end
				end
			elseif (s.pzambush < 26)
				s.momz = 0
				if (s.pzambush == 25)
				s.frame = D|FF_FULLBRIGHT
				s.momz = 0
						if s.pzreticule2 and s.pzreticule2.valid -- Got a target? FIRE!!!
						s.flags = $|MF_NOCLIP & ~ MF_ENEMY & ~MF_SHOOTABLE & ~MF_BOSS
						s.pzmissile = P_SpawnMissile(s, s.pzreticule2, MT_HBSHOT)
						if s.pzmissile and s.pzmissile.valid
						local f = s.pzmissile
						f.darkhyper = true --We give both types this
						f.flags2 = $|MF2_SUPERFIRE			
								for z in players.iterate
									if z.mo
										if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
											A_samquake(z.mo, 80*FRACUNIT, 28, 28)
											SAM_COM_BufInsertText(z, "tunes DARKPZ")
											P_SamFP(z, PAL_MIXUP, 6)
											z.mo.omegarushpanic = 12
										end
									end
								end
						S_StartSound(nil, sfx_hbsh) S_StartSound(s, sfx_hbsh)
						s.flags = $|MF_ENEMY|MF_SHOOTABLE|MF_BOSS & ~MF_NOCLIP --This game is an asshole.				
						end
					end
				end
			end
	-- Super knockback!! Nice!		
		elseif s.pzsuperknockback
			s.pzsuperknockback = $-1
				if s.pzknockbackangle != nil
				s.painfred = $+1
				A_SAMPARTICLE(s, MT_MPR5, 6, 8, -2, 6, SKINCOLOR_COBALT, P_RandomRange(44355, 58355))
				P_InstaThrust(s, s.pzknockbackangle, -68*FRACUNIT)
				s.momz = 11*FRACUNIT
				s.state = S_PZ_PAIN
				s.pzrollangle = s.pzrollangle and $+ANG30 or ANG30
				s.rollangle = s.pzrollangle
					if s.target and s.target.valid
					s.target.angle = R_PointToAngle2(s.target.x, s.target.y, s.x, s.y)
					end
				end
				
				if P_IsObjectOnGround(s) or (s.blockframes > 5) or (s.pzsuperknockback == 1) or s.pzknockbackangle == nil
				S_StopSound(s)
				s.rollangle = 0
				S_StartSound(nil, sfx_brakrx)
				S_StartSound(nil, sfx_smexp)
				S_StartSound(nil, sfx_pzouch)
					for z in players.iterate
						if z.mo
						and (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
							A_samquake(z.mo, 80*FRACUNIT, 9, 9)
							P_SamFP(z, PAL_MIXUP, 4)
						end
					end
					for d = 0,2
						S_StartSound(nil, sfx_brakrx)
						s.plexpand = P_SpawnMobj(s.x, s.y, s.z+s.height/4, MT_PBEXPANDW)
							if s.plexpand and s.plexpand.valid
							s.plexpand.scale = $*P_RandomRange(5,8)
							s.plexpand.scalespeed = $*P_RandomRange(20,35)
							s.plexpand.destscale = $*60
							s.plexpand.tics = $*5/3
							s.plexpand.color = SKINCOLOR_COBALT+d
							s.plexpand.colorized = true
							end
					end
					P_DamageMobj(s, nil, nil, 3) --Inflict all the damage!
					s.pzsuperknockback = 0					
				end
				
				if (leveltime % 3 == 0)
				A_BossScream(s, 0, MT_CYBRAKDEMON_VILE_EXPLOSION)
				else
				S_StartSound(s, sfx_s3kb4)
				P_SpawnMobj(s.x+P_RandomRange(-100,100)*FRACUNIT, s.y+P_RandomRange(-100,100)*FRACUNIT, s.z+P_RandomRange(-70,70)*FRACUNIT, MT_SONIC3KBOSSEXPLODE)
				end
	--Phazon Barrier!			
		elseif s.pzreflecttime
		
			s.pzreflecttime = $-1
			s.state = S_PZ_FLOAT
			s.momx = 0 s.momy = 0 s.momz = 0
			s.angle = $+(ANG20*2)
			
			LeafSpawn(s, nil, true, 90)
			DoPZGhost(s)
					
			if (s.pzreflecttime % 2 == 0) and (s.pzreflecttime > 25)
					s.invincible = 3
					DoPZBarrier(s, nil, nil, "special", 40)
						
					for d = 1,4
						LeafSpawn(s, nil, true, 350)
						s.ghs = P_SpawnMobj(s.x+P_RandomRange(-200,200)*FRACUNIT, s.y+P_RandomRange(-200,200)*FRACUNIT, s.z+P_RandomRange(1,80)*FRACUNIT, MT_IVSP)
						s.ghs.tics = P_RandomRange(50,80)
						s.ghs.angle = R_PointToAngle2(s.ghs.x, s.ghs.y, s.x, s.y)
						P_InstaThrust(s.ghs, s.ghs.angle, (P_RandomRange(3,20))*-FRACUNIT)						
						s.ghs.scale = $*P_RandomRange(1,3)
						s.ghs.momz = P_RandomRange(2,15)*FRACUNIT
						
						if P_RandomRange(0,1)
							s.ghs.color = SKINCOLOR_SUPERGOLD1
							s.ghs.colorized = true
						end				
					end
			end
			
			if (s.pzreflecttime % 20 == 0)
			S_StartSound(s, sfx_s3k79)
			S_StartSound(s, sfx_cmol)
			end
			LeafSpawn(s, nil, true, 200)
			LeafSpawn(s, nil, true, 600)
			
			if s.actiontimer and (s.actiontimer < 3)
			s.actiontimer = 3 --Extend timer.
			end
			
			if not s.pzreflecttime
			A_FaceTarget(s)
			s.colorized = false
			end
			
	--THE PHAZON SCREW ATTACK DIVE!			
		elseif s.phazoncooldown
			s.phazoncooldown = $-1
			s.state = S_PZ_FLOAT
			s.momx = 0 s.momy = 0
			
			if not (s.z < s.floorz+3*FRACUNIT)
			s.momz = -20*FRACUNIT
			else
			s.momz = 0
			end
			
			LeafSpawn(s, nil, true, 200)
			LeafSpawn(s, nil, true, 600)
			
			if s.actiontimer and (s.actiontimer < 3)
			s.actiontimer = 3 --Extend timer.
			end
		elseif s.phazondive
			if not P_IsObjectOnGround(s)
				if (leveltime % 3 == 0)
					local ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SAMUSZAP)
					if ghs.valid
					ghs.scale = s.scale*2
					ghs.momx = s.momx
					ghs.momy = s.momy
					ghs.momz = s.momz
					ghs.eflags = s.eflags
					ghs.color = P_RandomRange(SKINCOLOR_SUPERGOLD1, SKINCOLOR_SUPERGOLD5)
					ghs.morning = 4
						if (s.phazondive < 40) and ghs.valid
							DoPZGhost(s, P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5))
							LeafSpawn(s, nil, true, 90)
							LeafSpawn(s, nil, true, 300)
							LeafSpawn(s, nil, true, 600)
							ghs = P_SpawnMobj(s.x, s.y, s.z+((s.height/6)*P_MobjFlip(s)), MT_SAMUSZAP)
							ghs.color = s.color
							ghs.scale = $*3
							ghs.morning = 4
						end
					end
				end
			end
			
			s.phazondive = $-1
			s.state = S_PZ_ROLL
			if (leveltime % 3 == 0)
			s.colorized = false
			s.color = SKINCOLOR_NONE
			else
			s.colorized = true
			s.color = SKINCOLOR_SUPERSILVER1
			end
			
			if (s.phazondive >= 89)
				for d = 0,7
					s.stomp = P_SpawnMobj(s.x, s.y, s.z, MT_PARTICLE)
					s.stomp.momz = FRACUNIT*3
					s.stomp.tics = 12
					s.stomp.scale = FRACUNIT*3
					s.stomp.destscale = FRACUNIT*30
					s.stomp.frame = $|TR_TRANS60
					P_InstaThrust(s.stomp, ANGLE_45*d, 15*FRACUNIT)
				end
				s.momz = (s.phazondive*10/23)*FRACUNIT
				s.momx = $/2
				s.momy = $/2
				P_Thrust(s, s.angle, -2*FRACUNIT)
			elseif (s.phazondive >= 40)
				s.momz = 0 s.momx = 0 s.momy = 0
			elseif (s.phazondive < 40)
				if s.pzreticule4 and s.pzreticule4.valid
				s.angle = R_PointToAngle2(s.x, s.y, s.pzreticule4.x, s.pzreticule4.y) 
				end
				
				if s.phazondive == 39
					for z in players.iterate
						if z.mo
						and (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 2000*FRACUNIT)
							A_samquake(z.mo, 40*FRACUNIT, 8, 8)
							P_SamFP(z, PAL_MIXUP, 4)
							z.mo.omegarushpanic = 6
						end
					end
				s.blockframes = 0
				A_FaceTarget(s)
				S_StartSound(nil, sfx_satkf)
				S_StartSound(nil, sfx_pbchae)
				end
				
				P_InstaThrust(s, s.angle, 60*FRACUNIT)
				s.momz = -30*FRACUNIT
				
				if P_IsObjectOnGround(s) or (s.blockframes > 5)
 				S_StartSound(nil, sfx_bexpld)
			 	S_StartSound(nil, sfx_bgxpld)
			 	S_StartSound(nil, sfx_brakrx)
			 		 A_SAMUSEXPLOSIONS(s, 5, MT_SAMEXPLODE1, 5*FRACUNIT, 144000, true)
			 		 A_SAMUSEXPLOSIONS(s, 7, MT_SAMMISSILESMOKE, 50*FRACUNIT, 650000)
			 		 A_SAMUSEXPLOSIONS(s, 12, MT_SAMEXPLODE1, false, 1001, true)
			 		 A_SAMUSEXPLOSIONS(s, 20, MT_SAMMISSILESMOKE, false, 9001)
					 for z in players.iterate
						if z.mo
						z.mo.omegarushpanic = 0
							if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
								A_samquake(z.mo, 75*FRACUNIT, 20, 20)
								P_SamFP(z, PAL_MIXUP, 4)
								
								if (FixedHypot(FixedHypot(s.x-z.mo.x, s.y-z.mo.y), s.z-z.mo.z) < 200*FRACUNIT) and z.mo.health
								P_DamageMobj(z.mo, s, s)
								P_SamFP(z, PAL_NUKE, 20)
								P_InstaThrust(z.mo, R_PointToAngle2(z.mo.x, z.mo.y, s.x, s.y), 70*FRACUNIT)
								z.mo.momz = $-4*FRACUNIT
								z.mo.angle = R_PointToAngle2(z.mo.x, z.mo.y, s.x, s.y)
								end
							end
						end
					 end
				s.colorized = false
				s.phazondive = 0
				s.phazoncooldown = 45 --Invincibiliiiityyyy
				s.pzreflector2 = 20
				s.pzreflector = 45 
				end
				
				if s.phazondive == 1 --Never landed?? Just cancel, I guess..
				s.phazondive = 0
				s.colorized = false
				s.momz = 0
				s.state = S_PZ_FLOAT
				end				
			end
	--PHAZON GATTLING ACTION		
		elseif s.phazongattling
			s.phazongattling = $-1
			s.momx = 0 s.momy = 0 s.momz = 0
			s.state = S_PZ_SHOOT
			A_FaceTarget(s)
			if (s.phazongattling >= 89)
				s.momz = (s.phazongattling/3)*FRACUNIT	
			elseif (s.phazongattling < 89)
				if (s.phazongattling % 4 == 0) and s.pzreticule3 and s.pzreticule3.valid and not (s.state == S_PZ_PAIN)
				S_StartSound(s, sfx_plcm) S_StartSound(s, sfx_plcm)
				s.flags = $|MF_NOCLIP & ~MF_ENEMY & ~MF_SHOOTABLE & ~MF_BOSS --Don't clip into yourself	before you can even assign a target. How can this game even make that mistake?!
				s.pzgattle = P_SpawnMissile(s, s.pzreticule3, MT_PLSHOT)
				s.colorized = true
				s.color = SKINCOLOR_SKY				
					if s.pzgattle and s.pzgattle.valid
					s.pzgattle.darkhyper = true
					s.pzgattle.flags2 = $|MF2_SUPERFIRE|MF2_EXPLOSION
					s.pzgattle.color = SKINCOLOR_SUPERSKY2
					s.pzgattle.colorized = true
					end
					s.flags = $|MF_ENEMY|MF_SHOOTABLE|MF_BOSS & ~MF_NOCLIP					
				else
					s.color = SKINCOLOR_NONE
					s.colorized = true
				end
				if (s.phazongattling == 1)
				s.colorized = false
				S_StartSound(s, sfx_fizzle)
				s.phazongattling = 0
				s.state = S_PZ_FLOAT
				s.momz = -20*FRACUNIT
				end
			end
	--SLIDEBACK SHOT! Gives player room to dodge an incoming Phazon Missile or Hyper Beam!
		elseif s.slideback
		s.slideback = $-1
		s.frame = A|FF_FULLBRIGHT
			if s.hyperfire --Beam warning!!
			local ghs
				if (s.eflags & MFE_VERTICALFLIP)
					ghs = P_SpawnMobj(s.x, s.y, s.z+s.height*10/13, MT_SAMUSZAP)
				else
					ghs = P_SpawnMobj(s.x, s.y, s.z+s.height/4, MT_SAMUSZAP)
				end
				if ghs.valid
					ghs.scale = s.scale*30/41
					ghs.momx = s.momx/2
					ghs.momy = s.momy/2
					ghs.momz = s.momz/2
					ghs.eflags = s.eflags
					ghs.color = SKINCOLOR_COBALT
					ghs.morning = 4
				end
			end
		DoPZGhost(s, P_RandomRange(SKINCOLOR_WHITE, SKINCOLOR_JET))
			if (s.slideback == 29 or s.slideback == 49)
			S_StartSound(s, sfx_iceb) S_StartSound(s, sfx_s3k47)
				for d = 0,7
					s.stomp = P_SpawnMobj(s.x, s.y, s.z+8*FRACUNIT, MT_PARTICLE)
					s.stomp.momz = FRACUNIT*3
					s.stomp.tics = 18
					s.stomp.destscale = FRACUNIT*30
					s.stomp.frame = $|TR_TRANS60
					P_InstaThrust(s.stomp, ANGLE_45*d, 10*FRACUNIT)
					s.stomp.scale = FRACUNIT*3
				end
			end
			if s.z < s.floorz+130*FRACUNIT
			P_SpawnMobj(s.x, s.y, s.floorz, MT_EXPLODE)
			end	
			if (s.slideback > 15) --Tick down faster
			s.slideback = $-1
			end
			
		A_FaceTarget(s)			
		s.momz = FRACUNIT*8/s.slideback
		P_InstaThrust(s, s.angle, (s.slideback*(-2*FRACUNIT))+9*FRACUNIT)
			if s.slideback == 1
			s.momx = 0
			s.momy = 0
			s.momz = 0
			s.state = S_PZ_SHOOT
			 	if s.pzreticule2 and s.pzreticule2.valid -- Got a target? FIRE!!!
				s.flags = $|MF_NOCLIP & ~ MF_ENEMY & ~MF_SHOOTABLE & ~MF_BOSS
					if s.hyperfire
					s.pzmissile = P_SpawnMissile(s, s.pzreticule2, MT_HBSHOT)
					else
					s.pzmissile = P_SpawnMissile(s, s.pzreticule2, MT_SAMSUPERMISSILE)
					end
					if s.pzmissile and s.pzmissile.valid
					local f = s.pzmissile
					f.darkhyper = true --We give both types this
					f.flags2 = $|MF2_SUPERFIRE				
						if f.type == MT_SAMSUPERMISSILE
						S_StartSound(nil, sfx_smsh)
						f.momx = $*10/13 f.momy = $*10/13 f.momz = $*10/13 --Slow down a lot!
						f.pzbarrier = P_SpawnMobj(f.x, f.y, f.z, MT_PZBARRIER)
							if f.pzbarrier and f.pzbarrier.valid
								local b = f.pzbarrier
								if f.target
								b.target = f.target
								end
								b.darkpz = s
								b.borigin = f --cling to origin
								b.scale = FRACUNIT*10
							end
						else -- This is the Hyper Beam...
							for z in players.iterate
								if z.mo
									if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
										A_samquake(z.mo, 80*FRACUNIT, 28, 28)
										P_SamFP(z, PAL_MIXUP, 6)
										z.mo.omegarushpanic = 12
									end
								end
							end
						S_StartSound(nil, sfx_hbsh) S_StartSound(s, sfx_hbsh) S_StartSound(s, sfx_hbsh)
						end
					s.flags = $|MF_ENEMY|MF_SHOOTABLE|MF_BOSS & ~MF_NOCLIP --This game is an asshole.				
					end
				end
			s.pzmissile = nil
			s.hyperfire = nil --Discard useless data...
			s.pzreticule2 = nil
			s.slideback = 0			
			end
	--BASIC FLOATING AND RANDOM ACTIONS SETUP!
		elseif s.target and s.target.valid and s.target.health and s.target.player
		local t = s.target
		
			if t.crystalflashtime
				t.crystalflashtune = 1
			end
			if s.floattransition
				s.floattransition = $-1
			end
			--I give up, MAKE the damn music play.
			if (leveltime % 105 == 0) and s.health and not s.pzclone
				for z in players.iterate
					SAM_COM_BufInsertText(z, "tunes DARKPZ")
				end
			end
			if t.pzpaintime and not t.player.fusionmode
			and s.actiontimer and (s.actiontimer < 60)
				s.pzbossrngset = true
				s.pzbossrng = 10 --Spam barriers to give players time to get back on the platform and catch their breath.
			end
			if not s.actiontimer --Set up a cooldown before an action!
				if s.pzclone
					s.actiontimer = P_RandomRange(100,150)
				elseif t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(12,42)
				elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(40,62)
				else --casual
					s.actiontimer = P_RandomRange(55,95)
				end
			else
				if s.pzclone --Clones always spam the Wave Homer, sometimes attacking with the
				s.health = 1
				s.flags = $|MF_SHOOTABLE|MF_BOSS|MF_NOGRAVITY & ~MF_NOCLIP
					if s.originalpz and s.originalpz.valid
					elseif s and s.valid
					P_SpawnGhostMobj(s)
					s.pzdeathanim = 10
					return
					end
					if not (s.pzbossrng and s.pzbossrng >= 8)
					s.pzbossrng = 1
					s.pzbossrngset = true
					end
				end
				if not (s.actiontimer  < 3 and (s.state == S_PZ_PAIN)) --Don't get stunlocked without retaliating at least!
				s.actiontimer = $-1
				end
			end
		--All the magic gets decided when the actiontimer hits 1!	
			if s.actiontimer == 1
				if s.pzbossrngset --Looks like your attack was predetermined this time!
				s.pzbossrngset = false
				else	
				
				-- 1/2/3 = Wave Homers, 3 shots that slowly stalk and pressure a player while you can keep moving.
				-- 4 Phazon Dive. A modified screw attack with a bigger explosion and reflect radius, but not as strong as the real deal.
				-- 5 Phazon Missile. A modified SM with reflect barrier and concentrated explosion. Reflectable with your Screw Attack.
				-- 6 Phazon Vortex. A modified Gattling Vortex. Slower traveling, but does damage over-time if it hits at all!
				-- 7 Hyper Beam. Only available below 6 health, otherwise becomes Phazon Missile. Slow tracking, but EXTREMELY dangerous!
				-- 8/9 Dimensional Shift. Phases itself above you and dashes backwards. Nothin' personal, huntress.
				-- Clones - Appear at 8 and 3 remaining health respectively. Real Dark Samus has more afterimages and uses other attacks.
				-- As a Metroid, it's DNA rejects the Ice Beam. Fortunately you didn't have the Spazer Beam when it copied Samus.
				if t.player.fusionmode
				s.pzbossrng = P_RandomRange(1,9)
				else
				s.pzbossrng = P_RandomRange(1,10) --Let's decrease the odds of Dark Samus becoming a one-note clown spamming the same attack
				end
					if s.lastpzbossrng and ((s.pzbossrng == s.lastpzbossrng) or (s.pzbossrng < 4 and s.lastpzbossrng < 4))
						if (s.pzbossrng <= 3) --Don't spam Wave Homers, we don't need this to become Touhou.
						s.pzbossrng = P_RandomRange(4,8)
						elseif (s.pzbossrng == 4) -- Never spam phazon dives! That'd be both obnoxious and exploitable.
							if P_RandomRange(0,1)
							s.pzbossrng = $+1
							else
							s.pzbossrng = $-1
							end
						elseif (s.pzbossrng == 7) and not (s.health > 8)
						and (t.player.crazysamusmobs)
						s.pzbossrng = 5 --Too soon to bring out the Hyper Beam, use the Phazon Missile instead!
						else
						s.pzbossrng = P_RandomRange(1,9) --Reroll! If you STILL get the same one, fine....
						end
					end
					s.lastpzbossrng = s.pzbossrng
				end
				
				if s.pzbossrng <= 3 or s.pzclone --Spawn 3 wave homers, which then target targets which chase your target.
					A_FaceTarget(s)
					S_StartSound(s, sfx_wvchsh)
					if not s.pzclone --God, please don't cause seizures.
						S_StartSound(s, sfx_wvcm)
						S_StartSound(s, sfx_wvcm2)			
						for z in players.iterate
							if z.mo
								if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
									A_samquake(z.mo, 50*FRACUNIT, 1, 12)
									P_SamFP(z, PAL_MIXUP, 4)
								end
							end
						end	
					end
					for d = -1,1
						if d == 0 or s.pzclone
							s.wavehomer = P_SpawnMobj(s.x, s.y, s.z+280*FRACUNIT, MT_PZWAVEHOMER)					
						else					
							s.wavehomer = P_SpawnMobj(
							s.x+FixedMul((290*FRACUNIT), cos(s.angle+((ANG1*80)*d))),
							s.y+FixedMul((290*FRACUNIT), sin(s.angle+((ANG1*80)*d))),	
							s.z+180*FRACUNIT, MT_PZWAVEHOMER)
						end
						s.pzreticule = P_SpawnMobj(
						t.x+FixedMul((350*FRACUNIT), cos(t.angle+(ANGLE_90*d))),
						t.y+FixedMul((350*FRACUNIT), sin(t.angle+(ANGLE_90*d))),	
						t.z+t.height, MT_PZTARGET)
						
						if s.wavehomer and s.wavehomer.valid
						s.wavehomer.target = s
						s.wavehomer.flags2 = $|MF2_SUPERFIRE
							if s.pzreticule and s.pzreticule.valid
							s.pzreticule.target = t
							s.pzreticule.wavehomertarget = true 
							s.pzreticule.angside = d
							s.wavehomer.pztarget = s.pzreticule
							elseif t.valid
							s.wavehomer.pztarget = t
							end
							s.pzreticule = nil
						end
						if s.pzclone --Only spawn 1 Wave Homer if you are a clone.
							break
						end
					end
				
					if t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(8, 40)
					elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(40, 89)
					else --casual
					s.actiontimer = P_RandomRange(65, 145)
					end					
				elseif s.pzbossrng == 4 -- Use the Phazon Dive!!
					if t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(100, 100)
					elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(100, 100)
					else --casual
					s.actiontimer = P_RandomRange(100, 145)
					end
					s.phazondive = 100
					S_StartSound(s, sfx_sprnp)
					S_StartSound(s, sfx_mtrdol)
					S_StartSound(nil, sfx_satkc)
						s.pzbarrier = P_SpawnMobj(s.x, s.y, s.z, MT_PZBARRIER)
						if s.pzbarrier and s.pzbarrier.valid
							local b = s.pzbarrier
							b.target = s
							b.darkpz = s
							b.borigin = s --cling to origin
							b.scale = FRACUNIT*10
						end	
						s.pzreticule4 = P_SpawnMobj(t.x, t.y, t.z+t.height*2, MT_PZTARGET)					
						if s.pzreticule4 and s.pzreticule4.valid
							s.pzreticule4.target = t
							s.pzreticule4.scale = FRACUNIT*2 --Bigger scale = Faster chasing speed
							s.pzreticule4.fuse = 101
						end						
				
				elseif (s.pzbossrng == 5 or s.pzbossrng == 7) --Fire a Phazon Super Missile!
					if t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(66, 80)
					elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(70, 95)
					else --casual
					s.actiontimer = P_RandomRange(100, 140)
					end
					S_StartSound(nil, sfx_rail1)
					S_StartSound(nil, sfx_iceb)
					S_StartSound(nil, sfx_s3k47)
					A_FaceTarget(s)
						if s.pzbossrng == 7 // --Shoot the almighty Hyper Beam!
						and not (s.health > 8) and (t.player.crazysamusmobs)					
						s.slideback = 50
						S_StartSound(nil, sfx_cmcha)
						s.hyperfire = true						
							for z in players.iterate
								if z.mo
									if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 2500*FRACUNIT)
										A_samquake(z.mo, 70*FRACUNIT, 5, 5)
										z.mo.omegarushpanic = 55
									end
								end
							end
						else
						S_StartSound(s, sfx_mread) S_StartSound(s, sfx_mread)
						s.slideback = 30
						end
						s.pzreticule2 = P_SpawnMobj(t.x, t.y, t.z+t.height*2, MT_PZTARGET)					
						if s.pzreticule2 and s.pzreticule2.valid
						s.pzreticule2.target = t
						s.pzreticule2.fuse = 51
						end
						s.plexpand = P_SpawnMobj(s.x, s.y, s.z+s.height/4, MT_PBEXPANDW)
							if s.plexpand and s.plexpand.valid
							s.plexpand.scale = $*8
							s.plexpand.scalespeed = $*P_RandomRange(30,50)
							s.plexpand.destscale = $*60
							s.plexpand.tics = $*5/3
							s.plexpand.color = SKINCOLOR_COBALT
							s.plexpand.colorized = true
							end						
				elseif s.pzbossrng == 6 --Barrage Samus with a Phazon Vortex!
				
					if t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(100, 102)
					elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(110, 150)
					else --casual
					s.actiontimer = P_RandomRange(135, 200)
					end	
				
					S_StartSound(nil, sfx_s3k82)
					S_StartSound(nil, sfx_s3kb6)
					s.phazongattling = 99
					A_FaceTarget(s)
					s.pzreticule3 = P_SpawnMobj(t.x, t.y, t.z+t.height*2, MT_PZTARGET)					
						if s.pzreticule3 and s.pzreticule3.valid
						s.pzreticule3.target = t
						s.pzreticule3.scale = FRACUNIT*2 --Bigger scale = Faster chasing speed
						s.pzreticule3.fuse = 101
					end
					s.plexpand = P_SpawnMobj(s.x, s.y, s.z, MT_PBEXPAND)
					if s.plexpand and s.plexpand.valid
						s.plexpand.color = SKINCOLOR_SUPERGOLD3
						s.plexpand.scale = $*3
						s.plexpand.scalespeed = $*4
						s.plexpand.destscale = $*26
					end
				elseif s.pzbossrng == 10 --Phazon Barrier! Mainly to make the fight more slow-paced in Zero and Hyper mode.
					s.pzbarrier = P_SpawnMobj(s.x, s.y, s.z, MT_PZBARRIER)
					if s.pzbarrier and s.pzbarrier.valid
							local b = s.pzbarrier
							b.target = s
							b.darkpz = s
							b.borigin = s --cling to origin
							b.scale = FRACUNIT*10
					end	
					S_StartSound(nil, sfx_s3k82)
					S_StartSound(nil, sfx_s3kb6)
					S_StartSound(s, sfx_mtrdos)
					s.pzreflecttime = 75
					s.lastpzbossrng = 10
					
					if t.player.crazysamusmobs --normal mode
					s.actiontimer = 100
					else --casual
					s.actiontimer = 120
					end				
					
				elseif s.pzbossrng >= 8 --Teleport, Mario!
					s.lastpzbossrng = 6 --Never use a Phazon Vortex after this!
					if t.player.fusionmode --Fusion Mode.
					s.actiontimer = P_RandomRange(15, 30)
					elseif t.player.crazysamusmobs --normal mode
					s.actiontimer = P_RandomRange(30, 60)
					else --casual
					s.actiontimer = P_RandomRange(70, 100)
					end
					s.frame = A|FF_FULLBRIGHT
					s.ghs = P_SpawnGhostMobj(s)
					s.ghs.scale = $*2
					s.ghs.destscale = s.ghs.scalespeed+1
					s.ghs.tics = 16
					s.ghs.colorized = true
					s.ghs.color = SKINCOLOR_LAVENDER
					S_StartSound(nil, sfx_pztele)
					for d = 1,12
						s.ghs = P_SpawnMobj(s.x+P_RandomRange(200,200)*FRACUNIT, s.y+P_RandomRange(200,200)*FRACUNIT, s.z+P_RandomRange(1,80)*FRACUNIT, MT_THOK)
						s.ghs.tics = 24
						s.ghs.momx = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momy = P_RandomRange(-30,30)*FRACUNIT
						s.ghs.momz = P_RandomRange(-10,10)*FRACUNIT						
						s.ghs.sprite = SPR_MPR1
							if P_RandomRange(0,1)
							s.ghs.frame = Q|FF_FULLBRIGHT|TR_TRANS40
							else
							s.ghs.frame = P|FF_FULLBRIGHT|TR_TRANS40					
							end
					end
					
					if t.sam_automob and t.sam_automob.valid and t.sam_automob == s
					t.sam_faillock = true --release lock on
					t.sam_automob = nil
					end
									
					s.teleportdash = 12
					s.teleportdashangle = t.angle
					P_MoveOrigin(s, t.x, t.y, t.z+t.momz+200*FRACUNIT)
					if not (P_TryMove(s, s.x, s.y, true))
						for d = 1,18
							P_TryMove(s, s.x+FixedMul(-70*FRACUNIT, cos(ANG20*d)), s.y+FixedMul(-70*FRACUNIT, sin (ANG20*d)), true)
						end
					end
				end
			else
				if not ((s.state == S_PZ_SHOOT)) --Basic floating around. Shoot me, Samus-chan!
					if not s.floattime or not s.floatdirect or not s.floatdirectf
						if P_RandomRange(0,1)
						s.floatdirect = 1
						else
						s.floatdirect = -1
						end
						if P_RandomRange(0,2) --Favor approaching the player
						s.floatdirectf = 1
						else
						s.floatdirectf = -1
						end
						s.momx = 0 s.momy = 0 s.rollangle = 0
						if s.lastfloatdirect and (s.floatdirect == s.lastfloatdirect)
						s.floattime = P_RandomRange(8, 20)
						s.floatspeed = $+2
						else
						s.floatspeed = 1 --Transition your speed a bit more slowly!
						s.floattime = P_RandomRange(18, 30)
						s.floattransition = 5
						end
						s.lastfloatdirect = s.floatdirect
					end
					s.state = S_PZ_FLOAT
					A_FaceTarget(s) -- Always face target or this won't work right.
					if (leveltime % 2 == 0) and not s.pzclone --Spawn Phazon and fancy ghost effects, pls
						LeafSpawn(s, nil, true, 90)
						DoPZGhost(s)
					elseif s.pzclone and (leveltime % 6 == 0)
						DoPZGhost(s, SKINCOLOR_SKY)
					end
					if s.floattransition
					s.frame = A|FF_FULLBRIGHT
					elseif (s.floatdirect == -1)
					s.frame = B|FF_FULLBRIGHT
					else
					s.frame = C|FF_FULLBRIGHT
					end		
				
					--Sideways and front movement.
					if not (s.floatspeed > 17)
					s.floatspeed = $+1			
						if s.waverstunned
						s.floatspeed = 4 --Wave Beam slows PZ down
						end
					end
					if s.floattime
					s.floattime = $-1
					end
					P_InstaThrust(s, s.angle+(ANGLE_90*s.floatdirect), s.floatspeed*FRACUNIT)
						if s.pzclone and s.floatdirectf == 1
						P_Thrust(s, s.angle, FRACUNIT*P_RandomRange(2,5)) --Close in slower, will you?
						elseif s.floatdirectf == 1 and s.target and s.target.valid
						and  (FixedHypot(s.x-s.target.x, s.y-s.target.y) > 1200*FRACUNIT)
						P_Thrust(s, s.angle, FRACUNIT*P_RandomRange(20,25)) --Let's close the distance a bit.
						else
						P_Thrust(s, s.angle, FRACUNIT*(P_RandomRange(7,10)*s.floatdirectf)) --InstaThrust MUST be before this!
						end
				
					--Adjust height according to target
					if (s.z < t.z+18*FRACUNIT) or (s.z < s.floorz+5*FRACUNIT)
						s.momz = $+7355
					elseif (s.z > t.z+13*FRACUNIT)
						if s.momz > 0
						s.momz = 0
						else
						s.momz = $-10355
						end
					else
					s.momz = 0
					end
				elseif s.pzambush --Ambush a player with the Hyper Beam! This is instant death at 0%, do NOT get hit!
					if s.pzambush and s.target and s.target.valid
					s.pzambush = $-1
					s.state = S_PZ_HIDE
					end
					if not s.pzambush --Okay, let's fight, boys!
					s.state = S_PZ_LOOK
					end
				else
					if (s.tics < 9)
					s.frame = A|FF_FULLBRIGHT
					end
				end			
			end			
		end
		if not (s and s.valid) --Superlazy check....
		return
		end
		//Perform these actions regardless of an acquired target!
	//	s.color = SKINCOLOR_JET
	//	s.colorized = true
		if s.blockframes
		s.blockframes = $-1
		end
		if s.invincible
		s.invincible = $-1
		end
		if s.health
		s.pzlasthealth = s.health
		end
		if s.negatecrusher
		s.negatecrusher = $-1
			if s.target and s.target.valid
			P_MoveOrigin(s, s.target.x, s.target.y, s.target.z+230*FRACUNIT)
			end
		end
		if s.pzreflector -- Spam barrier function.
		s.pzreflector = $-1
			if (s.pzreflector > 39)
			DoPZBarrier(s, P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERSILVER5))
			elseif P_RandomRange(0,1)
			DoPZBarrier(s, P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5))
			else
			DoPZBarrier(s, SKINCOLOR_COBALT)
			end
		end
		if s.pzreflector2 -- Spam secondary barrier function. This one only happens after the Phazon Dive.
		s.pzreflector2 = $-1
			DoPZBarrier(s, nil, nil, true, s.pzreflector2*5)
		end
		if not s.pzdeathanim
			if (s.flags2 & MF2_FRET) --Never do this. Only villains do that.
			s.flags2 = $ & ~MF2_FRET
			s.flags2 = MF_SHOOTABLE|MF_BOSS|MF_NOGRAVITY
			end
			if s.teleportdash --Lock angle and dash back!
			s.teleportdash = $-1
			s.frame = A|FF_FULLBRIGHT
				if s.teleportdashangle
				s.angle = s.teleportdashangle 
				end
				P_InstaThrust(s, s.angle, -35*FRACUNIT)
				DoPZGhost(s, P_RandomRange(SKINCOLOR_SUPERPURPLE1, SKINCOLOR_SUPERPURPLE5))
			end			
			if s.pzknockback and not s.pzdeathanim
			s.pzknockback = $-1
				if s.pzknockbackforce != nil and s.pzknockbackangle != nil
				P_InstaThrust(s, s.pzknockbackangle, -s.pzknockbackforce*2*FRACUNIT)
					s.spinrundust = P_SpawnMobj(s.x+FixedMul(24*FRACUNIT, cos(s.angle+ANGLE_90)),s.y+FixedMul(24*FRACUNIT, sin(s.angle+ANGLE_90)), s.z, MT_SPINDUST)
					s.spinrundust.scale = FRACUNIT*3
					s.spinrundust.frame = P_RandomRange(0,2)
					s.spinrundust = P_SpawnMobj(s.x+FixedMul(24*FRACUNIT, cos(s.angle-ANGLE_90)),s.y+FixedMul(24*FRACUNIT, sin(s.angle-ANGLE_90)), s.z, MT_SPINDUST)
					s.spinrundust.frame = P_RandomRange(0,2)
					s.spinrundust.scale = FRACUNIT*3
					S_StartSound(s, sfx_s3k79)
				end
				if s.state == S_PZ_FLOAT
				s.frame = J
				end
			end
			if s.pzclone
			s.frame = $|TR_TRANS40|FF_FULLBRIGHT
				if s.justcloned
				s.justcloned = $-1
					if s.originalpz and s.originalpz.valid
					P_InstaThrust(s, R_PointToAngle2(s.x, s.y, s.originalpz.x, s.originalpz.y), -30*FRACUNIT)
					end
				end
			end
		end
	end
end, MT_PZBOSS)

addHook("MobjMoveBlocked", function(s, i)
	if s and s.valid 
		s.blockframes = s.blockframes and $+2 or 2
		if (s.blockframes > 4) and s.floatdirectf
		s.floatdirectf = $*-1 --Don't get stuck on walls.
			if s.floatdirect and P_RandomRange(0,1)
			s.floatdirect = $*-1
			end
		s.momz = 5*FRACUNIT*P_RandomRange(-1,1)
			if (s.blockframes > 35) -- Try teleporting unstuck?
			s.blockframes = 0
			s.pzbossrng = 8
			s.pzbossrngset = true
			end		
		end
	end
end, MT_PZBOSS)

addHook("MobjThinker", function(s)
	if s and s.valid 
	s.colorized = true
		if (s.scale <= FRACUNIT/2)
				s.destscale = FRACUNIT*3
				s.scalespeed = 50000		
				S_StartSound(s, sfx_cmol)
		elseif (s.scale >= FRACUNIT*3) or not s.scalestart
				s.scalestart = true
				s.scalespeed = 10000
				s.destscale = 10001	
		end
		if leveltime % 3 == 0
			if s.color == SKINCOLOR_COBALT		
			s.color = SKINCOLOR_COBALT
			else
			s.color = SKINCOLOR_SKY
			end
		end
		if ((s.state == S_WVSHOT1) or (s.state == S_WVSHOT2))
			s.frame = $|TR_TRANS30|FF_FULLBRIGHT
			if not s.fuse --Setup.
					s.plexpand = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_PBEXPAND) --Appearance effect.
					if s.plexpand
					s.plexpand.color = SKINCOLOR_SUPERSKY3
					s.plexpand.colorized = true
					s.plexpand.frame = $|TR_TRANS50
					s.plexpand.scale = FRACUNIT*7
					s.plexpand.scalespeed = $*10
					s.plexpand.destscale = $*40
					end	
				s.fuse = 280 --Emergency timer
			end			
			if s.pztarget and s.pztarget.valid
				P_HomingAttack(s, s.pztarget) --Slowly chase your target
				if leveltime % 4 == 0
				LeafSpawn(s, nil, true, 50)
				DoPZGhost(s, P_RandomRange(SKINCOLOR_GREY, SKINCOLOR_BLACK))
				end
			end
			if (s.fuse != nil)
				if (s.fuse > 30) and not (s.pztarget and s.pztarget.valid)
					s.fuse = 30 --Target gone, cancel yourself.
				end
				if (s.fuse <= 30) --Okay, vanish.	
					s.flags = $ & ~MF_SHOOTABLE & ~MF_MISSILE			
					if (s.fuse > 15)
					s.frame = $|TR_TRANS50 & ~TR_TRANS30
					else
					s.frame = $|TR_TRANS80 & ~TR_TRANS50 & ~TR_TRANS30
						if (s.fuse == 1) and s.valid
						s.state = S_NULL
						return
						end
					end
				end
			end
		elseif (s.state == S_WVXP1) and not s.saldsalf
			for d = 0,16
			LeafSpawn(s, nil, true, 400) --Lots of Phazon particles
			end
			for z in players.iterate
				if z.mo
					if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 1500*FRACUNIT)
						A_samquake(z.mo, 70*FRACUNIT, 1, 14)
						P_Thrust(z.mo, R_PointToAngle(z.mo.x, z.mo.y, s.x, s.y), -16*FRACUNIT) --Push everyone
						P_SamFP(z, PAL_NUKE, 5)
					end
				end
			end				
		S_StartSound(s, sfx_bkpoof) S_StartSound(s, sfx_smexp) S_StartSound(s, sfx_cmol)
		s.scale = s.scale*3
		s.destscale = $*10
		s.saldsalf = true
		end
	end
end, MT_PZWAVEHOMER)
addHook("MobjLineCollide", function(s, i) --Phase through stuff
	return false
end, MT_PZWAVEHOMER)
addHook("MobjLineCollide", function(s, i) --Difference with NOCLIP is that this'll still collide with objects
	return false
end, MT_PZBARRIER)

addHook("MobjThinker", function(s)
	if s and s.valid
		if s.borigin and s.borigin.valid
		local t = s.borigin
			if (s.borigin.type == MT_PZBOSS) and (s.borigin.phazondive or s.borigin.pzreflecttime)
				P_MoveOrigin(s, t.x, t.y,	t.z+t.height/2)
				if s.valid and s.borigin.pzreflecttime
					s.flags2 = $|MF2_DONTDRAW
				elseif s.valid and (s.borigin.phazondive > 50)
					s.scale = (FRACUNIT*500)/s.borigin.phazondive
					s.colorized = true
						if (leveltime % 5 == 0)
						s.color = P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5)
						else
						s.color = SKINCOLOR_COBALT
						end
					if (s.borigin.phazondive > 78)						
					s.frame = $|TR_TRANS90 & ~TR_TRANS60 & ~TR_TRANS50 & ~TR_TRANS40 & ~TR_TRANS70
					else
					s.frame = $|TR_TRANS70 & ~TR_TRANS60 & ~TR_TRANS50 & ~TR_TRANS80 & ~TR_TRANS90 & ~TR_TRANS40
					end
				elseif s.valid
					s.scale = FRACUNIT*10
					if (s.borigin.phazondive < 41) 
						if (leveltime % 5 == 0)
						DoPZGhost(s, P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5))
						else
						DoPZGhost(s, SKINCOLOR_COBALT)
						end
					end
				end
				return
			elseif (s.borigin.type == MT_SAMSUPERMISSILE)
				if s.borigin.health and s.borigin.darkhyper
				and not (s.borigin.flags2 & MF2_DEBRIS)
				and not (s.borigin.state == S_SAMSUPERMISSILEE)
						if (leveltime % 4 == 0)
						DoPZGhost(s, P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5))
						end
					P_MoveOrigin(s, t.x, t.y,	t.z+t.height/2)
					return
				elseif s and s.valid
				s.state = S_NULL
				return
				end
			elseif s and s.valid
			s.state = S_NULL
			return
			end
		elseif s and s.valid
			s.state = S_NULL
			return
		end
	end
end, MT_PZBARRIER)
addHook("MobjThinker", function(s)
	if s and s.valid
	and s.target and s.target.valid
	local t = s.target		
		if s.wavehomertarget 
			if s.angside
			P_MoveOrigin(s,
			t.x+FixedMul((350*FRACUNIT), cos(t.angle+(ANGLE_90*s.angside*-1))),
			t.y+FixedMul((350*FRACUNIT), sin(t.angle+(ANGLE_90*s.angside*-1))),	
			t.z+t.height)
			else
			P_MoveOrigin(s, t.x, t.y,	t.z+t.height)			
			end
		else
			P_HomingAttack(s, t)
		end
	end
end, MT_PZTARGET)

addHook("ShouldDamage", function(s, i, so, dmg, dmgtype) --Negate random crushing, pls....
	if dmgtype
		if (dmgtype == DMG_CRUSHED or dmgtype == DMG_DEATHPIT)
		return false
		end
	end
end, MT_PZBOSS)
addHook("MobjDeath", function(s, i, so, dmgtype) --Negate random crushing, pls....
	if dmgtype
		if (dmgtype == DMG_CRUSHED or dmgtype == DMG_DEATHPIT)
		s.negatecrusher = 2
			if s and s.valid and s.target and s.target.valid
			P_MoveOrigin(s, s.target.x, s.target.y, s.target.z+230*FRACUNIT)
			s.pzbossrng = 8
			s.actiontimer = 2
			s.pzbossrngset = true
			end
		return true
		end
	end
end, MT_PZBOSS)

local function PZReaction(s, i, so, dmg) --Damage reactions! Not as complex as the Omega's.
	if s.negatecrusher
	s.negatecrusher = 0
	s.flags = MF_NOGRAVITY|MF_SHOOTABLE|MF_BOSS
	s.flags2 = $ & ~MF2_FRET & ~MF2_BOSSDEAD & ~MF2_BOSSFLEE
		if not s.health and s.pzlasthealth
		s.health = s.pzlasthealth
		end
		return true
	end
	if s.health and s.invincible or (s.pzambush and s.pzambush > 50)--Still invincible...
		return true
	end
	if s.pzclone and s.originalpz and (so and so == s.originalpz) --Don't fight amongst yourself, men.
	or so and so.pzclone
		return true
	end
	if i and (i.darkhyper or ((i.flags & MF_MISSILE) and i.target == s or (s.originalpz and (i.target == s.originalpz))) )
		if (i.type == MT_PLSHOT) or (i.target == s) --Don't get mauled by reflected Phazon Vortex shots or your own attacks
		return true
		end
	end
	if (so and so.valid and (so == s)) --Don't hit yourself, stupid.
		return true
	end
--Kay, let's actually do the reaction part now.	
	if (s.health <= 0) or (so and so.player and so.player.hypermysticsonic)
		if s and s.valid
		s.pzdeathanim = 140 --Initiate dramatic death animation. You earned it. Unless you were HMS, you cheating little....
		s.fuse = 141
		s.painfred = 140
		s.momx = 0 s.momy = 0 s.momz = 0
		s.pzreflector = 8
		s.pzreflector2 = 14
		s.state = S_PZ_PAIN
		s.tics = 150
			if not s.pzclone
				for m in mobjs.iterate(mobjs) --Remove excess crap, 'cause you won!
					if m and m.valid
					and ((m.pzclone and m.originalpz and m.originalpz.valid and (m.originalpz == s)) or (m.type == MT_PZWAVEHOMER))
					m.state = S_NULL
					end
				end
			s.z = s.floorz+50*FRACUNIT
			P_LinedefExecute(11111)
			S_StartSound(nil, sfx_pzdead)
			S_StartSound(s, sfx_mtrdb)
				for z in players.iterate
					if z.mo
						if (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 4000*FRACUNIT)
							A_samquake(z.mo, 80*FRACUNIT, 1, 18)
							P_SamFP(z, PAL_RECYCLE, 12)
						end
					end
				end
			end
			return true
		else
			return --...wut?
		end
	else --We're not dying yet!
		if s and s.valid	
			if s.phazondive
				if i and i.player and i.health and (YouAreSamus(i) or i.player.powers[pw_super]) --Your cheap immitation can't defeat the real deal.
					if (i.player.sam_shinesparkfly and i.player.sam_shinesparkfly > 17)
					or (i.player.sam_screwattacking and i.player.sam_screwattacking > 23)
					or i.player.powers[pw_super]
						s.painfred = 55
						s.invincible = 25
						s.phazondive = 0
						i.momx = 0 i.momz = 0 i.momy = 0
						i.player.sam_shinesparkstop = 12
						S_StartSound(s, sfx_pzdead) S_StartSound(s, sfx_pzdead) S_StartSound(s, sfx_pzdead)
						S_StartSound(s, sfx_bkpoof) S_StartSound(nil, sfx_brakrx)
						S_StartSound(i, sfx_brakrx) S_StartSound(s, sfx_brakrx)
						s.pzsuperknockback = 105
						s.blockframes = 0
						s.actiontimer = 105
						s.pzknockbackangle = i.angle+ANGLE_180
						A_samquake(i, 80*FRACUNIT, 24, 24)
						i.angle = R_PointToAngle2(i.x-i.momx, i.y-i.momy, s.x, s.y)
						return true
					end
				end
				return true --Take no damage otherwise.
			else --Default damage behaviour
				if so and so.player and so.player.powers[pw_super] --Supers do extra damage!
				dmg = $+2 
				end			
				if i and (i.type == MT_ICCHARGECOMBO)
					s.invincible = 101
					s.painfred = 101
					i.addsaldsalf = true
				elseif i and i.gattlingvortex
					s.invincible = 55
					s.painfred = 55		
				elseif i and i.valid and (i.type == MT_ICCHARGESHOT)
					s.invincible = 70
					s.painfred = 65
				elseif dmg != nil
				
					s.invincible = dmg*30
					s.painfred = dmg*30
					s.pzknockback = dmg*8 --How many tics you're send flying for.
					s.pzknockbackforce = dmg*16
						if (dmg >= 2) or s.pzclone
						S_StartSound(s, sfx_mtrdop) S_StartSound(s, sfx_mtrdb)
						S_StartSound(nil, sfx_pzouch) S_StartSound(s, sfx_pzouch)
						end
					if i and i.valid
					s.pzknockbackangle = R_PointToAngle2(s.x, s.y, i.x, i.y)
						if (i.type == MT_SAMPOWERBOMB)
						s.invincible = 101
						s.painfred = 101
						end
					end
					
				else -- No damage info, so...uhh, default go?
				
				s.painfred = 24
				s.invincible = 12
				end
			end	

			
			if i and i.target and i.target.player --Switch target to whoever's attacking you.
			s.target = i
			end
			if not s.pzclone
				if (s.health < 11) and not s.darkclonephase1
				or (s.health < 6) and not s.darkclonephase2
					s.darkclonephase1 = true
					S_StartSound(nil, sfx_pztele)
					DoPZBarrier(s, SKINCOLOR_COBALT)
					DoPZBarrier(s, nil, nil, true, 70)
					for d = 1,3
						s.pzghs = P_SpawnMobj(s.x+P_RandomRange(-50,50), s.y+P_RandomRange(-50,50), s.z+100*d*FRACUNIT, MT_PZBOSS)
						if s.pzghs and s.pzghs.valid
						s.pzghs.flags = $ & ~MF_SHOOTABLE
						s.pzghs.pzclone = true
						s.pzghs.originalpz = s --Remember the OG.
						s.pzghs.actiontimer = P_RandomRange(90,230)
						s.pzghs.justcloned = 19
						s.pzghs.target = s.target
						s.pzghs.state = S_PZ_FLOAT
						s.pzghs.invincible = 50
						s.pzghs.painfred = s.painfred
							if not (P_TryMove(s.pzghs, s.pzghs.x, s.pzghs.y, true))
								for d = 1,18
								P_TryMove(s.pzghs, s.pzghs.x+FixedMul(-70*FRACUNIT, cos(ANG20*d)), s.pzghs.y+FixedMul(-70*FRACUNIT, sin (ANG20*d)), true)
								end
							end
						end
					end
					for z in players.iterate
						P_SamFP(z, PAL_RECYCLE, 14)
					end
					if (s.health < 5) or (s.target and s.target.player and not s.target.player.crazysamusmobs)
					s.darkclonephase2 = true --One more time!!
					end
				end
			end
		s.rollangle = 0	--Just incase, reset rollangle.
		s.samusHP = 8 s.samusHPmax = 8 --Reset your SamusHP value to 8!
		s.flags = $|MF_BOSS|MF_SHOOTABLE|MF_NOGRAVITY --Just incase....
		s.flags2 = $ & ~MF2_FRET
		end
		return
	end
end
addHook("MobjDamage", PZReaction, MT_PZBOSS)
addHook("MobjDeath", PZReaction, MT_PZBOSS)

local function PZCollide(s, m)
	if not (s and s.valid)
	or not (m and m.valid)
	return
	end
	if m.player and not s.phazondive
		if YouAreSamus(m) //Only melee players during the Phazon Dive.
			return false
		elseif not s.invincible
			if (m.z > s.z+s.height+20*FRACUNIT)
			or (s.z > m.z+m.height+20*FRACUNIT)
			return 
			end
			if (m.player.pflags & PF_JUMPED) or (m.player.pflags & PF_SPINNING) or (m.player.pflags & PF_THOKKED)
			m.momx = $*-1 m.momy = $*-1 m.momz = $*-1
			S_StartSound(m, sfx_dmpain)
			P_DamageMobj(s, m, m)
			return false
			end
		end
	end
	if (s.phazondive or s.pzreflecttime) and (m and (m.flags & MF_MISSILE) and (m.target != s))
	SamusBeamReflect(m, s)
	return false
	end
	if (m.darkhyper and m.target and m.target == s)
	or (m.type == MT_PZBARRIER or m.type == PZ_TARGET or m.type == MT_PZBOSS)
	return false
	end
	if s.pzreflecttime and not (m and m.player)
	return false
	end
end
addHook("MobjCollide", PZCollide, MT_PZBOSS)
addHook("MobjMoveCollide", PZCollide, MT_PZBOSS)

local function SamusIsWin(line, s) --Mission Complete
	for z in players.iterate
		if z.mo 
		SamusMission(z.mo, "\x82     THE OPERATION WAS", "\x82 COMPLETED SUCCESSFULLY", nil, 3, 0, false)
		end
	end
end
addHook("LinedefExecute", SamusIsWin, "SAMISWIN")

addHook("MobjThinker", function(s)
	if s.angle == ANGLE_90 and (s.state == S_PZ_REMAINS1)
	s.state = S_PZ_REMAINS3
	elseif s.tics == 199 and (s.state == S_PZ_REMAINS1)
	s.tics = $-P_RandomRange(0,191)
	end
end, MT_DARKPZREMAINS)