--=============================METROIDS=========================================
--Metroids. From Larva to Super Metroids, all in DSZ4. Omega Metroid is MTR2.
--===============================================================================

local function MetroidHover(s) //Metroid Hovering function, makes them passively hover over the ground.
		if s.type == MT_METROID and s.target --Swerve left and right for normal Metroids.
			if s.lungesfx
			s.lungesfx = $-1
			end
			if not s.leftswerve
			s.leftswerve = 32
			else
			s.leftswerve = $-1
			end
			if s.leftswerve > 16
			P_Thrust(s, s.angle+ANGLE_90, P_RandomRange(35355, 58555))
			else
			P_Thrust(s, s.angle-ANGLE_90, P_RandomRange(35355, 58555))	
			end
			if P_FaceStabCheckMeleeRange(s) and s.actiontroid and (s.actiontroid > 9)
				s.actiontroid = $-8  -- Get agitated and attack sooner if people get close.
				if not s.lungesfx
				s.lungesfx = 30
				S_StartSound(s, sfx_mtrd1)
				end
			end
		end
		if not s.type == MT_METROIDLARVA
			if not s.msfx --Also, make creepy sounds occasionally
			s.msfx = P_RandomRange(90,240)
			else
			s.msfx = $-1
				if s.msfx == 1
					if s.type == MT_SUPERMETROID
						S_StartSound(s, sfx_mtrdsp)
					else
					/*	if P_RandomRange(0,1)
						S_StartSound(s, sfx_mlrv2)
						else
						S_StartSound(s, sfx_mtrdsp)
						end */
					end
				end
			end
		end
		if s.z > s.floorz+50*FRACUNIT		
			if not (s.momz*P_MobjFlip(s) < -12*FRACUNIT)
				if (s.z > s.ceilingz-80*FRACUNIT) --Don't cling to the ceiling, pls
				s.momz = $-(5350*P_MobjFlip(s))
				else
				s.momz = $-(1120*P_MobjFlip(s))
				end
			end
		elseif not (s.momz*P_MobjFlip(s) > 8*FRACUNIT)
			s.momz = $+(26800*P_MobjFlip(s))	
		end
end


local function MetroidGhost(s) --Spawns Metroid Ghosts
	s.ghs = P_SpawnGhostMobj(s)
	s.ghs.blendmode = AST_ADD
	s.ghs.tics = 5
	s.ghs.scale = s.scale+P_RandomRange(20000, 50000)
end


local function MetroidZap(s, color)
local ghs
		if (s.eflags & MFE_VERTICALFLIP)
			ghs = P_SpawnMobj(s.x, s.y, s.z+s.height, MT_SAMUSZAP)
		else
			ghs = P_SpawnMobj(s.x, s.y, s.z-s.height/10, MT_SAMUSZAP)
		end
		if ghs.valid
			ghs.scale = s.scale*5/6
			ghs.momx = s.momx
			ghs.momy = s.momy
			ghs.momz = s.momz
			ghs.blendmode = AST_ADD
			ghs.eflags = s.eflags
			ghs.color = color
			ghs.morning = 4
		end	
end

local function MetroidApproach(s) --Make their movements tricky.
	if not (abs(s.momx)+abs(s.momy) > 20*s.scale)
		P_Thrust(s, R_PointToAngle2(s.x, s.y, s.target.x, s.target.y), 4*FRACUNIT)
	end	
	if not P_RandomRange(0,3)
		P_Thrust(s, R_PointToAngle2(s.x, s.y, s.target.x, s.target.y)+(ANGLE_90*P_RandomRange(-1,1)), 5*FRACUNIT)
	end
	if not P_RandomRange(0,5)
		s.momz = $+11*FRACUNIT
	elseif not P_RandomRange(0,7)
		s.momz = $-8*FRACUNIT
	end	
end

--Both regular Metroids and the Super Metroid use these.
--Quite an overly complex enemy.

local function MetroidThinker(s)
	if s.stuntroid
	s.actiontroid = s.stuntroid+5
	s.uimetroid = s.stuntroid
	s.stuntroid = $-1
	s.momz = ($/2)-35355
	s.momx = $/2
	s.momy = $/2
	s.barrelroll = 0
	s.rollangle = 0
	MetroidZap(s, SKINCOLOR_PURPLE)	
		if s.stuntroid <= 1
		s.color = SKINCOLOR_RED
		else
		s.color = SKINCOLOR_LAVENDER
		end

	elseif s.uimetroid
		if (s.uimetroid > 55) or (s.target and s.target.player and s.target.player.crazysamusmobs)
		s.uimetroid = $-1
		elseif leveltime % 2 == 0 --if in normal mode, give Metroids less dodge juice.
		s.uimetroid = $-1
		end
		if s.barrelroll == nil
		s.barrelroll = 0
		end
		if (s.sidesweep and (s.sidesweep > 3)) and s.sidesweepd
		s.barrelroll = $+(ANG30*s.sidesweepd)
		s.rollangle = s.barrelroll
		s.color = SKINCOLOR_SUPERGOLD5
		s.colorized = true
		elseif s.rollangle
		s.colorized = false
		s.color = SKINCOLOR_RED
		s.barrelroll = 0
		s.rollangle = 0
		end
