--===========================ITEM PICKUPS==============================
--Powerup pickups, ammo drops, tracking items in HUD, that's all in here.
--======================================================================

rawset(_G, "NewSamPickup",function(s, name, scale, time, color, trans) --Set Parameters
if not time time = 150 end
if not scale scale = FRACUNIT end
	if not color
		if name == "NRGDB0"
			color = SKINCOLOR_SUPERGOLD4
		else
			color = SKINCOLOR_NONE
		end
	end
	if not trans trans = TR_TRANS10 end

	--Move these two to the front of the row....
	if s.sampickuptime3 // and s.sampickuptime2
		if not s.sampickuptime		
			s.sampickupname = name
			s.sampickupscale = scale
			s.sampickuptime = time
			s.sampickupoffset = 6*FRACUNIT
			s.sampickuptrns = trans
			s.sampickupcolor = color
		else
	
			s.sampickupname3 = s.sampickupname2
			s.sampickupscale3 = s.sampickupscale2
			s.sampickuptime3 = s.sampickuptime2
			s.sampickupoffset3 = s.sampickupoffset2
			s.sampickuptrns3 = s.sampickuptrns2
			s.sampickupcolor3 = s.sampickupcolor2

			s.sampickupname2 = s.sampickupname
			s.sampickupscale2 = s.sampickupscale
			s.sampickuptime2 = s.sampickuptime
			s.sampickupoffset2 = s.sampickupoffset
			s.sampickuptrns2 = s.sampickuptrns
			s.sampickupcolor2 = s.sampickupcolor
	
			s.sampickupname = name
			s.sampickupscale = scale
			s.sampickuptime = time
			s.sampickupoffset = 6*FRACUNIT
			s.sampickuptrns = trans
			s.sampickupcolor = color
		end
	
	elseif s.sampickuptime2
		s.sampickupname3 = name
		s.sampickupscale3 = scale
		s.sampickuptime3 = time
		s.sampickupoffset3 = 6*FRACUNIT
		s.sampickuptrns3 = trans
		s.sampickupcolor3 = color
	
	elseif s.sampickuptime
		s.sampickupname2 = name
		s.sampickupscale2 = scale
		s.sampickuptime2 = time
		s.sampickupoffset2 = 6*FRACUNIT
		s.sampickuptrns2 = trans
		s.sampickupcolor2 = color
	else
		s.sampickupname = name
		s.sampickupscale = scale
		s.sampickuptime = time
		s.sampickupoffset = 6*FRACUNIT
		s.sampickuptrns = trans
		s.sampickupcolor = color
	end
end)

local function RingToSam(m)
	for d = 0,31 --How it SHOULD be done.
	if players[d] and players[d].metroidvisuals or (gametype == GT_HUNTERS)
			if m and m.valid
			and (m.type == MT_STARPOST)
				m.samspawnitem = P_SpawnMobj(m.x, m.y, m.z, MT_SMONTRACKER)
				m.samspawnitem.target = m
				m.samspawnitem.starposttracker = true
				m.metroidvisual = true
					if m and m.valid and m.health
					m.sprite = SPR_MPR1
					m.frame = O
					m.color = SKINCOLOR_RED
					end
					return
			elseif m and m.valid and m.health
					m.state = S_METRING1
					m.metroidvisual = true
					m.colorized = true
					m.color = SKINCOLOR_WHITE
					return
			end
		end
	end
end

addHook("MobjSpawn", RingToSam, MT_RING)
addHook("MobjSpawn", RingToSam, MT_FLINGRING)
addHook("MobjSpawn", RingToSam, MT_COIN)
addHook("MobjSpawn", RingToSam, MT_FLINGCOIN)

--Hunters only skins.
local function RingToSam7(m)
	if (gametype == GT_HUNTERS) and m
		m.state = S_HUNTERSMISSILE1
		m.scale = 75356
		if m.type == MT_INFINITYRING
		m.colorized = true
		m.scale = 95356
		m.color = SKINCOLOR_RED
		end
	end
end
addHook("MobjSpawn", RingToSam7, MT_BOUNCERING)
addHook("MobjSpawn", RingToSam7, MT_RAILRING)
addHook("MobjSpawn", RingToSam7, MT_AUTOMATICRING)
addHook("MobjSpawn", RingToSam7, MT_EXPLOSIONRING)
addHook("MobjSpawn", RingToSam7, MT_SCATTERRING)
addHook("MobjSpawn", RingToSam7, MT_GRENADERING)
addHook("MobjSpawn", RingToSam7, MT_EXPLOSIONRING)
addHook("MobjSpawn", RingToSam7, MT_INFINITYRING)
local function RingToSam8(m)
	if (gametype == GT_HUNTERS) and m
		m.state = S_HUNTERSMISSILE3
		m.scale = 120000
		m.info.deathstate = S_SPRK1
		local ghs = P_SpawnMobj(m.x, m.y, m.z, MT_SAMSPAWNITEMSONIC)
		ghs.ogmonitor = m
		ghs.tics = -1
		ghs.missilepanel = true
	end
end
addHook("MobjSpawn", RingToSam8, MT_BOUNCEPICKUP)
addHook("MobjSpawn", RingToSam8, MT_RAILPICKUP)
addHook("MobjSpawn", RingToSam8, MT_AUTOPICKUP)
addHook("MobjSpawn", RingToSam8, MT_SCATTERPICKUP)
addHook("MobjSpawn", RingToSam8, MT_GRENADEPICKUP)
addHook("MobjSpawn", RingToSam8, MT_EXPLODEPICKUP)

//Pity TV MobjSpawn doesn't work for some reason.

addHook("MobjThinker", function(m)
 if m.valid and m.triedspawn
 return end
	if G_GametypeHasSpectators() and leveltime > 8
	and not ((players[0] and players[0].sammatchmonitors) or (players[1] and players[1].sammatchmonitors))
		local boxrespawn = P_RandomRange(1, 120)
				if (boxrespawn < 60)
 					m.type = MT_RING_BOX 
				elseif (boxrespawn < 64)
 					m.type = MT_PITY_BOX
				elseif (boxrespawn < 73)
 					m.type = MT_FORCE_BOX	
				elseif (boxrespawn < 81)
 					m.type = MT_WHIRLWIND_BOX
				elseif (boxrespawn < 88)
 					m.type = MT_ELEMENTAL_BOX
				elseif (boxrespawn < 94)
 					m.type = MT_ATTRACT_BOX 
				elseif (boxrespawn < 100)
 					m.type = MT_ARMAGEDDON_BOX
				elseif (boxrespawn < 102)
 					m.type = MT_INVULN_BOX 
				elseif (boxrespawn < 118)
 					m.type = MT_SNEAKERS_BOX
				elseif (boxrespawn < 119)
 					m.type = MT_MIXUP_BOX
				else
 					m.type = MT_RECYCLER_BOX
				end
 				if m.valid and m.health
				m.state = mobjinfo[m.type].spawnstate
 				end
	end
	if players[0] and players[0].metroidvisuals 
	or players[1] and players[1].metroidvisuals
	or (gametype == GT_HUNTERS)
		if m and m.valid and m.health and not (m.type == MT_1UP_BOX)
		and not ( ((m.type >= MT_PITY_GOLDBOX) and (m.type <= MT_THUNDERCOIN_GOLDBOX)) and not (m.type == MT_EGGMAN_GOLDBOX))
		m.state = S_METBOX1
		m.metroidvisual = true
							if m.type == MT_FORCE_BOX
							m.color =SKINCOLOR_BLUE
							elseif m.type == MT_ARMAGEDDON_BOX
							m.color =SKINCOLOR_RED
							elseif m.type == MT_ELEMENTAL_BOX
							m.color =SKINCOLOR_EMERALD
							elseif m.type == MT_FLAMEAURA_GOLDBOX 
							m.color =SKINCOLOR_FLAME
							elseif m.type == MT_BUBBLEWRAP_GOLDBOX 
							m.color =SKINCOLOR_AQUA
							elseif m.type == MT_THUNDERCOIN_GOLDBOX 
							m.color =SKINCOLOR_BRONZE							
							elseif m.type == MT_ATTRACT_BOX 
							m.color =29
							elseif m.type == MT_WHIRLWIND_BOX
							m.color =SKINCOLOR_SKY
							elseif m.type == MT_PITY_BOX
							m.color =SKINCOLOR_MOSS
							elseif m.type == MT_INVULN_BOX
							m.color =SKINCOLOR_WHITE
							elseif m.type == MT_MIXUP_BOX
							elseif ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX))
							m.color =SKINCOLOR_BLACK
							elseif m.type == MT_SNEAKERS_BOX
							m.color =SKINCOLOR_MAGENTA
							else
							m.color =SKINCOLOR_ORANGE
							end			
			
		end
	end
	m.triedspawn = true
end, MT_PITY_BOX)

local function BoxToSam(m)
	if G_GametypeHasSpectators() and (m.flags & MF_MONITOR) and leveltime > 11
	and not ((players[0] and players[0].sammatchmonitors) or (players[1] and players[1].sammatchmonitors))
		if not ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX)) and not (m.type == MT_RING_REDBOX) and not (m.type == MT_RING_BLUEBOX)
		local boxrespawn = P_RandomRange(1, 120)
				if (boxrespawn < 60)
 					m.type = MT_RING_BOX
				elseif (boxrespawn < 64)
 					m.type = MT_PITY_BOX 
				elseif (boxrespawn < 73)
 					m.type = MT_FORCE_BOX
				elseif (boxrespawn < 81)
 					m.type = MT_WHIRLWIND_BOX
				elseif (boxrespawn < 88)
 					m.type = MT_ELEMENTAL_BOX 
				elseif (boxrespawn < 94)
 					m.type = MT_ATTRACT_BOX 
				elseif (boxrespawn < 100)
 					m.type = MT_ARMAGEDDON_BOX
				elseif (boxrespawn < 102)
 					m.type = MT_INVULN_BOX 
				elseif (boxrespawn < 118)
 					m.type = MT_SNEAKERS_BOX
				elseif (boxrespawn < 119)
 					m.type = MT_MIXUP_BOX
				else
 					m.type = MT_RECYCLER_BOX
				end
 				if m and m.valid and m.health
				m.state = mobjinfo[m.type].spawnstate
					if m and m.valid and (m.type == MT_PITY_BOX) 
					m.triedspawn = true
					end
 				end
 		end
	end
	if players[0] and players[0].metroidvisuals
	or players[1] and players[1].metroidvisuals
	or (gametype == GT_HUNTERS)
		if m and m.valid and m.health and not (m.type == MT_1UP_BOX)
		and not ((m.type >= MT_PITY_GOLDBOX) and (m.type <= MT_THUNDERCOIN_GOLDBOX))
		m.state = S_METBOX1
		m.metroidvisual = true
			if m.type == MT_FORCE_BOX
			m.color =SKINCOLOR_BLUE
			elseif m.type == MT_ARMAGEDDON_BOX
			m.color =SKINCOLOR_RED
			elseif m.type == MT_ELEMENTAL_BOX
			m.color =SKINCOLOR_EMERALD
			elseif m.type == MT_ATTRACT_BOX 
			m.color =29
			elseif m.type == MT_WHIRLWIND_BOX
			m.color =SKINCOLOR_SKY
			elseif m.type == MT_PITY_BOX
			m.color =SKINCOLOR_MOSS
			elseif m.type == MT_INVULN_BOX
			m.color =SKINCOLOR_WHITE
			elseif m.type == MT_MIXUP_BOX
			elseif ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX))
			m.color =SKINCOLOR_BLACK
			elseif m.type == MT_SNEAKERS_BOX
			m.color =SKINCOLOR_MAGENTA
			else
			m.color =SKINCOLOR_ORANGE
			end
		end
	end
end

addHook("MobjSpawn", BoxToSam, MT_RING_BOX)
addHook("MobjSpawn", BoxToSam, MT_RING_REDBOX)
addHook("MobjSpawn", BoxToSam, MT_RING_BLUEBOX)
addHook("MobjSpawn", BoxToSam, MT_SNEAKERS_BOX)
addHook("MobjSpawn", BoxToSam, MT_INVULN_BOX)
addHook("MobjSpawn", BoxToSam, MT_ATTRACT_BOX )
addHook("MobjSpawn", BoxToSam, MT_FORCE_BOX)
addHook("MobjSpawn", BoxToSam, MT_ARMAGEDDON_BOX)
addHook("MobjSpawn", BoxToSam, MT_WHIRLWIND_BOX)
addHook("MobjSpawn", BoxToSam, MT_ELEMENTAL_BOX)
//addHook("MobjSpawn", BoxToSam, MT_PITY_BOX)
addHook("MobjSpawn", BoxToSam, MT_EGGMAN_BOX)
addHook("MobjSpawn", BoxToSam, MT_EGGMAN_GOLDBOX)
addHook("MobjSpawn", BoxToSam, MT_RECYCLER_BOX)
addHook("MobjSpawn", BoxToSam, MT_MYSTERY_BOX)
addHook("MobjSpawn", BoxToSam, MT_SCORE1K_BOX)
addHook("MobjSpawn", BoxToSam, MT_SCORE10K_BOX)
addHook("MobjSpawn", BoxToSam, MT_MIXUP_BOX)
addHook("MobjSpawn", BoxToSam, MT_1UP_BOX)