/*	elseif s.paintroid
		s.paintroid = $-1
		if (s.paintroid % 2 == 0) and (s.paintroid > 1)
		s.color = SKINCOLOR_WHITE
		else
		s.color = SKINCOLOR_RED
		end */
	end
	if not s.actiontroid
		if s.target and s.target.player and s.target.player.crazysamusmobs
		s.actiontroid = P_RandomRange(50,85)
		else
		s.actiontroid = P_RandomRange(95,150) --Give players more time to aim if not doing hypermode	
		end
	S_StartSound(s, sfx_mtrdf)
	else
	s.actiontroid = $-1
	end
	--idle, stopping and looking for prey
	if not (s.target and s.target.valid)
		if s.wasattacking
		s.wasattacking = false
		s.target = nil
		s.momx = 0 s.momy = 0 s.momz = 0 --stop
		
		else
		
		MetroidHover(s)
			if (s.actiontroid % 5 == 0)
			P_LookForPlayers(s, 0, true) --Find players, infinite sight distance, but still has to be within sight
				if (s.target and s.target.valid) and not P_CheckSight(s, s.target)
				s.target = nil
				end
			end
		end
		
	--The Metroid Attacks!
	
	elseif s.target and s.target.valid
	s.wasattacking = true
		if s.actiontroid == 1 --Activate action
			s.rollangle = 0
			s.barrelroll = 0
			s.colorized = false
			local action = P_RandomRange(1,3)
			
			if action == 1 --Straight rush! 
			
				if (FixedHypot(FixedHypot(s.x-s.target.x, s.y-s.target.y), s.z-s.target.z) < 1650*FRACUNIT)
					if s.electroid --...unless you're an ELECTROID!! Slowly home into your enemy and corner them. You're invincible with electricity
					elseif s.magnetroid --...OR A MAGNETROID!!! Pull Samus towards you instead!
					else
					s.actiontroid = P_RandomRange(50,80)+38
					s.straightrusha = R_PointToAngle2(s.x, s.y, s.target.x, s.target.y)
					s.straightrushz = s.target.z+s.target.height/4
					s.straightrushprepare = 10
						if s.type == MT_SUPERMETROID
						s.straightrush = P_RandomRange(48, 58)
						else
						s.straightrush = P_RandomRange(29, 36)
						end
					end
				else
					s.actiontroid = P_RandomRange(15,50)
					MetroidApproach(s) --too far away, so approach instead.
				end
				
			elseif action == 2 --Lob Rush!	
			
				if (FixedHypot(FixedHypot(s.x-s.target.x, s.y-s.target.y), s.z-s.target.z) < 1650*FRACUNIT)
					s.actiontroid = P_RandomRange(50,80)+40
					s.lobrushprepare = 10 --Angle is constant here
					s.lobrushz = s.target.z+s.target.height/8
					s.lobrush = 26
					S_StartSound(s, sfx_mtrdl)
				else
					s.actiontroid = P_RandomRange(15,45)
					MetroidApproach(s) --too far away, so approach instead.
				end
			
			elseif action == 3 --Sideways sweep
				S_StartSound(s, sfx_mtrd2)
				s.actiontroid = P_RandomRange(8,15)+10
				s.sidesweep = 15
				if P_RandomRange(0,1)
				s.sidesweepd = 1
				else
				s.sidesweepd = -1
				end
			end
			
			
		else --Perform action
			if s.straightrush
				if s.straightrushprepare
					if s.straightrushprepare == 10
						s.plexpand = P_SpawnMobj(s.x, s.y, s.z, MT_PBEXPAND)
						S_StartSound(s, sfx_s3k82)
						S_StartSound(s, sfx_s3kb6)
						if s.plexpand
						s.plexpand.color = SKINCOLOR_CLOUDY
						s.plexpand.momx = s.momx/2
						s.plexpand.momy = s.momy/2
						s.plexpand.momz = s.momz/2
						s.plexpand.scale = $*P_RandomRange(1,2)
						s.plexpand.scalespeed = $*P_RandomRange(2, 4)
						s.plexpand.destscale = $*25
						end
				//	S_StartSound(s, sfx_s3ka2) --Beta sounds
					elseif (s.straightrushprepare == 1)
					S_StartSound(s, sfx_s3ka2)
					end
					MetroidGhost(s)
					s.momy = 0 s.momx = 0		
					s.momz = FRACUNIT
					s.straightrushprepare = $-1
				else
				s.straightrush = $-1
					if (s.straightrush > 3) --goooo
						MetroidGhost(s)
						if s.z < s.straightrushz-50*FRACUNIT
						s.momz = 15*FRACUNIT
						elseif s.z > s.straightrushz+50*FRACUNIT
						s.momz = -22*FRACUNIT
						else
						s.momz = $/2
						end
						P_InstaThrust(s, s.straightrusha, 20*s.scale)
					else
						if (s.straightrush == 1) and s.target and s.target.player
							if s.target.player.crazysamusmobs and P_RandomRange(0,1) --Huge chance of attacking again. Beware.
							s.actiontroid = 2
							end
						end
					s.momx = $*5/8
					s.momy = $*5/8
					s.momz = $*5/8
					end
				end
				
			elseif s.lobrush
			
				A_FaceTarget(s)
				if s.lobrushprepare --Zigzag upwards, or remove this later.
					if s.lobrushprepare == 1
					S_StartSound(s, sfx_mtrdp)
					s.momz = 0
					s.momx = 0
					s.momy = 0
					else
					s.momz = -FRACUNIT*4
					MetroidGhost(s)
						if s.lobrushprepare % 2 == 0
							P_InstaThrust(s, s.angle+ANGLE_90, 45*s.scale)
						else
							P_InstaThrust(s, s.angle-ANGLE_90, 45*s.scale)
						end
					end
					s.lobrushprepare = $-1
				else
				s.lobrush = $-1
					if (s.lobrush > 3) --Pounce that huntress! ...no, not retracting that.
						if (s.lobrush > 14)
						MetroidGhost(s)
							if not (s.z > (s.lobrushz+300*FRACUNIT))
							P_SetObjectMomZ(s, 10*FRACUNIT)
							else
							P_SetObjectMomZ(s, 5*FRACUNIT)
							end
						else
							if s.z < s.lobrushz-50*FRACUNIT
								s.momz = $+FRACUNIT*3
							elseif s.z > s.lobrushz+50*FRACUNIT
								if s.momz > 0
								s.momz = -FRACUNIT
								elseif s.z > s.lobrushz+450*FRACUNIT
								s.momz = $-FRACUNIT*5						
								elseif s.z > s.lobrushz+220*FRACUNIT
								s.momz = $-FRACUNIT*4
								else
								s.momz = $-FRACUNIT*2
								end
							else
							s.momz = $*5/7
							end
						end
						A_FaceTarget(s)
						P_InstaThrust(s, s.angle, (s.lobrush*2)*s.scale)
					else
					s.momx = $*5/8 --Slow down there!
					s.momy = $*5/8
					s.momz = $/2
					end
				end
				
			elseif s.sidesweep --Dodgy manuevers!
			
				if (s.sidesweep > 3)
				MetroidGhost(s)
				A_FaceTarget(s)
				P_InstaThrust(s, s.angle+(ANGLE_90*s.sidesweepd), 25*s.scale)
				else
				s.rollangle = 0
				s.barrelroll = 0
				s.momx = $*5/8 --Slow down there!
				s.momy = $*5/8
				end
				s.sidesweep = $-1				
			end
		MetroidHover(s)
			if (abs(s.momx)+abs(s.momy) > 5*FRACUNIT)
			MetroidGhost(s)
			end
			if not (abs(s.momx)+abs(s.momy) > 14*s.scale)
			P_Thrust(s, R_PointToAngle2(s.x, s.y, s.target.x, s.target.y), 3000)
			end
			if (s.z > (s.target.z+s.target.height/2))
			s.momz = $-2500
			else
			s.momz = $+2000
			end
		end
	end