addHook("MobjThinker", function(s)
	if s.metroidvisual 
		if s.health and (s.color < 25)
			if (s.color % 8 == 0) and not (s.flags2 & MF2_DONTDRAW) --Ooooo, we soooo special.
			P_SpawnMobj(s.x+(P_RandomRange(-80,80)*FRACUNIT), s.y+(P_RandomRange(-80,80)*FRACUNIT), s.z+(P_RandomRange(3,50)*FRACUNIT), MT_SUPERSPARK)
			end
		s.color = $+1
		elseif s.health and (s.color >= 25)
		s.color = 0
		end
	end
end, MT_MIXUP_BOX)

addHook("MobjThinker", function(s)
	if not s.sampickup
	s.sampickup = true
	end
end, MT_MPKU)

addHook("MobjThinker", function(s)
	if not s.sampickup
	s.sampickup = true
	end
end, MT_BMPKU)

addHook("MobjThinker", function(s)
	if not s.sampickup
	s.sampickup = true
	end
end, MT_SPKU)

addHook("MobjThinker", function(s)
	if not s.sampickup
	s.sampickup = true
	end
end, MT_MTNK)

addHook("MobjThinker", function(s)
	if leveltime and (leveltime % 12 == 0) and s.valid
		A_SAMPARTICLE(s, MT_MPR1, 50, 1, 1, 1, P_RandomRange(SKINCOLOR_SUPERGOLD3, SKINCOLOR_SUPERGOLD5), P_RandomRange(23355, 55353))
	end
	
	S_StartSound(s, sfx_pbpku)
		
	if not s.samsize
		s.samsize = true
		s.scale = $*10/6
	end
end, MT_PBOM)

addHook("MobjThinker", function(s)
	if s.hyperbeamammo and not s.colorchange
		if (leveltime % 2 == 0)		
		s.color = SKINCOLOR_SKY
		else
		s.color = SKINCOLOR_CLOUDY
		end
	elseif not s.colorchange
	s.color = SKINCOLOR_YELLOW
	s.colorchange = true
	end
end, MT_NRGD)


local function ChargeHomer(s)
	if s.chargehomertime
	s.chargehomertime = $-1
		if s.chargehomertime <= 0
			s.momx = 0 s.momy = 0 s.momz = 0
			s.chargehomertime = nil
				if s.z < s.floorz+18*FRACUNIT
				s.z = $+16*FRACUNIT
				end
			return
	/*	else
			if s.chargehomertarget and s.chargehomertarget.valid
			s.target = s.chargehomertarget
				if P_FaceStabCheckMeleeRange(s)
					P_SpawnGhostMobj(s)
					P_MoveOrigin(s, s.target.x+s.target.momx, s.target.y+s.target.momy, s.target.z+(s.target.height/3)+s.target.momz)
				end
			end */
		end 
	end
end

addHook("MobjThinker", ChargeHomer, MT_MPKU)
addHook("MobjThinker", ChargeHomer, MT_BMPKU)
addHook("MobjThinker", ChargeHomer, MT_SPKU)
addHook("MobjThinker", ChargeHomer, MT_PBOM)
addHook("MobjThinker", ChargeHomer, MT_NRGA)
addHook("MobjThinker", ChargeHomer, MT_NRGB)
addHook("MobjThinker", ChargeHomer, MT_NRGD)

--The Prism Orb for the Hunters gamemode and the easy campaign difficulty.
addHook("MobjThinker", function(s)
	if s.fuse and s.target and s.target.player and s.target.health
	local t = s.target
	local p = s.target.player
		s.fancyangle = s.fancyangle and $+ANGLE_45 or ANGLE_45
		s.angle = s.fancyangle+ANGLE_90
		if not (s.color > 114)
			s.color = $+1
		else
			s.color = SKINCOLOR_ROSY
		end
		if s.donttouch
		s.donttouch = $-1
		end
		if (s.fuse < 100) --Flicker
			if s.fuse % 2 == 0
				s.flags2 = $|MF2_DONTDRAW
			else
				s.flags2 = $ & ~MF2_DONTDRAW
			end
		end
		if not SAM_displayplayer(p)
			s.flags2 = $|MF2_DONTDRAW --Only display for 1 player.
		end
		
		--Spawn a spinning ghost
		local ghs = P_SpawnGhostMobj(s)
		if s.ghosttime
			ghs.tics = 6
			s.ghosttime = $-1
		else
			ghs.tics = 2
		end
		ghs.angle = s.fancyangle
		ghs.frame = $|FF_PAPERSPRITE
		ghs.blendmode = AST_ADD
		ghs.colorized = true
		if (s.flags2 & MF2_DONTDRAW)
			ghs.flags2 = $|MF2_DONTDRAW
		end
		if (leveltime % 3 == 0)
			ghs.color = SKINCOLOR_SUPERGOLD3
			if s.superprism
				ghs.tics = 3
				ghs.scale = s.scale*2
			else
				ghs.scale = s.scale+(s.scale/3)
			end
		else
			ghs.color = SKINCOLOR_BLUE
			ghs.scale = s.scale/2
		end
		--Lastly, attraction behaviour. It auto-attracts, but the charge beam has a pretty significant effect.
		local speed = 8*t.scale
		if p.sams_chargetime
			speed = 24*t.scale
		end
		--Attraction?
		if s.valid
			s.frame = $|FF_PAPERSPRITE
			local mult = FixedHypot(FixedHypot(t.x-s.x, t.y-s.y), t.z-s.z)
			if (mult < (70*speed))
				if mult < 1
					mult = 1
    			end
				if ghs and ghs.valid
				ghs.tics = $+5
				end
				if s.donttouch
					P_SetObjectMomZ(s, 12*FRACUNIT)
					s.momx = ($*8)/9
					s.momy = ($*8)/9					
				else
					s.momx = FixedMul(FixedDiv(t.x-s.x, mult), speed) 
					s.momy = FixedMul(FixedDiv(t.y-s.y, mult), speed)
					s.momz = FixedMul(FixedDiv(t.z-s.z, mult), speed)
				end
				
			else --Non-attraction.
				s.momx = ($*8)/9
				s.momy = ($*8)/9
				s.momz = ($*8)/9
			end
		end
	elseif s.valid
		s.state = S_NULL
	end
end, MT_NRGH)
addHook("MobjMoveCollide", function(s, v)
	if v and v.player and YouAreSamus(v) and s.target and s.target == v
	local p = v.player
		if (v.z > s.z+s.height)
		or (s.z > v.z+v.height+8*FRACUNIT)
		or s.donttouch
			return false
		end
		if s.superprism	
			local rng = P_RandomRange(0,10)
			if rng > 9 and p.sampwmax
				v.player.sampw = $+1*p.sam_ammodigitizer
				S_StartSound(nil, sfx_mtnk, p)
			elseif rng > 6 and p.samsupermissilesmax
				p.samsupermissiles = $+1*p.sam_ammodigitizer
				S_StartSound(nil, sfx_mpku, p)
			else
				p.sammissiles = $+3*p.sam_ammodigitizer
			end

		else --Normal Prism?
			if p.buffbottomtier and G_GametypeHasSpectators() and not p.sam_hyperbeam
				GiveSamusEnergy(p, 10, 3)
			else
				GiveSamusEnergy(p, 5, 3)
			end
			p.sammissiles = $+1*p.sam_ammodigitizer
		end
		S_StartSound(v, sfx_nrga)
		s.state = S_NULL
		return false
	else
		return false
	end
end, MT_NRGH)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+8*FRACUNIT)
			return nil
			end
			if not v.player.fusionmode
			v.player.sammissiles = $+2*v.player.sam_ammodigitizer
			else
			v.player.sammissiles = $+1*v.player.sam_ammodigitizer
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators()
			v.player.sammissiles = $+1*v.player.sam_ammodigitizer
			end
			
			NewSamPickup(v, "MPKUA0", 37555)
			S_StartSound(v, sfx_mpku)
			s.state = S_NULL
			return false
	end
end, MT_MPKU)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+8*FRACUNIT)
			return nil
			end
			if v.player.fusionmode
			v.player.sammissiles = $+3*v.player.sam_ammodigitizer
			else
			v.player.sammissiles = $+5*v.player.sam_ammodigitizer
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators()
			v.player.sammissiles = $+3*v.player.sam_ammodigitizer
			end
			
			NewSamPickup(v, "MPKUC0", 47555)	
			S_StartSound(v, sfx_mpku)
			s.state = S_NULL
			return false
	end
end, MT_BMPKU)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+8*FRACUNIT)
			return nil
			end
			if (v.player.samsupermissiles < v.player.samsupermissilesmax)
			v.player.samsupermissiles = $+1*v.player.sam_ammodigitizer
			else
			v.player.sammissiles = $+2*v.player.sam_ammodigitizer
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators() and v.player.samsupermissilesmax
			v.player.samsupermissiles = $+1*v.player.sam_ammodigitizer
			end
			
			NewSamPickup(v, "SPKUA0", 47555)	
			S_StartSound(v, sfx_mpku)
			s.state = S_NULL
			return false
	end
end, MT_SPKU)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+8*FRACUNIT)
			return nil
			end
			if (v.player.sampw < v.player.sampwmax)
			v.player.sampw = $+1*v.player.sam_ammodigitizer
			else
			v.player.sammissiles = $+2*v.player.sam_ammodigitizer
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators() and v.player.sampwmax
			v.player.sampw = $+1*v.player.sam_ammodigitizer
			end
			
			S_StopSound(s)
			NewSamPickup(v, "PBOMA0", 70555)
			S_StartSound(v, sfx_mtnk)
			s.state = S_NULL
			return false
	end
end, MT_PBOM)

rawset(_G, "ItemGetPopup", function(p, timer, color, text, textscale) --Text must be a string!
if not p
return
end
			if not timer
			p.samitemgettimer = 80
			else
			p.samitemgettimer = timer
			end
			if not color
			p.samitemcolor = SKINCOLOR_CARBON
			else
			p.samitemcolor = color
			end
			if not text
			p.samitemgetname = "Unknown"
			else
			p.samitemgetname = text
			end
			if not textscale
			p.samitemscale = 85000
			else
			p.samitemscale = textscale
			end
end)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+5)
			return nil
			end
			if v.player.sammissilesmax != nil
				if v.player.sammissilesmax
				P_SamFP(v.player, PAL_MIXUP, 7)
				S_StartSound(v, sfx_mtnk)
				else
				P_SamFP(v.player, PAL_MIXUP, 9)
				CONS_Printf(v.player, "You've obtained \x84Missiles!\x80 Press FIRE to shoot them, but watch your ammo!")
				S_StartSound(v, sfx_spwup)
				end
			SamusTutorial(v, "missiles")
			v.player.sammissilesmax = $+5
				if not v.player.fusionmode
				v.player.sammissiles = $+5
				end
			NewSamPickup(v, "MTNKD0", 55355, nil, nil)
			ItemGetPopup(v.player, 80, SKINCOLOR_CRIMSON, "Missiles", 70000)
			end
		s.state = S_NULL
		return false
		end
	end
end, MT_MTNK)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if v.player.nosuperpowert and G_GametypeHasSpectators()
			v.player.sammissiles = $+3
			S_StartSound(v, sfx_mpku)
					if not v.player.samhudmessagetime
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Super Missiles tanks are currently set to ammo."
					v.player.samhudmessage2 = nil
					end
				s.state = S_NULL
				return false
			elseif v.player.samsupermissilesmax
			P_SamFP(v.player, PAL_MIXUP, 7)
			S_StartSound(v, sfx_mtnk)
			else
			P_SamFP(v.player, PAL_MIXUP, 9)
			CONS_Printf(v.player, "You've obtained \x84Super Missiles!\x80 Hold FIRE until it clicks, then release!")
			S_StartSound(v, sfx_spwup)
			end
		SamusTutorial(v, "supermissiles")	
		v.player.samsupermissilesmax = $+2
			if not v.player.fusionmode
			v.player.samsupermissiles = $+2
			end
		NewSamPickup(v, "STNKD0", 55355)	
		ItemGetPopup(v.player, 80, SKINCOLOR_CRIMSON, "Super Missiles", 105355)
		s.state = S_NULL
		return false
	end
end, MT_STNK)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if v.player.nosuperpowert and G_GametypeHasSpectators()
			P_GivePlayerRings(v.player, 30)
			S_StartSound(v, sfx_nrga)
					if not v.player.samhudmessagetime
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Power Bombs tanks are currently set to health."
					v.player.samhudmessage2 = nil
					end
				s.state = S_NULL
				return false
			elseif v.player.sampwmax
			P_SamFP(v.player, PAL_MIXUP, 7)
			S_StartSound(v, sfx_mtnk)
			else
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained a \x84Power Bomb!\x80 Hold C2/NormalFire as the Morph Ball, then release!")
			end
		SamusTutorial(v, "pw")	
		v.player.sampwmax = $+1
			if not v.player.fusionmode
			v.player.sampw = $+1
			end
		NewSamPickup(v, "PTNKD0", 55355)	
		ItemGetPopup(v.player, 80, SKINCOLOR_RED, "Power Bombs", 88355)			
		s.state = S_NULL
		return false
	end
end, MT_PTNK)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.samspbs
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x83Speed Booster!\x80 Hold Custom 1 to dash!")
			ItemGetPopup(v.player, 80, SKINCOLOR_GREEN, "Speed Booster", 100355)		
			v.player.samspbs = true
			SamusTutorial(v, "variasuit")
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+3
			end
			NewSamPickup(v, "SPBSA0", 52355)
		s.state = S_NULL
		return false
		end
	end