end

//These are the Metroids. They're alot more dangerous than your usual robotic menaces, but they are weak to ice.

addHook("MobjSpawn", function(s)
	s.color = SKINCOLOR_RED
	s.scale = 115500
	s.notmscaled = true
	P_SpawnGhostMobj(s)	
end, MT_METROID)
addHook("MobjRemoved", function(s)
	if s and s.valid and s.mytracker and s.mytracker.metroidtracker
	s.mytracker.metroidtracker = $-1
	end
end, MT_METROID)

//Metroids are VERY tricky to take out!
local function MetroidDamage(s,i,so)
	if s and s.valid
		if s.state == S_MTRDFROZEN
		and not ((i.type == MT_ICSHOT) or i.icejet)
			s.shattertroid = true
			return
		end
		if so and so.player --If you're in a special state, you may deal direct kills!
		and (so.player.powers[pw_super] or so.player.powers[pw_invulnerability] or so.player.hypermysticsonic)
		return
		end
		if not i and (s.uimetroid and s.uimetroid > 64) --still invincible from dodging frames
		return true
		end
		if s.latchtarget and s.target.valid and s.target.health --Invincible while sucking
		and not (i and (i.type == MT_SAMPOWERBOMB or i.type == MT_SAMMORPHBOMB or i.type == MT_SAMMBOP))
		return true
		end
		if i and i.valid
			if (i.type == MT_ICCHARGECOMBO) --Icebeam combo = instant death
			or ((i.type == MT_SAMPOWERBOMB) and ( (i.phase == nil) or (i.phase and (i.phase < 2)) )) --Only the powerbomb core kills!
				return
			elseif (s.uimetroid and s.uimetroid > 64) --invincible dodging frames
				return true 
			elseif i.type == MT_ICSHOT or i.type == MT_ICCHARGESHOT
			or i.type == MT_HBSHOT or i.icejet or i.skin == "dirk" --Dodge once, or get hit. Anything with icejet can freeze.
				if not s.uimetroid
				and not (i.icejet or i.skin == "dirk") --Dodge! Not Dirk, though, making him chase Metroids all over would be sad.
					s.uimetroid = 73
					s.actiontroid = 36
					S_StartSound(s, sfx_mtrd2)
					s.sidesweep = 15
						if s.sidesweepd
						s.sidesweepd = $*-1
						elseif P_RandomRange(0,1)
						s.sidesweepd = 1
						else
						s.sidesweepd = -1
						end
					s.lobrush = 0
					s.straightrush = 0
					return true
				elseif not (i.type == MT_HBSHOT) --Hyper Beam doesn't freeze
					s.state = S_MTRDFROZEN
					s.tics = 105
					s.momx = 0 s.momy = 0 s.momz = 0
					s.lobrush = 0 s.straightrush = 0 s.actiontroid = 107 s.sidesweep = 0 s.uimetroid = 0
					S_StartSound(s, sfx_icfr)
					return true
				else
					P_KillMobj(s, i, so)
					return true
				end
			elseif i.type == MT_SAMSUPERMISSILE or i.type == MT_WVCHARGESHOT or i.type == MT_PLCHARGESHOT
			or i.type == MT_SAMMORPHBOMB or i.type == MT_SAMMBOP or i.type == MT_SAMPOWERBOMB
			or i.metroidpusher or i.type == MT_CORK or i.type == MT_LHRT --These attacks will stun, but deal no damage
				S_StartSound(s, sfx_mtrds)
				S_StartSound(s, sfx_mtrd2)
				s.actiontroid = P_RandomRange(37,50)
				s.sidesweep = 0
				s.lobrush = 0
				s.straightrush = 0
				if so and so.player and so.player.crazysamusmobs
				s.stuntroid = 40
				else
				s.stuntroid = 120 //Normal players get triple stun time
				end
				s.momx = $/5
				s.momy = $/5
				P_Thrust(s, i.angle, 30*FRACUNIT)
				return true
			elseif i.type == MT_WVSHOT --Absorb this one
				return true
			elseif (i.flags & MF_MISSILE)
				SamusBeamReflect(i, s)
				return true
			end
		end
		return true		
	end
end
//addHook("ShouldDamage", MetroidDamage, MT_METROID)
addHook("MobjDamage", MetroidDamage, MT_METROID)

addHook("MobjThinker", function(s)
	if s and s.valid
		if s.notmscaled
		s.scale = 115500
		s.notmscaled = false
		end
		if s.shattertroid --Shatter effect
			s.shattertroid = false
			S_StartSound(s, sfx_icbr)
			A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000)) A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(67000, 99000))
			A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000)) A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(67000, 99000))
			A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000)) A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(67000, 99000))
			A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000)) A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(67000, 99000))
			A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000)) A_SAMPARTICLE(s, MT_MPR8, 4, 6, -1, 13, SKINCOLOR_SKY, P_RandomRange(57000, 99000))
				for z in players.iterate
					if z.mo
						if (FixedHypot(FixedHypot(s.x-z.mo.x, s.y-z.mo.y), s.z-z.mo.z) < 1000*FRACUNIT)
							A_samquake(z.mo, 12*FRACUNIT, 9, 1)
							P_SamFP(z, PAL_RECYCLE, 3)
						end
					end
				end	
		end
		if s.state == S_MTRDFROZEN
			s.missileresist = false
			s.momx = 0
			s.momy = 0
			s.momz = 0
			if (s.tics < 60) --Don't let it unfreeze!!
				if (s.tics % 2 == 0) and (s.tics > 1)
				s.colorized = true
				s.color = SKINCOLOR_SUPERSILVER1
				else
				s.colorized = false
				s.color = SKINCOLOR_RED
					if s.tics == 1
					s.shattertroid = true
					S_StartSound(s, sfx_mtrdl)
					end
				end
			elseif s.colorized
			s.colorized = false
			s.color = SKINCOLOR_RED
			end
		elseif not s.health --Dying State
			s.momx = 0
			s.momy = 0
			s.momz = P_RandomRange(-2,6)*35355
			s.destscale = 12*FRACUNIT
			s.scalespeed = FRACUNIT/15
			if leveltime % 4 == 0
			S_StartSound(s, sfx_mtrdb)
			s.bmb = P_SpawnMobj(s.x+P_RandomRange(-50,50)*s.scale, s.y+P_RandomRange(-50, 50)*s.scale, s.z+P_RandomRange(-50, 60)*s.scale, MT_THOK)
			s.bmb.state = S_MINIEXP1
			s.bmb.color = P_RandomRange(SKINCOLOR_YELLOW, SKINCOLOR_EMERALD)
			s.bmb.scale = s.scale*5/4
			end
			if leveltime % 2 == 0
			P_InstaThrust(s, s.angle+ANGLE_90, P_RandomRange(8,20)*FRACUNIT)
			s.color = SKINCOLOR_SUPERSILVER1
			s.colorized = true
			else
			P_InstaThrust(s, s.angle-ANGLE_90, P_RandomRange(8,20)*FRACUNIT)			
			s.color = SKINCOLOR_LAVENDER
			s.colorized = false
			end
			
			if (s.state == S_MTRDDEAD2)
			  if (s.tics < 15)
			  s.frame = $|TR_TRANS80 & ~TR_TRANS60 & ~TR_TRANS70
			  	if (s.tics == 1)
				s.plexpand = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_PBEXPAND)
					if s.plexpand
					s.plexpand.scale = s.scale
					s.plexpand.scalespeed = $*P_RandomRange(7, 11)
					s.plexpand.destscale = $*25
					end	
					
					S_StartSound(nil, sfx_mtrdd)
					for d = 1,3
						if P_RandomRange(0,1) or (d == 1) --guarantee one item
							s.itemrng = P_RandomRange(1,8)
							if s.itemrng == 1
							s.item = MT_SPKU
							elseif s.itemrng == 2
							s.item = MT_BMPKU
							elseif s.itemrng < 5
							s.item = MT_NRGA
							elseif s.item == 6
							s.item = MT_NRGB
							else
							s.item = MT_MPKU
							end
							P_SpawnMobj(s.x+P_RandomRange(-70,70)*FRACUNIT, s.y+P_RandomRange(-70,70)*FRACUNIT, s.z+P_RandomRange(-50,50)*FRACUNIT, s.item)
						end
					end
			  	end
			 end
			return
			end
		elseif s.latchtarget --Found a tasty snack to murderize? Let's do the behaviour! 
			if not s.latchtarget.valid or not s.latchtarget.health or not s.latchtarget.player or s.stuntroid
			or (s.state == S_MTRDFROZEN) or not s.health or (s.latchtarget.sam_deathball and YouAreSamus(s.latchtarget)) --Check first...
				s.stuntroid = 20
				s.latchtarget = nil
				s.latchsuck = 0
				return
				
			elseif s.latchtarget.valid
			
			local t = s.latchtarget
			t.metroidsnack = 2
			t.sam_systemreboot = 3
				if t.player and t.player.samtoken
				t.player.samtoken = 0
				P_SamFP(t.player, PAL_NUKE, 3)
				print("\x85"+t.player.name+" got hit and lost the emerald tokens...")
				end
			if t.player.viewrollangle < 0
			t.player.viewrollangle = $+ANG1/2
			elseif t.player.viewrollangle > 0
			t.player.viewrollangle = $-ANG1/2
			end
			s.momx = t.momx s.momy = t.momy s.momz = t.momz
			P_MoveOrigin(s, t.x, t.y, t.z+t.height*5/7)
			S_StartSound(s, sfx_mtrds)
			MetroidZap(s, P_RandomRange(SKINCOLOR_YELLOW, SKINCOLOR_EMERALD))
				if not s.latchsuck
					if YouAreSamus(t)
						if (t.player.sam_energy and (t.player.sam_energy > 99))
						s.latchsuck = 1
						elseif t.player.crazysamusmobs
							if (t.player.sam_energy and (t.player.sam_energy % 2 == 0))
							s.latchsuck = 2 --The last energy tank takes 50% longer
							else
							s.latchsuck = 1
							end
						else
						s.latchsuck = 3 --Go easier on normal-mode players
						end
					else
						if (t.player.rings and (t.player.rings > 7))
						s.latchsuck = 6 --Slower on Sonic chars since they use rings.
						else
						s.latchsuck = 10
						end
					end
				else
				s.latchsuck = $-1
				end
				if not s.latchsuck2  --The sequel sucks.
				s.latchsuck2 = 35
					if YouAreSamus(t)
						if not t.player.sammorphed					
							if P_RandomRange(0,1)
							t.player.viewrollangle = ANG20
							else
							t.player.viewrollangle = ANG20*-1
							end
						end
					P_SamFP(t.player, PAL_NUKE, 3)
					HighPain(t)
					end
				else
				s.latchsuck2 = $-1
				end
				if (s.anim_duration > 1) s.anim_duration = 1 end
				
				--The actual energy sucking damage and effects
				
				if s.latchsuck == 1
					if YouAreSamus(t)
						if t.player.sam_energy and (t.player.sam_energy > 1)
						t.player.sam_energy = $-1
						A_samquake(s, 20*FRACUNIT, 1, 1, true)
						s.latchsuck = 0
						s.survivemetroid = 8
						elseif s.survivemetroid
						s.survivemetroid = $-1
						else
						s.survivemetroid = 8
						P_KillMobj(t, s, s) 
						S_StartSound(s, sfx_mtrdf)
						s.momz = 2*FRACUNIT s.momx = $/4 s.momy = $/4
						s.latchtarget = nil
						return
						end
					else
						if t.player.rings
						s.survivemetroid = 5
						P_GivePlayerRings(t.player, -1) --Shields won't help you here.
						S_StartSound(t, sfx_antiri)
						elseif s.survivemetroid --Give players a short moment to live!
						s.survivemetroid = $-1
						else
						s.survivemetroid = 5
						P_KillMobj(t, s, s) --Yer ded
						S_StartSound(s, sfx_mtrdf)
						s.momz = 2*FRACUNIT s.momx = $/4 s.momy = $/4
						s.latchtarget = nil
						return						
						end
					end				
				end
				--Escape certain death by rolling!
				if (t.player.speed > 22*FRACUNIT) and (t.player.sammorphed or (t.player.pflags & PF_SPINNING))
				or t.player.hypermysticsonic or t.player.powers[pw_super] or t.player.powers[pw_invulnerability]
				or t.crystalflashtime or P_PlayerInPain(t.player)
				or (t.player.sam_screwattacking and t.player.sam_screwattacking == 2)
				or t.player.sam_shinesparkfly
				s.momz = 2*FRACUNIT s.momx = t.momx*-1 s.momy = t.momy*-1
				S_StartSound(s, sfx_mtrd2)
				s.stuntroid = 30
				s.latchsuck = 0
				s.actiontroid = P_RandomRange(37, 65)
				P_SamFP(t.player, PAL_RECYCLE, 3)
				s.latchtarget = nil
					for d = 1,18
						if (P_TryMove(s, s.x+FixedMul(-50*FRACUNIT, cos(ANG20*d)), s.y+FixedMul(-50*FRACUNIT, sin (ANG20*d)), false))
						return
						end
					end
				return
				end
			end
		else --Use the living Metroid thinker!
		s.latchsuck = 0
		s.missileresist = true
		MetroidThinker(s)
		end
	end