end, MT_SPBS)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_bombs
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained\x85 Bombs!\x80 In morph ball mode, press C2/normalfire and destroy breakable barricades!")
			ItemGetPopup(v.player, 80, SKINCOLOR_BROWN, "Morph Bombs", 80355)	
			v.player.sam_bombs = true
			SamusTutorial(v, "bombs")
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+2
			P_GivePlayerRings(v.player, 10)
			end
		NewSamPickup(v, "GVSTI0", 92355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_MHBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if (v.player.sam_gravitysuit and not (v.player.sam_gravitysuit == 2))
				P_SamFP(v.player, PAL_MIXUP, 9)
				S_StartSound(v, sfx_spwup)
				if netgame or splitscreen
				CONS_Printf(v.player, "You got the \x81Gravity feature!\x80 Move faster underwater, become immune to lava, and gain extra defense!")
				else
				CONS_Printf(v.player, "You got the \x81Gravity Suit!\x80 Move faster underwater, become immune to lava, and gain extra defense!")
				end
				v.player.sam_gravitysuit = 2
				v.player.sam_gravitysuitjustgot = 75
				ItemGetPopup(v.player, 80, SKINCOLOR_GRAVITYSUIT, "Gravity Suit", 110000)

			elseif not v.player.sam_gravitysuit

				P_SamFP(v.player, PAL_MIXUP, 9)
				S_StartSound(v, sfx_spwup)
				
				if netgame or splitscreen
				CONS_Printf(v.player, "You got the \x87Varia feature!\x80 Gain defense and become immune to toxic damage!")
				else
				CONS_Printf(v.player, "You got the \x87Varia Suit!\x80 Gain defense and become immune to toxic damage!")
				end
			
				v.player.sam_gravitysuit = 1
				v.player.sam_gravitysuitjustgot = 75
				ItemGetPopup(v.player, 80, SKINCOLOR_VARIASUIT, "Varia Suit", 94000)

			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
				return false
			else
				S_StartSound(v, sfx_mpku)
				v.player.sampw = $+1
			end
			if not v.player.sam_gravitysuit
			NewSamPickup(v, "GVSTF0", 90355)
			else
			NewSamPickup(v, "GVSTB0", 90355)
			end
		s.state = S_NULL
		return false
		end
	end
end, MT_GVST)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_gravitysuit
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			if netgame or splitscreen
			CONS_Printf(v.player, "You got the \x87Varia feature!\x80 Gain defense and become immune to toxic damage!")
			else
			CONS_Printf(v.player, "You got the \x87Varia Suit!\x80 Gain defense and become immune to toxic damage!")
			end
			v.player.sam_gravitysuit = 1
			v.player.sam_gravitysuitjustgot = 75
			ItemGetPopup(v.player, 80, SKINCOLOR_VARIASUIT, "Varia Suit", 94000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+1
			v.player.samsupermissiles = $+1
			end
		NewSamPickup(v, "GVSTF0", 90355)
		s.state = S_NULL
		return false
		end
	end
end, MT_VRST)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+6*FRACUNIT)
			return nil
			end
			if not v.player.sam_screwattack
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x83Screw Attack!\x80 Double tap JUMP/C1 midjump to become a deadly projectile!")
			v.player.sam_screwattack = true
			SamusTutorial(v, "screwattack")
			ItemGetPopup(v.player, 80, SKINCOLOR_GOLD, "Screw Attack", 90000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+2
			v.player.samsupermissiles = $+1
			end
		NewSamPickup(v, "GVSTD0", 83355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_SATK)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sambsbl
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x83 Boost Ball!\x80 Hold C1/FIRE while morphed, then release to boost!")
			v.player.sambsbl = true
			ItemGetPopup(v.player, 80, SKINCOLOR_GREEN, "Boost Ball", 88000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+4
			end
		NewSamPickup(v, "BSBLA0", 56355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_BSBL)

addHook("MobjThinker", function(s)
	if s and not s.sizered	
		s.scale = $*10/8
		s.sizered = true
	end
end, MT_BSBL)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_highjump
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x83Hi-Jump!\x80 You jump higher, AND can jump with the Spring Ball!")
			v.player.sam_highjump = true
			ItemGetPopup(v.player, 80, SKINCOLOR_GREEN, "Hi - Jump", 70000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sampw = $+1
			end
		NewSamPickup(v, "SPBLB0", 76355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_SPBL)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_spiderball
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x83Spider Ball!\x80 Tap jump against a wall to climb for as long as you have charge.")
			v.player.sam_spiderball = true
			SamusTutorial(v, "spiderball")
			ItemGetPopup(v.player, 80, SKINCOLOR_GREEN, "Spider Ball", 92000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+4
			end
		NewSamPickup(v, "MPR9X0", 106355)
		s.state = S_NULL
		return false
		end
	end
end, MT_SPDRBL)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_spacejump
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x83Space Jump!\x80 Press jump in midair for an aerial jumpboost!")
			v.player.sam_spacejump = true
			ItemGetPopup(v.player, 80, SKINCOLOR_GREEN, "Space Jump", 81000)
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+1
			v.player.samsupermissiles = $+1
			end
		NewSamPickup(v, "SJMPA0", 35355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_SJMP)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if v and not (v.player.sam_energytanksmax and (v.player.sam_energytanksmax > 12))
				if v and (v.player.sam_energytanksmax != nil and (v.player.sam_energytanksmax < 1))
				S_StartSound(v, sfx_spwup)
				CONS_Printf(v.player, "You've obtained an\x84 Energy Tank!\x80 Your maximum energy capacity has been permanently increased by 50 units!")
				else
				S_StartSound(v, sfx_mtnk)
				end
			P_SamFP(v.player, PAL_RECYCLE, 7)
			v.player.sam_energytanksmax = $+1
			if not v.player.fusionmode
			GiveSamusEnergy(v.player, 50, 3)
		//	P_GivePlayerRings(v.player, 50)
			end
			ItemGetPopup(v.player, 80, SKINCOLOR_BLUE, "Energy Tank", 85000)
			else
			S_StartSound(v, sfx_nrga)
			GiveSamusEnergy(v.player, 50, 3)
		//	P_GivePlayerRings(v.player, 50)
			end
		NewSamPickup(v, "ETNKA0", 35355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_ENGTNK)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_chargebeam
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Charge Beam!\x80 Hold C2/NormalFire to charge your arm cannon!")
			v.player.sam_chargebeam = true
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Charge Beam"
			v.player.samitemscale = 88000
			SamusTutorial(v, "chargebeam")

			elseif not v.player.sam_powerbeamcombo and not (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())

			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Power Beam Combo!\x80 With +10 missiles, hold Fire after your Power Beam is charged fully!")
			v.player.sam_powerbeamcombo = true
			SamusTutorial(v, "beamcombo")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Super Missile"
			v.player.samitemscale = 110355
			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+1
			v.player.samsupermissiles = $+1
					if not v.player.samhudmessagetime and (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Beam Combo pickups are turned off."
					v.player.samhudmessage2 = nil
					end
			end
		NewSamPickup(v, "CHBMA0", 83355)
		s.state = S_NULL
		return false
		end
	end
end, MT_CHBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_spazerbeam
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x85Spazer Beam!\x80 The beam spreads when fired.")
			v.player.sam_spazerbeam = true SamusTutorial(v, "gravitysuit")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Spazer Beam"
			v.player.samitemscale = 88000
			v.player.sam_wantstoswitch = 2 A_SAMBEAMSWITCH(v.player)

			elseif not v.player.sam_spazerbeamcombo and not (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())

			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Spazer Beam Combo!\x80 With +15 missiles, hold Fire after your Spazer Beam is charged fully!")
			v.player.sam_spazerbeamcombo = true
			SamusTutorial(v, "beamcombo")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Force Crasher"
			v.player.samitemscale = 105000


			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+1
			v.player.samsupermissiles = $+1
					if not v.player.samhudmessagetime and (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Beam Combo pickups are turned off."
					v.player.samhudmessage2 = nil
					end
			end
		NewSamPickup(v, "SPBMA0", 40355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_SPBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_wavebeam
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x85Wave Beam!\x80 This tricky beam bounces and paralyzes foes.")
			v.player.sam_wavebeam = true SamusTutorial(v, "gravitysuit")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Wave Beam"
			v.player.samitemscale = 83000
			v.player.sam_wantstoswitch = 3  A_SAMBEAMSWITCH(v.player)

			elseif not v.player.sam_wavebeamcombo and not (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())

			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Wave Beam Combo!\x80 With +15 missiles, hold Fire after your Wave Beam is charged fully!")
			v.player.sam_wavebeamcombo = true
			SamusTutorial(v, "beamcombo")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Waveblast Buffer"
			v.player.samitemscale = 113000

			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sammissiles = $+3
					if not v.player.samhudmessagetime and (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Beam Combo pickups are turned off."
					v.player.samhudmessage2 = nil
					end
			end
		NewSamPickup(v, "WVBMA0", 40355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_WVBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_icebeam
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x85Ice Beam!\x80 The beam explodes upon impact and can freeze foes.")
			v.player.sam_icebeam = true SamusTutorial(v, "gravitysuit")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Ice Beam"
			v.player.samitemscale = 81000

			elseif not v.player.sam_icebeamcombo and not (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())

			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Ice Beam Combo!\x80 With +15 missiles, hold Fire after your Ice Beam is charged fully!")
			v.player.sam_icebeamcombo = true
			SamusTutorial(v, "beamcombo")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Blizzard Burst"
			v.player.samitemscale = 113000
			v.player.sam_wantstoswitch = 4  A_SAMBEAMSWITCH(v.player)


			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.sampw = $+1
					if not v.player.samhudmessagetime and (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Beam Combo pickups are turned off."
					v.player.samhudmessage2 = nil
					end
			end
		NewSamPickup(v, "ICBMA0", 40355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_ICBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_plasmabeam
			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the \x85Plasma Beam!\x80 This powerful mid-range beam pierces the enemy.")
			v.player.sam_plasmabeam = true SamusTutorial(v, "gravitysuit")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Plasma Beam"
			v.player.samitemscale = 86000
			v.player.sam_wantstoswitch = 5  A_SAMBEAMSWITCH(v.player)

			elseif not v.player.sam_plasmabeamcombo and not (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())

			P_SamFP(v.player, PAL_MIXUP, 9)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You've obtained the\x85 Plasma Beam Combo!\x80 It consumes 5 missiles p/s! Hold Fire after your Plasma Beam is charged fully!")
			v.player.sam_plasmabeamcombo = true
			SamusTutorial(v, "beamcombo")
			v.player.samitemgettimer = 80
			v.player.samitemcolor = SKINCOLOR_BLACK
			v.player.samitemgetname = "Gattling Vortex"
			v.player.samitemscale = 110000

			elseif (gametype == GT_COOP) and (netgame or splitscreen) and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)
			return false
			else
			S_StartSound(v, sfx_mpku)
			v.player.samsupermissiles = $+2
					if not v.player.samhudmessagetime and (v.player.sam_beamcombosrestrict and G_GametypeHasSpectators())
					v.player.samhudmessagetime = 50
					v.player.samhudmessage1 = "\x85"+"Beam Combo pickups are turned off."
					v.player.samhudmessage2 = nil
					end
			end
		NewSamPickup(v, "PLBMA0", 40355)	
		s.state = S_NULL
		return false
		end
	end
end, MT_PLBM)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+5*FRACUNIT)
			return nil
			end
			if v.player.fusionmode
			GiveSamusEnergy(v.player, 5, 2)
			else
			GiveSamusEnergy(v.player, 10, 2)
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators()
			GiveSamusEnergy(v.player, 20, 2)
			end
		NewSamPickup(v, "NRGAB0", 65555, nil, nil, TR_TRANS40)
		S_StartSound(v, sfx_nrga)
		s.state = S_NULL
		return false
		end
	end
end, MT_NRGA)

--Become a better health pickup if the player is low on health.
addHook("MobjThinker", function(s)
	if s.spawnNRGB == nil
		if (gametype == GT_COOP)
		and gamemap != 28
			for z in players.iterate
				if z.mo and YouAreSamus(z.mo)
				and z.sam_energy != nil and z.sam_energytanksmax != nil
					if z.sam_energy < ((99+(z.sam_energytanksmax*50))/2)
					and (FixedHypot(s.x-z.mo.x, s.y-z.mo.y) < 3000*FRACUNIT)
						P_SpawnMobjFromMobj(s,0,0,0, MT_NRGB)
						s.flags = $|MF_NOCLIP|MF_NOCLIPTHING
						s.flags2 = $|MF2_DONTDRAW
						s.fuse = 1
					end
				end
			end
		end
		s.spawnNRGB = true
	end
end, MT_NRGA)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height+5*FRACUNIT)
			return nil
			end
			if v.player.fusionmode
			GiveSamusEnergy(v.player, 10, 2)
			elseif v.player.sam_hyperbeam and G_GametypeHasSpectators()
			GiveSamusEnergy(v.player, 15, 2)
			else
			GiveSamusEnergy(v.player, 25, 2)
			end
			if v.player.buffbottomtier and G_GametypeHasSpectators()
			GiveSamusEnergy(v.player, 35, 2)
			end
		NewSamPickup(v, "NRGBC0", 65555, nil, nil, TR_TRANS30)	
		S_StartSound(v, sfx_nrga)
		s.state = S_NULL
		return false
		end
	end
end, MT_NRGB)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if (v.z > s.z+s.height)
		or (s.z > v.z+v.height+5*FRACUNIT)
		return nil
		end
			if s.hyperbeamammo
				NewSamPickup(v, "NRGDB0", 75555, nil, SKINCOLOR_SKY)
				if v.player.sam_energy != nil and (v.player.sam_energy < 50)
				v.player.sam_energy = 50 --Set energy to a minimum level
				end
				if v.player.fusionmode
				v.player.sam_hyperbeamammo = $+25
				else
				v.player.sam_hyperbeamammo = $+50
				end
			v.player.sam_restricthyper = nil
			else
				NewSamPickup(v, "NRGDB0", FRACUNIT, nil, SKINCOLOR_SUPERGOLD4, TR_TRANS30)
				if v.player.fusionmode
				GiveSamusEnergy(v.player, 25, 3)
				elseif v.player.sam_hyperbeam and G_GametypeHasSpectators()
				GiveSamusEnergy(v.player, 30, 3) 
				else
				GiveSamusEnergy(v.player, 50, 3)
				end
				if v.player.buffbottomtier and G_GametypeHasSpectators() and not v.player.sam_hyperbeam
				GiveSamusEnergy(v.player, 75, 3)
				end
			end
			
			S_StartSound(v, sfx_nrga)
			s.state = S_NULL
			return false
	end
end, MT_NRGD)


addHook("MobjDeath", function(m, i, s)
if players[0] and not (players[0].coopboxrespawn)
return
end
	if (m.flags & MF_MONITOR) and (gametype == GT_COOP) and (netgame or splitscreen) and m.valid and not ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX)) and not (mobjinfo[m.type].doomednum == 429)
	   if m and m.valid and s and s.player
	   and not (m.samgotme != nil and not (players[0] and s.player == players[0]) and (s.player.samusnum and (m.samgotme & (s.player.samusnum)) or m.samgotme == s.player.samusnum) )
	   and not (players[0] and s.player == players[0] and m.samgotmehost) 

		if s and s.player


		m.smontracker = P_SpawnMobj(m.x, m.y, m.z, MT_SMONTRACKER)
		m.smontracker.mymon = m.type
			if (s.player.samusnum != nil) and s.player.samusnumdecided 
			and (s.player.coopboxrespawn and (s.player.coopboxrespawn > 1))
				if m.samgotme == nil
				m.samgotme = 0
				end
				if m.smontracker and m.smontracker.valid
				m.smontracker.gotmestorage = m.samgotme
				end
				if players[0] and s.player == players[0]
				m.samgotmehost = true
					if m.smontracker and m.smontracker.valid
					m.smontracker.gotmestoragehost = true
					end
				elseif m.samgotmehost and m.smontracker and m.smontracker.valid
					m.smontracker.gotmestoragehost = true
				end
				if m.smontracker and m.smontracker.valid
				m.smontracker.gotmestorage = $|s.player.samusnum
				end
				m.samgotme = $|s.player.samusnum
			end
		if players[0] and players[0].coopboxrespawn and players[0].coopboxrespawn == 2
		m.smontracker.tics = 20
		else
		m.smontracker.tics = 1020
		end
		m.smontracker.pp = m.eflags
		m.smontracker.pp2 = m.flags2
		m.flags2 = $|MF2_DONTDRAW
		return
		end
	   end
	end
end)


addHook("MobjThinker", function(s)
		if s.valid and s.zap
			if s.target and s.target.valid
			s.momx = s.target.momx s.momy = s.target.momy s.momz = s.target.momz
			end
			if s.tics <= 1
				if s.zap <= 2
				s.sprite = SPR_SPRK
				else
				s.sprite = SPR_MPR9 s.color = 26
				end
				if s.sprite == SPR_MPR9
					if s.frame == A
					s.frame = H|TR_TRANS40|FF_FULLBRIGHT
					s.tics = 2
					elseif s.frame == H|TR_TRANS40|FF_FULLBRIGHT
					s.frame = I|TR_TRANS50|FF_FULLBRIGHT
					s.tics = 2
					elseif s.frame == I|TR_TRANS50|FF_FULLBRIGHT
					s.frame = J|TR_TRANS60|FF_FULLBRIGHT
					s.tics = 2
					end
				else
					if s.frame == A
					s.frame = B|TR_TRANS40|FF_FULLBRIGHT
					s.tics = 2
					elseif s.frame == B|TR_TRANS40|FF_FULLBRIGHT
					s.frame = C|TR_TRANS50|FF_FULLBRIGHT
					s.tics = 2
					elseif s.frame == C|TR_TRANS50|FF_FULLBRIGHT
					s.frame = D|TR_TRANS60|FF_FULLBRIGHT
					s.tics = 2
					end
				end
			end
		end
end, MT_THOK)

local function ScaleFix(s) --SRB2 doesn't do this by default, I guess.
	if not s.tracedone and s.tracer
		s.scale = s.tracer.scale
		s.tracedone = true
	end 
end
addHook("MobjThinker", ScaleFix, MT_CRUSHCLAW)
addHook("MobjThinker", ScaleFix, MT_BANPSPRING)
local function TheBabySpawn(s, m) --Baby Behaviour
				if not m.babycolor
				m.radius = $*2 --To make it easier to shoot.
				m.height = $*2
				m.babycolor = P_RandomRange(SKINCOLOR_BONE, SKINCOLOR_YELLOW)
				else
				m.ghs = P_SpawnGhostMobj(m)
				m.ghs.tics = 2
				m.ghs.momx = m.momx m.ghs.momy = m.momy m.ghs.momz = m.momz
				m.ghs.color = m.babycolor m.ghs.colorized = true
				end
					if (m.type == MT_REDBUZZ)
						if (m.state == S_RBUZZLOOK1 or m.state == S_RBUZZLOOK2)
							if not m.zoters
							m.zoters = 50
							else
							m.zoters = $-1
								if m.zoters > 24
								m.momz = -FRACUNIT
								m.z = $-FRACUNIT
								else
								m.momz = FRACUNIT
								m.z = $+FRACUNIT
								end
							end
						elseif m.zoters
						m.zoters = 0
						m.momz = 0
						end
						m.frame = $|FF_FULLBRIGHT --They appear in dark areas usually.
					end
end
local function TheLeecher(s, m)
				--This type acts like a Metroid. Bomb or spin fast to break free.
					if s.pouncecd
					s.pouncecd = $-1
					end
					if s.pounce
					m.metroidleech = true
					s.pounce = $+1
						if not m.target or (m.target and not m.target.health) or m.target and not P_CheckSight(m, m.target)
						or m.target and (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) > 1100*FRACUNIT)
						or (s.pounce > 60) and m.target.player and ((m.target.player.pflags & PF_SPINNING) or m.target.player.sammorphed) and (m.target.player.speed > 28*FRACUNIT)
						s.pouncecd = 60
						s.pounce = 0
						m.metroidleech = nil
						S_StartSound(m, sfx_s3k82)
						P_MoveOrigin(m, m.x, m.y, m.z+80*FRACUNIT)
						end
					end
					if m.target and not s.pouncecd and P_CheckSight(m, m.target)
						if (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 580*FRACUNIT)
							if not s.pounce
								s.pounce = 1
									s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
									S_StartSound(m, sfx_s3k82)
									S_StartSound(m, sfx_s3k41)
										if s.plexpand
										s.plexpand.color = SKINCOLOR_EMERALD
										s.plexpand.momx = m.momx/2 s.plexpand.momy = m.momy/2 s.plexpand.momz = m.momz/2
										s.plexpand.scale = $*P_RandomRange(1,2)
										s.plexpand.scalespeed = $*P_RandomRange(2, 4)
										s.plexpand.destscale = $*25
									end
							end
						end
						if s.pounce
							if (s.pounce < 12)
								m.momx = m.momx/2 m.momy = m.momy/2 m.momz = m.momz/2
							elseif (s.pounce > 12)
								m.metroidleech = true
								m.momx = FixedMul(FixedDiv(m.target.x-m.x, 600*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
								m.momy = FixedMul(FixedDiv(m.target.y-m.y, 600*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
								m.momz = FixedMul(FixedDiv(m.target.z-m.z, 600*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
								if (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 100*FRACUNIT)
								P_MoveOrigin(m, m.target.x, m.target.y, m.target.z+m.target.height/2)
									if not (m.target.player and (m.target.player.exiting or (m.target.flags & (MF_NOCLIP|MF_NOCLIPTHING)) or m.target.player.sam_screwattacking
									or m.target.player.powers[pw_nocontrol] or m.target.player.powers[pw_flashing] or m.target.player.powers[pw_super] or m.target.player.powers[pw_invulnerability]))
										if leveltime % 19 == 0 and m.target.player
										P_SamFP(m.target.player, PAL_NUKE, 4)
										m.target.sam_systemreboot = 20
										m.target.player.viewrollangle = P_RandomRange(-14,14)*ANG1
										end
										if m.target.player and (YouAreSamus(m.target)) and (m.target.player.sam_energy and m.target.player.sam_energy > 1) and leveltime % 2 == 0
										m.target.player.sam_energy = $-1
											if m and not S_SoundPlaying(m, sfx_buzz2)
											S_StartSound(m, sfx_buzz2)
											end
										elseif (YouAreSamus(m.target) != true) and (m.target.player and m.target.player.rings) and (leveltime % 3 == 0) and m.target.player
										m.target.player.rings = $-1
											if m and not S_SoundPlaying(m, sfx_buzz2)
											S_StartSound(m, sfx_itemup)
											end
											if not m.target.player.rings
											P_PlayRinglossSound(m.target)
											m.target.player.powers[pw_flashing] = 70
											end
										elseif m.target and ((m.target.player and (m.target.player.rings <= 0) and not YouAreSamus(m.target)) or (YouAreSamus(m.target) and m.target.player.sam_energy <= 1))
										P_DamageMobj(m.target, nil, nil)
										end
									else
										m.metroidleech = nil
									end
								elseif (s.pounce > 60)
									s.pouncecd = 120
									s.pounce = 0
									m.metroidleech = nil
								end
							end
						end
					end
end
local function TheBolter(s, m)
				--This enemy will shock you, with some enemies like the egguard holding teleporting powers.
					if (m.type == MT_EGGGUARD) and m.target and P_CheckSight(m, m.target) 
					and ((m.state == S_EGGGUARD_WALK1) or (m.state == S_EGGGUARD_WALK2) or (m.state == S_EGGGUARD_WALK3)  or (m.state == S_EGGGUARD_WALK4))
					P_TryMove (m, m.x+FixedMul(180355, cos(m.angle)), m.y+FixedMul (180355, sin (m.angle)), false)
						if m.tracer and m.tracer.valid
						P_TryMove (m.tracer, m.x+FixedMul(180355+m.momx, cos(m.angle)), m.y+FixedMul (180355+m.momy, sin (m.angle)), true)
						end
						if s.cctimer == nil
						s.cctimer = 0
						end
						if not s.cctimer
							if m.target and (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 1400*FRACUNIT) and (P_RandomRange(15, 0) == 14)
							and not (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 300*FRACUNIT)
							s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
							S_StartSound(m, sfx_s3k5a)
							S_StartSound(m, sfx_s3k8e)
								if s.plexpand
								s.plexpand.momx = m.momx/2
								s.plexpand.momy = m.momy/2
								s.plexpand.momz = m.momz/2
								s.plexpand.scale = $*2
								s.plexpand.scalespeed = $*3
								s.plexpand.destscale = $*25
								end
							s.cctimer = 180
							end

						elseif s.cctimer
							if s.cctimer == 150 and m.target and m.target.player					
								if ((FixedHypot(m.x-m.target.x, m.y-m.target.y)) > 2000*FRACUNIT)
								or (m.z < m.target.z-450*FRACUNIT) or (m.z > m.target.z+600*FRACUNIT)
								s.cctimer = 149
								return
								end
											
							local ghs = P_SpawnGhostMobj(m)	
							ghs.destscale = $*99 ghs.scalespeed = $*2
							ghs.blendmode = AST_ADD
							P_TryMove(m, m.target.x+FixedMul(280*FRACUNIT+(m.target.player.speed*5), cos(m.target.angle)), m.target.y+FixedMul (280*FRACUNIT+(m.target.player.speed*5), sin (m.target.angle)), true)
							m.z = (m.target.z-8*FRACUNIT)+(m.target.player.aiming/50)-(m.target.momz*4)	
							
							
								if m.tracer and m.tracer.valid 
								P_MoveOrigin(m.tracer, m.x+FixedMul(180355+m.momx, cos(m.angle)), m.y+FixedMul (180355+m.momy, sin (m.angle)), m.z)
								end
								S_StartSound(m, sfx_s3k41)
								A_SAMUSEXPLOSIONS(m, 22, MT_IVSP, false, 4000)
								A_SAMUSEXPLOSIONS(m, 16, MT_SUPERSPARK, false, 2200)
							end
							if s.cctimer > 130
								if (s.cctimer % 2 == 0)
								m.flags2 = $ & ~MF2_DONTDRAW
									if m.tracer and m.tracer.valid
									m.flags2 = $ & ~MF2_DONTDRAW
									end
								else
								m.flags2 = $|MF2_DONTDRAW
									if m.tracer and m.tracer.valid
									m.flags2 = $|MF2_DONTDRAW
									end
								end					
							end
							if s.cctimer > 129
							m.flags2 = $ & ~MF2_DONTDRAW
								if m.tracer and m.tracer.valid
								m.flags2 = $ & ~MF2_DONTDRAW
								end
							m.tics = $+1
							m.momx = 0
							m.momy = 0
							m.momz = 2
								if m.target
									A_FaceTarget(m)
								end
							end

						s.cctimer = $-1
						end
					end
					if (m.type == MT_GSNAPPER and m.state == S_GSNAPPER2) and m.target and P_CheckSight(m, m.target)
					P_TryMove (m, m.x+FixedMul(320355, cos(m.angle)), m.y+FixedMul (320355, sin (m.angle)), false)
					end
					if ((m.type == MT_SPRINGSHELL) or (m.type == MT_YELLOWSHELL)) and m.target and P_CheckSight(m, m.target) and not (m.state == S_SSHELL_STND) and not (m.state == S_YSHELL_STND)
					P_TryMove (m, m.x+FixedMul(240355, cos(m.angle)), m.y+FixedMul (240355, sin (m.angle)), false)
					end
					if not s.bolttimer
						if (m.type == MT_GFZFISH)
						s.bolttimer = P_RandomRange(170, 260)
						elseif s.bolttimer == nil
						s.bolttimer = P_RandomRange(61, 102)
						else
						s.bolttimer = P_RandomRange(95, 190)
						end
					end
					if m and (m.target and m.target.valid and P_CheckSight(m, m.target)) or m and ( (m.type == MT_GFZFISH) or (m.type == MT_BUGGLE) and (m.momx or m.momy))
						if (s.bolttimer < 70) and not (s.bolttimer < 45)
							if P_IsObjectOnGround(m)
		  					A_SAMPARTICLE(m, MT_MPR4, 50, 2, 1, 6, SKINCOLOR_GOLD, P_RandomRange(27355, 58353))
							else
							s.smontracker = P_SpawnMobj(m.x+(P_RandomRange(-77, 77))*FRACUNIT, m.y+(P_RandomRange(-77, 77))*FRACUNIT, m.z+(P_RandomRange(-30, 30))*FRACUNIT, MT_IVSP)
							end
						elseif (s.bolttimer < 45) and not (s.bolttimer < 32)
							if P_IsObjectOnGround(m)
		  					A_SAMPARTICLE(s, MT_MPR4, 50, 2, 1, 6, SKINCOLOR_BLACK, P_RandomRange(21355, 42353))
							else
							s.smontracker = P_SpawnMobj(m.x+(P_RandomRange(-77, 77))*FRACUNIT, m.y+(P_RandomRange(-77, 77))*FRACUNIT, m.z+(P_RandomRange(-30, 30))*FRACUNIT, MT_SUPERSPARK)
							end
						end
						s.bolttimer = $-1
					elseif s.bolttimer and (s.bolttimer <= 70)
						s.bolttimer = $-1
					end
					if (s.bolttimer == 70)
						S_StartSound(m, sfx_wvcm2)
						s.bolttimer = 69
					elseif s.bolttimer == 30
						S_StartSound(m, sfx_wvcm)
					elseif (s.bolttimer < 30)
						S_StartSound(m, sfx_cmol)
						s.smontracker = P_SpawnMobj(m.x+(P_RandomRange(-150, 150))*FRACUNIT, m.y+(P_RandomRange(-150, 150))*FRACUNIT, m.z+(P_RandomRange(-40, 60))*FRACUNIT, MT_THOK)
						s.smontracker.flags = MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_BOUNCE|MF_GRENADEBOUNCE
						s.smontracker.scale = m.scale
						s.smontracker.target = m
						s.smontracker.bolterattack = true
						s.smontracker.blendmode = AST_ADD
						s.smontracker.renderflags = $|RF_FULLBRIGHT
						s.smontracker.sprite = SPR_SPRK
						s.smontracker.frame = A|TR_TRANS30
						s.smontracker.height = 45*FRACUNIT
						s.smontracker.radius = 40*FRACUNIT				
						s.smontracker.tics = 3
						s.smontracker.zap = (P_RandomRange(1, 4))
					end
end
local function TheFloater(s, m)
				--This enemy has exceptional flying powers, usually with some extra abilities.
					if (m.type == MT_UNIDUS)
						if s.mguncd == nil s.mguncd = 30
						elseif s.mguncd and m.target s.mguncd = $-1
						end
						if m.target and not s.mguncd
							if not s.mgunspin 
							s.mgunspin = 1
							s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
							S_StartSound(m, sfx_s3k5a)
							S_StartSound(m, sfx_s3k8e)
								if s.plexpand
								s.plexpand.momx = m.momx/2
								s.plexpand.momy = m.momy/2
								s.plexpand.momz = m.momz/2
								s.plexpand.scale = $*P_RandomRange(1,2)
								s.plexpand.scalespeed = $*P_RandomRange(2, 4)
								s.plexpand.destscale = $*25
								end
							else
							s.mgunspin = $+1
								if (s.mgunspin > 25)
									if P_CheckSight(m, m.target)
									S_StartSound(m, sfx_s3k54)
									s.tryit = P_SpawnPointMissile(m, m.target.x+(m.target.momx*9), m.target.y+m.target.momy*9, m.target.z+m.target.height/2+m.target.momz*6, MT_ENERGYBALL, m.x, m.y, m.z+m.height/2)
										if s.tryit and s.tryit.valid
										s.tryit.flags = $|MF_MISSILE & ~MF_PAIN & ~MF_NOCLIPHEIGHT & ~MF_NOCLIP
										s.tryit.momx = $*5/6
										s.tryit.momy = $*5/6
										s.tryit.momz = $*5/6
										s.tryit.scale = 35355
										s.tryit.destscale = 70710 
										s.tryit.scalespeed = $/4
										end
									end
									s.mguncd = 105
									s.mgunspin = 0
								end
							end
						end		
					end
					if (m.type == MT_VULTURE and (m.state == S_VULTURE_ZOOM1)) or m.type != MT_VULTURE
					m.flags = $|MF_FLOAT|MF_NOGRAVITY
					end
					if (m.type == MT_VULTURE)
						if m.target
							if (leveltime % 8 == 0)
							S_StartSound(m, sfx_gbeep)
							end
						else
							if (leveltime % 35 == 0)
							S_StartSound(m, sfx_gbeep)
							end
						end
						if not m.kamibomb and m.health
						m.kamibomb = P_SpawnMobj(m.x, m.y, m.z, MT_THOK)
						m.kamibomb.sprite = SPR_NPLM
						m.kamibomb.frame = A
						elseif m.kamibomb and m.kamibomb.valid and (leveltime % 2 == 0)
						m.kamibomb.sprite = SPR_NPLM
						m.kamibomb.frame = A
						m.kamibomb.tics = 3
						m.kamibomb.scale = 100000
						P_MoveOrigin(m.kamibomb, m.x+m.momx, m.y+m.momy, m.z+m.height/2+m.momz)
							if ( (m.target and (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) <= 192*FRACUNIT) ) or not m.health ) and m.kamibomb and m.kamibomb.valid
							m.kamikazeboom = P_SpawnMobj(m.x, m.y, m.z+m.height/2, MT_THROWNEXPLOSION)
							m.kamikazeboom.kamibomb = true
							m.kamibomb.state = S_NULL
								if m.kamikazeboom and m.kamikazeboom.valid
								S_StartSound(m.kamikazeboom, sfx_bexpld)
								A_samquake(12*FRACUNIT, 4)
								m.kamikazeboom.sprite = SPR_NPLM
								m.kamikazeboom.frame = A
								P_ExplodeMissile(m.kamikazeboom)
								end						
							end
						end
						if m.kamibomb and m.kamibomb.valid and m and m.valid and m.health 
							if (leveltime % 2 == 0)
							m.kamibomb.sprite = SPR_NPLM
							m.kamibomb.frame = A
							else
							m.kamibomb.sprite = SPR_NPLM
							m.kamibomb.frame = B
							end
						end
					end
					if m.target and m.type != MT_VULTURE or m.target and m.type == MT_VULTURE and (m.state == S_VULTURE_ZOOM1)
						if m.target.z+m.target.height < m.z
						m.momz = -3*FRACUNIT
						elseif m.target.z > m.z
						m.momz = 3*FRACUNIT
						end
					end
					if m.type == MT_REDCRAWLA
					m.gfx = P_SpawnMobj(m.x, m.y, m.z-5*FRACUNIT, MT_SAMCHARGEGFX)
					m.gfx.scale = m.scale/(P_RandomRange(5,20))
					m.gfx.color = SKINCOLOR_PINK
					m.gfx.momx = s.momx/2
					m.gfx.momy = s.momy/2
					m.flags = $|MF_FLOAT|MF_NOGRAVITY
						if m.target and not (s.state == S_SPOS_STND)
							if not s.sideswing and (P_RandomRange(0, 100) == 99)
							s.sideswing = P_RandomRange(9, 14)
							s.sideswingdirect = P_RandomRange(0, 1) 
							end
							if s.sideswing
							s.sideswing = $-1
							A_FaceTarget(m)
								if s.sideswingdirect 
								P_InstaThrust(m, m.angle+ANGLE_90, 10*FRACUNIT)
								else
								P_Thrust(m, m.angle-ANGLE_90, 10*FRACUNIT)
								end

							end
							if (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) > 1500*FRACUNIT) and not s.sideswing
							A_FaceTarget(m)
							P_InstaThrust(m, m.angle, 12*FRACUNIT)
							elseif not s.sideswing
							P_InstaThrust(m, m.angle, 7*FRACUNIT)
							end
							if leveltime % 2 == 0
							P_SpawnGhostMobj(m)
							end
						end
					end
end
local function TheMachineGunner(s, m)
				--Machine Gunner speaks for itself, no? Typically very dangerous foes
					if s.mguncd == nil s.mguncd = 30
					elseif s.mguncd and m.target s.mguncd = $-1
					end
					if m.target and not s.mguncd
						if not s.mgunspin 
						s.mgunspin = 1
						s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
						S_StartSound(m, sfx_s3k5a)
						S_StartSound(m, sfx_s3k8e)
							if s.plexpand
							s.plexpand.momx = m.momx/2
							s.plexpand.momy = m.momy/2
							s.plexpand.momz = m.momz/2
							s.plexpand.scale = $*P_RandomRange(1,2)
							s.plexpand.scalespeed = $*P_RandomRange(2, 4)
							s.plexpand.destscale = $*25
							end
						else
						s.mgunspin = $+1
							if (s.mgunspin == 23)
							s.mgunstrafe = P_RandomRange(0, 1)
							end
							if (s.mgunspin > 25)
								
								if (m.type == MT_JETTGUNNER) or (m.type == MT_CRAWLACOMMANDER) or m.type == MT_CACOLANTERN
									if leveltime % 2 == 0 and P_CheckSight(m, m.target)
									P_SpawnGhostMobj(m)
									A_FaceTarget(m)
										if s.mgunstrafe
										P_InstaThrust(m, m.angle+ANGLE_90, 15*FRACUNIT)
										else
										P_InstaThrust(m, m.angle-ANGLE_90, 15*FRACUNIT)
										end
										if m.type == MT_CACOLANTERN
										P_SpawnPointMissile(m, m.target.x+(m.target.momx*15), m.target.y+m.target.momy*15, m.target.z+m.target.momz*9, MT_CACOFIRE, m.x, m.y, m.z+m.height/2)
										else
										S_StartSound(m, sfx_s3k4d)
										P_SpawnPointMissile(m, m.target.x+(m.target.momx*15), m.target.y+m.target.momy*15, m.target.z+m.target.momz*9, MT_JETTBULLET, m.x, m.y, m.z+m.height/2)
										end
									end
									if (s.mgunspin > 40)
									s.mguncd = 105
									s.mgunspin = 0
										if m.type == MT_CACOLANTERN
										P_InstaThrust(m, m.angle, 5*FRACUNIT)
										end
									end
								elseif (m.type == MT_POPUPTURRET) and not (m.scale == 130712) 
									if P_CheckSight(m, m.target)
									m.sprite = SPR_TURR
									m.frame = I
									S_StartSound(m, sfx_trfire)
									P_SpawnMissile(m, m.target, MT_TURRETLASER)
									end
									if m and m.valid and (s.mgunspin > 59)
									m.reactiontime = 1
									m.state = S_TURRETPOPDOWN2
									s.mguncd = 105
									s.mgunspin = 0
									end
								elseif (m.type == MT_SNAILER)
									if leveltime % 4 == 0 and P_CheckSight(m, m.target)
									S_StartSound(m, sfx_rlaunc)
									s.tryit = P_SpawnPointMissile(m, m.target.x+(m.target.momx*25), m.target.y+m.target.momy*25, m.target.z+m.target.momz*18, MT_ROCKET, m.x, m.y, m.z+m.height/2)
										if s.tryit and s.tryit.valid
										s.tryit.destscale = s.scale*3 
										s.tryit.scalespeed = $/3
										end
									end
									if (s.mgunspin > 70)
									s.mguncd = 105
									s.mgunspin = 0
									end
								elseif (m.type == MT_DRAGONBOMBER)
									S_StartSound(m, sfx_trfire)
									P_SpawnMissile(m, m.target, MT_TURRETLASER)
									if (s.mgunspin > 70)
									s.mguncd = 105
									s.mgunspin = 0
									end									
								end
							end
						end
					end
end
local function TheRammer(s, m)
					if ((m.type == MT_FACESTABBER) or (m.type == MT_GSNAPPER)) and m.target and P_CheckSight(m, m.target) 
					and not (m.state == S_FACESTABBER_CHARGE4) and not (m.state == S_GSNAPPER_STND) and P_IsObjectOnGround(m)
					P_TryMove (m, m.x+FixedMul(160355, cos(m.angle)), m.y+FixedMul (160355, sin (m.angle)), false)
					end
					if m.dodgecd
					m.dodgecd = $-1
					m.dodgeret = false
						if (m.dodgecd == 69)
							S_StartSound(m, sfx_s3ka6)
							S_StartSound(m, sfx_s3kb6)
							S_StartSound(m, sfx_s3k82)
							S_StartSound(m, sfx_s3k9e)
							S_StartSound(m, sfx_s3k9e)
							if (m.type == MT_JETJAW)
								if P_RandomRange(0,1) == 1
								s.fishdodge = true
								end
							end
							m.dodgecd = 68
						elseif (m.dodgecd > 58)
							if m.samroll == nil
							m.samfroll = ANG30
							else
							m.samfroll = $+ANG30
							m.rollangle = m.samfroll
							end
					//	P_SpawnGhostMobj(m)
							if (m.type == MT_JETJAW)
								if s.fishdodge
								P_InstaThrust(m, m.angle+ANGLE_90, 15*FRACUNIT)
								else
								P_InstaThrust(m, m.angle-ANGLE_90, 15*FRACUNIT)
								end
							end
						elseif m.samfroll
						m.samfroll = nil
						m.rollangle = 0
						end
					else
					m.dodgeret = true
					end
					if s.pouncecd
					s.pouncecd = $-1
					end
					if s.pounce
					s.pounce = $+1
						if (s.pounce > 30)
						s.pouncecd = 60
						s.pounce = 0
						end
					end
					if m.target and not s.pouncecd and not (m.dodgecd and m.dodgecd > 40) and P_CheckSight(m, m.target)
						if (FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 640*FRACUNIT)
							if not s.pounce
							s.pounce = 1
								s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
								S_StartSound(m, sfx_s3k82)
								S_StartSound(m, sfx_s3kb6)
									if s.plexpand
									s.plexpand.color = SKINCOLOR_CLOUDY
									s.plexpand.momx = m.momx/2
									s.plexpand.momy = m.momy/2
									s.plexpand.momz = m.momz/2
									s.plexpand.scale = $*P_RandomRange(1,2)
									s.plexpand.scalespeed = $*P_RandomRange(2, 4)
									s.plexpand.destscale = $*25
								end
								if (m.type == MT_GSNAPPER)
								P_SetObjectMomZ(m, 10*FRACUNIT, true)
								m.momx = 0
								m.momy = 0
								end
							end
						elseif (m.type == MT_REDBUZZ) and not (m.state == S_RBUZZLOOK1) and not (m.state == S_RBUZZLOOK2) and not s.pounce
						P_TryMove (m, m.x+FixedMul(240355, cos(m.angle)), m.y+FixedMul (240355, sin (m.angle)), false)
						end
						if s.pounce
							if s.pounce == 12
								if not (m.flags & MF_NOGRAVITY) and not (m.type == MT_SKIM) and P_IsObjectOnGround(m) or (m.type == MT_GSNAPPER)
								A_FaceTarget(m)
								P_InstaThrust(m, m.angle, 31*FRACUNIT)
								P_SetObjectMomZ(m, 6*FRACUNIT, true)
									if (m.type == MT_GSNAPPER)
									m.momz = m.momz/9
									S_StartSound(m, sfx_thok)
									P_SpawnMobj(m.x, m.y, m.z+m.height/2, MT_THOK)
										if (FixedHypot(m.x-m.target.x, m.y-m.target.y) < 230*FRACUNIT)
										P_SetObjectMomZ(m, -15*FRACUNIT, true)
										end
									end
								end
								s.pounce = 13
								if not (m.flags & MF_NOGRAVITY) and not P_IsObjectOnGround(m) and not (m.type == MT_GSNAPPER)
								s.pounce = 0
								end
							elseif (s.pounce < 12)
								m.momx = m.momx/2
								m.momy = m.momy/2
								if (m.type == MT_GSNAPPER)
									if (s.pounce == 2)
									m.target = nil
									end
								P_SpawnGhostMobj(m)
								else
								m.momz = m.momz/2
								end
							elseif (s.pounce > 12)
								if (m.flags & MF_NOGRAVITY) or (m.type == MT_SKIM and m.eflags & MFE_TOUCHWATER)
								A_FaceTarget(m)
								P_SpawnGhostMobj(m)
								m.momx = FixedMul(FixedDiv(m.target.x-m.x, 500*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
								m.momy = FixedMul(FixedDiv(m.target.y-m.y, 500*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
									if ((m.type == MT_JETTBOMBER or m.type == MT_SKIM)) and (leveltime % 4 == 0)
									s.mined = P_SpawnMobj(m.x, m.y, m.z+m.height/3, MT_MINE)
									s.mined.target = m
									S_StartSound(m, sfx_s3k51)
										if (m.target.z+(m.target.height*4) < m.z)
										m.momz = 5*FRACUNIT
										end
									end
									if not (m.type == MT_JETTBOMBER)
									m.momz = FixedMul(FixedDiv(m.target.z-m.z, 500*FRACUNIT), FixedDiv(132*FRACUNIT, 3*FRACUNIT/2))
									end
								elseif not (m.type == MT_SKIM)
									if m.type == MT_FACESTABBER
									m.sprite = SPR_CBFS
									m.frame = H
									end
									if not (m.type == MT_GSNAPPER)
									P_SpawnGhostMobj(m)
									end
								end
							end
						end
					end
end
local function TheFlamer(s, m)
--The flamer has a flamethrower. Some have better range or reaction time.
					if m.type == MT_POPHAT
						if not m.startupflame
						m.scale = $*2
						m.startupflame = true
						m.thetank = true
						m.health = $+1
						end									
					end
					if m.target and P_CheckSight(m, m.target) and m.target.health
						if s.flamercooldown and not s.tryitstartup
						s.flamercooldown = $-1
						end
						if (m.type == MT_BLUECRAWLA) and not (m.state == S_POSS_STND)
						P_TryMove (m, m.x+FixedMul(160355, cos(m.angle)), m.y+FixedMul (160355, sin (m.angle)), false)
						end
						if not s.tryitstartup and not s.flamercooldown
						and ( ((FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 400*FRACUNIT) and m.type != MT_ROBOHOOD and m.type != MT_PYREFLY)
						or ((FixedHypot(FixedHypot(m.x-m.target.x, m.y-m.target.y), m.z-m.target.z) < 1200*FRACUNIT) and (m.type == MT_ROBOHOOD or m.type == MT_PYREFLY)) )
						s.tryitstartup = 1

							s.plexpand = P_SpawnMobj(m.x, m.y, m.z, MT_PBEXPAND)
							S_StartSound(m, sfx_s3k82)
							S_StartSound(m, sfx_s3kb6)
								if s.plexpand
								s.plexpand.color = SKINCOLOR_CLOUDY
								s.plexpand.momx = m.momx/2
								s.plexpand.momy = m.momy/2
								s.plexpand.momz = m.momz/2
								s.plexpand.scale = $*2
								s.plexpand.scalespeed = $*3
								s.plexpand.destscale = $*25
								end

						end
						if s.tryitstartup and s.tryitstartup < 11
							if ((m.type == MT_BLUECRAWLA) and (leveltime % 2 == 0))
							s.tryitstartup = $+1
							else
							s.tryitstartup = $+1
							end
						elseif s.tryitstartup and (s.tryitstartup < 41)
						s.tryitstartup = $+1
							if (m.type == MT_MINUS) and (P_IsObjectOnGround(m) or ((m.state >= S_MINUS_DIGGING1) and (m.state <= S_MINUS_DIGGING4)))
							m.state = S_MINUS_POPUP
							end
							if leveltime % 3 == 0
								if m.type == MT_POPHAT
								s.tryit = P_SpawnMissile(m, m.target, MT_GREENFLAME)
								else
								s.tryit = P_SpawnMissile(m, m.target, MT_CYBRAKDEMON_FLAMESHOT)
								end
								if s.tryit and s.tryit.valid
								s.tryit.target = m
								s.tryit.renderflags = $|RF_FULLBRIGHT
								s.tryit.rollangle = P_RandomRange(-30,30)*ANG1
								s.tryit.blendmode = AST_ADD
								s.tryit.mahflamer = m
								s.tryit.destscale = $*3
								if m.type == MT_PYREFLY
								s.tryit.fuse = 33
								elseif m.type == MT_ROBOHOOD
								s.tryit.fuse = 44
								else
								s.tryit.momz = $/2
								s.tryit.fuse = 15
								end
								
								s.tryit.flags = $|MF_NOCLIPHEIGHT|MF_MISSILE & ~MF_SCENERY
								s.tryit.craymobfire = true
								
									if s.tryit and (s.tryit.momz <= 0) and not m.type == MT_ROBOHOOD
									P_SetObjectMomZ(s.tryit, FRACUNIT, false)
									end
								end
							end
						elseif s.tryitstartup and s.tryitstartup > 26
							if (m.type == MT_MINUS) or (m.type == MT_BLUECRAWLA)
							s.flamercooldown = 28
							end
						s.tryitstartup = 0
						end
					else
						s.tryitstartup = 0
					end
end

local FlashMobjC={SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERORANGE5,SKINCOLOR_RED, SKINCOLOR_WHITE, SKINCOLOR_SUPERGOLD3}
//The SMONtracker tracks a target and will modify it's behaviour without having to create new states/thingtypes.
addHook("MobjThinker", function(s)
	if s.valid
		if s.gotmestorage and (s.tics > 20)
		s.tics = 20
		end
	/*	if s.sam_scoretracker --Keep track of match score!
			s.scoreboard
			for z in players.iterate	
			end
			return
		end */
		if s.starposttracker and s.target
		local t = s.target
			s.tics = $+1
			if not s.monstart3
				if not s.target.montargetedyet3
				s.target.montargetedyet3 = true
				s.monstart3 = true
				elseif s and s.valid
				s.state = S_NULL
				return
				end
			end
			t.tics = $+1
			t.sprite = SPR_MPR1
			t.frame = O|TR_TRANS20
				if not s.scaler
				t.destscale = $*10/6 
				s.scaler = true
				end
				if (t.state != S_STARPOST_IDLE) 
					if leveltime % 3 == 0
					t.color = SKINCOLOR_ORANGE
					else
					t.color = SKINCOLOR_SUPERGOLD3
					end
				else
				t.color = SKINCOLOR_RED
				end
			
			if (s.valid) and not (s.target and s.target.valid)
			s.state = S_NULL
			return
			end

		elseif s.thebaby and s.target and s.target.valid
			local m = s.target
			if m.health and not s.thebabyspawned
					--This type spawns a baby once, then goes to other behaviour. Because of this, subtypes like rammer are possible.
						for d = 1,4
							if (m.type == MT_CRUSHSTACEAN or m.type == MT_BANPYURA or m.type == MT_JETJAW)
								if d == 2 or d == 4
									s.muhbaby = P_SpawnMobj(m.x+FixedMul(210*FRACUNIT, cos(m.angle+ANGLE_90*d)), m.y+FixedMul(210*FRACUNIT, sin(m.angle+ANGLE_90*d)), m.z, m.type)
										if s.muhbaby and s.muhbaby.valid
										s.muhbaby.scale = m.scale/2
										s.muhbaby.eflags = m.eflags
										s.muhbaby.flags2 = m.flags2
										s.muhbaby.flags = m.flags
										s.muhbaby.othermom = m
										s.muhbaby.thebabyspawn = true
										s.muhbaby.notabee = true
										m.smontracker = P_SpawnMobj(m.x, m.y, m.z, MT_SMONTRACKER)
										m.smontracker.target = s.muhbaby
										m.smontracker.thebabyspawn = true
										m.smontracker.notabee = true
										m.smontracker.othermom = m
										end
								end
							elseif d != 1
								if m.type == MT_PTERABYTE
								s.muhbaby = P_SpawnMobj(m.x+FixedMul(180*FRACUNIT, cos(m.angle+ANGLE_112h*d)), m.y+FixedMul(180*FRACUNIT, sin(m.angle+ANGLE_112h*d)), m.z-250*FRACUNIT+(d*(100*FRACUNIT)), MT_PYREFLY)
									if s.muhbaby and s.muhbaby.valid
									s.muhbaby.scale = m.scale/2
									s.muhbaby.radius = $*2
									s.muhbaby.height = $*2
									end
								else
								s.muhbaby = P_SpawnMobj(m.x+FixedMul(140*FRACUNIT, cos(m.angle+ANGLE_112h*d)), m.y+FixedMul(140*FRACUNIT, sin(m.angle+ANGLE_112h*d)), m.z, MT_REDBUZZ)
									if s.muhbaby and s.muhbaby.valid
									s.muhbaby.scale = m.scale/3
									s.muhbaby.thebabyspawn = true
									s.muhbaby.othermom = m
									m.smontracker = P_SpawnMobj(m.x, m.y, m.z, MT_SMONTRACKER)
									m.smontracker.target = s.muhbaby
									m.smontracker.thebabyspawn = true
									m.smontracker.othermom = m
									end
								end
							end
						end
						s.thebabyspawned = true
						
						if s.valid
						s.state = S_NULL
						return
						end
			end
			
		elseif s.flashingt and s.target and not (s.target.type == MT_METROID or s.target.type == MT_SUPERMETROID or s.target.type == MT_METALSONIC_BATTLE)
		local m = s.target --Make enemies flash when Samus shoots them!
			if m.gavecolorpermission == nil
				if not m.color
				m.gavecolorpermission = true --Careful not to break enemies with colors. Did it make sense to have "colorized" be a boolean rather than skincolor_t variable?
				else
				m.gavecolorpermission = false
				end
			end
			if not s.monstart2
				if not m.montargetedyet2 and not (m.flags2 & MF2_DONTDRAW) and not (m.flags2 & MF2_FRET) and not m.superbrak
				m.montargetedyet2 = true
				s.monstart2 = true
				elseif s.valid
				s.state = S_NULL
				return
				end
			end
			if s.flashingt != nil
				if (s.flashingt % 2 == 0)
				m.flags2 = $|MF2_DONTDRAW
				else
					if m.gavecolorpermission != nil
					m.color = FlashMobjC[P_RandomRange(1,5)]
					m.colorized = true
					end				
				m.flags2 = $ & ~MF2_DONTDRAW
				end
				s.flashingt = $-1
				if (s.flashingt <= 1) and s.valid
					if m and m.valid
					m.montargetedyet2 = nil
					m.flags2 = $ & ~MF2_DONTDRAW
						if m.gavecolorpermission != nil
						m.color = 0
						m.colorized = false
						end		
					end
				s.state = S_NULL
				return
				end
			end
		elseif s.target and (s.target.flags & MF_ENEMY) and not (s.target.flags & MF_BOSS) and s.target.health
		and (s.bolter or s.floater or s.machinegunner or s.rammer or s.flamer or s.leecher or s.thebaby or s.thebabyspawn or s.thetank) --Or...y'know, just s.hyperenemy?
--Okay, we're looking at hyper enemies here!
			if not s.monstart
				if not s.target.montargetedyet
				s.target.montargetedyet = true
				s.monstart = true
				elseif s.valid
				s.state = S_NULL
				return
				end
			end
			local m = s.target
			s.tics = 3 --Keep the tracker at 3 tics so it doesn't disappear until it's target does
			if m.valid and not m.spazershocked and not m.waverstunned
				if s.thebabyspawn and m and m.health --Baby enemy behaviour. Slightly different from general enemies, and have less health.
					TheBabySpawn(s, m)				
				elseif s.leecher
					TheLeecher(s, m)				
				elseif s.bolter and m.health
					TheBolter(s, m)
				elseif s.floater
					TheFloater(s, m)
				elseif s.machinegunner 
					TheMachineGunner(s, m)
				elseif s.rammer 
					TheRammer(s, m)
				elseif s.flamer and m.health
					TheFlamer(s, m) --These are kinda like TF2 classes at this point
				elseif s.thetank
					if m.thetank and (m.health and m.health == 1)
					m.colorized = true
					m.color = SKINCOLOR_RED
						if leveltime % 6 == 0
						s.smoke = P_SpawnMobj(m.x, m.y, m.z+m.height, MT_SMOKE)
						s.smoke.momz = FRACUNIT*8*P_MobjFlip(m)
						s.smoke.scale = m.scale
						s.smoke.destscale = m.scale*10
						s.smoke.fuse = 50
						end
					elseif not m.thetank and m.health
					m.thetank = true
					m.scale = $+105000
					m.health = $+1
					end
				end
			end

		elseif s.target and (s.target.flags & MF_BOSS) --Faster bosses and SuperBrak.
		local t = s.target
			if not s.monstart
				if not t.montargetedyet
				t.montargetedyet = true
				s.monstart = true
				elseif s.valid
				s.state = S_NULL
				return
				end
			end
			s.tics = $+1
			if t.superbrakbigjump or t.superbrakjump
			return
			end
			if ((t.tics > 2) and (t.tics < 20)) and not (t.tics == -1) and t.health and not t.frozenbox --Check everything over and over.
			and not ((t.state >= S_CYBRAKDEMON_VILE_ATTACK2) and (t.state <= S_CYBRAKDEMON_VILE_ATTACK6)) --Messing with tics gets...messy.
			and not (t.superbrak and (t.health < 11) and (t.tics < 7))
			t.tics = $-2
			end
			if t.superbrak and ((t.tics > 2) and (t.tics < 20)) and t.health and not t.frozenbox  and not (t.tics == -1)
			and not ((t.state >= S_CYBRAKDEMON_VILE_ATTACK2) and (t.state <= S_CYBRAKDEMON_VILE_ATTACK6))
			and not (t.health < 25)
			t.tics = $-1
			end
			if t.superbrak and ((t.tics > 2) and (t.tics < 20)) and t.health and not t.frozenbox and not (t.tics == -1)
			and not ((t.state >= S_CYBRAKDEMON_VILE_ATTACK2) and (t.state <= S_CYBRAKDEMON_VILE_ATTACK6))
			and (t.health > 43) and not (t.health > 52)
			t.tics = $-2
			end
		elseif s.mymon
			if (s.tics == 1)
			s.mun = P_SpawnMobj(s.x, s.y, s.z, s.mymon)
			s.mun.eflags = s.pp
			s.mun.flags2 = s.pp2
				if s.gotmestorage
				s.mun.samgotme = s.gotmestorage
				end
				if s.gotmestoragehost
				s.mun.samgotmehost = true 
				end
			s.state = S_NULL
			return
			end
		elseif s.valid
		s.state = S_NULL
		return	
		end
	end
end, MT_SMONTRACKER)

--The Gunship floats up and down and checks if it fits in the place it's in, landing/shrinking accordingly.

addHook("MobjThinker", function(s)
	if s.valid
	
		if s.checktimer == nil
			s.checktimer = 15
		elseif s.checktimer
		s.checktimer = $-1
			if s.checktimer == 1 and s.tracer and s.tracer.valid
				if ( ( ((s.tracer.state == S_PLAY_STND) or (s.tracer.state == S_PLAY_SPRING) or (s.tracer.state == S_PLAY_FALL))
				and not P_IsObjectOnGround(s.tracer) and not (s.tracer.player and (s.tracer.player.pflags & PF_JUMPED)))    
				or not (P_CheckSight(s, s.tracer)) and (FixedHypot(FixedHypot(s.x-s.tracer.x, s.y-s.tracer.y), s.z-s.tracer.z) > 200*FRACUNIT) ) 
				
				or s.tracer.samspinpad
					s.rettp = true
					s.checktimer = 0
				end
			end
		end
		
		if s.rettp and s.tracer and s.tracer.valid and P_IsObjectOnGround(s.tracer) and (s.tracer.ceilingz > s.floorz+100*FRACUNIT)
		and P_CheckPosition(s, s.tracer.x+50*FRACUNIT, s.tracer.y+50*FRACUNIT) and not s.tracer.samspinpad
			P_MoveOrigin(s, s.tracer.x+50*FRACUNIT, s.tracer.y+50*FRACUNIT, s.tracer.z+s.tracer.height/2)
			S_StartSound(s, sfx_appear)
			S_StartSound(s, sfx_appear)
			s.rettp = nil
		end
		
		if not s.bigship or (s.eflags & MFE_VERTICALFLIP)
		s.scale = 155000
		s.sss = P_SpawnPointMissile(s, s.x, s.y, s.z+s.height+160*FRACUNIT, MT_SAMWALLJUMP, s.x, s.y, s.z+s.height+180*FRACUNIT)
		s.ssss = P_SpawnPointMissile(s, s.x, s.y, s.z+s.height+60*FRACUNIT, MT_SAMWALLJUMP, s.x, s.y, s.z+s.height+70*FRACUNIT)
		s.ogmaxz = s.z+190*FRACUNIT
		s.ogmaxztime = 80
		s.ogz = s.z
		s.bigship = true
		s.flags = $|MF_SOLID
			if (s.z >= s.ceilingz-50*FRACUNIT)
			P_MoveOrigin(s, s.x, s.y, s.floorz)
			end
			if (s.ceilingz < s.z+s.height+180*FRACUNIT)
			s.landingmode = true
			s.flags = $|MF_NOCLIPHEIGHT
			s.yougottaland = false
			elseif s.yougottaland and not ((gametype == GT_COOP) and gamemap == 23)
			s.landingmode = true
			s.flags = $|MF_NOCLIPHEIGHT
			end
			if (s.ceilingz < s.z+s.height+100*FRACUNIT) or s.yougottaland and not ((gametype == GT_COOP) and gamemap == 23) and not ((gametype == GT_COOP) and gamemap == 08)
			s.scalespeed = $/4
			s.destscale = FRACUNIT
			S_StartSoundAtVolume(s, sfx_s3k72, 100)
			end
		s.downfloat = false
		s.upfloat = true
		s.maxfloat = s.z+50*FRACUNIT
			if s.landingmode
			s.minfloat = s.floorz-10*FRACUNIT
			else
			s.minfloat = s.z+10*FRACUNIT
			end
		end

		if not S_SoundPlaying(s, sfx_s3ka1) and not s.landedmode
		S_StartSoundAtVolume(s, sfx_s3ka1, 5)
		end

		if (leveltime % 2 == 0) and not s.landedmode
		s.ship_sjmpgfx = P_SpawnMobj(s.x, s.y-120*FRACUNIT, s.z-5*FRACUNIT, MT_SAMCHARGEGFX)
		s.ship_sjmpgfx.scale = s.scale/(P_RandomRange(8,15))
		s.ship_sjmpgfx.color = SKINCOLOR_SKY
		s.ship_sjmpgfx.momx = s.momx/2
		s.ship_sjmpgfx.momy = s.momy/2
		s.ship_sjmpgfx = P_SpawnMobj(s.x, s.y+120*FRACUNIT, s.z-5*FRACUNIT, MT_SAMCHARGEGFX)
		s.ship_sjmpgfx.scale = s.scale/(P_RandomRange(8,15))
		s.ship_sjmpgfx.color = SKINCOLOR_SKY
		s.ship_sjmpgfx.momx = s.momx/2
		s.ship_sjmpgfx.momy = s.momy/2

		s.ship_sjmpgfx = P_SpawnMobj(s.x-120*FRACUNIT, s.y, s.z-5*FRACUNIT, MT_SAMCHARGEGFX)
		s.ship_sjmpgfx.scale = s.scale/(P_RandomRange(8,15))
		s.ship_sjmpgfx.color = SKINCOLOR_SKY
		s.ship_sjmpgfx.momx = s.momx/2
		s.ship_sjmpgfx.momy = s.momy/2
		s.ship_sjmpgfx = P_SpawnMobj(s.x+120*FRACUNIT, s.y, s.z-5*FRACUNIT, MT_SAMCHARGEGFX)
		s.ship_sjmpgfx.scale = s.scale/(P_RandomRange(8,15))
		s.ship_sjmpgfx.color = SKINCOLOR_SKY
		s.ship_sjmpgfx.momx = s.momx/2
		s.ship_sjmpgfx.momy = s.momy/2
			if s.landingmode 
			s.landedmode = true
			end
		end
		if s.upfloat
			if s.ogmaxztime
			s.ogmaxztime = $-1
				if (s.ogmaxztime == 1) and s.ogmaxz
					if (s.z < s.ogmaxz)
					s.scalespeed = $/4
					s.destscale = FRACUNIT
					S_StartSoundAtVolume(s, sfx_s3k72, 100)
					s.landingmode = true
					s.flags = $|MF_NOCLIPHEIGHT
					end
				end
			end
			s.ogmaxz = s.z+190*FRACUNIT
			if s.landingmode
			s.downfloat = true
			s.upfloat = false
			end
			if s.z > (s.maxfloat-15*FRACUNIT)
			s.momz = 32000
			else
			s.momz = 64000
			end
			if (s.z > s.maxfloat)
			s.ogmaxztime = 0
			s.downfloat = true
			s.upfloat = false
				if not s.firstdown and not s.landingmode
				s.firstdown = true
					if (s.floorz+100*FRACUNIT < s.z)
					s.firstrapidcheck = true
					s.minfloat = s.floorz+20*FRACUNIT
					s.maxfloat = s.floorz+60*FRACUNIT
					end
				end
			end
		end
		if s.firstrapidcheck
			if (s.floorz+40*FRACUNIT < s.z) and not s.upfloat and not P_IsObjectOnGround(s)
			s.minfloat = s.floorz+20*FRACUNIT
			s.maxfloat = s.floorz+60*FRACUNIT
			else
			s.firstrapidcheck = false
			end
		end
		if s.downfloat
			if s.z < (s.maxfloat-25*FRACUNIT) and not s.landingmode and not P_IsObjectOnGround(s)
			s.momz = -32000
			elseif not (s.landingmode and (s.z <= s.minfloat)) and not P_IsObjectOnGround(s)
			s.momz = -64000
			elseif s.landingmode and s.momz
			s.momz = 0
			end
			if ((s.z < s.minfloat) or P_IsObjectOnGround(s)) and not s.landingmode
			s.downfloat = false
			s.upfloat = true
			end
		end
		if s.dying --GFZ1 smoking fx
			if not s.dyingsoundp
			s.dyingsoundp = true
			local doit = false
				for z in players.iterate
					if z.mo and not z.sam_saveselect
						if netgame
						or (z.jointime and z.jointime > 4)
							if (FixedHypot(FixedHypot(s.x-z.mo.x, s.y-z.mo.y), s.z-z.mo.z) < 620*FRACUNIT)
							A_samquake(z.mo, 14*FRACUNIT, 7, 1)
							P_SamFP(z, PAL_NUKE, 6)
							P_PlayRinglossSound(z.mo, z)
							doit = true
							end
						end
					end
				end	
				if doit == true
					S_StartSound(s, sfx_dmpain)
					S_StartSound(s, sfx_pstop) S_StartSound(s, sfx_befall)
				end
			end
			if (leveltime % 5 == 0)
			s.ghs = P_SpawnMobj(s.x+P_RandomRange(-200,200)*FRACUNIT, s.y+P_RandomRange(-200,200)*FRACUNIT, s.z+P_RandomRange(-50,150)*FRACUNIT, MT_SAMCHARGEGFX)
			s.ghs.scale = FRACUNIT/P_RandomRange(2,8)
			s.ghs.color = SKINCOLOR_BLACK
			s.ghs.target = s
			end
			if (leveltime % 7 == 0)
			s.ghs = P_SpawnMobj(s.x+P_RandomRange(-150,150)*FRACUNIT, s.y+P_RandomRange(-150,150)*FRACUNIT, s.z+P_RandomRange(-50,150)*FRACUNIT, MT_SMOKE)
			s.ghs.scale = FRACUNIT*P_RandomRange(1,2)
			end
			if (leveltime % 18 == 0) and not P_RandomRange(0,2)
			S_StartSound(s, sfx_s3kb4)
			P_SpawnMobj(s.x+P_RandomRange(-300,300)*FRACUNIT, s.y+P_RandomRange(-300,300)*FRACUNIT, s.z+P_RandomRange(-50,200)*FRACUNIT, MT_SONIC3KBOSSEXPLODE )
			end
			if (leveltime % 98 == 0)
			S_StartSound(s, sfx_cmol)
					for d = 1,20
						s.ghs = P_SpawnMobj(s.x+P_RandomRange(-120,120)*FRACUNIT, s.y+P_RandomRange(-120,120)*FRACUNIT, s.z+P_RandomRange(5,90)*FRACUNIT, MT_MINECARTSPARK)
						s.ghs.scale = FRACUNIT/12
						s.ghs.fuse = 30
						P_InstaThrust(s.ghs, P_RandomRange(1,359)*ANG1, P_RandomRange(12,24)*FRACUNIT)
					end			
			end			
		end
	end
end, MT_SAMUSSHIP)

addHook("MobjSpawn", function(s)
	for z in players.iterate --GUYS! I'm ALREADY here!!
		if z.mo and z.mo.sam_sprstship
		z.mo.sam_sprstship = false
		end
	end
end, MT_SAMUSSHIP)

local function ShipCollide(s, v)
   if v
	if v.player and (gametype == GT_COOP)
		if not v.player.firstshipin
			v.player.samhudmessagetime = 24
			v.player.samhudmessage1 = "Jump on your gunship and press\x83 spin\x82 to enter."
			v.player.samhudmessage2 = nil	
		elseif v.player.sams_itemcompletionprev == nil
		v.player.sams_itemcompletionprev = 0
		elseif v.player.sams_itemcompletion != nil and v.player.icr13 != nil and v.player.icr14 != nil and v.player.icr15 != nil and v.player.icr17 != nil
		and v.player.sams_itemcompletionprev < (v.player.sams_itemcompletion-v.player.icr13-v.player.icr14-v.player.icr15-v.player.icr17)
			v.player.samhudmessagetime = 24
			v.player.samhudmessage1 = "\x87 New data's\x82 available inside your gunship."
			v.player.samhudmessage2 = nil
		end
	end
	if (v.z < s.z+s.height-2*FRACUNIT) and (v.z > s.z-s.height)
		if v.player
			if (v.player.pflags & PF_STARTJUMP)
			and (v.momz > 5*FRACUNIT) and (v.momz < 7*FRACUNIT)
				v.momz = 7*FRACUNIT
			end
		end
		return false
	elseif (v.z > s.z+s.height/3) and (v.z < s.z+s.height+11*FRACUNIT)
		if v.player and v.health and not v.player.sam_exitship
		v.player.sam_shipready = 2
			if v.player.sam_shipready and not (v.player.sam_hyperbeampanic)
				if (v.player.cmd.buttons & BT_USE) and not (v.player.sams_usecd and (v.player.sams_usecd > 1))
				and not v.player.sam_intoship
					if v.gravitylights and v.gravitylights.valid
					P_SpawnGhostMobj(v.gravitylights)
					end
				v.player.sam_intoship = 35
				v.player.sam_st = s
				if v.player.sams_itemcompletion != nil and v.player.icr13 != nil and v.player.icr14 != nil and v.player.icr15 != nil and v.player.icr17 != nil
				v.player.sams_itemcompletionprev = v.player.sams_itemcompletion-v.player.icr13-v.player.icr14-v.player.icr15-v.player.icr17
				end
				v.player.firstshipin = true
				end
			end
		end
	end
   end
end

addHook("MobjCollide", ShipCollide, MT_SAMUSSHIP)
addHook("MobjMoveCollide", ShipCollide, MT_SAMUSSHIP)

//Next two items are optional passive bonuses that won't count towards completion!
//This one's the ammo digitizer. More ammo restored means more incentive to cause mayhem with beam combos

addHook("MobjThinker", function(s)
	if s.valid
		if (leveltime % 10 == 0)
		A_SAMPARTICLE(s, MT_MPR1, 50, 1, 1, 1,  P_RandomRange(SKINCOLOR_SUPERGOLD3, SKINCOLOR_SUPERGOLD5), P_RandomRange(23355, 55353))
		end
		S_StartSound(s, sfx_pbpku)		
		if not (s.samholo and s.samholo.valid)
		s.color = SKINCOLOR_GOLD
		s.samholo = P_SpawnMobj(s.x, s.y, s.z,  MT_BONUSHOLOGRAM)
		else
			s.samholo.tics = 2
			P_MoveOrigin(s.samholo, s.x, s.y, s.z)
			if not s.trnsphase
			s.trnsphase = 30
			else
				local trn = TR_TRANS10*max( 1,min(6,6-(s.trnsphase-9)/2) ) //Mathematics! 
				s.samholo.frame = S|(trn)|FF_FULLBRIGHT		
				s.trnsphase = $-1
			end	
		end
	end
end, MT_AMMODIGITIZER)

--Bonus item 2. Doesn't count for completion.
addHook("MobjThinker", function(s)
	if s.valid
		if (leveltime % 10 == 0)
		A_SAMPARTICLE(s, MT_MPR1, 50, 1, 1, 1,  SKINCOLOR_ROSY, P_RandomRange(23355, 55353))
		end
		S_StartSound(s, sfx_pbpku)		
		if not (s.samholo and s.samholo.valid)
		s.color = SKINCOLOR_ROSY
		s.samholo = P_SpawnMobj(s.x, s.y, s.z,  MT_BONUSHOLOGRAM)
		else
			s.samholo.tics = 2
			P_MoveOrigin(s.samholo, s.x, s.y, s.z)
			if not s.trnsphase
			s.trnsphase = 30
			else
				local trn = TR_TRANS10*max( 1,min(6,6-(s.trnsphase-9)/2) ) //Mathematics! 
				s.samholo.frame = T|(trn)|FF_FULLBRIGHT		
				s.trnsphase = $-1
			end	
		end
	end
end, MT_AUTOTANK)

--Bonus item 3. Doesn't count for completion.
addHook("MobjThinker", function(s)
	if s.valid
		if (leveltime % 10 == 0)
		A_SAMPARTICLE(s, MT_MPR1, 50, 1, 1, 1,  SKINCOLOR_SKY, P_RandomRange(23355, 55353))
		end
		S_StartSound(s, sfx_pbpku)		
		if not (s.samholo and s.samholo.valid)
		s.color = SKINCOLOR_SKY
		s.samholo = P_SpawnMobj(s.x, s.y, s.z,  MT_BONUSHOLOGRAM)
		else
			s.samholo.tics = 2
			P_MoveOrigin(s.samholo, s.x, s.y, s.z)
			if not s.trnsphase
			s.trnsphase = 30
			else
				local trn = TR_TRANS10*max( 1,min(6,6-(s.trnsphase-9)/2) ) //Mathematics! 
				s.samholo.frame = Z|(trn)|FF_FULLBRIGHT		
				s.trnsphase = $-1
			end	
		end
	end
end, MT_SCANVISOR)


addHook("MobjThinker", function(s)
	if s.valid
		if not s.gripscaled
			s.scale = $*2
			s.gripscaled = true
		end
		if not (s.griporb and s.griporb.valid)
			s.griporb = P_SpawnMobjFromMobj(s,0,0,0, MT_BONUSHOLOGRAM)
			s.griporb.sprite = SPR_GVST
			s.griporb.blendmode = AST_ADD
			s.griporb.renderflags = $|RF_FULLBRIGHT
			s.griporb.frame = N
			s.griporb.plus = 1
			
			s.sprite = SPR_GVST
			s.frame = M
			s.plus = 1
			s.renderflags = $|RF_SEMIBRIGHT
		end
		
		local t = s.griporb
		t.tics = 3 t.fuse = 3
		t.anim_duration = 3		
		P_MoveOrigin(t, s.x, s.y, s.z)
		
		--Animate the item and its overlaying orb at the same time.
		
		s.frame = (s.frame & FF_FRAMEMASK)
		if s.frame >= M
			s.plus = -1
		elseif s.frame <= K
			s.plus = 1
		end
		
		t.frame = (t.frame & FF_FRAMEMASK)
		if t.frame >= Q
			t.plus = -1
		elseif t.frame <= N
			t.plus = 1
		end

		s.frame = $+s.plus
		s.frame = max($, K)
		s.frame = min($, M)

		t.frame = $+s.plus
		t.frame = max($, N)
		t.frame = min($, Q)
		t.frame = $|TR_TRANS60
		
	end
end, MT_PWGRP)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
				return nil
			end
			
			if not v.player.sam_power_grip			
				P_SamFP(v.player, PAL_MIXUP, 6)
				S_StartSound(v, sfx_spwup)				
				CONS_Printf(v.player, "You got the\x82 Power Grip!\x80 You can now jump and morph onto ledges!")
				v.player.sam_power_grip = true
				ItemGetPopup(v.player, 80, SKINCOLOR_POWERSUIT, "Power Grip", 94000)			
			elseif (gametype == GT_COOP) and (netgame or splitscreen)
			and not (v.player.coopboxrespawn and v.player.coopboxrespawn == 2)			
				return false				
			else			
				S_StartSound(v, sfx_mpku)
				v.player.sammissiles = $+3			
			end
			
			NewSamPickup(v, "GVSTK0", 88750)
			
			if s.griporb and s.griporb.valid
				s.griporb.state = S_NULL
			end
			
			s.state = S_NULL
			return false
		end
	end
end, MT_PWGRP)

addHook("MobjCollide", function(s, v)
	return false
end, MT_PWGRPLD)
addHook("MobjMoveCollide", function(s, v)
	return false
end, MT_PWGRPLD)

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s.valid
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not (v.player.sam_ammodigitizer and v.player.sam_ammodigitizer == 3)			
			P_SamFP(v.player, PAL_MIXUP, 14)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You upgraded with the\x87 Ammo Digitizer!\x80 Ammo pickups restore 3x the ammo.")
			v.player.sam_ammodigitizer = 3
			ItemGetPopup(v.player, 80, SKINCOLOR_YELLOW, "Ammo Digitizer", 100000)
			NewSamPickup(v, "MPR1S0", 35355)
				if not ((gametype == GT_COOP) and (multiplayer or netgame))			
				s.state = S_NULL
				return false
				end
			else
			return false
			end
		end
	end
end, MT_AMMODIGITIZER)

//Not to be confused with reserve tanks, which revive you from death.

addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s.valid
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_autotank			
			P_SamFP(v.player, PAL_MIXUP, 14)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You upgraded with the\x87 Auto Tank!\x80 Slowly auto-restore up to 99 energy!")
			v.player.sam_autotank = 99
			NewSamPickup(v, "MPR1T0", 35355)
			ItemGetPopup(v.player, 80, SKINCOLOR_ROSY, "Auto Tank", 87000)
				if not ((gametype == GT_COOP) and (multiplayer or netgame))	
				s.state = S_NULL --stay behind to let other players obtain the item too.
				end
			return false
			else
			return false
			end
		end
	end
end, MT_AUTOTANK)

//Sorta more like an Aeon Pulse
addHook("MobjMoveCollide", function(s, v)
	if v.player and v and YouAreSamus(v)
		if s.valid
			if (v.z > s.z+s.height)
			or (s.z > v.z+v.height)
			return nil
			end
			if not v.player.sam_scanvisor
			P_SamFP(v.player, PAL_MIXUP, 14)
			S_StartSound(v, sfx_spwup)
			CONS_Printf(v.player, "You upgraded with the\x84 Scan Visor!\x80 Stand still to scan your surroundings.")
			v.player.sam_scanvisor = true
			SamusTutorial(v, "scanvisor")
			NewSamPickup(v, "MPR1Z0", 35355)
			ItemGetPopup(v.player, 80, SKINCOLOR_SLATE, "Scan Visor", 87000)
				if not ((gametype == GT_COOP) and (multiplayer or netgame))	
				s.state = S_NULL --stay behind to let other players obtain the item too.
				end
			return false
			else
			return false
			end
		end
	end
end, MT_SCANVISOR)
--Alternate token skin for damage challenge
addHook("MobjThinker", function(s)
	if s.valid
		if not s.checkedchallenge
		s.checkedchallenge = true 
			for z in players.iterate
				if not z.tokensrb2style or z.tokensrb2style == 1
				s.samustoken = true
				s.flags2 = $|MF2_DONTDRAW
				end
			end
		elseif s.samustoken and leveltime % 2 == 0
			s.clight = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_SAMMISSILELIGHT)
			s.clight.scale = s.scale/15
			s.clight.scalespeed = $/4
			s.clight.layers = 2
			s.clight.tokenlight = true
		end
	end
end, MT_TOKEN)