end, MT_METROID)

--The Super Metroid is an enormous Metroid larva that was forced to mature through radiation. Incredibly dangerous!

addHook("MobjSpawn", function(s)
	s.color = SKINCOLOR_RED
	s.notmscaled = true
	s.scale = FRACUNIT*4
	S_StartSound(s, sfx_mtrds1)
	P_SpawnGhostMobj(s)
end, MT_SUPERMETROID)
addHook("MobjThinker", function(s)
	if s.notarealegg  --oops, just a prop.
	s.tics = $+1
		if (leveltime % 5 == 0)
			for z in players.iterate
				if z.mo and (z.mo.flags2 & MF2_TWOD)
				z.sams_morphcd = 8 --force Samus to stay in morph ball in the 2D section
				end
			end
		end
	return
	end
	if s.notmscaled
	s.scale = FRACUNIT*4
	s.notmscaled = false
	end
	if s.valid 
		if (gamemap < 46)
			P_SpawnMobj(s.x, s.y, s.z, MT_METROID)
			s.state = S_NULL --Let's not.
			return
		else
			MetroidThinker(s)
		end
	end	
end, MT_SUPERMETROID)



































//METROID 2

























//The Egg that hatches the Larva.

addHook("MobjDeath", function(s, i, so)
	if so and so.player
	S_StopMusic(so.player)
	S_StartSound(s, sfx_ambin2)
	end
end, MT_METROIDLARVAEGG)
addHook("MobjThinker", function(s)
	if not s.noregspawned and not s.panicstart
	s.noregspawned = true
	s.noreg = P_SpawnMobj(s.x, s.y, s.z, MT_SUPERMETROID)
	s.noreg.notarealegg = true
	s.noreg.noregspawned = true
	s.noreg.state = S_THOK
	s.noreg.tics = -1
	s.noreg.flags = MF_NOGRAVITY|MF_NOCLIP
	s.noreg.flags2 = MF2_DONTDRAW
	end 
	
if s.metroidtracker != nil
	if s.metroidtracker <= 1
			for sectorsam in sectors.iterate
				if (sectorsam.tag == 99)
					for fof in sectorsam.ffloors()
					EV_CrumbleChain(sectorsam, fof)
					end
				end
			end
			S_StartSound(nil, sfx_crumbl)
			for player in players.iterate
				if player.mo and player.mo.health
					if (FixedHypot(s.x-player.mo.x, s.y-player.mo.y) < 16080*FRACUNIT)
					SAM_COM_BufInsertText(player, "tunes TNSION")
					P_SamFP(player, PAL_WHITE, 4)
					end
				end
			end	
		if s and s.valid
		s.state = S_NULL
		end
	end
return
elseif s.panicstart --Time for bad things....
	s.panicstart = $-1
	s.noregspawned = true
		if s.panicstart == 300
		S_StartSound(nil, sfx_crumbl)
		S_StartSound(nil, sfx_mtrdop)
		P_StartQuake(50*FRACUNIT, 9)		
		P_LinedefExecute(1280)
		elseif s.panicstart == 250
			S_StartSound(nil, sfx_mtrdow)
			P_StartQuake(7*FRACUNIT, 90)
		elseif s.panicstart == 170 or s.panicstart == 110 or s.panicstart == 40
			S_StartSound(nil, sfx_mtrdop)
			P_StartQuake(40*FRACUNIT, 12)		
		elseif s.panicstart == 25
			S_StartSound(nil, sfx_mtrd2)
		elseif s.panicstart == 1 and s.valid
			S_StartSound(nil, sfx_mtrd1)
			S_StartSound(nil, sfx_crumbl)
			S_StartSound(nil, sfx_bkpoof)			
			P_StartQuake(40*FRACUNIT, 11)
			for sectorsam in sectors.iterate
				if (sectorsam.tag == 128) or (sectorsam.tag == 130) or (sectorsam.tag == 131)
				or (sectorsam.tag == 74) or (sectorsam.tag == 75)
					for fof in sectorsam.ffloors()
					EV_CrumbleChain(sectorsam, fof)
					end
				end
			end
			for player in players.iterate
				if player.mo and player.mo.health
					if (FixedHypot(s.x-player.mo.x, s.y-player.mo.y) < 5080*FRACUNIT)
					SAM_COM_BufInsertText(player, "tunes METRD")
					P_SamFP(player, PAL_WHITE, 4)
					end
				end
			end
			s.metroidtracker = 1
			s.panicstart = 0
			for m in mobjs.iterate(mobjs)
				if m and m.valid and m.type == MT_SPIKEBALL
					m.metroid = P_SpawnMobj(m.x, m.y, m.z, MT_METROID)
					if m.metroid and m.metroid.valid
					m.metroid.color = SKINCOLOR_RED
					m.metroid.angle = m.angle
					m.metroid.actiontroid = 5
					m.metroid.mytracker = s
					s.metroidtracker = $+1
					end
					m.state = S_NULL
				end
			end
		end
	return
elseif s.hatchdebris
s.hatchdebris = $-1
A_SAMPARTICLE(s, MT_MPR2, 4, 7, 10, 7, SKINCOLOR_MOSS)
return
else
	if not s.spawnset 
		s.spawnset = true
		s.scale = 98355
		s.color = SKINCOLOR_MOSS		
	end
	if leveltime % 16 == 0 and s and s.health and not s.hatchtimer
		for player in players.iterate
			if player.mo and player.mo.health
				if (FixedHypot(s.x-player.mo.x, s.y-player.mo.y) < 180*FRACUNIT)
				and (player.mo.y > 14000*FRACUNIT) --damnit, garbage nodebuilders.
				S_StopMusic(player)
				s.hatchtimer = 52
				S_StartSound(s, sfx_ambin2)
				end
			end
		end
	elseif s.hatchtimer and s.health
		s.hatchtimer = $-1
		if s.hatchtimer == 1
		P_KillMobj(s) --Be born into this world, little Metroid!
		end
	elseif not s.hatched and (s.state == S_MRLVEGGHATCHD)
		s.hatched = true
		s.hatchdebris = 7
		S_StartSound(s, sfx_mlrvh)
		S_StartSound(s, sfx_s244)
		s.larvaspawn = P_SpawnMobj(s.x, s.y, s.z+s.height/3, MT_METROIDLARVA)
		if s.larvaspawn and s.larvaspawn.valid
		s.larvaspawn.angle = s.angle
		s.larvaspawn.color = SKINCOLOR_RED
		end
	end
end
end, MT_METROIDLARVAEGG)

//Metroid Larva. Unfortunately, despite it's cuteness, your mission is to take it out!

addHook("MobjSpawn", function(s)
	s.color = SKINCOLOR_RED
	s.destscale = 75000
	s.samusHP = 1
	s.powerbeamsamusHP = 5
	s.risetimer = 20
	s.larvatimer = P_RandomRange(70, 130)
	s.notmscaled = true
	P_SpawnGhostMobj(s)	
	if P_RandomRange(0,1)
	S_StartSound(s, sfx_mlrv1)
	else
	S_StartSound(s, sfx_mlrv2)	
	end
end, MT_METROIDLARVA)
addHook("MobjThinker", function(s)
//Spawn rising state

	if s.notmscaled
	s.destscale = 75000
	s.samusHP = 1
	s.notmscaled = false
	elseif s.risetimer and not s.deathanim
	s.risetimer = $-1
	s.ghs = P_SpawnGhostMobj(s)
	s.ghs.tics = 5
		if (s.risetimer > 7)
		P_SetObjectMomZ(s, 7*FRACUNIT, false)
		elseif not s.risetimer
		s.momz = 0
		else
		s.momz = $/2
		end
		
//Normal living state
	
	elseif not s.deathanim
	MetroidHover(s) --Hover all the time.
		if s.color != SKINCOLOR_RED
		s.color = SKINCOLOR_RED
		end
		if not s.larvatimer
		s.larvatimer = P_RandomRange(70, 130)
		else
			s.larvatimer = $-1
			if (s.larvatimer == 1) --Will it get curious?
				if P_RandomRange(0,1)
				S_StartSound(s, sfx_mlrv1)
					P_LookForPlayers(s, 5000*FRACUNIT, true, true)
					if s.tracer and s.tracer.valid
					s.curious = P_RandomRange(80, 240)
					s.curiousd = P_RandomRange(-1, 1)
					s.larvatimer = s.curious+30
						if not s.curiousd
						s.curiousd = 1
						end
					end
				else
				S_StartSound(s, sfx_mlrv2)
				s.larvatimer = P_RandomRange(70, 130)
				end
			end
			if s.curious
			s.wascurious = 9
			s.curious = $-1
				if s.tracer
					if not (abs(s.momx)+abs(s.momy) > 20*FRACUNIT)
					P_Thrust(s, R_PointToAngle2(s.x, s.y, s.tracer.x, s.tracer.y), 3000)
					P_Thrust(s, R_PointToAngle2(s.x, s.y, s.tracer.x, s.tracer.y)+(ANGLE_90*s.curiousd), P_RandomRange(1000, 3000))
					end
					if (s.z > s.z+(s.tracer.z+s.tracer.height))
					s.momz = $-3000
					end
				end
			else
			//	if s.tracer --Attack enemies for us.
			//	P_RadiusAttack(s, s.tracer, 38*FRACUNIT)
			//	end
				if s.wascurious
					s.wascurious = $-1
					s.momx = $*15/16 s.momy = $*15/16 s.momz = $*15/16
					if s.wascurious == 1
					s.momx = 0 s.momy = 0 s.momz = 0
					end
				end
			end
		end
	end
	
//Death State	

	if s.deathanim
		if s.deathanim > 60
		P_SetObjectMomZ(s, 11*FRACUNIT)
		else
			if P_IsObjectOnGround(s)
			P_SetObjectMomZ(s, 6*FRACUNIT)
			else
			P_SetObjectMomZ(s, -25355, true)
			end
		end
		if s.deathanim % 8 == 0
		S_StartSound(s, sfx_mtrdb)
		s.bmb = P_SpawnMobj(s.x+P_RandomRange(-50,50)*s.scale, s.y+P_RandomRange(-50, 50)*s.scale, s.z+P_RandomRange(-50, 50)*s.scale, MT_THOK)
		s.bmb.state = S_MINIEXP1
		s.bmb.color = SKINCOLOR_FLAME
		end
		if s.deathanim % 2 == 0
		s.color = SKINCOLOR_SUPERSILVER1
		s.colorized = true
		else
		s.color = SKINCOLOR_LAVENDER
		s.colorized = false
		end
		if s.fuse == 1 --end it.
		s.bmb = P_SpawnMobj(s.x, s.y, s.z, MT_THOK)
		s.bmb.tics = 130
		s.bmb.flags2 = $|MF2_DONTDRAW
		s.panicstarter = P_SpawnMobj(s.x, s.y, s.z, MT_METROIDLARVAEGG)
		s.panicstarter.panicstart = 485 --Start off the Metroid panic! Should be 485
		s.panicstarter.flags = MF_NOGRAVITY|MF_NOCLIP
		s.panicstarter.flags2 = $|MF2_DONTDRAW
		S_StartSound(s.bmb, sfx_mlrvd)
		P_SpawnMobj(s.x, s.y, s.z, MT_EXPLODE)
		s.ghs = P_SpawnGhostMobj(s)
		s.ghs.destscale = FRACUNIT*20
		s.ghs.tics = 24
		s.ghs.fuse = 24
		s.ghs.rollangle = s.rollangle
		P_SetObjectMomZ(s.ghs, 2*FRACUNIT, true)
		s.ghs.color = SKINCOLOR_RED
		return
		end
	s.deathanim = $-1
	s.rollangle = $+FixedAngle(P_RandomRange(14,30)*FRACUNIT)	
	A_SAMPARTICLE(s, MT_MPR5, 7, 4, -2, 8, SKINCOLOR_GREEN, P_RandomRange(19355, 49999))
	end
end, MT_METROIDLARVA)
addHook("MobjDeath", function(s, i, so)
	if not (so and so.player) --Don't get hurt by non-player things.
	return true
	end
	s.deathanim = 70
	s.fuse = 70
	P_SpawnGhostMobj(s)	
	s.color = SKINCOLOR_LAVENDER
	if i and i.valid
		P_InstaThrust(s, R_PointToAngle2(s.x, s.y, i.x-i.momx, i.y-i.momy), -9*FRACUNIT)
	elseif so and so.valid
		P_InstaThrust(s, R_PointToAngle2(s.x, s.y, so.x, so.y), -9*FRACUNIT)		
	end
	if so and YouAreSamus(so) and (gametype == GT_COOP)
	SamusDialogue(so, "... ", nil, "SAMSAD", 5, 0, 130)
	end
/*	if gamemap // == ACZ4, whatever this'll be. Debating whether I'll stop music everywhere or just here.
		for z in players.iterate
		S_StopMusic(z)
		end
	end */
end, MT_METROIDLARVA)

addHook("MobjDeath", function(s, i, so) --More mercy mechanics.
	if (so and so.player and YouAreSamus(so) and so.player.sam_energy != nil and so.player.sam_energy < 50)
	P_SpawnMobj(s.x, s.y, s.z, MT_NRGB)
	end
end, MT_METROID)

//Ice Jets instead of Fire Jets!

addHook("MobjSpawn", function(s)
	A_FindTarget(s, MT_FLAMEJET, 0)
		if s.target and s.target.iceshooter
		s.icejet = true
		s.state = S_ICSHOT1
		s.blendmode = AST_ADD
		s.destscale = FRACUNIT*4
		s.fuse = 26
		end
end, MT_FLAMEJETFLAME)
addHook("MobjThinker", function(s)
	if s.icejet
		if (s.state < S_ICSHOT1)
		s.state = S_ICSHOT1
		s.destscale = FRACUNIT*4
		s.fuse = 26
		end
	end
end, MT_FLAMEJETFLAME)

//Shell changes scenery

addHook("MobjThinker", function(s)
	if not s.preset
		s.preset = true
		if (s.flags2 & MF2_AMBUSH)
		s.frame = F
		s.color = SKINCOLOR_MOSS
		s.scale = 105300
		else
		s.scale = 153000
		end
	end
end, MT_METROIDSHELL)

--Stupid crushers ruining everything, get out of here!
local function FuckCrushers(s, i, so, damage, dmgtype)
	if (dmgtype == DMG_CRUSHED or dmgtype == DMG_DEATHPIT)
	return false
	end
end
addHook("ShouldDamage", FuckCrushers, MT_METROIDLARVA)
addHook("ShouldDamage", FuckCrushers, MT_METROID)
addHook("ShouldDamage", FuckCrushers, MT_SUPERMETROID)
local function FuckCrushers2(s, i, so, dmgtype) --The sequel
	if dmgtype
		if (dmgtype == DMG_CRUSHED or dmgtype == DMG_DEATHPIT)
		s.negatecrusher = 2
		s.health = 1
		s.flags = MF_NOGRAVITY|MF_ENEMY|MF_SHOOTABLE|MF_SLIDEME
		s.flags2 = $ & ~MF2_FRET
			for d = 1,18
				if (P_TryMove(s, s.x+FixedMul(-50*FRACUNIT, cos(ANG20*d)), s.y+FixedMul(-50*FRACUNIT, sin (ANG20*d)), true))
				return true
				end
			end
		return true
		end
	end
end
addHook("MobjDeath", FuckCrushers2, MT_METROIDLARVA)
addHook("MobjDeath", FuckCrushers2, MT_METROID)
addHook("MobjDeath", FuckCrushers2, MT_SUPERMETROID)