freeslot("MT_SAMSPAWNITEM", "MT_SAMSPAWNITEMSONIC")

--===========================FUNCTIONS PAGE==============================
--This Lua section houses functions I can refer back to for the sake of organization (and general laziness)
--=======================================================================

--Checks for either skin.
rawset(_G, "YouAreSamus", function(s)
	if s.skin == "samus"
	or s.skin == "basesamus"
		return true
	else
		return false
	end
end)

rawset(_G, "SamusBeamFire", function(s, var1, var2, var3)
local p = s.player
local crosshaired
	if s.sam_automob and s.sam_automob.valid
		local t = s.sam_automob			
		--Re-adjust aim right before shooting. This causes issues with lag otherwise!
		s.angle = R_PointToAngle2(s.x, s.y, t.x, t.y)
		p.drawangle = s.angle
		if t.superbrak
		p.aiming = R_PointToAngle2(0, 0, R_PointToDist2(s.x, s.y, t.x, t.y), ((t.z+(t.height/2)) - s.z)	)
		elseif s.z > t.z+t.height
		p.aiming = R_PointToAngle2(0, 0, R_PointToDist2(s.x, s.y, t.x, t.y), (t.z - s.z)	)
		else
		p.aiming = R_PointToAngle2(0, 0, R_PointToDist2(s.x, s.y, t.x, t.y), ((t.z+(t.height/5)) - s.z)	)	
		end
			
		
	elseif (p.pflags & PF_ANALOGMODE) and not p.sammorphed --Analog mode autoaim.
		P_LookForEnemies(p)
			if s.target and ( ((s.target.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) or s.target.frozenbox)) or (s.target.type == MT_EGGSHIELD) or (s.target.type == MT_MINUS) ) and s.target.health and ((s.target.flags & MF_SHOOTABLE) or s.target.frozenbox)
			and (FixedHypot(FixedHypot(s.x-s.target.x, s.y-s.target.y), s.z-s.target.z) < 2000*FRACUNIT) and (P_CheckSight(s, s.target))
				s.automob = s.target
			end
	elseif not netgame
		if (CV_FindVar("crosshair").value == 1)
		and p.aiming < 6000*FRACUNIT and p.aiming > -6000*FRACUNIT
		p.aiming = $+80*FRACUNIT
		crosshaired = true
		end	
	end
	if (twodlevel or (s.flags2 & MF2_TWOD)) --2D aiming feature. Hold up or down to shoot diagonally.
		if (p.cmd.forwardmove > 0)
		p.aiming = 6000*FRACUNIT
		s.diagshoot = true
		elseif (p.cmd.forwardmove < 0)
		p.aiming = -6000*FRACUNIT
		s.diagshoot = true
		end
	elseif (p.powers[pw_carry] == CR_MINECART) --Aiming in minecarts is glitched, so just disable vertical aiming.
	and not s.sam_automob
	p.aiming = 0
	end
	
	p.sams_firecd = 2
	p.sam_shinesparkstop = 0
	p.sams_supermissileready = 0
	p.sams_beamanim = 15 --The animation.
	
	if not (var1 and (var1 == MT_SPCHARGESHOT))
	P_SpawnPlayerMissile(s, MT_SAMMONBREAKER) --Little invisible explosion that destroys monitors at point blank range.
	end

		
	if var1 --Do recoil?
	and ((var1 == MT_PLCHARGESHOT) or (var1 == MT_SPCHARGESHOT) or (var1 == MT_SAMSUPERMISSILE) or (var1 == MT_HBSHOT)
	or (var1 == MT_ICCHARGESHOT) or (var1 == MT_PBCHARGESHOT) or (var1 == MT_ICCHARGECOMBO) or (var1 == MT_SPCHARGECOMBO) )
			if (var1 == MT_SAMSUPERMISSILE) --How much recoil to add to the shot?
			p.recoilmult = 3
			elseif (var1 == MT_PLCHARGESHOT)
			p.recoilmult = 6
			elseif (var1 == MT_SPCHARGESHOT)
			p.recoilmult = 2
			elseif (var1 == MT_PBCHARGESHOT)
			p.recoilmult = 11
			elseif (s.eflags & MFE_UNDERWATER)
			p.recoilmult = 2
			else
			p.recoilmult = 1
			end
			
			if (var1 == MT_SPCHARGESHOT) 
			s.meleeshot = 2
			end

				if (p.aiming < 5000*FRACUNIT) and (p.aiming > -5000*FRACUNIT)
					P_Thrust(s, s.angle, -11*FRACUNIT/p.recoilmult)
				elseif (p.aiming < 9000*FRACUNIT) and (p.aiming > -9000*FRACUNIT)
					P_Thrust(s, s.angle, -8*FRACUNIT/p.recoilmult)
				else
					P_Thrust(s, s.angle, -2*FRACUNIT/p.recoilmult)
				end
				if (s.momz > 2*FRACUNIT) and (s.momz < -2*FRACUNIT)
					s.momz = $+(FixedMul(FixedMul(-30*FRACUNIT/p.recoilmult, s.scale), sin(p.aiming)))
				elseif (s.momz > 6*FRACUNIT) and (s.momz < -6*FRACUNIT)
					s.momz = $+(FixedMul(FixedMul(-10*FRACUNIT/p.recoilmult, s.scale), sin(p.aiming)))
				else
					s.momz = $+(FixedMul(FixedMul(-4*FRACUNIT/p.recoilmult, s.scale), sin(p.aiming)))
				end
	end

	if not var2	

		if var3
				
				local vortexrng = P_RandomRange(1, 3)			
				if (vortexrng < 2)
				vortexrng = SKINCOLOR_RED
				elseif vortexrng == 2
				vortexrng = SKINCOLOR_CRIMSON
				else
				vortexrng = SKINCOLOR_ORANGE
				end
				
				if var3 == 4 // Middle shot
				p.sams_shot = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
				p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.gattlingvortex1 = true
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				elseif var3 == 8 // Rightshot
				p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*32))), s.y+FixedMul(96*FRACUNIT, sin(s.angle-(ANG2*32))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle-(ANG2*2), FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				elseif var3 == 12 // Up-rightshot
				p.sams_shot = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*20))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*20))), s.z+((s.height*10/11)*(P_MobjFlip(s))), var1)
				p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))+(2*FRACUNIT)*(P_MobjFlip(s))
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle-ANG2, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				elseif var3 == 16 // Upshot
				p.sams_shot = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height*10/8)*(P_MobjFlip(s))), var1)
				p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))+(5*FRACUNIT)*(P_MobjFlip(s))
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				elseif var3 == 20 // Leftupshot
				p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle+(ANG2*8))), s.y+FixedMul(96*FRACUNIT, sin(s.angle+(ANG2*8))), s.z+((s.height*10/11)*(P_MobjFlip(s))), var1)
				p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))+(2*FRACUNIT)*(P_MobjFlip(s))
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle+ANG2, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				elseif var3 == 24 // Leftshot
				p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle+(ANG2*24))), s.y+FixedMul(96*FRACUNIT, sin(s.angle+(ANG2*24))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
				p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
				p.sams_shot.angle = s.angle+ANG2
				p.sams_shot.blendmode = AST_ADD
				P_Thrust(p.sams_shot, s.angle+(ANG2*2), FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				end

				if p.sams_shot and p.sams_shot.valid
				p.sams_shot.color = vortexrng
				p.sams_shot.gattlingvortex = true
				p.sams_shot.blendmode = AST_ADD
				end

		elseif s.automob and s.automob.valid and s.automob.health
		
			p.sams_shot = P_SpawnMissile(s, s.automob, var1)
			p.sams_shot.blendmode = AST_ADD

		else

//Basic Shot function.

			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height)), var1)
			else
			p.sams_shot = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
			end
			
		end
		
		if p.sams_shot and p.sams_shot.valid
		
		p.plshot = p.sams_shot
		p.sams_shot.target = s
		p.sams_shot.scale = s.scale
		p.sams_shot.blendmode = AST_ADD
		
		if p.sams_beamcombocharge and (p.sams_shot.type == MT_SAMSUPERMISSILE)
		p.sams_shot.shinyshot = true --Makes the powerbeam combo shiny.
		end
		
		if not (s.eflags & MFE_VERTICALFLIP)
		p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))
		end
		
		if not var3 and p.sams_shot.valid
		p.sams_shot.angle = s.angle+ANG2
			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))*20/19
			else
			p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
			end
		P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
		end
		
			if p.sams_shot and p.sams_shot.valid and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot.flags2 = MF2_OBJECTFLIP
				if p.sams_shot.type == MT_WVCHARGESHOT
				p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))-s.height*5/4
				else
				p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))-s.height*5/7
				end
			end
			if p.sams_shot and p.sams_shot.valid and (p.sams_shot.type == MT_SAMMISSILE)
			p.sams_shot.flags2 = $|MF2_SCATTER
			end
			if p.sams_shot and p.sams_shot.valid and ((p.sams_shot.type == MT_SAMSUPERMISSILE) or (p.sams_shot.type == MT_ICCHARGECOMBO))
			p.sams_shot.flags2 = $|MF2_RAILRING|MF2_SUPERFIRE
				if (p.sams_shot.type == MT_ICCHARGECOMBO)
				p.sams_shot.scale = $*20
				p.sams_shot.z = $-(s.scale*5)
				p.sams_shoty = P_SpawnMobj(s.x+s.momx+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+s.momy+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), MT_ICCHARGESHOT)
					if p.sams_shoty and p.sams_shoty.valid and p.sams_shot and p.sams_shot.valid
					p.plshot = p.sams_shoty
					p.sams_shoty.target = s
					p.sams_shoty.scale = s.scale
					p.sams_shoty.romio = p.sams_shot
					p.sams_shoty.angle = s.angle+ANG2
					p.sams_shoty.z = $+(FixedMul(FixedMul(p.sams_shoty.info.speed, s.scale), sin(p.aiming))*(P_MobjFlip(s)))
					p.sams_shoty.momz = $+FixedMul(FixedMul(p.sams_shoty.info.speed, p.sams_shoty.scale), sin(p.aiming))
					P_Thrust(p.sams_shoty, s.angle, FixedMul(FixedMul(p.sams_shoty.info.speed, s.scale), cos(p.aiming)))
						if p.sams_shoty and (s.eflags & MFE_VERTICALFLIP)
						p.sams_shoty.z = s.z+(2*s.height/3)-FixedMul(p.sams_shoty.info.height, s.scale)
						p.sams_shoty.flags2 = MF2_OBJECTFLIP
						end
					end 
				end
			end
		end
	elseif var2 and (var2 == 1)
	    if ((s.flags2 & MF2_TWOD) or twodlevel)

		p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*16))), s.y+FixedMul(s.radius*4, sin(s.angle-(ANG2*16))), s.z+((s.height/3)+s.height/6*(P_MobjFlip(s))), var1)
			if p.sams_shot and p.sams_shot.valid
			p.plshot = p.sams_shot
			p.sams_shot.blendmode = AST_ADD
			p.sams_shot.target = s
			p.sams_shot.scale = s.scale
			p.sams_shot.angle = s.angle
			p.sams_shot.wave4 = true
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))
			end
			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))*20/19
			else
			p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))+s.height/6
			end
			P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot.flags2 = MF2_OBJECTFLIP
				p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
		p.sams_shot2 = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+FixedMul(s.radius*4, sin(s.angle-(ANG2*4))), s.z+((s.height/3)-s.height/6*(P_MobjFlip(s))), var1)
			if p.sams_shot2 and p.sams_shot2.valid
			p.plshot2 = p.sams_shot2
			p.sams_shot2.blendmode = AST_ADD
			p.sams_shot2.target = s
			p.sams_shot2.scale = s.scale
			p.sams_shot2.wave2 = true
			p.sams_shot2.angle = s.angle
			P_SpawnGhostMobj(p.sams_shot2)
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))-s.height/6
			end
			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot2.momz = ($+FixedMul(FixedMul(p.sams_shot2.info.speed, p.sams_shot2.scale), sin(p.aiming)))*20/19
			else
			p.sams_shot2.momz = $+FixedMul(FixedMul(p.sams_shot2.info.speed, p.sams_shot2.scale), sin(p.aiming))
			end
			P_Thrust(p.sams_shot2, s.angle, FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot2 and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot2.flags2 = MF2_OBJECTFLIP
				p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
		p.sams_shot3 = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle+(ANG2*8))), s.y+FixedMul(s.radius*4, sin(s.angle+(ANG2*8))), s.z+((s.height/3)+s.height/2*(P_MobjFlip(s))), var1)
			if p.sams_shot3 and p.sams_shot3.valid
			p.plshot3 = p.sams_shot3
			p.sams_shot3.blendmode = AST_ADD
			p.sams_shot3.target = s
			p.sams_shot3.scale = s.scale
			p.sams_shot3.wave2 = true
			p.sams_shot3.wave5 = true
			p.sams_shot3.angle = s.angle
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot3.z = $+(FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), sin(p.aiming)))+s.height/2
			end
			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot3.momz = ($+FixedMul(FixedMul(p.sams_shot3.info.speed, p.sams_shot3.scale), sin(p.aiming)))*20/19
			else
			p.sams_shot3.momz = $+FixedMul(FixedMul(p.sams_shot3.info.speed, p.sams_shot3.scale), sin(p.aiming))
			end
			P_Thrust(p.sams_shot3, s.angle, FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot3 and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot3.flags2 = MF2_OBJECTFLIP
				p.sams_shot3.z = $+(FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
			if p.sams_shot and p.sams_shot3
			p.sams_shot.lilbro3 = p.sams_shot3
			p.sams_shot3.lilbro1 = p.sams_shot
			end
			if p.sams_shot and p.sams_shot2
			p.sams_shot.lilbro2 = p.sams_shot2
			p.sams_shot2.lilbro1 = p.sams_shot
			end
			if p.sams_shot2 and p.sams_shot3
			p.sams_shot2.lilbro3 = p.sams_shot3
			p.sams_shot3.lilbro2 = p.sams_shot2
			end

	    else 
		
		p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*16))), s.y+FixedMul(s.radius*4, sin(s.angle-(ANG2*16))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
			if p.sams_shot and p.sams_shot.valid
			p.plshot = p.sams_shot
			p.sams_shot.blendmode = AST_ADD
			p.sams_shot.target = s
			p.sams_shot.scale = s.scale
			p.sams_shot.angle = s.angle
			p.sams_shot.wave4 = true
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))
			end
			if (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.momz = ($+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming)))*20/19
			else
			p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
			end
			P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot.flags2 = MF2_OBJECTFLIP
				p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
		p.sams_shot2 = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+FixedMul(s.radius*4, sin(s.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
			if p.sams_shot2 and p.sams_shot2.valid
			p.plshot2 = p.sams_shot2
			p.sams_shot2.blendmode = AST_ADD
			p.sams_shot2.target = s
			p.sams_shot2.scale = s.scale
			p.sams_shot2.wave2 = true
			p.sams_shot2.angle = s.angle+ANG2
				if p.sams_shot2 and p.sams_shot2.valid 
					if not (s.eflags & MFE_VERTICALFLIP)
					p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))
					end
					if (s.eflags & MFE_VERTICALFLIP)
					p.sams_shot2.momz = ($+FixedMul(FixedMul(p.sams_shot2.info.speed, p.sams_shot2.scale), sin(p.aiming)))*20/19
					else
					p.sams_shot2.momz = $+FixedMul(FixedMul(p.sams_shot2.info.speed, p.sams_shot2.scale), sin(p.aiming))
					end
					P_Thrust(p.sams_shot2, s.angle, FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), cos(p.aiming)))
					if p.sams_shot2 and (s.eflags & MFE_VERTICALFLIP)
					p.sams_shot2.flags2 = MF2_OBJECTFLIP
					p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
					end
				end
			end
		p.sams_shot3 = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle+(ANG2*8))), s.y+FixedMul(s.radius*4, sin(s.angle+(ANG2*8))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
			if p.sams_shot3 and p.sams_shot3.valid
			p.plshot3 = p.sams_shot3
			p.sams_shot3.blendmode = AST_ADD
			p.sams_shot3.target = s
			p.sams_shot3.scale = s.scale
			p.sams_shot3.wave2 = true
			p.sams_shot3.wave5 = true
			p.sams_shot3.angle = s.angle+ANG2+ANG2
			if p.sams_shot3 and p.sams_shot3.valid
				if not (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot3.z = $+(FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), sin(p.aiming)))
				end
				if p.sams_shot3 and p.sams_shot3.valid				
					if (s.eflags & MFE_VERTICALFLIP)
					p.sams_shot3.momz = ($+FixedMul(FixedMul(p.sams_shot3.info.speed, p.sams_shot3.scale), sin(p.aiming)))*20/19
					else
					p.sams_shot3.momz = $+FixedMul(FixedMul(p.sams_shot3.info.speed, p.sams_shot3.scale), sin(p.aiming))
					end
					P_Thrust(p.sams_shot3, s.angle, FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), cos(p.aiming)))
						if p.sams_shot3 and (s.eflags & MFE_VERTICALFLIP)
						p.sams_shot3.flags2 = MF2_OBJECTFLIP
						p.sams_shot3.z = $+(FixedMul(FixedMul(p.sams_shot3.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
						end
					end
					if p.sams_shot and p.sams_shot3
					p.sams_shot.lilbro3 = p.sams_shot3
					p.sams_shot3.lilbro1 = p.sams_shot
					end
					if p.sams_shot and p.sams_shot2
					p.sams_shot.lilbro2 = p.sams_shot2
					p.sams_shot2.lilbro1 = p.sams_shot
					end
					if p.sams_shot2 and p.sams_shot3
					p.sams_shot2.lilbro3 = p.sams_shot3
					p.sams_shot3.lilbro2 = p.sams_shot2
					end
				end
			end
	    end


	elseif var2 and (var2 == 2)
		if s.automob and s.automob.valid and s.automob.health
		p.sams_shot = P_SpawnMissile(s, s.automob, var1)
		else
		p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
		end
			if p.sams_shot and p.sams_shot.valid
			p.plshot = p.sams_shot
			p.sams_shot.blendmode = AST_ADD
			p.sams_shot.target = s
			p.sams_shot.scale = s.scale
			p.sams_shot.angle = s.angle+ANG2
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))
			end
			if p.sams_shot and p.sams_shot.valid			
				p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
				P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
					if p.sams_shot and (s.eflags & MFE_VERTICALFLIP)
					p.sams_shot.flags2 = MF2_OBJECTFLIP
					p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
					end
				end
			end
		if s.automob and s.automob.valid and s.automob.health
		p.sams_shot2 = P_SpawnMissile(s, s.automob, var1)
		else
		p.sams_shot2 = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
		end
			if p.sams_shot2 and p.sams_shot2.valid
			p.plshot2 = p.sams_shot2
			p.sams_shot2.blendmode = AST_ADD
			p.sams_shot2.target = s
			p.sams_shot2.scale = s.scale
			p.sams_shot2.wave2 = true
			p.sams_shot2.angle = s.angle+ANG2
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))
			end
			p.sams_shot2.momz = $+FixedMul(FixedMul(p.sams_shot2.info.speed, p.sams_shot2.scale), sin(p.aiming))
			P_Thrust(p.sams_shot2, s.angle, FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot2 and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot2.flags2 = MF2_OBJECTFLIP
				p.sams_shot2.z = $+(FixedMul(FixedMul(p.sams_shot2.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
			if p.sams_shot and p.sams_shot2
			p.sams_shot2.lilbro1 = p.sams_shot
			p.sams_shot.lilbro2 = p.sams_shot2
			end
	elseif var2 and (var2 == 3)
		if s.automob and s.automob.valid and s.automob.health
		p.sams_shot = P_SpawnMissile(s, s.automob, var1)
		else
		p.sams_shot = P_SpawnMobj(s.x+FixedMul(s.radius*4, cos(s.angle-(ANG2*4))), s.y+FixedMul(s.radius*4, sin(p.mo.angle-(ANG2*4))), s.z+((s.height/3)*(P_MobjFlip(s))), var1)
		end
			if p.sams_shot and p.sams_shot.valid
			p.plshot = p.sams_shot
			p.sams_shot.blendmode = AST_ADD
			p.sams_shot.target = s
			p.sams_shot.wave2 = true
			p.sams_shot.scale = s.scale
			p.sams_shot.angle = s.angle+ANG2
			if not (s.eflags & MFE_VERTICALFLIP)
			p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))
			end
			p.sams_shot.momz = $+FixedMul(FixedMul(p.sams_shot.info.speed, p.sams_shot.scale), sin(p.aiming))
			P_Thrust(p.sams_shot, s.angle, FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), cos(p.aiming)))
				if p.sams_shot and (s.eflags & MFE_VERTICALFLIP)
				p.sams_shot.flags2 = MF2_OBJECTFLIP
				p.sams_shot.z = $+(FixedMul(FixedMul(p.sams_shot.info.speed, s.scale), sin(p.aiming)))+s.height*5/7
				end
			end
	end
	if crosshaired and not netgame --Adjust Samus' aim to compensate if using the "cross" crosshair.
	p.aiming = $-80*FRACUNIT
	end
	s.sam_beamroll = 0
	s.sam_forcebeamroll = 0
	if s.diagshoot
	p.aiming = 0
	s.diagshoot = nil
	end
	--Failsafe to stop wallclips.
	if (p.sams_shot and p.sams_shot.valid)
	and not P_TryMove(p.sams_shot, p.sams_shot.x, p.sams_shot.y, true)
		P_MoveOrigin(p.sams_shot, s.x, s.y, s.z+(s.height/2))
		p.sams_shot.wallclipped = true
	end
	s.automob = nil
end)

function A_SAMUSMOBHP(m, p)
	if m and m.valid
			if (m.type == MT_METROID)
				m.samusHP = nil --Go directly to damage system
			elseif (p and (p.crazysamusmobs or p.fusionmode))
				if m.thebabyspawn or m.type == MT_HANGSTER
				m.samusHP = 3
				m.samusHPmax = 3
				elseif (m.type == MT_CYBRAKDEMON) or (m.type == MT_POPHAT)
				m.samusHP = 12
				m.samusHPmax = 12
				elseif ((m.type == MT_FACESTABBER) or (m.type == MT_UNIDUS) or (m.type == MT_DRAGONBOMBER) or (m.type == MT_METROIDPART)
				or (m.type == MT_YELLOWSHELL) or (m.type == MT_SPRINGSHELL) or (m.type == MT_SNAILER))
				or ((m.flags & MF_BOSS) and not (m.type == MT_METALSONIC_BATTLE))
				m.samusHP = 9 m.samusHPmax = 9
				elseif (m.type == MT_BLUECRAWLA or m.type == MT_GFZFISH or m.type == MT_GOLDBUZZ or m.type == MT_PTERABYTE)
				m.samusHP = 6 m.samusHPmax = 6
				else
				m.samusHP = 7 m.samusHPmax = 7
				end
			else
				if (m.type == MT_CYBRAKDEMON) or (m.type == MT_POPHAT) or (m.type == MT_METROIDPART)
				m.samusHP = 9 m.samusHPmax = 9
				elseif m.thebabyspawn or m.type == MT_HANGSTER --It's like stealing candy from a baby, which is fine by me
				m.samusHP = 2 m.samusHPmax = 2
				elseif ((m.type == MT_FACESTABBER) or (m.type == MT_UNIDUS) or (m.type == MT_YELLOWSHELL) or (m.type == MT_SPRINGSHELL) or (m.type == MT_SNAILER))
				or ((m.flags & MF_BOSS) and not (m.type == MT_METALSONIC_BATTLE))
				m.samusHP = 6 m.samusHPmax = 6
				elseif (m.type == MT_BLUECRAWLA or m.type == MT_GFZFISH or m.type == MT_GOLDBUZZ)
				m.samusHP = 3 m.samusHPmax = 3
				else
				m.samusHP = 4 m.samusHPmax = 4
				end
			end
			//Set beam weaknesses and resistances. Highly recommended to give only 1 of each to an enemy, but exceptions can exist.
				if (m.type == MT_BLUECRAWLA or m.type == MT_GFZFISH or m.type == MT_POPUPTURRET or m.type == MT_DETON or m.type == MT_JETTBOMBER
				or m.type == MT_GSNAPPER or m.type == MT_DRAGONBOMBER or m.type == MT_HIVEELEMENTAL or m.type == MT_SHLEEP or m.type == MT_SPINBOBERT)
				m.spazweak = true
				end
				if (m.type == MT_GOLDBUZZ or m.type == MT_REDBUZZ or m.type == MT_BUGGLE or m.type == MT_REDCRAWLA or m.type == MT_VULTURE 
				or m.type == MT_JETJAW or m.type == MT_CRAWLACOMMANDER or m.type == MT_PYREFLY or m.type == MT_CANARIVORE or m.type == MT_BUMBLEBORE
				or m.type == MT_HANGSTER)
				m.waveweak = true
				end
				if (m.type == MT_FACESTABBER or m.type == MT_POINTY or m.type == MT_UNIDUS or m.type == MT_ROBOHOOD or m.type == MT_MINUS
				or m.type == MT_GSNAPPER or m.type == MT_SKIM or m.type == MT_CRUSHSTACEAN or m.type == MT_BANPYURA or m.type == MT_CACOLANTERN)
				m.iceweak = true
				end
				if (m.type == MT_YELLOWSHELL or m.type == MT_SPRINGSHELL or m.type == MT_SNAILER or m.type == MT_EGGGUARD
				or m.type == MT_JETTGUNNER or m.type == MT_POPHAT or m.type == MT_PENGUINATOR or m.type == MT_GOOMBA or m.type == MT_BLUEGOOMBA)
				m.plasmaweak = true
				end
				
			if (m.type == MT_JETJAW or m.type == MT_CRAWLACOMMANDER or m.type == MT_POINTY or m.type == MT_VULTURE or m.type == MT_SKIM
			or m.type == MT_GOLDBUZZ or m.type == MT_REDBUZZ or m.type == MT_CANARIVORE or m.type == MT_HANGSTER or m.type == MT_METROID or m.type == MT_SUPERMETROID)
			m.spazresist = true
			end
			if (m.type == MT_JETTBOMBER or m.type == MT_JETTGUNNER or m.type == MT_GSNAPPER or m.type == MT_SNAILER or m.type == MT_EGGGUARD 
			or m.type == MT_POINTY or m.type == MT_PTERABYTE or m.type == MT_SPINBOBERT)
			m.waveresist = true
			end
			if (m.type == MT_POPUPTURRET or m.type == MT_SPRINGSHELL or m.type == MT_YELLOWSHELL or m.type == MT_GSNAPPER or m.type == MT_CRAWLACOMMANDER
			or m.type == MT_DRAGONBOMBER or m.type == MT_PYREFLY or m.type == MT_HIVEELEMENTAL or m.type == MT_POPHAT or m.type == MT_PENGUINATOR or m.type == MT_SUPERMETROID)
			m.iceresist = true
			end
			if (m.type == MT_FACESTABBER or m.type == MT_UNIDUS or m.type == MT_MINUS or m.type == MT_BUGGLE or m.type == MT_JETJAW
			or m.type == MT_ROBOHOOD or m.type == MT_CRUSHSTACEAN or m.type == MT_BANPYURA or m.type == MT_CACOLANTERN)
			m.plasmaresist = true
			end
			if (m.type == MT_FACESTABBER or m.type == MT_UNIDUS or m.type == MT_CYBRAKDEMON or m.type == MT_EGGSHIELD
			or m.type == MT_HIVEELEMENTAL or m.type == MT_SPINBOBERT or m.type == MT_METROID or m.type == MT_SUPERMETROID)
			m.missileresist = true
			end
	end
end	

--Second dialogue function, used for item popups and mission announcements!
rawset(_G, "SamusMission", function(s, text1, text2, text3, style, nextbox, instant) --Text, style, and nextbox is all we need for this
	if not (s.valid and s.player) -- Everything breaks if there's no valid player or mobj.
	and not (s.player.sam_saveselect) and not modeattacking
	return false
	end
	if not s.samusmission
	--Carbon Copy from SamusDialogue
		s.samusmission = {
		active = false,
		noscale = nil,
		dontrender = 0,
		text1 = 0,
		text2 = 0,
		text3 = 0,
		maxchars1 = 0,
		maxchars2 = 0,
		maxchars3 = 0,
		currentchars1 = 0,
		currentchars2 = 0,
		currentchars3 = 0,
		textwait = nil,
		animtimer = nil,
		textboxscale = nil,
		textboxtrns = nil,
		textboxstyle = nil,
		animendtimer = nil,
		nextbox = nil,
		delay = 10}
	elseif s.samusmission and s.samusmission.active
	return false
	end
	--Use r instead of t here
	local r = s.samusmission
		r.active = true
		r.text1 = text1
		r.maxchars1 = (string.len(r.text1))	
		r.textboxstyle = style
		r.nextbox = nextbox
		r.delay = 10
		
		if not text2
		r.text2 = 0
		r.maxchars2 = 0		
		else
		r.text2 = text2
		r.maxchars2 = (string.len(r.text2))
		end	
		
		if not text3
		r.text3 = 0
		r.maxchars3 = 0
		else
		r.text3 = text3
		r.maxchars3 = (string.len(r.text3))
		end		
		
		if instant --Instantly display all text?
		r.currentchars1 = r.maxchars1
		r.currentchars2 = r.maxchars2
		r.currentchars3 = r.maxchars3
		r.animendtimer = 160
		else
		r.animendtimer = 120
		r.currentchars1 = 0
		r.currentchars2 = 0
		r.currentchars3 = 0
		end
		
		if not r.noscale --Don't do the fade-in again.
		r.animtimer = 18
		r.textboxscale = 356
		r.textboxtrns = TR_TRANS90
		end
		if s.sam_acz4msg
		r.delay = 30
		r.animendtimer = 325
		end
end)

--Sets up Samus' dialogue thinker! I'm going to try and tutorialize this since my code is a bit hard to read otherwise

--s: The player mobj. Player.mo will do.
--Text1: First line of dialogue. MUST be present. Does not auto-correct in length, so make sure your text is not too long. 
--Text2: Second line of dialogue. Use nil if you don't want anything beyond the first line.
--Icon: "SAMDEF" is the default Samus face.
--Style: Set this to 1 to make the computer talk. The icon will be ignored. Otherwise set this to 2.
--Nextbox: Used for the hardcoded dialogue. Always set this to 0 and set player.mo.samusdialogue.customnextbox instead!
--DialogueWait: How many tics to wait before the dialogue actually starts?
--AlignType1: Set this to "small" if you want the first line to have small text. Otherwise set this to nil.
--AlignType2: Set this to "small" if you want the second line to have small text. Otherwise set this to nil.
--Text3: An optional third line of text. Make sure AlignType 1 and 2 are set to "small" as well if you're using this. Set to nil if you don't want to use it.

rawset(_G, "SamusDialogue", function(s, text1, text2, icon, style, nextbox, dialoguewait, aligntype1, aligntype2, text3) --Sets up Samus' dialogue thinker!
	if not (s.valid and s.player) -- Everything breaks if there's no valid player or mobj.
	return false
	end
	if not s.samusdialogue
	--Is this not setup yet? Well, set it up, boys!	Table trick stolen from Motdspork, who stole it from Bloops!
		local samusdialogue = {
		active = false,
		noscale = nil,
		dontrender = 0,
		text1 = text1,
		maxchars1 = 0,
		text2 = 0,
		maxchars2 = 0,
		text3 = 0,
		currentchars3 = 0,
		maxchars3 = 0,
		samuscolor = 0,
		currentchars1 = 0,
		currentchars2 = 0,
		align1 = "left",
		align2 = "left",		
		textwait = nil,
		animtimer = nil,
		endoffset = nil,
		textboxscale = nil,
		textboxtrns = nil,
		textboxpic = nil,
		textboxpic2 = nil, --Nil until confirmed otherwise!
		textboxstyle = nil,
		animendtimer = nil,
		nextbox = nil,
		textboxpic = nil,
		lastpic = nil,
		tbscolor = SKINCOLOR_SUPERORANGE1,
		tbsd = 1,
		transitflash = V_90TRANS,
		samuscolor2 = 5,
		textboxpic2 = nil,
		customnextboxready = false,
		customnextbox = 0}
	s.samusdialogue = samusdialogue
	elseif s.samusdialogue and s.samusdialogue.active
	return false
	end
	
	local t = s.samusdialogue
		t.active = true
		t.text1 = text1
		t.maxchars1 = (string.len(t.text1))
		t.customnextboxready = false
		
		if not aligntype1
		t.align1 = "left"
		else
		t.align1 = aligntype1
		end
		if not aligntype2
		t.align2 = "left"
		else
		t.align2 = aligntype2
		end
		
		if not text2
		t.text2 = 0
		t.maxchars2 = 0		
		else
		t.text2 = text2
		t.maxchars2 = (string.len(t.text2))
		end
		
		if not text3
		t.text3 = 0
		t.maxchars3 = 0		
		else
		t.text3 = text3
		t.maxchars3 = (string.len(t.text3))
		end		
		
		if s.player.sam_screwattacking and s.player.prescrewcolor --Don't use the screw attack colors!
		t.samuscolor = s.player.prescrewcolor
		else
		t.samuscolor = s.color
		end
		
		t.currentchars1 = 0
		t.currentchars2 = 0
		t.currentchars3 = 0
		
		if dialoguewait --Wait a bit?
		t.dontrender = dialoguewait
		else
		S_StartSound(s, sfx_samtm1) --Play sound immediately.
		t.dontrender = 0
		end
		
		if not t.noscale or t.lastpic == nil --Don't do the animation again.
		t.animtimer = 18
		t.textboxscale = 356
		t.textboxtrns = TR_TRANS90
		end
		
		t.tbscolor = SKINCOLOR_SUPERRED1
		t.tbsd = 1		
		t.endoffset = 0
		t.textboxpic = icon
		t.textboxpic2 = nil --Nil until confirmed otherwise!
		t.textboxstyle = style
		if not nextbox and not t.customnextbox --Last textbox stays a little longer!
		t.animendtimer = 100
			if not text2
			t.animendtimer = 75
			end
		else
		t.animendtimer = 75
			if not text2
			t.animendtimer = 25
			end
		end
		t.nextbox = nextbox
			if s.player.sam_gravitysuit --Change to Varia/Gravity Suit versions if necessary.
				if icon == "SAMDEF"
				t.textboxpic = "SAMDEFVA"
					if s.player.samvisorcolor and (s.player.sam_gravitysuit == 2)
					t.samuscolor2 = s.player.samvisorcolor 
					t.textboxpic2 = "SAMDEFVL" --Add the overlay for the Gravity Lights!
					end	
				elseif icon == "SAMSAD"
				t.textboxpic = "SAMSADVA"
					if s.player.samvisorcolor and (s.player.sam_gravitysuit == 2)
					t.samuscolor2 = s.player.samvisorcolor 
					t.textboxpic2 = "SAMSADVL" --Add the overlay for the Gravity Lights!
					end
				elseif icon == "SAMPRE"
				t.textboxpic = "SAMPREVA"
					if s.player.samvisorcolor and (s.player.sam_gravitysuit == 2)
					t.samuscolor2 = s.player.samvisorcolor 
					t.textboxpic2 = "SAMPREVL" --Add the overlay for the Gravity Lights!
					end							
				end
			end
			if t.noscale
			t.noscale = nil
				--If the lastpic is the same as the previous pic and we're not doing an animation, don't do anything!
				if (t.lastpic != nil) and (t.lastpic != icon) and t.textboxstyle != 1 --No flash if computer style
				t.transitflash = V_90TRANS
				end
			end
			if style == 1
			t.textboxcolor = SKINCOLOR_CRIMSON
			t.lastpic = nil
			else
			t.textboxcolor = SKINCOLOR_SKY
			t.lastpic = t.textboxpic
			end
end)

rawset(_G, "SamResetBeam", function(p)
	p.sam_powerbeamequip = true
	p.sam_spazerbeamequip = false
	p.sam_wavebeamequip = false
	p.sam_icebeamequip = false
	p.sam_plasmabeamequip = false
	p.sam_hyperbeamequip = false
end)

--Sets up Metroid Skins for rings, boxes, and saveposts. s can be nil, it doesn't matter.
rawset(_G, "SetMetroidVisuals", function(s)
local visuals = false
for z in players.iterate
	if z and z.metroidvisuals or (gametype == GT_HUNTERS)
		visuals = true
	end
end
	if visuals
		for m in mobjs.iterate(mobjs)
			if m.valid and m.flags != nil and (m.flags & MF_MONITOR) 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
			if m.valid and ((m.type == MT_RING) or (m.type == MT_COIN)) and m.health
				m.state = S_METRING1
				m.metroidvisual = true
				m.colorized = true
				m.color = SKINCOLOR_WHITE	
			end
			if 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.valid and m.health
				m.sprite = SPR_MPR1
				m.frame = O
				m.color = SKINCOLOR_RED
				end			
			end 
		end
	end
end)

rawset(_G, "SAM_RemoveLDgrp", function(s)
	if s.sam_pwgrp and s.sam_pwgrp.valid
		s.sam_pwgrp.state = S_NULL
	end
	if s.sam_pwgrpS and s.sam_pwgrpS.valid	
		s.sam_pwgrpS.state = S_NULL
	end
end)

--Much needed shortcut
rawset(_G, "CancelScrewAttack", function(s,p)
	local check = false
	if p.sam_screwattacking
		p.aiming = 0
		p.sam_screwattacking = 0
		p.sams_screwattackcd = 35
		check = true
		if p.mo
			if not p.mo.sam_ldclmb
				p.mo.sam_ldclmb = 5
			end
		end
	end
	if s and s.valid 
		s.sam_screwattackspbs = nil
		if s.spriteyscale == 74555
		or s.spritexscale == 50010
			s.spriteyscale = FRACUNIT
			s.spritexscale = FRACUNIT
		end		
		if s.sam_screwattackfling
		S_StopSoundByID(s, sfx_satkrl)
		s.friction = 59392
		s.sam_screwattackfling = nil
			if p.sam_firstperson
				SamCam(p, false)
				p.visorclosein = 15
			end
			if P_IsObjectOnGround(s) and p.panim == PA_ROLL
				s.state = S_PLAY_FALL
			end
			p.sams_screwattackcd = 1	
			check = true
		end
		if p.prescrewcolor
			s.color = p.prescrewcolor
			s.colorized = false
			check = true
		end
	end
	return check
end)

rawset(_G, "SetSamusColor", function(s, p) 
	if not s 
	or not YouAreSamus(s)
	or not p
	or (p.sam_screwattacking and p.prescrewcolor)
	return false --Cancel in these cases
	end
	
	if not s.color --Always have SOME color assigned!
	s.color = SKINCOLOR_GREEN
	end
	if not p.skincolor
	p.skincolor = SKINCOLOR_GREEN
	end
	
	if G_GametypeHasTeams() --Assign team colors 
		if p.ctfteam == 2
		s.color = SKINCOLOR_BLUE
		p.skincolor = SKINCOLOR_BLUE
		elseif p.ctfteam == 1
		s.color = SKINCOLOR_RED
		p.skincolor = SKINCOLOR_RED		
		end
		return true
	else --Asign Suit Colors if you have them!
		if not p.sam_gravitysuit
				if p.customsuitc1
					if s.color != p.customsuitc1
					s.color = p.customsuitc1
					end
					if not (p.customsuitc1 >= SKINCOLOR_SUPERSILVER1)
					or ((p.customsuitc1 >= SKINCOLOR_POWERSUIT) and (p.customsuitc1 <= SKINCOLOR_PLASMABURNED))
					p.skincolor = p.customsuitc1
					return true
					end
				end
		elseif (p.sam_gravitysuit == 1)
				if p.customsuitc2
					if s.color != p.customsuitc2
					s.color = p.customsuitc2
					end
					if not (p.customsuitc2 >= SKINCOLOR_SUPERSILVER1)
					or ((p.customsuitc2 >= SKINCOLOR_POWERSUIT) and (p.customsuitc2 <= SKINCOLOR_PLASMABURNED))
					p.skincolor = p.customsuitc2
					return true
					end
				end				
		elseif (p.sam_gravitysuit >= 2)
				if p.customsuitc3
					if s.color != p.customsuitc3
					s.color = p.customsuitc3
					end
					if not (p.customsuitc3 >= SKINCOLOR_SUPERSILVER1)
					or ((p.customsuitc3 >= SKINCOLOR_POWERSUIT) and (p.customsuitc3 <= SKINCOLOR_PLASMABURNED))
					p.skincolor = p.customsuitc3
					return true
					end
				end			
		end
	end
end)


--Sets up Samus' tutorial thinker! Adds things to a list, then executes.
rawset(_G, "SamusTutorial", function(s, item, stopit) 
 --Probably annoying, but that's why we have an "off" option.
	if s.player.nosamustutorials
	or s.player.samustutorialsdone
	return false
	end
	if not s.player.samustutorial
		local samustutorial = {
		active = false,
		noscale = nil,
		dontrender = 0,
		textflags = 0,
		animtimer = 0,
		goodbyedialogue = 0,
		textboxscale = 356,
		textboxtrns = V_90TRANS,
		textboxtrns2 = V_90TRANS,
		textboxflash = V_90TRANS,
		animendtimer = nil,
		beams = false,
		beamscomplete = false,
		missiles = false,
		missilescomplete = false,
		supermissiles = false,
		supermissilescomplete = false,
		beamcombo = false,
		beamcombocomplete = false,
		gravitysuit1 = false,
		gravitysuit1complete = false,
		gravitysuit2 = false,
		gravitysuit2complete = false,
		scanvisor = false,
		scanvisorcomplete = false,
		hyperbeam = false,
		hyperbeamcomplete = false,
		screwattack = false,
		screwattackcomplete = false,
		bombs = false,
		bombscomplete = false,
		pw = false,
		pwcomplete = false,
		spiderball = false,
		spiderballcomplete = false,
		lockon = false,
		lockoncomplete = false,
		chargebeam = false,
		chargebeamcomplete = false,
		monitorhunt = false,
		monitorhuntcomplete = false
		}	
	s.player.samustutorial = samustutorial	
	end	
	local t = s.player.samustutorial
local gotathing	= false
	--Add which to the list?
		if item == "lockon"
			if stopit
				if t.lockon
					t.lockon = false
					t.lockoncomplete = true
					EndSamusTutorial(t,s)
				else
				return
				end
			else
				if not t.lockon and not t.lockoncomplete
				t.lockon = true gotathing = true
				end
			end		
		elseif item == "beams"
			if stopit
				if t.beams
					t.beams = false
					t.beamscomplete = true
					EndSamusTutorial(t,s)
				else
				return
				end
			else
				if not t.beams and not t.beamscomplete
				t.beams = true gotathing = true
				end
			end
		elseif item == "monitorhunt"
			if stopit
				if t.monitorhunt
					t.monitorhunt = false
					t.monitorhuntcomplete = true
					EndSamusTutorial(t,s)
				else
				return
				end
			else
				if not t.monitorhunt and not t.monitorhuntcomplete
				t.monitorhunt = true gotathing = true
				end
			end					
		elseif item == "chargebeam"
			if stopit
				if t.chargebeam
					t.chargebeam = false
					t.chargebeamcomplete = true
					EndSamusTutorial(t,s)
				else
				return
				end
			else
				if not t.chargebeam and not t.chargebeamcomplete
				t.chargebeam = true gotathing = true
				end
			end			
		elseif item == "missiles"
			if stopit
				if t.missiles
					if not t.beams
					t.missiles = false
					t.missilescomplete = true
					EndSamusTutorial(t, s)
					end
				return
				end
			elseif not t.missiles and not t.missilescomplete
				t.missiles = true gotathing = true
			end
		elseif item == "supermissiles"
			if stopit
				if t.supermissiles
					if not (t.beams or t.missiles)
					t.supermissiles = false
					t.supermissilescomplete = true
					EndSamusTutorial(t, s)
					end
				return
				end
			elseif not t.supermissiles and not t.supermissilescomplete
				t.supermissiles = true gotathing = true
			end
		elseif item == "beamcombo"
			if stopit
				if t.beamcombo
					if not (t.missiles or t.beams or t.supermissiles)
					t.beamcombo = false
					t.beamcombocomplete = true
					EndSamusTutorial(t,s)
					end
					return
				end
			elseif not t.beamcombo and not t.beamcombocomplete
				t.beamcombo = true gotathing = true
			end
		elseif item == "variasuit" --Secretly Speedbooster and Swap Weapons because I changed my mind.
			if stopit
				if t.gravitysuit1
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo)
					t.gravitysuit1 = false
					t.gravitysuit1complete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.gravitysuit1 and not t.gravitysuit1complete
				t.gravitysuit1 = true gotathing = true
			end
		elseif item == "gravitysuit"
			if stopit
				if t.gravitysuit2 
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1)
					t.gravitysuit2 = false
					t.gravitysuit2complete = true	
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.gravitysuit2 and not t.gravitysuit2complete
				t.gravitysuit2 = true gotathing = true
			end
		elseif item == "scanvisor"
			if stopit
				if t.scanvisor 
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2)
					t.scanvisor = false
					t.scanvisorcomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.scanvisor and not t.scanvisorcomplete
				t.scanvisor = true gotathing = true
			end
		elseif item == "screwattack"
			if stopit
				if t.screwattack 
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2 or t.scanvisor)
					t.screwattack = false
					t.screwattackcomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.screwattack and not t.screwattackcomplete
				t.screwattack = true gotathing = true
			end
		elseif item == "bombs"
			if stopit
				if t.bombs
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2 or t.scanvisor or t.screwattack)			
					t.bombs = false
					t.bombscomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.bombs and not t.bombscomplete
				t.bombs = true gotathing = true
			end
		elseif item == "pw"
			if stopit
				if t.pw 
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2 or t.scanvisor
					or t.screwattack or t.bombs)
					t.pw = false
					t.pwcomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.pwcomplete and not t.pw
				t.pw = true gotathing = true
			end
		elseif item == "spiderball"
			if stopit
				if t.spiderball
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2 or t.scanvisor
					or t.screwattack or t.bombs or t.pw)
					t.spiderball = false
					t.spiderballcomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.spiderball and not t.spiderballcomplete
				t.spiderball = true gotathing = true
			end
		elseif item == "hyperbeam"
			if stopit
				if t.hyperbeam
					if not (t.missiles or t.beams or t.supermissiles or t.beamcombo or t.gravitysuit1 or t.gravitysuit2 or t.scanvisor
					or t.screwattack or t.bombs or t.pw or t.spiderball)
				
--There was probably a more efficient way to go about this, but unfortunately I won't hear about it until AFTER the project's out.	
			
					t.hyperbeam = false
					t.hyperbeamcomplete = true
					EndSamusTutorial(t,s)
					end
				return
				end
			elseif not t.hyperbeamcomplete and not t.hyperbeam
				t.hyperbeam = true gotathing = true
			end
		end				
	if stopit
	return
	end
	if gotathing and not (t.textboxscale >= FRACUNIT)
		t.textboxtrns2 = V_90TRANS
		
		if t.goodbyedialogue
		t.goodbyedialogue = 0
		t.textboxscale = 356
		t.textboxtrns = V_90TRANS		
		end
		if t.noscale --Don't do the animation again.
		t.animtimer = 18
		t.textboxflash = V_90TRANS --Overlay a flash.
		t.noscale = nil
		else
		t.textboxscale = 356
		t.textboxtrns = V_90TRANS
		end
		t.active = true
	end
end)

rawset(_G, "SpaceJumpGFX", function(s, color, tscale, frame) 
	s.ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SAMCHARGEGFX)
	s.ghs.state = S_SAMCHARGEGFX4
	s.ghs.sprite = SPR_MPR9
	s.ghs.frame = frame
	s.ghs.tics = 12
	s.ghs.scale = s.scale/tscale
	s.ghs.destscale = $*5
	s.ghs.color = color
	s.ghs.ret2spring = true
	s.ghs.target = s
end)


--Opening Monitor behaviour
function A_SAMITEM(s, m, sonicstyle)
	if not (s.valid) or not (m and m.valid)
	return
	end
	if (gametype == GT_COMPETITION) and (m.flags & MF_MONITOR) and m.health
		if s.target and s.target.player and s.target.player.numboxes != nil
		s.target.player.numboxes = $+1
		end
	end
	if m.holdon
		m.samgotme = 0
		m.samgotmehost = false
		m.health = 1
	return
	elseif ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX)) or ((m.flags & MF_MONITOR) and (mobjinfo[m.type].doomednum == 4064) or (mobjinfo[m.type].doomednum == 429))
		if s.target and s.target.player
		P_KillMobj(m, s, s.target)
			if not ((s.type == MT_WVCHARGESHOT) and s.bufferguard) and not (s.type == MT_PLSHOT) and not (s.type == MT_PLCHARGESHOT)
			P_ExplodeMissile(s)
			end
		end
	elseif G_GametypeHasTeams() and ((m.type == MT_RING_REDBOX) or (m.type == MT_RING_BLUEBOX))		
		if s.target and s.target.player and m.health
		and ( ((s.target.player.ctfteam == 1) and (m.type == MT_RING_REDBOX))
		or ((s.target.player.ctfteam == 2) and (m.type == MT_RING_BLUEBOX)) )
			m.samspawnitem = P_SpawnMobj(m.x, m.y, m.z, MT_SAMSPAWNITEM) 
			m.samspawnitem.chozobox = m m.samspawnitem.eflags = m.eflags m.samspawnitem.flags2 = m.flags2
			m.flags = $1|MF_NOCLIP & ~MF_SHOOTABLE & ~MF_SOLID m.flags2 = $1|MF2_DONTDRAW
			if not ((s.type == MT_WVCHARGESHOT) and s.bufferguard)
			and not (s.type == MT_PLSHOT) and not (s.type == MT_PLCHARGESHOT)
				P_ExplodeMissile(s)
			end
		end
	else
	   if m.health and s.target and s.target.player
	   and ( G_GametypeHasSpectators() or not
	   (m.samgotme != nil and not (players[0] and s.target.player == players[0]) and (s.target.player.samusnum and (m.samgotme & (s.target.player.samusnum)) or m.samgotme == s.target.player.samusnum) )
	   and not (players[0] and s.target.player == players[0] and m.samgotmehost) and not (mobjinfo[m.type].doomednum == 429) )
		m.samspawnitem = P_SpawnMobj(m.x, m.y, m.z, MT_SAMSPAWNITEM)
		m.samspawnitem.chozobox = m
		SamusTutorial(s.target, "monitorhunt", true)
			if s.target and s.target.player
				if (gametype == GT_COOP) and (s.target.player.samusnum != nil) and s.target.player.samusnumdecided 
				and (s.target.player.coopboxrespawn and (s.target.player.coopboxrespawn > 1))
					if m.samgotme == nil
					m.samgotme = 0
					end
					if players[0] and s.target.player == players[0]
					m.samgotmehost = true
					end
				m.samgotme = $|s.target.player.samusnum
				end
			m.samspawnitem.tracer = s.target
			end
			if s.player
				m.samspawnitem.tracer = s
			end		
		m.samspawnitem.eflags = m.eflags
		m.samspawnitem.flags2 = m.flags2
			if ((m.type >= MT_PITY_GOLDBOX) and (m.type <= MT_THUNDERCOIN_GOLDBOX)) and not (m.type == MT_GRAVITY_GOLDBOX) 
			m.samspawnitem.goldlaststate = m.state
			m.state = S_THOK
			m.tics = -1
			end
		m.flags = $1|MF_NOCLIP & ~MF_SHOOTABLE & ~MF_SOLID
		m.flags2 = $1|MF2_DONTDRAW
		
		
			--Open Box effect
			local brng = P_RandomRange(1,360)
			S_StartSound(m, sfx_cdfm50)
			
			for d = 1,3
				local debris = P_SpawnMobjFromMobj(m, d,d,d, MT_THOK)
					debris.sprite = SPR_MXP4
					debris.tics = 10
					debris.color = m.color
					
					if players[0] and players[0].metroidvisuals
					or players[1] and players[1].metroidvisuals
					or (gametype == GT_HUNTERS)					
						debris.frame = T
					else
						debris.frame = U
					end
					
					debris.rollangle = brng+((ANG1*69)*d)+ANGLE_45
					debris.flags = MF_BOUNCE|MF_GRENADEBOUNCE|MF_NOCLIPTHING
					debris.flags2 = $ & ~MF2_DONTDRAW
					P_InstaThrust(debris, brng+((ANG1*110)*d), 8*m.scale+(2*d*FRACUNIT))
					P_SetObjectMomZ(debris, (4*FRACUNIT)+(2*d*FRACUNIT))
					
					if s.momx
						debris.momx = $+(s.momx/20)
					end
					if s.momy
						debris.momy = $+(s.momy/20)
					end
			end
			
			if not ((s.type == MT_WVCHARGESHOT) and s.bufferguard)
			and not (s.type == MT_PLSHOT) and not (s.type == MT_PLCHARGESHOT)
			P_ExplodeMissile(s)
			end
			
	   else
			if not (m.gotmonalready and m.gotmonalready.valid)
				S_StartSound(m, sfx_bedeen)
				m.ghs = P_SpawnGhostMobj(m)
				m.ghs.destscale = m.scale*10 
				m.ghs.tics = 30
				m.gotmonalready = P_SpawnMobj(m.x, m.y,m.z, MT_FAKESAMUSTHOK)
				m.gotmonalready.scale = m.scale*5/6
				m.gotmonalready.eflags = m.eflags
				m.gotmonalready.state = S_ZAPS1
				m.gotmonalready.fuse = 18
			else
				m.gotmonalready.fuse  = 18
			end			
	   end
	end
end

/*
--Local RNG function that won't cause desyncing. Based on Alfredo's code.
--NEVER use this for anything that needs to be synced!
local samrandomseed = 3135128580
rawset(_G, "SamLocalRNG", function(a, b, s, p) 
if not (s.player and (SAM_displayplayer(s.player))
return
end
	samrandomseed = $*(max(gamemap+leveltime, 1)%128)
	samrandomseed = $-(s.x+s.y+s.z)
		
	if samrandomseed == 0 --Ignore division warning.
		samrandomseed = 3126124580
	end
			
	yurandomseed = $/2
	local dumb = ((samrandomseed*36548569) >> 4) & (FRACUNIT-1)	
	return ((dumb * (b-a+1)) >> FRACBITS) + a
end */

function A_SAMPARTICLE(s, object, coord, momentum, minuszmomentum, zmomentum, color, scale, spazer, customtarget)
//	if s and object and coord and momentum and zmomentum and color
		s.sparker = P_SpawnMobj(s.x+((P_RandomRange(-coord, coord))*FRACUNIT), s.y+((P_RandomRange(-coord, coord))*FRACUNIT), s.z+((P_RandomRange(0, s.height/FRACUNIT))*FRACUNIT), object)
		s.sparker.color = color
		s.sparker.blendmode = AST_ADD
		if ((s.type == MT_WVCHARGESHOT) and s.target and s.target.player)
		s.sparker.target = s.target
		s.sparker.charged = true
		s.sparker.wavenope = true
		else
		s.sparker.target = s
		end
		s.sparker.momx = (P_RandomRange(-momentum, momentum))*FRACUNIT
		s.sparker.momy = (P_RandomRange(-momentum, momentum))*FRACUNIT
		s.sparker.momz = (P_RandomRange(minuszmomentum, zmomentum))*FRACUNIT	
		if scale
		s.sparker.scale = scale
		else
		s.sparker.scale = s.scale
		end
		if spazer
			if (spazer == "ice")
			s.sparker.flags = $1|MF_BOUNCE|MF_GRENADEBOUNCE|MF_NOCLIPHEIGHT
			s.sparker.combograce = 6
			s.sparker.icesummon = s
			elseif (s.type == MT_PLSHOT) and s.target
			s.sparker.target = s.target
			s.sparker.morning = 60
			else
			s.sparker.spazersummon = true
			end
		end
		if customtarget
		s.sparker.target = customtarget
		end
		return (s.sparker)	
end

rawset(_G, "ExplodePush", function(p, m, var3) --Normally explosions don't use this system...
	if (m.samusHP and m.samusHP > 6) --But I want to slightly nerf missiles, powerbeam chargeshots and bombs
		if not (m.type == MT_METROIDPART) and not (m.type == MT_PZBOSS)
			for d = 1,5 --to encourage players to use more varied weaponry. 
				if P_RandomRange(0,1) 
				m.moseyflash = P_SpawnMobj(m.x, m.y, m.z+m.height/2, MT_SONIC3KBOSSEXPLODE)
				S_StartSound(m, sfx_cybdth)
				else
				S_StartSound(m, sfx_dmpain)
				m.moseyflash = P_SpawnMobj(m.x, m.y, m.z+m.height/2, MT_SMOKE)
				end
				m.moseyflash.scale = m.scale
				m.moseyflash.eflags = m.eflags
				m.moseyflash.destscale = m.scale*3
				m.moseyflash.momx = (P_RandomRange(-8, 8)*m.scale)
				m.moseyflash.momy = (P_RandomRange(-8, 8)*m.scale)
				P_SetObjectMomZ(m.moseyflash, (P_RandomRange(1, 3)*FRACUNIT))
			end
			m.moseyflash = P_SpawnMobj(m.x, m.y, m.z, MT_SMONTRACKER)
			m.moseyflash.target = m
			m.moseyflash.flashingt = 18
		elseif m.omega and m.omega.valid
			m.omega.painfyellow = 9
		else
			m.painfyellow = 14
		end
		if (m.type == MT_METROIDPART and (m.samusHP > 5) and p.type == MT_SAMMISSILE)
		m.samusHP = 5
		else
		m.samusHP = $-6
		end
		if not NoPushList(m)
			P_Thrust(m, R_PointToAngle2(m.x, m.y, p.x, p.y), -13*FRACUNIT)
		end
		if not m.target and (m.flags & MF_ENEMY)
			if p.target and p.target.valid and p.target.health and not (m.type == MT_GFZFISH)
			m.angle =  R_PointToAngle2(m.x, m.y, p.target.x, p.target.y)
			end
		end
	else
		P_DamageMobj(m, p, var3, 1)
	end
end)
rawset(_G, "GiveSamusEnergy", function(p, amount, flash) 
	p.sam_energy = $+amount --Any overflowing energy goes to the hyperbeam
	if flash
		p.sam_energyflash = flash --How long your bar flashes. Generally 1 or 2 tics.
	end
end)

addHook("MobjThinker", function(s)
	if s and s.chozobox or s.ammospawner
		    if s.ammospawner
		    s.tics = $+1
			if s.currentammotimer and not (s.currentammo and s.currentammo.valid)
				if s.currentammotimer and not (s.currentammo and s.currentammo.valid)
				s.currentammotimer = $-1
				elseif not (s.currentammo and s.currentammo.valid)
				s.currentammotimer = 750
				end
		    	elseif not (s.currentammo and s.currentammo.valid) and not s.currentammotimer
				if (s.ammospawner < 12)
				s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_NRGA)
				elseif (s.ammospawner < 34)
				s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_NRGB)
				elseif (s.ammospawner < 48)
				s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_MPKU)
				elseif (s.ammospawner < 78)
				s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_BMPKU)
				elseif (s.ammospawner <= 95)
					if players[0] and players[0].nosuperpowert
					or players[1] and players[1].nosuperpowert
					s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_MPKU)
					else
					s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_SPKU)
					end
				elseif (s.ammospawner > 95)
					if players[0] and players[0].nosuperpowert
					or players[1] and players[1].nosuperpowert
					s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_BMPKU)
					else
					s.currentammo = P_SpawnMobj(s.x, s.y, s.z+((16*FRACUNIT)*(P_MobjFlip(s))),  MT_PBOM)
					end
				end
				if s.currentammo and s.currentammo.valid
				s.currentammo.dontsuckme = true
				end
				s.currentammotimer = 750
			end
		    return
		    end
		local m = s.chozobox
		local samusrng = P_RandomRange(1, 100)
		local item = nil
 		if (s.state == S_SAMSPAWNITEM1)

			if (m.type == MT_SNEAKERS_BOX)
				if (samusrng < 7)
					if s.tracer and s.tracer.player 
						if not s.tracer.player.sam_bombs
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
						elseif s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 10)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.sam_spiderball
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
						elseif not s.tracer.player.sam_power_grip
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PWGRP)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					end
				elseif (samusrng < 8)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
				elseif (samusrng < 26)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBL)
				elseif (samusrng < 64)
					if s.tracer and s.tracer.player
						if not s.tracer.player.samspbs
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_BSBL)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
					end
				elseif (samusrng < 95)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sambsbl
						item = P_SpawnMobj(m.x, m.y, m.z, MT_BSBL)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_BSBL)
					end
				else
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
				end

			elseif (m.type == MT_INVULN_BOX)
				if (samusrng < 28)
					if s.tracer and s.tracer.player
						if not (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 20))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.samsupermissilesmax
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
					end
				elseif (samusrng < 50)
					if G_GametypeHasSpectators()
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
					else
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							elseif not s.tracer.player.sam_spiderball
							item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
							elseif (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 77)) and not s.tracer.player.sampwmax
							item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
							elseif s.tracer.player.sam_energy and (s.tracer.player.sam_energy >= 85+(s.tracer.player.sam_energytanksmax*50))
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
						end
					end
				elseif (samusrng < 60)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sammissilesmax
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.samsupermissilesmax
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						elseif not s.tracer.player.sam_highjump
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBL)
						elseif s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 145) and (s.tracer.player.sampwmax != nil and (s.tracer.player.sampwmax < 5))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
						else
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))),  MT_PBOM)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_PBOM)
					end
				elseif (samusrng < 69)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_chargebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
					end
				elseif (samusrng < 75)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_chargebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						elseif not s.tracer.player.sam_gravitysuit
						item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
						elseif not s.tracer.player.sam_gravitysuit == 1
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						elseif not s.tracer.player.sam_power_grip
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PWGRP)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
					end
				elseif (samusrng < 96)
					if s.tracer and s.tracer.player and not s.tracer.player.sammissilesmax and (gametype == GT_COOP)
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
					end
				else
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBL)
				end

			elseif (m.type == MT_ARMAGEDDON_BOX)
				if (samusrng < 9)
					if not s.tracer and s.tracer.player and s.tracer.player.sam_chargebeam
					item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
					end
				elseif (samusrng < 18)
					if s.tracer and s.tracer.player				
						if not s.tracer.player.sam_bombs
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
						elseif not (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 10))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 115) and not s.tracer.player.sam_screwattack
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					end
				elseif (samusrng == 18)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
				elseif (samusrng < 54)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_bombs
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
						elseif not (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 10))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.sam_chargebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						elseif (gametype == GT_COOP) and not s.tracer.player.sam_spazerbeam 
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
						elseif (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 88)) and not s.tracer.player.sam_plasmabeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)					
						elseif s.tracer.player.sam_plasmabeam and not s.tracer.player.sam_plasmabeamcombo
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
						elseif (samusrng < 40) and s.tracer.player.samsupermissilesmax and (s.tracer.player.samsupermissilesmax > 9) and s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 120)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
					end
				elseif (samusrng < 94)
					if s.tracer and s.tracer.player and (samusrng < 84)
						if not s.tracer.player.sam_chargebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						elseif (gametype == GT_COOP) and not s.tracer.player.sam_spazerbeam 
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
						end
					else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
					end
				else
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
				end

			elseif (m.type == MT_WHIRLWIND_BOX) or (m.type == MT_FLAMEAURA_BOX)
				if (samusrng < 11)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
				elseif (samusrng < 14)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_spiderball
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
						elseif not (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 15))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)						
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
					end
				elseif (samusrng < 28)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
				elseif (samusrng < 83)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_icebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ICBM)
						elseif not s.tracer.player.sam_spacejump
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
						elseif not s.tracer.player.sam_icebeamcombo
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ICBM)
						elseif not s.tracer.player.sam_power_grip
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PWGRP)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ICBM)
					end
				else
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBL)
				end

			elseif (m.type == MT_PITY_BOX)
				if (samusrng < 10)
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ICBM)
				elseif (samusrng < 20)
					item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
				elseif (samusrng < 41)
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							elseif s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
							elseif not s.tracer.player.sam_power_grip
							item = P_SpawnMobj(m.x, m.y, m.z, MT_PWGRP)							
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
					end
				elseif (samusrng < 53)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_powerbeamcombo
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
						end
					else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
					end
				elseif (samusrng < 70)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
				elseif (samusrng < 87)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
				elseif (samusrng < 91)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
				else
				item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
				end

			elseif (m.type == MT_FORCE_BOX)
				if (samusrng < 3)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_gravitysuit
						item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
					end
				elseif (samusrng < 25)
						if s.tracer and s.tracer.player
							if ((s.tracer.player.sammissilesmax) and (s.tracer.player.sammissilesmax < 10))
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							elseif not s.tracer.player.sam_powerbeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
							elseif ((s.tracer.player.sammissilesmax) and (s.tracer.player.sammissilesmax > 49)) and not s.tracer.player.sam_gravitysuit
							item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
							elseif not s.tracer.player.sam_power_grip
							item = P_SpawnMobj(m.x, m.y, m.z, MT_PWGRP)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
				elseif (samusrng < 34)
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_powerbeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
							elseif (s.tracer.player.samsupermissilesmax) and (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 15))
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							elseif (s.tracer.player.samsupermissilesmax and s.tracer.player.samsupermissilesmax > 5) and (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 30))
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						end
				elseif (samusrng < 47)
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if not s.tracer.player.sambsbl
							item = P_SpawnMobj(m.x, m.y, m.z, MT_BSBL)
							elseif s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
						end
					elseif s.tracer and s.tracer.player and not s.tracer.player.sambsbl
							item = P_SpawnMobj(m.x, m.y, m.z, MT_BSBL)
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
					end
				else
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							elseif ((s.tracer.player.sammissilesmax) and (s.tracer.player.sammissilesmax < 15))
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							elseif not s.tracer.player.samsupermissilesmax
							item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							end
						else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_chargebeam
							item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
							elseif not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						end
					end
				end

			elseif (m.type == MT_ATTRACT_BOX) or (m.type == MT_THUNDERCOIN_BOX)
				if (samusrng < 25)
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							elseif s.tracer.player.sam_wavebeam and not s.tracer.player.sam_wavebeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
							elseif not s.tracer.player.sam_powerbeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
							elseif (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 145) and s.tracer.player.samsupermissilesmax != nil and s.tracer.player.samsupermissilesmax < 6)
							item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
				elseif (samusrng < 28)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
				elseif (samusrng < 50)
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
						end
					elseif s.tracer and s.tracer.player and (s.tracer.player.sam_energy >= 99) and not s.tracer.player.samspbs
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
					end
				else
					if s.tracer and s.tracer.player
						if (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 15)) or not s.tracer.player.sammissilesmax
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.sam_wavebeamcombo and (samusrng > 61)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
						elseif not s.tracer.player.sam_spiderball and (samusrng < 62)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
						end
					elseif (samusrng < 62)
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
					end
				end

			elseif (m.type == MT_ELEMENTAL_BOX) or (m.type == MT_BUBBLEWRAP_BOX)
				if (samusrng < 12)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sam_gravitysuit
						item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
						elseif s.tracer.player.sam_gravitysuit and (s.tracer.player.sam_gravitysuit == 1)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						elseif not multiplayer
							if (samusrng < 4)
							item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
					end
				elseif (samusrng < 38)
					if s.tracer and s.tracer.player
						if s.tracer.player.sam_spazerbeam and not s.tracer.player.sam_spazerbeamcombo
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
						elseif (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 145) and s.tracer.player.samsupermissilesmax != nil and s.tracer.player.samsupermissilesmax < 10)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					end
				elseif (samusrng < 55)
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
						end
					else
						if s.tracer and s.tracer.player
							if (s.tracer.player.samsupermissilesmax and (s.tracer.player.samsupermissilesmax > 7)) and not s.tracer.player.sam_screwattack
							item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						end
					end
				elseif (samusrng < 59)
				item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
				else
					if s.tracer and s.tracer.player
						if s.tracer.player.sam_spazerbeam and (s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax < 25))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						elseif not s.tracer.player.sam_spazerbeamcombo
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
					end
				end

			elseif (m.type == MT_MIXUP_BOX)
				if s.tracer and s.tracer.player
					if s.tracer.player.nosuperpowert
					s.tracer.player.sammissilesmax = $+5
					s.tracer.player.sammissiles = $+5
					CONS_Printf(s.tracer.player, "You got just a missile tank! It's a good day to go on strike!")
					else
					s.tracer.player.sammissilesmax = $+5
					s.tracer.player.sammissiles = $+5
					s.tracer.player.samsupermissilesmax = $+2
					s.tracer.player.samsupermissiles = $+2
					s.tracer.player.sampwmax = $+1
					s.tracer.player.sampw = $+1
					CONS_Printf(s.tracer.player, "You got one of each ammo tank! It's a good day to be a Bounty Hunter.")
					end
					P_SamFP(s.tracer.player, PAL_MIXUP, 10)
					s.tracer.player.samitemgettimer = 86
					s.tracer.player.samitemcolor = SKINCOLOR_PINK
					s.tracer.player.samitemgetname = "Super Ammo Tank"
					s.tracer.player.samitemscale = 105000
					S_StartSound(s.tracer, sfx_spwup)
				end

			elseif (m.type == MT_1UP_BOX)
				if s.tracer and s.tracer.player and s.tracer.player.sam_energytanksmax 
					if (s.tracer.player.sam_energytanksmax >= 12)
						if mapheaderinfo[gamemap].lvlttl and (mapheaderinfo[gamemap].lvlttl == "Black Core")
						and s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 96)
						and (s.tracer.player.sam_energytanksmax < 12)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK) --The final energy tank, at the last moment!
						elseif (samusrng > 83) 
						and (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 90) and s.tracer.player.samsupermissilesmax != nil and s.tracer.player.samsupermissilesmax < 10)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						elseif (samusrng > 82)  
						and (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 89) and s.tracer.player.sampwmax != nil and s.tracer.player.sampwmax < 5)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
						elseif (samusrng > 76)  
						and (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 94) and not s.tracer.player.sam_screwattack)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SATK)
						elseif (samusrng > 74)  
						and (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 93) and not (s.tracer.player.sam_gravitysuit and s.tracer.player.sam_gravitysuit >= 2))
						item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
						elseif (samusrng > 60)  
						and (s.tracer.player.sams_itemcompletion and (s.tracer.player.sams_itemcompletion > 90))
						and (s.tracer.player.sam_powerbeamcombo != true or s.tracer.player.sam_spazerbeamcombo != true or s.tracer.player.sam_wavebeamcombo != true
						or s.tracer.player.sam_icebeamcombo != true or s.tracer.player.sam_plasmabeamcombo != true)
							if not s.tracer.player.sam_powerbeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
							elseif not s.tracer.player.sam_spazerbeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
							elseif not s.tracer.player.sam_wavebeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_WVBM)
							elseif not s.tracer.player.sam_icebeamcombo
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ICBM)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_PLBM)
							end
						elseif (samusrng < 60)
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
						else
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
						end
					elseif (s.tracer.player.sam_energytanksmax < 7) and (samusrng > (s.tracer.player.sam_energytanksmax*10))
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
					elseif (s.tracer.player.sam_energytanksmax > 6) and (samusrng > (s.tracer.player.sam_energytanksmax*8))
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
					elseif (samusrng < 25)
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGA)
					elseif (samusrng < 58)
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
					end
				else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)		
				end

				for nya in mobjs.iterate(mobj)
					if (nya.type == MT_OVERLAY) and nya.target and (nya.target == m)
						if (FixedHypot(m.x-nya.x, m.y-nya.y) < 32355)
						nya.flags2 = $1|MF2_DONTDRAW
						m.lifeiconvanished = nya
						end
					end
				end
				if item
				m.samspawneditem = item
				end
			elseif not (((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX)) or ((m.type == MT_GRAVITY_GOLDBOX) or (m.type == MT_GRAVITY_BOX))) //Regular boxes
				if (samusrng < 5)
					if (samusrng == 1) and (gametype == GT_COOP) and s.tracer and s.tracer.player 
					and s.tracer.player.samsupermissilesmax and (s.tracer.player.samsupermissilesmax > 9) and s.tracer.player.sampwmax != nil and (s.tracer.player.sampwmax < 5)
						item = P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
					elseif (samusrng < 3) and s.tracer and s.tracer.player
						if s.tracer.player.sam_bombs and not s.tracer.player.samspbs
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
						elseif s.tracer.player.sam_bombs and not s.tracer.player.sam_spiderball
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPDRBL)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
					end
				elseif (samusrng < 34)
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_bombs
							item = P_SpawnMobj(m.x, m.y, m.z, MT_MHBM)
							elseif s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
							elseif G_GametypeHasSpectators() and s.tracer.player.sammissilesmax != nil and (s.tracer.player.sammissilesmax < 15)
								item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
							else

								if s.tracer.player.sammissilesmax and (s.tracer.player.sammissilesmax > 50)
								and not s.tracer.player.samsupermissilesmax
								item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
								elseif (samusrng < 28) and not s.tracer.player.buffbottomtier
								item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_MPKU)
								else
								item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_BMPKU)
								end
							end
						elseif (samusrng < 28)
							if s.tracer and s.tracer.player and s.tracer.player.buffbottomtier
								if (samusrng < 30) and not s.tracer.player.sam_autotank --Stop making me take pity and pay attention!
								item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_AUTOTANK)
								elseif not (s.tracer.player.sam_ammodigitizer and (s.tracer.player.sam_ammodigitizer >= 2))
								item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_AMMODIGITIZER)
								else
								P_SpawnMobj(m.x, m.y, m.z+(m.height*(P_MobjFlip(m))), MT_MTNK) --If I ever hear about the funny stacked missile tanks 
								item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK) --...that person screwed up hard.
								end
							else
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_MPKU)
							end
						else
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_BMPKU)
						end
				elseif (samusrng < 37)
					if G_GametypeHasSpectators()
						if s.tracer and s.tracer.player
							if s.tracer.player.sam_hyperbeam
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
							elseif not s.tracer.player.sam_gravitysuit
							item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
							elseif s.tracer.player.buffbottomtier and s.tracer.player.sam_gravitysuit and (s.tracer.player.sam_gravitysuit == 1)
							item = P_SpawnMobj(m.x, m.y, m.z, MT_GVST)
							else
							item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_ENGTNK)
						end
					else
						if s.tracer and s.tracer.player
							if not s.tracer.player.sam_gravitysuit
							item = P_SpawnMobj(m.x, m.y, m.z, MT_VRST)
							else
							P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGA)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGA)
						end
					end
				elseif (samusrng < 63)
					if s.tracer and s.tracer.player and not s.tracer.player.sammissilesmax
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					elseif (samusrng < 49) and s.tracer and s.tracer.player and s.tracer.player.buffbottomtier
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_ENGTNK)
					elseif (samusrng < 43) or G_GametypeHasSpectators()
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGD)
					elseif (samusrng < 56)
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGB)
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height)*(P_MobjFlip(m))), MT_NRGA)
					end
				elseif (samusrng < 81)
					if s.tracer and s.tracer.player.buffbottomtier and s.tracer.player.samsupermissilesmax and not s.tracer.player.sampwmax
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_PTNK)
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_SPKU)
					end
				elseif (samusrng < 85)
					if s.tracer and s.tracer.player
						if not s.tracer.player.sampwmax
							if not s.tracer.player.samsupermissilesmax or s.tracer.player.buffbottomtier
							item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
							else
							item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_SPKU)
							end
						else
						item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_PBOM)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z+((m.height/2)*(P_MobjFlip(m))), MT_PBOM)
					end
				elseif (samusrng < 99)
					if s.tracer and s.tracer.player and s.tracer.player.buffbottomtier
						if not s.tracer.player.samsupermissilesmax or (s.tracer.player.samsupermissilesmax and (s.tracer.player.samsupermissilesmax < 4))
						P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						elseif not s.tracer.player.sampwmax
						P_SpawnMobj(m.x, m.y, m.z, MT_PTNK)
						else
						P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_MTNK)
					end
				else
					if s.tracer and s.tracer.player
						if not s.tracer.player.samsupermissilesmax
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						elseif not s.tracer.player.sam_chargebeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_CHBM)
						elseif not s.tracer.player.sam_spacejump
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SJMP)
						elseif not s.tracer.player.sam_spazerbeam
						item = P_SpawnMobj(m.x, m.y, m.z, MT_SPBM)
						elseif not s.tracer.player.samspbs
						P_SpawnMobj(m.x, m.y, m.z, MT_SPBS)
						elseif not s.tracer.player.sam_highjump
						P_SpawnMobj(m.x, m.y, m.z, MT_SPBL)
						else
						item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
						end
					else
					item = P_SpawnMobj(m.x, m.y, m.z, MT_STNK)
					end
				end
			end
			if (item and item.valid) --So did we get one?
				m.samspawneditem = item	
			end
 	 	end
 		if (s.state == S_SAMSPAWNITEM2) //Flip the item if it's supposed to be flipped.
			if not s.poyo
				if not players[0] or (players[0].sam_respawnboxer == nil or players[0].sam_respawnboxer >= 30) --Default spawn time
				local respawntime = 1050
					for d = 0,31
						if players[d] and players[d].valid
							if (d > 20)
							respawntime = $-P_RandomRange(10,30)
							else
							respawntime = $-P_RandomRange(40,70)
							end
						end
					end
					if (respawntime < 140)
					respawntime = 140 --Never go below 4 seconds.
					end
					s.tics = respawntime --Our final respawntime.

				elseif players[0] and players[0].sam_respawnboxer --Custom spawn time?
					s.tics = ((players[0].sam_respawnboxer)*35)
				else
					s.tics = 999 --Failsafe
				end
				s.poyo = true
			end
			if item and m and m.valid
			m.samspawneditem = item
				if m.samspawneditem and m.samspawneditem.valid and not s.monitorflippedyet
					if ((m.flags2 & MF2_OBJECTFLIP) or (m.eflags & MFE_VERTICALFLIP))
					m.samspawneditem.flags2 = $|MF2_OBJECTFLIP
					m.samspawneditem.eflags = $|MFE_VERTICALFLIP
					end
					s.monitorflippedyet = true
				end
			end
			if (gametype == GT_COOP)
				if players[0] and players[0].coopboxrespawn and (players[0].coopboxrespawn > 1) --Get it ready to respawn for others if you're in coop.
				or players[1] and players[1].coopboxrespawn and (players[1].coopboxrespawn > 1)
					if not (m.samspawneditem and m.samspawneditem.valid) and (s.tics > 20) --Does your spawned item no longer exist? Respawn monitor! 
					s.tics = 20
					end
				elseif (players[0] and not players[0].coopboxrespawn) or (players[1] and not players[1].coopboxrespawn) --In single player, remove monitor
					if s and s.valid
					s.state = S_NULL
					return
					end
				end
			end
		end
 		if (s.state == S_SAMSPAWNITEM3)
		 	if G_GametypeHasSpectators() and not ( (players[0] and players[0].sammatchmonitors) or (players[1] and players[1].sammatchmonitors) )
		 	and not ( m and m.valid and ((m.type == MT_RING_REDBOX) or (m.type == MT_RING_BLUEBOX)))
				if m and m.valid and not ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX))
				local boxrespawn = P_RandomRange(1, 120)
					if (boxrespawn < 60)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_RING_BOX)
					elseif (boxrespawn < 64)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_PITY_BOX)
					 	if m.respawnedbx and m.respawnedbx.valid
						m.respawnedbx.triedspawn = true
						end
					elseif (boxrespawn < 73)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_FORCE_BOX) 	
					elseif (boxrespawn < 81)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_WHIRLWIND_BOX)
					elseif (boxrespawn < 88)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ELEMENTAL_BOX)
					elseif (boxrespawn < 94)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ATTRACT_BOX )
					elseif (boxrespawn < 100)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ARMAGEDDON_BOX)
					elseif (boxrespawn < 102)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_INVULN_BOX)
					elseif (boxrespawn < 118)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_SNEAKERS_BOX)
					elseif (boxrespawn < 119) and (leveltime > 10)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_MIXUP_BOX)
					else
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_RECYCLER_BOX)
					end
 					if m and m.respawnedbx and ((m.eflags & MFE_VERTICALFLIP) or (m.flags2 & MF2_OBJECTFLIP))
 					m.respawnedbx.flags2 = m.flags2 & ~MF2_DONTDRAW
 					end
					if players[0] and players[0].metroidvisuals or players[1] and players[1].metroidvisuals
					or (gametype == GT_HUNTERS)
						if m.respawnedbx and m.respawnedbx.valid and m.respawnedbx.flags != nil
						and (m.respawnedbx.flags & MF_MONITOR) and not (m.respawnedbx.type == MT_1UP_BOX)
						and not (((m.respawnedbx.type >= MT_PITY_GOLDBOX) and (m.respawnedbx.type <= MT_THUNDERCOIN_GOLDBOX)) and not (m.respawnedbx.type == MT_EGGMAN_GOLDBOX))
						m.respawnedbx.state = S_METBOX1
						m.respawnedbx.metroidvisual = true
							if m.respawnedbx.type == MT_FORCE_BOX
							m.respawnedbx.color =SKINCOLOR_BLUE
							elseif m.respawnedbx.type == MT_ARMAGEDDON_BOX
							m.respawnedbx.color =SKINCOLOR_RED
							elseif m.respawnedbx.type == MT_ELEMENTAL_BOX
							m.respawnedbx.color =SKINCOLOR_EMERALD
							elseif m.respawnedbx.type == MT_FLAMEAURA_GOLDBOX 
							m.respawnedbx.color =SKINCOLOR_FLAME
							elseif m.respawnedbx.type == MT_BUBBLEWRAP_GOLDBOX 
							m.respawnedbx.color =SKINCOLOR_AQUA
							elseif m.respawnedbx.type == MT_THUNDERCOIN_GOLDBOX 
							m.respawnedbx.color =SKINCOLOR_BRONZE							
							elseif m.respawnedbx.type == MT_ATTRACT_BOX 
							m.respawnedbx.color =29
							elseif m.respawnedbx.type == MT_WHIRLWIND_BOX
							m.respawnedbx.color =SKINCOLOR_SKY
							elseif m.respawnedbx.type == MT_PITY_BOX
							m.respawnedbx.color =SKINCOLOR_MOSS
							elseif m.respawnedbx.type == MT_INVULN_BOX
							m.respawnedbx.color =SKINCOLOR_WHITE
							elseif m.respawnedbx.type == MT_MIXUP_BOX
							elseif ((m.respawnedbx.type == MT_EGGMAN_BOX) or (m.respawnedbx.type == MT_EGGMAN_GOLDBOX))
							m.respawnedbx.color =SKINCOLOR_BLACK
							elseif m.respawnedbx.type == MT_SNEAKERS_BOX
							m.respawnedbx.color =SKINCOLOR_MAGENTA
							else
							m.respawnedbx.color =SKINCOLOR_ORANGE
							end
						end
					end

 					if m and m.samspawneditem and m.samspawneditem.valid
 					m.samspawneditem.state = S_NULL
 					end
 					if m and m.valid
 					P_RemoveMobj(m)
					end
				end

 		 	elseif m and m.valid and not (gametype == GT_COMPETITION) and (netgame or splitscreen)
				if m.lifeiconvanished and m.lifeiconvanished.valid and m.lifeiconvanished.flags2
				m.lifeiconvanished.flags2 = $1 & ~MF2_DONTDRAW
				else
				m.lifeiconvanished = nil
				end
				if m.metroidvisual
 				m.state = S_METBOX1
				else
 				m.state = m.info.spawnstate
				end
 				m.flags = $1|MF_SHOOTABLE & ~MF_NOCLIP
 				m.flags = $1|MF_SOLID & ~MF_NOTHINK
 				m.flags2 = $1 & ~MF2_DONTDRAW
				if m.goldlaststate
				m.state = m.goldlaststate
				end
 				if m and m.samspawneditem and m.samspawneditem.valid
 				m.samspawneditem.state = S_NULL
 				end
 		 	end
 		end
	elseif s.valid
	s.state = S_NULL
	end
end, MT_SAMSPAWNITEM)

--Sonic Version, though not actually active for monitor bopping right now.
addHook("MobjThinker", function(s)
	if s.valid and s.ogmonitor and s.ogmonitor.valid
		if s.missilepanel
			if s.ogmonitor and s.ogmonitor.valid
			s.ogmonitor.angle = $+(ANG2*2)
			else
			s.state = S_NULL
			end
			return
		elseif s.holdontime
		s.holdontime = $-1
			if not s.holdontime
			and s.ogmonitor and s.ogmonitor.valid
			s.ogmonitor.holdon = nil
			s.state = S_NULL
			end
			return
		end
		if s.waittics == nil
			if gametype == GT_COOP
				s.waittics = 105
			else
				local totalplayers = 0
				for d = 0,31
					if players[tonumber(d)] and players[tonumber(d)].valid
					totalplayers = $+1
					end
				end
				s.waittics = 1000-(totalplayers*27)
			end	
		end
		
		s.waittics = $-1
		
		if not s.waittics
			if gametype == GT_COOP
			s.ogmonitor.health = 1
			s.ogmonitor.state = s.ogstate
			s.ogmonitor.flags = s.ogflags
			s.ogmonitor.flags2 = s.ogflags2
			s.state = S_NULL
			return
			else
				local boxrespawn = P_RandomRange(1, 120)			
					if (boxrespawn < 60)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_RING_BOX)
					elseif (boxrespawn < 64)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_PITY_BOX)
					 	if m.respawnedbx and m.respawnedbx.valid
						m.respawnedbx.triedspawn = true
						end
					elseif (boxrespawn < 73)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_FORCE_BOX) 	
					elseif (boxrespawn < 81)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_WHIRLWIND_BOX)
					elseif (boxrespawn < 88)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ELEMENTAL_BOX)
					elseif (boxrespawn < 94)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ATTRACT_BOX )
					elseif (boxrespawn < 100)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_ARMAGEDDON_BOX)
					elseif (boxrespawn < 102)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_INVULN_BOX)
					elseif (boxrespawn < 118)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_SNEAKERS_BOX)
					elseif (boxrespawn < 119) and (leveltime > 10)
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_MIXUP_BOX)
					else
 					m.respawnedbx = P_SpawnMobj(m.x, m.y, m.z, MT_RECYCLER_BOX)
					end
			end
		end
	elseif s.valid
	s.state = S_NULL
	return
	end
end, MT_SAMSPAWNITEMSONIC)

function A_SAMUSEXPLOSIONS(actor, var1, var2, var3, var4, color, nii)
	if not (actor and actor.valid)
		return
	end
	if nii and nii == "brakdust"
	 for sa = 0,16 
		local smmk = P_SpawnMobj(actor.x, actor.y, actor.z+25*FRACUNIT, var2)
		smmk.scale = actor.scale
		smmk.target = actor
		smmk.color = SKINCOLOR_SKY
		smmk.brakandco = true
		smmk.blendmode = AST_ADD
		smmk.eflags = actor.eflags
		smmk.flags2 = actor.flags2
		smmk.momx = ( (var1*(actor.scale/FRACUNIT))*cos((sa*ANGLE_45+(ANG2*4))) + (actor.momx/2) )
		smmk.momy = ( (var1*(actor.scale/FRACUNIT))*sin((sa*ANGLE_45+(ANG2*4))) + (actor.momy/2) )
	 end

	else
	 for sa = 0,08
		local smmk = P_SpawnMobj(actor.x, actor.y, actor.z+FixedMul(FRACUNIT, (P_MobjFlip(actor)*actor.scale)), var2)
		if smmk and smmk.valid and not nii
		smmk.flags = $1|MF_NOCLIPHEIGHT
		smmk.scale = actor.scale
		smmk.target = actor
		end
		smmk.eflags = actor.eflags
		smmk.blendmode = AST_ADD
		smmk.flags2 = actor.flags2
		smmk.samussmmk = true
		smmk.momx = ( (var1*(actor.scale/FRACUNIT))*cos((sa*ANGLE_45)) + (actor.momx/2) )
		smmk.momy = ( (var1*(actor.scale/FRACUNIT))*sin((sa*ANGLE_45)) + (actor.momy/2) )
		if var4
		P_SetObjectMomZ(smmk, var4, true)
		end
		if var3
		P_MoveOrigin(smmk, smmk.x, smmk.y, smmk.z+FixedMul(var3, (P_MobjFlip(actor)*actor.scale)))
		end
		if color
			if (color == true)
			smmk.pworsm = true
			else
			smmk.color = color
				if actor.type == MT_SAMMISSILE
				smmk.colorized = true
				smmk.blendmode = AST_ADD
				smmk.flags2 = $|MF2_SHADOW
				end
			end
		end
	 end
	 if var2 == MT_SAMSHATTERFOF
	 P_SpawnMobj(actor.x, actor.y, actor.z+90*FRACUNIT, var2)
	 P_SpawnMobj(actor.x, actor.y, actor.z-90*FRACUNIT, var2)
	 end
	end
	if actor and actor.valid and (actor.darkhyper or actor.type == MT_PZBOSS) and smmk and smmk.valid --Extra addon for Dark Samus
		smmk.color = SKINCOLOR_COBALT
		smmk.colorized = true
	end
end
//var1 = width range, var2 = height range, var3 = source
function A_Samuskillstuff(actor, var1, var2, var3, var4, var5, var6)
	local p = actor
	    searchBlockmap("objects", function(ref, m)
--	    for m in mobjs.iterate(mobjs)
		  if m.valid 
		  and not ((m.type == MT_METROIDPART) and not ((p.type == MT_SAMPOWERBOMB) or (p.type == MT_SAMMISSILE))) --Omegas are better affected by direct attacks!
		  and not (m.samreflecttime and (p.type != MT_HBSHOT))
		  
		 	 if ((p.type == MT_SAMSUPERMISSILE) or (p.type == MT_SAMPOWERBOMB) or (p.type == MT_HBSHOT))
			 and ( ((m.type == MT_SALOONDOOR) or (m.type == MT_SALOONDOORCENTER))
			 or (m.type == MT_EGGSHIELD) )
			 
				if not (p.x > m.x+(var1)) and not (p.x < m.x-(var1))
				and not (p.y > m.y+(var1)) and not (p.y < m.y-(var1))
				and not (p.z > m.z+(var2)) and not (p.z < m.z-(var2))			
			 		if (m.type == MT_EGGSHIELD) and m.valid and m.health and not (p.type == MT_SAMSUPERMISSILE)
						if m.target and (m.target.type == MT_EGGGUARD) and (m.target.health)
						local guard = m.target
							if m and m.valid
							m.state = S_NULL
							end
							if guard and guard.valid
							guard.flags = MF_ENEMY|MF_SHOOTABLE
							guard.state = S_EGGGUARD_RUN1
							P_DamageMobj(guard, p, p.target)
							end
						end		 
					 elseif ((m.type == MT_SALOONDOOR) or (m.type == MT_SALOONDOORCENTER))
					 and not (m.flags & MF_NOCLIP)
							S_StartSound(m, sfx_smexp)
							m.hh = P_SpawnMobj(m.x, m.y, m.z, MT_BOSSEXPLODE)
							m.hh.scale = $*6
							m.flags = $|MF_NOCLIP
							if (m.type == MT_SALOONDOOR)
							P_KillMobj(m, p, p)
							end
					end
				end
				
			elseif (m.flags & (MF_MONITOR)) and m.health and (m.flags & (MF_SHOOTABLE)) and not (p and p.player)
				if not (p.x > m.x+(var1/3)) and not (p.x < m.x-(var1/3))
				and not (p.y > m.y+(var1/3)) and not (p.y < m.y-(var1/3))
				and not (p.z > m.z+(var2/2)) and not (p.z < m.z-(var2/2))			
				and not ( ((m.type == MT_EGGMAN_BOX) or (m.type == MT_EGGMAN_GOLDBOX)) and (p.type == MT_SAMPOWERBOMB))				
					A_SAMITEM(p, m)
				end
				
			elseif ((p.type == MT_SAMPOWERBOMB) or (p.type == MT_HBSHOT) or (p.type == MT_SAMSUPERMISSILE))
			and ((m.type == MT_TURRET) or (m.type == MT_SPIKE) or (m.type == MT_WALLSPIKE))  
				if m.health
				and not (p.x > m.x+var1) and not (p.x < m.x-var1)
				and not (p.y > m.y+var1) and not (p.y < m.y-var1)
				and not (p.z > m.z+var2) and not (p.z < m.z-var2)		
					P_KillMobj(m, p, var3)
				end
				
			elseif ((m.type == MT_TNTBARREL) or (m.type == MT_PROXIMITYTNT) or (m.type == MT_BIGMINE)) and m.health
				if not (p.x > m.x+var1) and not (p.x < m.x-var1)
				and not (p.y > m.y+var1) and not (p.y < m.y-var1)
				and not (p.z > m.z+var2) and not (p.z < m.z-var2)
					if (m.type == MT_PROXIMITYTNT)
						if not m.onetimexp
						m.onetimexp = true
						m.state = S_PROXIMITY_TNT_TRIGGER23
						m.tics = 1
						end
					else
					P_KillMobj(m, p, var3)
					end
				end	

			elseif ( ( ((m.flags & (MF_ENEMY|MF_BOSS)) and (m.flags & MF_SHOOTABLE)) or m.player) 
			or (m.type == MT_ICBLOCK) or (m.type == MT_EGGSHIELD) or (m.type == MT_MINUS)) and not (m.flags2 & MF2_FRET)
				if m.health
				and not (p.x > m.x+var1) and not (p.x < m.x-var1)
				and not (p.y > m.y+var1) and not (p.y < m.y-var1)
				and not (p.z > m.z+var2) and not (p.z < m.z-var2)
				and not (m.info.mass == 2006)
					if (p.type == MT_SAMPOWERBOMB) and (p.target and p.target == m) and not p.gravitysuitjustgot
						if m.player and m.player.sammorphed
						and not (m.z < p.z-78*FRACUNIT) and not (m.z > p.z+78*FRACUNIT)
						and FixedHypot(m.x-p.x, m.y-p.y) <= 123*FRACUNIT
							P_SetObjectMomZ(m, 1350000)
							m.bombjump = 28
							m.bombjumpangle = (R_PointToAngle2(p.x, p.y, m.x, m.y))
 							if ( (FixedHypot(m.x-p.x, m.y-p.y)) <= 4*FRACUNIT)
								m.bombjumpdist = 0
 							else
								m.bombjumpdist = (FixedHypot(m.x-p.x, m.y-p.y))
 							end
							m.powerbombjump = 3

							if m.spiderballing --Samus Returns-style PowerBomb fling!
							m.spiderballing = 0
							SamSpiderCharge(m.player, m, 103)
							m.spiderbanim = 7
							m.angle = $+ANGLE_180
							m.smmachballpw = 8
							S_StartSound(m, sfx_brakrx)
							S_StartSound(m, sfx_bkpoof)
							P_InstaThrust(m, m.angle, 59*FRACUNIT)

							m.morphedmachspeed = 45*FRACUNIT
							m.morphedmachactive = true
							m.smmachball = 0
							m.smmachballwait = 0
							m.initialmockbspeed = 45*FRACUNIT
							m.player.pflags = $ & ~PF_JUMPED & ~PF_STARTJUMP
							m.bombjump = 0
							m.momz = $/2
							P_NukeEnemies(m, m, 0)
							end

						end
					end			
					if (m.type == MT_ICBLOCK) and not (actor.type == MT_ICSHOT)
					m.icethisfool = true
					end
					if ((m.type == MT_EGGSHIELD) and not (actor.type == MT_SAMMISSILE)) or (m.type == MT_MINUS)
						P_KillMobj(m, p, var3) 
					elseif var4 and not (m.z < p.z-(150*FRACUNIT*(P_MobjFlip(p))) ) 
 	    			and not (m.player) and not ( (p.type == MT_SPCHARGECOMBO) or (p.type == MT_SPAZERSHOCK) )
						if (p.type == MT_SAMMISSILE and not m.missileresist) or (p.type == MT_PBCHARGESHOT)
							ExplodePush(p, m, var3)
						else
					
						P_DamageMobj(m, p, var3, 1)
						end

					elseif var5 and (var5 == "combowave") and not (p.target and (m == p.target)) and ( ((G_GametypeHasSpectators() or p.sambeamreflected) and (m.player)) or (m.flags & (MF_ENEMY|MF_BOSS)) )
							p.meleeblast = P_SpawnMobj(m.x, m.y, m.z, MT_SPAZERSHOCK)
							p.meleeblast.rocket = m
							p.meleeblast.mojo = true
							m.spazershocked = true
							m.spcombod = true
							p.meleeblast.angle = p.angle
							if p.target
							p.meleeblast.target = p.target
							end

							S_StartSound(m, sfx_smexp)
							S_StartSound(m, sfx_smexp)
					elseif var5 and ( ((p.type == MT_HBSHOT) and (G_GametypeHasSpectators() or p.sambeamreflected) and ((p.type == MT_SAMPOWERBOMB) or not (p.target and p.target == m))) or not (m.player) ) 
						if (p.type == MT_HBSHOT)
					   	  if not (p.lasthyper and p.lasthyper == m)
							p.meleeblast = P_SpawnMobj(m.x, m.y, m.z, MT_SPAZERSHOCK)
							p.meleeblast.rocket = m
							m.spazershocked = true
							p.meleeblast.angle = p.angle
							m.specialexpangle = (R_PointToAngle2(m.x, m.y, p.x, p.y))
							if p.target
							p.meleeblast.target = p.target
							p.meleeblast.hypered = true
							end

							S_StartSound(m, sfx_smexp)
							P_ExplodeMissile(p)
					   	  end
						elseif (p.type == MT_SAMPOWERBOMB)
							if (m.type == MT_PZBOSS)
							 	if not p.phase
								P_DamageMobj(m, p, var3, 2)
								else
								P_DamageMobj(m, p, var3, 1)
								end
							else
								if m.superbrak or not p.phase
						  	  	P_DamageMobj(m, p, var3, 3)
							  	else
								P_DamageMobj(m, p, var3, 1)
								end
							end
						elseif (p.type == MT_SAMSUPERMISSILE)
							if (m.type == MT_PZBOSS)
								if not m.invincible and (m.samusHP > 7)
								m.samusHP = 1
								m.painfyellow = 25
								m.invincible = 25
								else
								P_DamageMobj(m, p, var3, 1)
								end
							else
								P_DamageMobj(m, p, var3, 2)
							end
						else
						P_DamageMobj(m, p, var3, 1)
						end					
					elseif var6 and m and m.valid
					
						if not ((actor.type == MT_ICSHOT) or (actor.type == MT_ICCHARGESHOT))
					
							if m.player and m.player.sammorphed and (p.target and (p.target == m))
							and not (m.z < p.z-18*FRACUNIT) and not (m.z > p.z+18*FRACUNIT)
							and ( (FixedHypot(m.x-p.x, m.y-p.y)) <= 64*FRACUNIT)
								if (m.eflags & MFE_UNDERWATER)
								P_SetObjectMomZ(m, 950000)
								m.bombjump = 28
								else
								P_SetObjectMomZ(m, 1350000)
								m.bombjump = 28
								end
								m.bombjumpangle = (R_PointToAngle2(p.x, p.y, m.x, m.y))
 								if ( (FixedHypot(m.x-p.x, m.y-p.y)) <= 4*FRACUNIT)
								m.bombjumpdist = 0
 								else
								m.bombjumpdist = (FixedHypot(m.x-p.x, m.y-p.y))
 								end
							elseif not (m.player) or p.sambeamreflected
								if (p.type == MT_SAMMORPHBOMB or (p.type == MT_SAMMBOP))
									ExplodePush(p, m, var3)
								else
								P_DamageMobj(m, p, var3)
								end
							end
							
						else
						
							if not m.player and m.health
								if (m.type == MT_METROIDPART) and m.hitbox
									P_DamageMobj(m, p, var3, 1)
								elseif (actor.type == MT_ICCHARGESHOT)
							
									if not m.frozenbox and (m.health < 3) and not (m.type == MT_PYREFLY)
									and (m.flags & MF_SHOOTABLE)
										if (m.type == MT_METROID) or (m.type == MT_METROIDLARVA) or (m.type == MT_SUPERMETROID) --Metroids use custom behaviour
										P_DamageMobj(m, p, var3, 1)
										else
										m.health = 1
										m.frozenmobj = P_SpawnMobj(m.x, m.y, m.z, MT_FREEZETRACKER)
										m.frozenmobj.chozobox = m
										m.frozenmobj.samusshooter = var3
										end
									elseif (m.health > 2)
									P_DamageMobj(m, p, var3, 1)
									end
								elseif ((actor.type == MT_ICSHOT) and m.iceresist)
									p.sam_resisthud = 18
								elseif not ((actor.type == MT_ICSHOT) and m.iceresist)
									if m.iceweak
									p.sam_crithud = 18
									A_SAMUSEXPLOSIONS(m, 7, MT_SMOKE, false, 1000, SKINCOLOR_BLACK)
									A_SAMUSEXPLOSIONS(m, 7, MT_MPR8, false, 90000, SKINCOLOR_SKY, "nii")
									A_SAMUSEXPLOSIONS(m, 4, MT_MPR8, false, 8000, SKINCOLOR_WHITE, "nii")
									end
									if not m.frozenbox and (m.health == 1)
									and (m.flags & MF_SHOOTABLE)
										if (m.type == MT_METROID) or (m.type == MT_METROIDLARVA) or (m.type == MT_SUPERMETROID) --Metroids use custom behaviour
										P_DamageMobj(m, p, var3, 1)
										else
										m.frozenmobj = P_SpawnMobj(m.x, m.y, m.z, MT_FREEZETRACKER)
										m.frozenmobj.chozobox = m
										m.frozenmobj.samusshooter = var3
										end
									elseif (m.health > 1)
									P_DamageMobj(m, p, var3)
									end
								end
							end
						end
					end
					if m and m.valid
						if not m.player and (m.health <= 1) and not (m.flags2 & MF2_FRET) and not m.frozenmobj and not (actor and (actor.type == MT_ICSHOT))
							if not (p.type == MT_HBSHOT)
							and not (p.type == MT_SAMMORPHBOMB or (p.type == MT_SAMMBOP) or (p.type == MT_SAMMISSILE) or (p.type == MT_PBCHARGESHOT))
								P_DamageMobj(m, p, var3, 1)
							end
						elseif (p.type == MT_SAMSUPERMISSILE) and m.player
							P_SamFP(m.player, PAL_MIXUP, 2)
							m.sam_flashfade = 12
							m.sam_flashfadecolor = SKINCOLOR_RED
						end

						if m.player and (G_GametypeHasSpectators() or p.sambeamreflected and not (p.target and p.target.player))
							if not (p.target and (p.target == m))
							P_DamageMobj(m, p, var3)
							end
						end
					end
				end
			end
		  end
	    end, p, p.x-(var1+160*FRACUNIT), p.x+(var1+160*FRACUNIT), p.y-(var1+160*FRACUNIT), p.y+(var1+160*FRACUNIT))		  
	--    end
end

rawset(_G, "samwallcheck", function(s,p)
if p.sam_iamahuntersbot and not p.hunterwalljump
or p.sam_walljumpsound
or (s.sam_ldclmb and s.sam_ldclmb > 22)
return false
end
	local wm
	local dm = 3
	if (s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling)
	dm = 1
	end
					if (twodlevel or (s.flags2 & MF2_TWOD)) 
						if (p.cmd.sidemove > 0)
							if (s.angle == 0)
							wm = P_SPMAngle(s, MT_SAMWALLJUMP, ANGLE_180)
							p.sams_jumpcd = 3
							return true
							end
						elseif (p.cmd.sidemove < 0)
							if (s.angle == ANGLE_180)
							wm = P_SPMAngle(s, MT_SAMWALLJUMP, 0)
							p.sams_jumpcd = 3
							return true
							end
						end
						
					else --3D it is
					
					local sidemove = p.cmd.sidemove --Calculate side input first.					
						if (sidemove < 0)
							sidemove = $*-1
						end
						if p.sam_screwattacking --This one's free.
						and not (p.pflags & PF_ANALOGMODE)
							if not (p.cmd.sidemove or p.cmd.forwardmove)
							or ((p.cmd.forwardmove > 40) and (sidemove < 15))
								local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle)
								p.sams_jumpcd = 3	
								return true
							elseif (p.cmd.forwardmove > 40) --Omni-directional walljump
							or ((sidemove >= 15) and not ((p.cmd.forwardmove < 15) and (p.cmd.forwardmove > -15)))
							or (sidemove > 40)
							local turnang = R_PointToAngle2(0, 0, -(p.cmd.forwardmove<<16), -(p.cmd.sidemove<<16))						
							local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle-turnang)
								if ghs and ghs.valid
									if (sidemove > 15) --Sideways walljump!
									or ((s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling) and not ((p.cmd.forwardmove > 40) and (sidemove < 15)))
									ghs.scale = s.scale*5/dm
									end
									ghs.sideangle = s.angle-turnang
								end
								p.sams_jumpcd = 300
								return true
							end
						end
						if (p.pflags & PF_ANALOGMODE)
						
							if not (p.cmd.sidemove or p.cmd.forwardmove) --Old style analog walljump
							local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle)
								if ghs and ghs.valid
									if (sidemove > 15) --Sideways walljump!
									and not (s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling)
									ghs.scale = s.scale*5/dm
									end
								end
								p.sams_jumpcd = 3
								return true
							else --Newly adjusted easycake walljump controls, courtesy of SArun4
								local trueturn = (s.angle-((p.cmd.angleturn<<16)+(R_PointToAngle2(0, 0, p.cmd.forwardmove<<16, -(p.cmd.sidemove<<16)))))
								local walljumpauthorized = false
								
								if trueturn == 0
									walljumpauthorized = true
								else
									local newturn = trueturn/ANG1
									if newturn < 0
										newturn = $*-1
									end	
									if (newturn < 35)
									walljumpauthorized = true
									end
								end
								if walljumpauthorized
									local momang = R_PointToDist2(s.x, s.y, s.x+s.momx, s.y+s.momy)
									local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle)
									if ghs and ghs.valid
										if (sidemove > 15)
										and not (s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling)
									--	or (s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling)
										ghs.scale = s.scale*5/dm
										end
									end
									p.sams_jumpcd = 3
									return true
								end
							end 
							
						elseif (p.cmd.forwardmove < 0) --Regular walljump
						and (sidemove < 15)
							local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle)
							if ghs and ghs.valid
								if s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling
									ghs.scale = s.scale*3
									ghs.momx = $*3
									ghs.momy = $*3
								end
							end
							p.sams_jumpcd = 3
							return true
						elseif (p.cmd.forwardmove > 40) --Omni-directional walljump
						or ((sidemove >= 15) and not ((p.cmd.forwardmove < 15) and (p.cmd.forwardmove > -15)))
						or (sidemove > 40)
							local turnang = R_PointToAngle2(0, 0, -(p.cmd.forwardmove<<16), -(p.cmd.sidemove<<16))						
							local ghs = P_SPMAngle(s, MT_SAMWALLJUMP, s.angle-turnang)
							if ghs and ghs.valid
								if (sidemove >= 15)
								or (s.sam_afterboost or p.sam_screwattacking or s.sam_screwattackfling)
									if not ((p.sam_screwattacking or s.sam_screwattackfling)
									and (p.cmd.forwardmove > 40) and (sidemove < 15))
									ghs.scale = s.scale*5/dm
									end
								end
								ghs.sideangle = s.angle-turnang
							end
							p.sams_jumpcd = 3
							return true
						end
					end
end)

--Walljump has hit, let's go!

function A_SAMWALLJUMP(s, var1, var2)
	if not s.target or not s.health
		return
	elseif not (s.target.player and s.target.health) and not (s.target.type == MT_SAMUSSHIP)
		return
	elseif (s.target and s.target.wallnopejump)
		s.state = S_NULL
		return
	end
local t = s.target
	if (t.type == MT_SAMUSSHIP) and not s.done
		t.yougottaland = true
		s.flags = $1|MF_NOCLIPHEIGHT
		s.health = 0
		s.done = true
		if s.valid
		s.state = S_NULL
		end
	elseif t.player and t.player.sammorphed
		t.spiderballgo = true
		t.spiderballstillgood = 2
		if s.valid
		s.state = S_NULL
		end
	elseif t.player and t.player.sammorphed and t.spiderballing
		t.spiderballstillgood = 2
		if s.valid
		s.state = S_NULL
		end
		
	elseif t.player and not t.player.sammorphed
	
	P_SpawnMobjFromMobj(s, 0,0,0, MT_SMOKE)
	
	t.player.pflags = $ & ~ PF_STARTJUMP
	S_StopSoundByID(t, sfx_sjmp)
	local spbs = false
	local jumpangle = t.angle
	local diminish = 1
	local p = t.player
		if p.samspbschargefull or t.sam_screwattackspbs
		or t.sam_afterboost
			spbs = true
		end
		if s.sideangle != nil	
			jumpangle = s.sideangle
		end
		
		--Sideways anims and diminishers
		if p.cmd.sidemove < 0
			if t.sam_sidejump
				if t.sam_sidejump >= 0
				t.sam_sidejump = -1
				else
				t.sam_sidejump = $-1
				end
			else
				t.sam_sidejump = -1
			end
		elseif p.cmd.sidemove > 0
			if t.sam_sidejump
				if t.sam_sidejump <= 0
				t.sam_sidejump = 1
				else
				t.sam_sidejump = $+1
				end
			else
				t.sam_sidejump = 1
			end
		else
			t.sam_sidejump = 0
		end		
		if t.sam_sidejump and not (t.sam_sidejump == 1 or t.sam_sidejump == -1)
		diminish = t.sam_sidejump
		t.sam_sidejumpcd = 6
			if diminish < 0
			diminish = $*-1
			end
			if (diminish > 18)
			diminish = 18
			end
			diminish = $*20000	
		end
		
	--And the actual walljump begins.	
	
		if (t.eflags & MFE_UNDERWATER)
			if not (twodlevel or (t.flags2 & MF2_TWOD))
			
 				P_InstaThrust(t, jumpangle, FixedMul(-8*FRACUNIT, t.scale))
					if s.sideangle != nil
						P_SetObjectMomZ(t, 3*FRACUNIT-(diminish/2))
						if spbs and (p.cmd.forwardmove > 15) --Assuming only gravity suit boys can get here...
							P_Thrust(t, jumpangle, FixedMul(-13*FRACUNIT, t.scale))
							P_Thrust(t, t.angle, FixedMul(16*FRACUNIT, t.scale))
						end						
						
					else --Standard underwater walljump
					
					t.sam_sidejump = 0
					t.angle = $+ANGLE_180
						if (t.player.pflags & PF_ANALOGMODE)
						t.player.drawangle = $+ANGLE_180
						end
						if spbs
						P_SetObjectMomZ(t, 210000-diminish)
						P_Thrust(t, t.angle, FixedMul(22*FRACUNIT, t.scale))
						else						
						P_SetObjectMomZ(t, 4*FRACUNIT-diminish)	
						end
					end
				t.lastsamusangle = t.angle	
				t.player.powers[pw_nocontrol] = 2
			
			else
				t.sam_sidejump = 0
				P_SetObjectMomZ(t,  350000)
 				P_Thrust(t, t.angle, FixedMul(FRACUNIT/2, t.scale))
			end
			
		else
		
			if not (twodlevel or (t.flags2 & MF2_TWOD))
				if spbs and s.sideangle != nil and not (abs(p.cmd.sidemove) > 11) --Preventing weird bug.
					p.sams_jumpcd = 10
					if s and s.valid s.state = S_NULL end
					return false	
				end
				P_InstaThrust(t, jumpangle, FixedMul(-15*FRACUNIT, t.scale))
				
					if s.sideangle != nil
					
						if spbs
							if (abs(p.cmd.forwardmove) > 15) --And something fun for the advanced players!
								P_Thrust(t, jumpangle, FixedMul(-14*FRACUNIT, t.scale))
								P_Thrust(t, t.angle, FixedMul(18*FRACUNIT, t.scale))
								P_SetObjectMomZ(t, 395000-diminish)
							end
						else
							P_SetObjectMomZ(t, 460000-diminish)
						end
						
					else --Backwards standard walljump
					
						t.sam_sidejump = 0
						t.angle = $+ANGLE_180
						
						if (p.pflags & PF_ANALOGMODE)
							p.drawangle = $+ANGLE_180
						end
						
						if spbs
							P_SetObjectMomZ(t, 430000)
							P_Thrust(t, t.angle, FixedMul(25*FRACUNIT, t.scale))
						else
							P_SetObjectMomZ(t, 550000)
						end
					end	
					
				t.lastsamusangle = t.angle	
				p.powers[pw_nocontrol] = max($,2)
				
			else
				t.sam_sidejump = 0
 				P_Thrust(t, t.angle, FixedMul(FRACUNIT/2, t.scale))
				P_SetObjectMomZ(t, 700000)
			end
		end
		
		if p.sam_spacejumped and p.sam_spacejumpedboost and (p.sam_spacejumpedboost > 3)
			p.sam_spacejumpedboost = 0
			p.sam_spacejumped = false
		end
		
		--Silently restore speedbooster
		if t.sam_afterboost and not p.samspbschargefull
			p.samspbschargefull = true
			p.samspbscharge = 140
		end
		
		--Walljump "circle" effect
		local ghs = P_SpawnMobjFromMobj(t, 0, 0, 12*t.scale, MT_THOK)
		ghs.sprite = SPR_MPR9
		ghs.frame = A|FF_PAPERSPRITE
		ghs.angle = R_PointToAngle2(t.x, t.y, t.x+t.momx, t.y+t.momy)+ANGLE_90
		ghs.scale = $/50
		ghs.colorized = true	
		ghs.tics = 9 ghs.fuse = 8
		ghs.color = t.color
		ghs.scalespeed = $*2
		ghs.destscale = $*99

		p.noprimerun = 23
		p.sam_walljumpsound = 5
		p.sam_walljumping = 13
		p.sam_framejump = 0
		p.samybeam = 0
		p.sam_j1ready = 0
		t.state = S_PLAY_ROLL
		t.sam_beamroll = 0
		
		--Sideways anims and diminishers
		if p.cmd.sidemove < 0
			t.sam_forcebeamroll = 10
			t.sam_forcebeamnum = -13
		elseif p.cmd.sidemove > 0
			t.sam_forcebeamroll = 10
			t.sam_forcebeamnum = 13
		end

		--Are we screwattacking? Then do something especially special!
		
		if p.sam_screwattacking or t.sam_screwattackfling
		local didfling
		local didboost
			if t.sam_screwattackfling
			didfling = true
				if t.sam_screwattackfling and t.sam_screwattackfling.speedboosted
				didboost = true
				t.sam_afterboost = 7
				end
			else
				if not twodlevel
				and not (s.flags2 & MF2_TWOD)
				and not p.threedimensionalexplosion	
					if (CV_FindVar("chasecam").value == 0)		
						p.sam_firstperson = true
					else
						p.sam_firstperson = false
					end
					SamCam(p, true)
				end
			end
			ghs.color = SKINCOLOR_SUPERGOLD5
			p.sam_walljumpsound = 0
			t.sam_sidejump = 0
			S_StartSound(t, sfx_satklh)
			
			--Make a tiny table just for this move!
			t.sam_screwattackfling = {
			timer = -15,
			angle = ghs.angle-ANGLE_90,
			speed = 44,
			walljumpavailable = true,
			speedboosted = false,
			chainsaw = false,
			momz = t.momz
			}
			local yu = t.sam_screwattackfling --And now the table is Yuji Uekawa, because of course.			
			if t.sam_screwattackspbs
			or didboost
				if didboost
				S_StartSound(t, sfx_satkf)
				else
				S_StartSound(t, sfx_sprna)
				end
				yu.speed = 63
				t.sam_screwattackspbs = false
				yu.speedboosted = true
			end
			
			p.powers[pw_nocontrol] = max($,5)
			
			--Screw Attack walljump physics.
			if didfling
				if s.sideangle != nil
					if yu.speedboosted
						t.momx = $*4/3
						t.momy = $*4/3
					else
						t.momx = $*3/2
						t.momy = $*3/2
					end
				else
					if not (s.eflags & MFE_UNDERWATER)
					P_SetObjectMomZ(t, 11*FRACUNIT)
					end
					P_Thrust(t, yu.angle, 6*FRACUNIT)
				end
			else
				if not (s.eflags & MFE_UNDERWATER)
					P_SetObjectMomZ(t, 9*FRACUNIT)
				end
			end
			--Screw Attack walljump particles.
			for d = -6,6,1
				local ghs = P_SpawnMobjFromMobj(t,0,0,t.height/5, MT_THOK)
				P_InstaThrust(ghs, (t.angle)+((ANG1*7)*d), p.speed+(10*FRACUNIT))
				P_SetObjectMomZ(ghs, (5*t.scale)+t.momz)
				ghs.sprite = SPR_MPR6
				ghs.flags = $|MF_BOUNCE|MF_GRENADEBOUNCE & ~MF_NOGRAVITY
				ghs.color = SKINCOLOR_SUPERGOLD5+2-(d*3)
				ghs.colorized = true
				ghs.tics = 25
				ghs.fuse = 15
				ghs.frame = P_RandomRange(0,4)|P_RandomRange(2,7)*FRACUNIT|FF_FULLBRIGHT
				ghs.blendmode = AST_ADD
				ghs.destscale = $*99	
			end			
		end
		
	end
end

COM_AddCommand("samusmatch", function(p, var1, var2)
 if var1 and (var1 == "hidegore" or var1 == "HideGore" or var1 == "HIDEGORE")
	if p.sam_hidegore
	CONS_Printf(p, "\x87"+"Corpse Scene in stage is already hidden! Restart game to reset setting.")
		if p.mo
		S_StartSound(p.mo, sfx_sdenid)
		end
 	else
	CONS_Printf(p, "\x82"+"Corpse Scene in stage is now hidden.")
		p.sam_hidegore = true
								for m in mobjs.iterate(mobjs)
									if (consoleplayer and p and p == consoleplayer) and (m.type == MT_DARKPZREMAINS)
									m.flags2 = MF2_DONTDRAW
									end
								end
		if p.mo
		S_StartSound(p.mo, sfx_samtm7)
		end
	end
	return
 end
 if not (IsPlayerAdmin(p) or (p == server) )
 CONS_Printf(p, "Command is for an admin only.")
 return end
 p.shotbeambefore = true
	if var1
		if (var1 == "0")
		print("Samus starts fresh on powerups each match!")
		S_StartSound(nil, sfx_mpku)
			for z in players.iterate
			z.samusmatch = 0
			end
		
		elseif (var1 == "1")
		print("Samus now keeps every powerup she gets between matches!")
		S_StartSound(nil, sfx_mtnk)
			for z in players.iterate
			z.samusmatch = 1
			end
		
		elseif (var1 == "2")
			print("Samus now starts with every powerup in a match!")
			S_StartSound(nil, sfx_spwup)
			for z in players.iterate
				z.samusmatch = 2
			end
		elseif (var1 == "JUSTINBAILEY")  or (var1 == "justinbailey") or (var1 == "JustinBailey") or (var1 == "Justinbailey")
			for z in players.iterate

				if (z.sammissilesmax != nil and (z.sammissilesmax < 100))
					z.sammissilesmax = 100
				end
				if (z.sammissiles != nil and (z.sammissiles < 100))
					z.sammissiles = 100
				end
				if (z.samsupermissilesmax != nil and (z.samsupermissilesmax < 10))
					z.samsupermissilesmax = 10
				end
				if (z.samsupermissiles != nil and (z.samsupermissiles < 10))
					z.samsupermissiles = 10
				end
				if  (z.sampwmax != nil and (z.sampwmax < 5))
					z.sampwmax = 5
				end
				if  (z.sampw != nil and (z.sampw < 5))
					z.sampw = 5
				end
				
				z.samspbs = true
				z.sambsbl = true
				z.sam_spiderball = true
				z.sam_bombs = true
				z.sam_highjump = true
				z.sam_spacejump = true
				z.sam_chargebeam = true
				z.sam_spazerbeam = true
				z.sam_wavebeam = true
				z.sam_icebeam = true
				z.sam_plasmabeam = true
				z.sam_screwattack = true
				z.sam_powerbeamcombo = true
				z.sam_spazerbeamcombo = true
				z.sam_wavebeamcombo = true
				z.sam_icebeamcombo = true
				z.sam_plasmabeamcombo = true
				z.sam_power_grip = true
					
				if not z.sam_gravitysuit or (z.sam_gravitysuit and (z.sam_gravitysuit == 1))
					z.sam_gravitysuit = 2
				end
				if not modeattacking --Not in record attack.
					P_SamFP(z, PAL_MIXUP, 9)
					S_StartSound(nil, sfx_spwup)
				end
			end
		elseif (var1 == "ENGAGERIDLEYMOTHERFUCKER")  or (var1 == "engageridleymotherfucker") or (var1 == "EngageRidleyMotherFucker") or (var1 == "Engageridleymotherfucker") or (var1 == "engage") 
			for z in players.iterate
				if G_GametypeHasSpectators()
				z.sammissilesmax = 5
				else
				z.sammissilesmax = 0
				end
				z.samsupermissilesmax = 0
				z.sampwmax = 0
				z.sam_spiderball = false
				z.samspbs = false
				z.sambsbl = false
				z.sam_bombs = false
				z.sam_highjump = false
				z.sam_spacejump = false
				z.sam_chargebeam = false
				z.sam_spazerbeam = false
				z.sam_wavebeam = false
				z.sam_icebeam = false
				z.sam_plasmabeam = false
				z.sam_hyperbeam = false
				z.sam_powerbeamcombo = false
				z.sam_spazerbeamcombo = false
				z.sam_wavebeamcombo = false
				z.sam_icebeamcombo = false
				z.sam_plasmabeamcombo = false
				z.sam_screwattack = false
				z.sam_fullypoweredsuit = false
				z.sam_power_grip = false
				SamResetBeam(z)
				z.sams_itemcompletion = 0
				z.sam_energytanksmax = 0
				z.sam_gravitysuitjustgot = 0
				z.sam_autotank = nil
				z.sam_ammodigitizer = 1

				if z.sam_gravitysuit
				z.sam_gravitysuit = 0
				SetSamusColor(z.mo, z) 
				end

				if not (var2 and (var2 == "7"))
				P_SamFP(z, PAL_NUKE, 9)
				P_DoPlayerPain(z, nil, nil)
				CONS_Printf(z, "\x85"+"You got hit by a plot device! There goes all your gear...again")
				S_StartSound(nil, sfx_mario2)
				end
			end
		elseif (var1 == "Ragdolls")  or (var1 == "ragdolls") or (var1 == "RAGDOLLS") or (var1 == "RagDolls")
			if p.samusragdolls
			print("\x85"+"Nothing but serious business here, sir.")
				for z in players.iterate
				z.samusragdolls = false
				end			
			else
			print("\x82"+"The funnies have been activated.")
				for z in players.iterate
				z.samusragdolls = true
				end
			end
		end
	else
	CONS_Printf(p, "\x82SamusMatch - 0: Start fresh each Match. 1: Keep items between Matches. 2: Start with all powerups. 3: No Samus")
	CONS_Printf(p, "The default setting is 0.")
	end
end)
COM_AddCommand("energytanks", function(p, var1)
 if not ( IsPlayerAdmin(p) or (p == server) )
 CONS_Printf(p, "Command is for an admin only.")
 return end
	if (var1 != nil) and (tonumber(var1) != nil)
		if (tonumber(var1) >= 0) and (tonumber(var1) <= 12)
			for z in players.iterate
			z.sam_energytanksstart = tonumber(var1)
			end
			CONS_Printf(p, "New energy tank start-amount for matches set!")
		else
			CONS_Printf(p, "Start amount must be set between 0 and 12.")
		end
	else
	CONS_Printf(p, "\x82"+"Start amount for match. 1 tank increases energy by 50. Max is 12 tanks.")
	end
end)
COM_AddCommand("AutoSpeedBooster", function(p, var1)
	if var1
		if (var1 == "1") or (var1 == "on") or (var1 == "ON") or (var1 == "On")
		CONS_Printf(p, "\x82"+"Auto Speed Boost toggled on")
		p.autospeedbooster = 1
		elseif (var1 == "0") or (var1 == "off") or (var1 == "Off") or (var1 == "OFF")
		CONS_Printf(p, "\x82"+"Auto Speed Boost toggled off")
		p.autospeedbooster = 0
		end
		p.shotbeambefore = true
	else
	CONS_Printf(p, "\x82"+"If set to ON, speedboost will automatically be active without pressing CUSTOM 1")
	end
end)
COM_AddCommand("LockOnType", function(p, var1)
	if var1
		if (var1 == "1") or (var1 == "toggle") or (var1 == "Toggle") or (var1 == "TOGGLE")
		CONS_Printf(p, "\x82"+"Lock On style set to toggle")
		p.sam_lockontoggle = true
		elseif (var1 == "0") or (var1 == "hold") or (var1 == "Hold") or (var1 == "HOLD")
		CONS_Printf(p, "\x82"+"Lock On style set to hold")
		p.sam_lockontoggle = false
		else
			if p.sam_lockontoggle
			CONS_Printf(p, "\x82"+"Lock On style set to hold")
			p.sam_lockontoggle = false				
			else
			CONS_Printf(p, "\x82"+"Lock On style set to toggle")
			p.sam_lockontoggle = true			
			end
		end
		p.shotbeambefore = true
	else
	CONS_Printf(p, "\x82"+"Set your lock on to either toggle or hold.")
	end
end)
COM_AddCommand("SwapFire", function(p, var1)
	if var1
		if (var1 == "1") or (var1 == "on") or (var1 == "ON") or (var1 == "On")
		CONS_Printf(p, "\x82"+"Fire buttons swapped! Fire missiles with NORMALFIRE, shoot beams with FIRE!")
		p.swapfire = 1
		elseif (var1 == "0") or (var1 == "off") or (var1 == "Off") or (var1 == "OFF")
		CONS_Printf(p, "\x82"+"Fire buttons reverted to normal! Fire missiles with FIRE, shoot beams with NORMALFIRE!")
		p.swapfire = 0
		end
		p.shotbeambefore = true
	else
	CONS_Printf(p, "\x82"+"If set to ON, NORMALFIRE will fire missiles, and beams will be shot with FIRE.")
	end
end)
COM_AddCommand("ToggleSamusCustomButtons", function(p)
	if not p.c1c2disable
		CONS_Printf(p, "\x81"+"Custom 1 and Custom 2 are now disabled as useable buttons for Samus' actions. Autospeedbooster is highly recommended.")
		p.c1c2disable = true
	else
		CONS_Printf(p, "\x83"+"Custom 1 and Custom 2 are now enabled again as useable buttons for Samus' actions.")
		p.c1c2disable = nil
	end
end)
COM_AddCommand("SpawnGunShip", function(p)
 if not ( IsPlayerAdmin(p) or (p == server) )
 CONS_Printf(p, "Command is for admins.")
 return end
	if p.nogunshipspawn
	print("\x82"+"Samus' gunship will now appear again upon player spawn.")
	end
	for ns in players.iterate
		ns.nogunshipspawn = nil
	end
	for m in mobjs.iterate(mobjs)
		if m and m.valid and (m.type == MT_SAMUSSHIP)
		p.shipexists = m
		end
	end
	if not p.shipexists and p.mo and p.mo.valid
		P_SpawnMobj(p.mo.x+FixedMul(-65000, cos(p.mo.angle)), p.mo.y+FixedMul (-65000, sin (p.mo.angle)), p.mo.z, MT_SAMUSSHIP)
	end
	p.shipexists = nil
end)

COM_AddCommand("GravityLights", function(p, var1)
	if (var1 != nil) and (tonumber(var1) != nil)
		if (tonumber(var1) >= 1) and (tonumber(var1) <= tonumber(SKINCOLOR_PLASMABURNED)) and not (tonumber(var1) == tonumber(SKINCOLOR_EMERALD))
			p.samvisorcolor = tonumber(var1)
			CONS_Printf(p, "\x83"+"New visor and light colors set!")
		else
			CONS_Printf(p, "Start amount must be set between 1 and 102. Cannot pick 43.")
		end
		p.shotbeambefore = true
	else
	CONS_Printf(p, "\x82"+"Choose any color for the gravity suit lights between \x83"+"1 and 40"+"\x82, except for\x85 20!")
	end
end)

COM_AddCommand("CustomSuits", function(p, var1, var2, var3)
	if not p.mo
	CONS_Printf(p, "Player character does not exist.")
	return
	end
	if not YouAreSamus(p.mo)
	CONS_Printf(p, "Need to use Samus to use this command.")
	return
	end
	if G_GametypeHasTeams()
	CONS_Printf(p, "Cannot set this in team games.")
	return
	end
	if var1 and (var1 == "steady" or var1 == "Steady" or var1 == "STEADY")
		CONS_Printf(p, "Suit colors set to steady. You'll remain whatever color you pick regardless of suit.")
		p.customsuitc1 = 0
		p.customsuitc2 = 0
		p.customsuitc3 = 0
		return		
	end
	if (var1 != nil) and (tonumber(var1) != nil) and (var2 != nil) and (tonumber(var2) != nil) and (var3 != nil) and (tonumber(var3) != nil)
		if (tonumber(var1) >= 1) and (tonumber(var1) <= 40) and (tonumber(var2) >= 1) and (tonumber(var2) <= 40) and (tonumber(var3) >= 1) and (tonumber(var3) <= 40)
			p.customsuitc1 = tonumber(var1)
			p.customsuitc2 = tonumber(var2)
			p.customsuitc3 = tonumber(var3)
			CONS_Printf(p, "\x83"+"New custom suit colors set!")
			SetSamusColor(p.mo, p) 
			if (p.customsuitc1 >= SKINCOLOR_SUPERSILVER1)
			p.forceskincolor1 = p.customsuitc1
			else
			p.forceskincolor1 = 0
			end
			if (p.customsuitc2 >= SKINCOLOR_SUPERSILVER1)
			p.forceskincolor2 = p.customsuitc2
			else
			p.forceskincolor2 = 0
			end
			if (p.customsuitc3 >= SKINCOLOR_SUPERSILVER1)
			p.forceskincolor3 = p.customsuitc3
			else
			p.forceskincolor3 = 0
			end
			p.shotbeambefore = true
		else
			CONS_Printf(p, "Set 3 color numbers for each suit upgrade in order of power>varia>gravity. Example:\x82 CustomSuits 25 14 12")
		end
	else
	CONS_Printf(p, "Set 3 color numbers for each suit upgrade in order of power>varia>gravity. Example:\x82 CustomSuits 25 14 12")
	end
end)
local function SPDMsg(p)
	CONS_Printf(p, "Choose a number from this list! You can also set another player's node number at the end to spawn it in front of them!")
	CONS_Printf(p, "\x85 0=Bombs 1=Charge 2=Spazer 3=Wave 4=Ice 5=Plasma\x82 6=Hi-Jump 7=SpaceJump 8=SpeedBooster 9=BallUpgrade")
	CONS_Printf(p, "\x82 10=SuitUpgrade 11=ScrewAttack\x83 12=MissileTank 13=SuperMissileTank 14=PBOMB tank 15=EnergyTank")
end
COM_AddCommand("AntiSeizureMode", function(p)
	if p.sam_sensitive
	CONS_Printf(p, "\x84"+"Viewrolling, quakes, and flashes from Samus are back.")
	p.sam_sensitive	= false
	else
	CONS_Printf(p, "\x83"+"Most viewrolls, quakes, and flashes from Samus are now turned off for you.")
	p.sam_sensitive	= true
	end
end)
COM_AddCommand("SamusPowerDrop", function(p, var1, wt)
	if (IsPlayerAdmin(p) or (p == server))
	and p.valid and p.mo
		if not wt
			wt = p
		elseif (wt != nil and tonumber(wt) != nil and not (tonumber(wt) > 31))
		and players[tonumber(wt)] and players[tonumber(wt)].valid and players[tonumber(wt)].mo
			wt = players[tonumber(wt)]
		else
			CONS_Printf(p, "\x85"+"Invalid playernum.")
			SPDMsg(p)
			return
	 	end		
	local i
	    if tonumber(var1) != nil and (tonumber(var1) < 20)
			if (var1 == "0")
			print(p.name+"\x82 spawned Morph Ball Bombs for \x80"+wt.name)
			i = MT_MHBM
			elseif (var1 == "1")
			print(p.name+"\x82 spawned the Charge Beam for \x80"+wt.name)
			i = MT_CHBM
			elseif (var1 == "2")
			print(p.name+"\x82 spawned the Spazer Beam for \x80"+wt.name)
			i = MT_SPBM
			elseif (var1 == "3")
			print(p.name+"\x82 spawned the Wave Beam for \x80"+wt.name)
			i = MT_WVBM
			elseif (var1 == "4")
			print(p.name+"\x82 spawned the Ice Beam for \x80"+wt.name)
			i = MT_ICBM
			elseif (var1 == "5")
			print(p.name+"\x82 spawned the Plasma Beam for \x80"+wt.name)
			i = MT_PLBM
			elseif (var1 == "6")
			print(p.name+"\x82 spawned the High Jump/Spring Ball for \x80"+wt.name)
			i = MT_SPBL
			elseif (var1 == "7")
			print(p.name+"\x82 spawned the Space Jump boots for \x80"+wt.name)
			i = MT_SJMP
			elseif (var1 == "8")
			print(p.name+"\x82 spawned the Speed Booster for \x80"+wt.name)
			i = MT_SPBS
			elseif (var1 == "9")
				if not wt.sambsbl 
				i = MT_BSBL
				print(p.name+"\x82 spawned the Boost Ball for \x80"+wt.name)
				else
				i = MT_SPDRBL
				print(p.name+"\x82 spawned the Spider Ball for \x80"+wt.name)
				end
			elseif (var1 == "10")
				if wt.sam_gravitysuit
				print(p.name+"\x82 spawned the Gravity Suit for \x80"+wt.name)
				i = MT_GVST
				else
				print(p.name+"\x82 spawned the Varia Suit for \x80"+wt.name)
				i = MT_VRST
				end
			elseif (var1 == "11")
			print(p.name+"\x82 spawned the Screw Attack for \x80"+wt.name)
			i = MT_SATK
			elseif (var1 == "12")
			print(p.name+"\x82 spawned a Missile Tank for \x80"+wt.name)
			i = MT_MTNK
			elseif (var1 == "13")
			print(p.name+"\x82 spawned a Super Missile Tank for \x80"+wt.name)
			i = MT_STNK
			elseif (var1 == "14")
			print(p.name+"\x82 spawned a Powerbomb Tank for \x80"+wt.name)
			i = MT_PTNK
			elseif (var1 == "15")
			print(p.name+"\x82 spawned an Energy Tank for \x80"+wt.name)
			i = MT_ENGTNK
			elseif (var1 == "16")
			print(p.name+"\x82 spawned the Auto Tank for \x80"+wt.name)
			i = MT_AUTOTANK			
			elseif (var1 == "17")
			print(p.name+"\x82 spawned the Ammo Digitizer for \x80"+wt.name)
			i = MT_AMMODIGITIZER	
			elseif (var1 == "18")
			print(p.name+"\x82 spawned the Scan Visor for \x80"+wt.name)
			i = MT_SCANVISOR
			elseif (var1 == "19")
			print(p.name+"\x82 spawned the Power Grip for \x80"+wt.name)
			i = MT_PWGRP				
			end		
			if i
			P_SpawnMobj(wt.mo.x+FixedMul(210*FRACUNIT, cos(wt.mo.angle)), wt.mo.y+FixedMul (210*FRACUNIT, sin (wt.mo.angle)), wt.mo.z, i)		
			else
			SPDMsg(p)
			end
	    else
			CONS_Printf(p, "Choose who you want to receive the item, putting their nodenumber behind the item number.")
			SAM_COM_BufInsertText(p, "nodes")	     
	     end
		 p.shotbeambefore = true
	else
		CONS_Printf(p, "You can't access this right now!")
	end
end)

function A_SAMBEAMSWITCH(p)
	if p.sams_shotcd
	and not ( (p.sam_powerbeammeltdown and p.sam_powerbeamequip) or (p.sam_spazerbeammeltdown and p.sam_spazerbeamequip) or (p.sam_icebeammeltdown and p.sam_icebeamequip)
	or (p.sam_wavebeammeltdown and p.sam_wavebeamequip) or (p.sam_plasmabeammeltdown and p.sam_plasmabeamequip) )
	return
	end
	if p.mo and not p.sam_beamswitch and not p.sams_weappress
		if p.sam_wantstoswitch
			if p.sam_wantstoswitch == 1
				if not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wantstoswitch == 2
				if p.sam_spazerbeam and not p.sam_spazerbeamequip
				p.sam_powerbeamequip = false
				p.sam_spazerbeamequip = true
				p.sam_wavebeamequip = false
				p.sam_icebeamequip = false
				p.sam_plasmabeamequip = false
				p.sam_hyperbeamequip = false
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wantstoswitch == 3
				if p.sam_wavebeam and not p.sam_wavebeamequip
				p.sam_powerbeamequip = false
				p.sam_spazerbeamequip = false
				p.sam_wavebeamequip = true
				p.sam_icebeamequip = false
				p.sam_plasmabeamequip = false
				p.sam_hyperbeamequip = false
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wantstoswitch == 4
				if p.sam_icebeam and not p.sam_icebeamequip
				p.sam_powerbeamequip = false
				p.sam_spazerbeamequip = false
				p.sam_wavebeamequip = false
				p.sam_icebeamequip = true
				p.sam_plasmabeamequip = false
				p.sam_hyperbeamequip = false
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wantstoswitch == 5
				if p.sam_plasmabeam and not p.sam_plasmabeamequip
				p.sam_powerbeamequip = false
				p.sam_spazerbeamequip = false
				p.sam_wavebeamequip = false
				p.sam_icebeamequip = false
				p.sam_plasmabeamequip = true
				p.sam_hyperbeamequip = false
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wantstoswitch == 6
				if p.sam_hyperbeam and not p.sam_hyperbeamequip
				p.sam_powerbeamequip = false
				p.sam_spazerbeamequip = false
				p.sam_wavebeamequip = false
				p.sam_icebeamequip = false
				p.sam_plasmabeamequip = false
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			end
			
			if p.mo
			SamusTutorial(p.mo, "gravitysuit", true)
			end
			
			p.sam_wantstoswitch = 0
		
		elseif (p.cmd.buttons & BT_WEAPONNEXT) and not p.sam_scrollswap
		or (p.cmd.buttons & BT_WEAPONPREV) and p.sam_scrollswap

			if p.sam_powerbeamequip
				if p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end

			elseif p.sam_spazerbeamequip
				if p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_spazerbeamequip = false
				elseif p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_spazerbeamequip = false
				elseif p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_spazerbeamequip = false
				elseif p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_spazerbeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end

			elseif p.sam_wavebeamequip
				if p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_wavebeamequip = false
				elseif p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_wavebeamequip = false
				elseif p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_wavebeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end

			elseif p.sam_icebeamequip
				if p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_icebeamequip = false
				elseif p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_icebeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_plasmabeamequip
				if p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_plasmabeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_hyperbeamequip
				if not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			end
			if p.mo
			SamusTutorial(p.mo, "gravitysuit", true)
			end
		elseif (p.cmd.buttons & BT_WEAPONPREV) and not p.sam_scrollswap
		or (p.cmd.buttons & BT_WEAPONNEXT) and p.sam_scrollswap


			if p.sam_hyperbeamequip
				if p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_hyperbeamequip = false
				elseif p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_hyperbeamequip = false
				elseif p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_hyperbeamequip = false
				elseif p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_hyperbeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_plasmabeamequip
				if p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_plasmabeamequip = false
				elseif p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_plasmabeamequip = false
				elseif p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_plasmabeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_icebeamequip
				if p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_icebeamequip = false
				elseif p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_icebeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_wavebeamequip
				if p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_wavebeamequip = false
				elseif not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_spazerbeamequip
				if not p.sam_powerbeamequip
				SamResetBeam(p)
				p.sam_beamswitch = 11
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			elseif p.sam_powerbeamequip
				if p.sam_hyperbeam
				p.sam_hyperbeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_plasmabeam and not p.sam_plasmabeammeltdown
				p.sam_plasmabeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_icebeam and not p.sam_icebeammeltdown
				p.sam_icebeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_wavebeam and not p.sam_wavebeammeltdown
				p.sam_wavebeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.sam_spazerbeam and not p.sam_spazerbeammeltdown
				p.sam_spazerbeamequip = true
				p.sam_beamswitch = 11
				p.sam_powerbeamequip = false
				elseif p.mo
				S_StartSound(p.mo, sfx_sdenid)
				end
			end
			
			if p.mo
			SamusTutorial(p.mo, "gravitysuit", true)
			end
		end
	end
	p.sams_supermissileready = 0
	p.sams_shotcd = 12
	p.sams_weappress = true
end

/*
rawset(_G, "SamusShotImpact", function(s)
	if s.sam_correctdist != nil and s.sam_correctangle != nil
	local ogx = s.x
	local ogy = s.y
	local ogz = s.z
		P_MoveOrigin(s,
		s.x+FixedMul(s.sam_correctdist, cos(s.sam_correctangle)),
		s.y+FixedMul(s.sam_correctdist, sin(s.sam_correctangle)),
		s.z)

		s.sam_correctdist = nil
		s.sam_correctangle = nil
		
		return true
	else
		return false
	end
end) */

--Spawn a glowing mofo.
rawset(_G, "SamusBulletHole", function(s, scale, color, burn, noground)
if not (s or s.valid)
	return false --There's no object! This can happen since we're checking this post object-death.
end	
local onground
local onwall
	--Did we hit a floor?
	if P_IsObjectOnGround(s) --HA! Piece of cake, too easy!
		onground = true
	end
	
	--Then did we hit a wall?
	if not onground
		if s.sam_hitline and s.sam_hitline.valid --This one won't be as easy.
			local x,y = P_ClosestPointOnLine(s.x, s.y, s.sam_hitline)
			onwall = R_PointToAngle2(s.x, s.y, x, y)
		else
		
		local dist = FRACUNIT*150
		local lastdist
		searchBlockmap("lines", function(s, linedef)	
			local x,y = P_ClosestPointOnLine(s.x, s.y, linedef)
			if lastdist == nil
			or (R_PointToDist2(s.x, s.y, x, y) < lastdist)
				onwall = R_PointToAngle2(s.x, s.y, x, y)
				lastdist = R_PointToDist2(s.x, s.y, x, y)
			end
		end, s, s.x-dist, s.x+dist, s.y-dist, s.y+dist)
		end
	end
	
	--We found neither? Last chance generosity check!
	if onwall == nil
		if (s.z-s.height <= s.floorz)
			onground = true
		else
			return nil
		end
	end
	
	--Okay, spawn the graphic depending on circumstance!
	if onground or (onwall != nil)
	
		local ghs = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_THOK)
		ghs.scale = scale/4
		ghs.fuse = 10
		ghs.tics = 12
		ghs.blendmode = AST_ADD
		ghs.sprite = SPR_OILF
		
		if onground
			ghs.frame = A|FF_FULLBRIGHT|TR_TRANS70|FF_FLOORSPRITE
			ghs.renderflags = $|RF_NOCOLORMAPS|RF_SHADOWDRAW|RF_FLOORSPRITE|RF_SLOPESPLAT|RF_OBJECTSLOPESPLAT|RF_FULLBRIGHT
		else --Much more complex on walls...
			ghs.angle = onwall+ANGLE_90
			ghs.frame = A|FF_FULLBRIGHT|TR_TRANS60|FF_PAPERSPRITE
			ghs.renderflags = $|RF_NOCOLORMAPS|RF_PAPERSPRITE|RF_FULLBRIGHT			
			ghs.flags = $|MF_SOLID|MF_NOCLIPTHING & ~MF_NOCLIP & ~MF_NOCLIPHEIGHT
			ghs.radius = 1 ghs.height = 1
			for d = 1,99
				if not (P_TryMove(ghs, ghs.x+FixedMul(25356,cos(onwall)), ghs.y+FixedMul(25356,sin(onwall)), true))
				d = 100
				end
			end
			ghs.flags = $|MF_NOCLIP|MF_NOCLIPHEIGHT & ~MF_SOLID
			ghs.destscale = $*99
			if (ghs.z-150*FRACUNIT > s.z) --failsafe
			or (ghs.z+150*FRACUNIT < s.z)
			P_MoveOrigin(ghs, s.x, s.y, s.z)
			end
		end	

		if color
			ghs.color = color 
			ghs.colorized = true
		end
		
		if burn --Leave behind a burn?
			local ghs2 = P_SpawnMobj(ghs.x, ghs.y, ghs.z, MT_THOK)
			ghs2.scale = scale
			ghs2.blendmode = AST_ADD
			ghs2.sprite = SPR_MPR5
			ghs2.angle = ghs.angle
				if onground
					ghs2.frame = F|FF_FULLBRIGHT|TR_TRANS40|FF_FLOORSPRITE
					ghs2.renderflags = $|RF_FLOORSPRITE|RF_SLOPESPLAT|RF_OBJECTSLOPESPLAT
				else
					ghs2.angle = ghs.angle
					ghs2.frame = F|FF_FULLBRIGHT|TR_TRANS30|FF_PAPERSPRITE
					ghs2.renderflags = $|RF_PAPERSPRITE
					if (ghs2.z-150*FRACUNIT > s.z) --failsafe
					or (ghs2.z+150*FRACUNIT < s.z)
					P_MoveOrigin(ghs2, s.x, s.y, s.z)
					end		
				end	
			ghs2.frame = F|FF_TRANS30|FF_PAPERSPRITE
			ghs2.fuse = 100
			ghs2.tics = 105	
		end
	end
	return ghs
end)

--Spawn a prism from an object!
rawset(_G, "SpawnSamusPrism", function(s, target, superprism)
	local ghs = P_SpawnMobj(s.x, s.y, s.z+(s.height/2), MT_NRGH)
	ghs.blendmode = AST_ADD
	ghs.fuse = 260
	ghs.donttouch = 11
	ghs.target = target
	ghs.colorized = true
	ghs.ghosttime = 10
	P_InstaThrust(ghs, P_RandomRange(1,359)*ANG1, 45*FRACUNIT)
	P_SetObjectMomZ(ghs, P_RandomRange(12,26)*FRACUNIT)
	if superprism --Big boi.
		ghs.color = SKINCOLOR_EMERALD
		ghs.destscale = 2*FRACUNIT
		ghs.superprism = true
	else
		ghs.color = SKINCOLOR_ROSY
		ghs.scalespeed = $*3
	end
end)

--Effect for players in particular.

rawset(_G, "WaveOverloadEffect", function(s)						
	local ghs = P_SpawnGhostMobj(t)
	ghs.tics = 11
	ghs.blendmode = AST_ADD
	ghs.scalespeed = $/10*P_RandomRange(5,8)
	ghs.destscale = $*50
	ghs.colorized = true
	ghs.momx = P_RandomRange(-3,3)*FRACUNIT 
	ghs.momy = P_RandomRange(-3,3)*FRACUNIT
	ghs.momz = P_RandomRange(0,2)*FRACUNIT*P_MobjFlip(t)
		if s.dietime % 4 == 0
			A_SAMPARTICLE(t, MT_MPR1, 4, 4, -2, 6, SKINCOLOR_GOLD, P_RandomRange(9355, 30355))
			A_SAMPARTICLE(t, MT_MPR1, 5, 3, -3, 6, SKINCOLOR_MAGENTA, P_RandomRange(35355, 65354))					
			ghs.color = P_RandomRange(SKINCOLOR_SUPERPURPLE1, SKINCOLOR_SUPERPURPLE5)
		else
			t.angle = $+ANG10
			ghs.color = SKINCOLOR_GRAVITYSUIT
		end
end)

--Lazy shortcut function.

rawset(_G, "SamShinySplat", function(s, color, fuse)
	local ghs = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
	ghs.sprite = SPR_OILF
	ghs.frame = A|TR_TRANS60|FF_FULLBRIGHT
	ghs.flags = $|MF_NOGRAVITY & ~MF_NOCLIPHEIGHT
	ghs.colorized = true
	ghs.color = color
	ghs.blendmode = AST_ADD
	ghs.destscale = $*99
	ghs.flags2 = $|MF2_SPLAT
	ghs.renderflags = $|RF_SLOPESPLAT|RF_OBJECTSLOPESPLAT
	ghs.fuse = fuse ghs.tics = fuse+12
	return ghs
end)

--The Death Ball hurts, man.
rawset(_G, "DeathBallImpact", function(s, i)
		if s != i and s.player
		P_InstaThrust(i, R_PointToAngle(i.x, i.y, s.x, s.y), -20*FRACUNIT)
		P_SetObjectMomZ(i, 6*FRACUNIT, true)
		end
		
		for d = 1,8 --Even I couldn't stand the old code for this one...
			if s != i and s.player
			local ghs = P_SpawnMobj(s.x+FixedMul(-180*FRACUNIT, cos(s.angle+(ANGLE_45*d))), s.y+FixedMul(-180*FRACUNIT, sin (s.angle+(ANGLE_45*d))), s.z+FixedMul(FRACUNIT*20, (P_MobjFlip(s)*s.scale)), MT_SAMMORPHBOMB)
			if ghs and ghs.valid
				ghs.flags = $|MF_GRENADEBOUNCE|MF_BOUNCE & ~MF_NOGRAVITY
				ghs.target = i
				ghs.flags2 = $|MF2_DONTDRAW
				S_StopSound(ghs)
				if (ghs.floorz > s.floorz+140*FRACUNIT) --Oh, geez, don't clip up there.
					ghs.state = S_NULL
				end
			end
			end
			local ghs = P_SpawnMobj(s.x+FixedMul(-130*FRACUNIT, cos(s.angle+(ANGLE_45*d))), s.y+FixedMul(-130*FRACUNIT, sin (s.angle+(ANGLE_45*d))), s.z+FixedMul(FRACUNIT*20, (P_MobjFlip(s)*s.scale)), MT_MINIFIRE)
			if ghs and ghs.valid
				ghs.flags = $ & ~MF_NOGRAVITY
				ghs.target = i
				ghs.morning = 140
				S_StopSound(ghs)
				if (ghs.floorz > s.floorz+140*FRACUNIT)
					ghs.state = S_NULL
				end
			end
			
			ghs = P_SpawnMobj(s.x+FixedMul(-150*FRACUNIT, cos(s.angle+(ANGLE_45*d))), s.y+FixedMul(-150*FRACUNIT, sin (s.angle+(ANGLE_45*d))), s.z+FixedMul(FRACUNIT*20, (P_MobjFlip(s)*s.scale)), MT_THOK)
			ghs.sprite = SPR_MPR9
			ghs.frame = 26|FF_FULLBRIGHT|TR_TRANS20
			ghs.blendmode = AST_ADD
			ghs.scale = 160000
			ghs.destscale = $*99
			ghs.scalespeed = $*3
			P_SetObjectMomZ(ghs, 3*FRACUNIT)		
		end
		
	local ghs = SamShinySplat(i, SKINCOLOR_SUPERGOLD5, 16)
	ghs.frame = A|TR_TRANS60|FF_FULLBRIGHT
	ghs.scalespeed = $*2
	
	for d = 1,29
		local ghs = P_SpawnMobj(
		s.x+FixedMul((100+(d*7)*FRACUNIT),cos(s.angle)),
		s.y+FixedMul((100+(d*7)*FRACUNIT),sin(s.angle)),
		s.z, MT_THOK)
			ghs.eflags = s.eflags
			ghs.sprite = SPR_MPR9
			P_SetObjectMomZ(ghs, (30-d)*FRACUNIT)
			if d % 2 == 0
				ghs.frame = V|TR_TRANS40|FF_FULLBRIGHT
				P_SetObjectMomZ(ghs, 5*FRACUNIT)
				ghs.scale = $*2
				ghs.color = SKINCOLOR_RED
			else
				ghs.frame = W|TR_TRANS10|FF_FULLBRIGHT
				ghs.scale = $*3
				ghs.color = SKINCOLOR_SUPERGOLD3
			end
			ghs.rollangle = d*ANG20
			ghs.blendmode = AST_ADD
			ghs.destscale = $*99
			ghs.fuse = 8+d
			ghs.tics = 99		
	end	
end)

--The Wave Charge Shot has a status effect!
rawset(_G, "InflictWaveOverLoad", function(s, time, inflictor)
local p = s.player
	S_StartSound(s, sfx_dmpain)
	s.sam_systemreboot = time
//	P_SamFP(p, PAL_NUKE, 3)
	s.sam_flashfade = 20
	s.sam_flashfadecolor = SKINCOLOR_PURPLE	
	SamusMission(s, "  SYSTEM MALFUNCTION!", nil, nil, 3, 0, false)
	
	if s.samusmission
		s.samusmission.textwait = 0	
		s.samusmission.animtimer = 0
	end
	
	--Counterattack with an instant shinespark?
	if p.sam_shinespark and inflictor and inflictor.valid
	
		if P_IsObjectOnGround(s)
			if (s.eflags & MFE_VERTICALFLIP)
			s.z = $-50*FRACUNIT
			else
			s.z = $+50*FRACUNIT
			end
		end
		if inflictor.player
			P_SamFP(inflictor.player, PAL_NUKE, 3)
			S_StartSound(nil, sfx_spbsc, inflictor.player)
		end
		p.sams_morphcd = 35
		p.sams_jumpcd = 10
		p.sams_firecd = 0
		p.sams_shotcd = 22
		p.sams_mshotcd = 22
		p.samspbschargefull = false
		p.sam_spacejumped = true
		p.samspbscharge = 0
		p.bsblboost = 0
		p.bsblboostattack = 0
		p.sambsblchargefull = false
		p.sams_supermissileready = 0
		p.sam_shinespark = 0
		S_StartSound(s, sfx_spbsc)
		for d = 1,3
			local ghs = P_SpawnMobj(s.x, s.y, s.z+((s.height*3/5)*P_MobjFlip(s)), MT_PBEXPAND)
			ghs.scale = s.scale*2
			ghs.scalespeed = $*9
			ghs.destscale = s.scale*25
			ghs.colorized = true
			ghs.color = SKINCOLOR_PURPLE-1+d
		end	
		p.sam_shinesparkdirect = R_PointToAngle2(s.x, s.y, inflictor.x, inflictor.y)
		s.angle = p.sam_shinesparkdirect
		if p.sammorphed
			p.sam_shinesparkdirectx = FixedMul(FRACUNIT*140, s.scale)
		else
			p.sam_shinesparkdirectx = FixedMul(FRACUNIT*66, s.scale)
		end
		p.sam_shinesparkdirectz = 0 
		s.momz = FRACUNIT
		p.sam_shinesparkfly = 17
		
	else --Regular behaviour
	
		s.sam_waveoverload = time-4
		
	end
end)

 --Disintegrate our foes. M is the dust-spawner, style is type.
 --explodepush makes it push-based without disintegration, playerpush makes Samus do it.
rawset(_G, "Dustintegrate", function(m, style, i, explodepush, playerpush)
	if m.player and m.player.hypermysticsonic
	or m.crystalflashanim
		return
	end
	
	local s = P_SpawnMobj(m.x, m.y, m.z, MT_DUSTTRACKER)
	
		if m.player
			m.sprite2 = SPR2_DEAD
			m.frame = A|FF_FULLBRIGHT
			S_StopSound(m)
		end
		
		s.target = m
		m.flags2 = $|MF2_DONTDRAW
		
		if style
			if style == 3
				s.hyperdust = true
			elseif style == 2
				s.plasmadust = true
				m.plasmadust = true
			else
				s.metroiddust = true
				m.metroiddust = true
			end
		end
		
		if not explodepush
			for d = 1,2
			local ghs = P_SpawnGhostMobj(m)
				if d == 1
				ghs.color = SKINCOLOR_CRIMSON
				else
				ghs.color = SKINCOLOR_YELLOW
				end
			ghs.colorized = true
			ghs.tics = 13
			ghs.fuse = 13
			ghs.scalespeed = $*3*d
			ghs.destscale = $*20
			end
		end
		
		
		s.formershell = P_SpawnGhostMobj(m)	
		s.formershell.tics = 91
		s.formershell.fuse = 91
		s.formershell.renderflags = $|RF_FULLBRIGHT
		
		if not explodepush
			s.formershell.colorized = true
			s.formershell.scalespeed = $/6
			if s.metroiddust
				s.formershell.scalespeed = $/3
			end		
			s.formershell.destscale = $*5
		end
		if explodepush --Pay attention, you NEED an inflictor for this one.
			s.dtexplodepush = 1
			s.formershell.flags = $ & ~MF_NOGRAVITY & ~MF_NOCLIPHEIGHT & ~MF_NOCLIP
			P_SetObjectMomZ(s.formershell, explodepush)
			P_Thrust(s.formershell, R_PointToAngle2(s.formershell.x, s.formershell.y, i.x, i.y), explodepush*-2)
			s.formershell.rollangle = $+(P_RandomRange(-45,45)*ANG1)
			
			if playerpush --Override explodepush settings....
				s.dtplayerpush = true
				S_StartSound(i, sfx_dmpain)
				if i.player.sam_screwattacking
					P_SetObjectMomZ(s.formershell, 11*FRACUNIT, false)
				else
					P_SetObjectMomZ(s.formershell, explodepush/4, false)
				end
				P_InstaThrust(s.formershell, i.angle, i.player.speed+20*FRACUNIT)
			end
			
		elseif (s.formershell.z > s.floorz+50*FRACUNIT) and not i
			s.formershell.flags = $ & ~MF_NOGRAVITY & ~MF_NOCLIPHEIGHT
			s.formershell.rollangle = $+(P_RandomRange(-45,45)*ANG1)
			P_SetObjectMomZ(s.formershell, 4*FRACUNIT, true)
			P_Thrust(s.formershell, s.formershell.angle, -5*FRACUNIT)
		end
		
		if not explodepush
		s.ghs2 = P_SpawnMobj(m.x, m.y, m.z, MT_THOK) --Make the sound!
		s.ghs2.flags2 = $|MF2_DONTDRAW
		s.ghs2.tics = 130
			if style == 1 --Metroid Husk
				S_StartSound(s.ghs2, sfx_s3k81) S_StartSound(s.ghs2, sfx_s1c4) S_StartSound(s.ghs2, sfx_s1b8)
			elseif not i or not style --Knockback.
				S_StartSound(s.ghs2, sfx_s233)
				S_StartSound(s.ghs2, sfx_s233)
				S_StartSound(s.ghs2, sfx_s3k43) 
			elseif i and i.valid --Turn into ashes.
				s.superdisintegrate = true
				S_StartSound(s.ghs2, sfx_pldisi)
				s.formershell.rollangle = $+(ANG1*P_RandomRange(-95,95))
				s.formershell.flags = $ & ~MF_NOCLIP & ~MF_NOCLIPHEIGHT & ~MF_NOGRAVITY
				s.formershell.renderflags = $|RF_FULLBRIGHT
				s.formershell.momx = i.momx/4
				s.formershell.momy = i.momy/4
				s.formershell.momz = i.momz/4
			end
		end

		s.dthealth = m.health --there's a good chance our friend will disappear soon....		
		s.dtradius = m.radius --So copy some values from our target
		s.dtangle = m.angle		
		s.dtsprite = m.sprite
		s.dtframe = m.frame
		s.dtheight = m.height
		s.dtscale = m.scale
		s.renderflags = $|RF_FULLBRIGHT
		s.dtxloc = s.formershell.x 
		s.dtyloc = s.formershell.y 
		s.dtzloc = s.formershell.z
		s.dtcolor = m.color
		
		if s.selectedframe
			if s.selectedsprite
				s.formershell.sprite = s.selectedsprite
			else 
				s.formershell.sprite = m.sprite
			end
			s.formershell.frame = s.selectedframe
		else
			s.formershell.frame = $ & ~TR_TRANS10 & ~TR_TRANS20 & ~TR_TRANS30 & ~TR_TRANS40 & ~TR_TRANS50 & ~TR_TRANS60 & ~TR_TRANS70 & ~TR_TRANS80 & ~TR_TRANS90
			s.selectedframe = s.formershell.frame
		end
end)

--Destroy all of Samus' powerups.
rawset(_G, "CollectSamusTax", function(p, keepachievements) 
			if G_GametypeHasSpectators()
				p.sammissilesmax = 5
			else
				if (p.sam_energy < 99)
				p.sam_energy = 99
				end
				p.sammissilesmax = 0
			end
				if not keepachievements
				p.sam_achievement1 = 0
				p.sam_achievement2 = 0
				p.sam_achievement3 = 0
				end
				p.crystalflashchance = 0
				p.samsupermissilesmax = 0
				p.sampwmax = 0
				p.sam_spiderball = false
				p.sam_power_grip = false
				p.samspbs = false
				p.sambsbl = false
				p.sam_bombs = false
				p.sam_highjump = false
				p.sam_spacejump = false
				p.sam_chargebeam = false
				p.sam_spazerbeam = false
				p.sam_wavebeam = false
				p.sam_icebeam = false
				p.sam_plasmabeam = false
				p.sam_hyperbeam = false
				p.sam_powerbeamcombo = false
				p.sam_spazerbeamcombo = false
				p.sam_wavebeamcombo = false
				p.sam_icebeamcombo = false
				p.sam_plasmabeamcombo = false
				p.sam_screwattack = false
				p.sam_fullypoweredsuit = false
				SamResetBeam(p)
				p.sams_itemcompletion = 0
				p.sam_energytanksmax = 0
				p.sam_gravitysuitjustgot = 0
				p.sam_autotank = nil
				p.sam_ammodigitizer = 1
				p.sam_gravitysuit = 0
				
				if p.mo
				SetSamusColor(p.mo, p) 
				end
end)

--Whatever causes the visor-glaring explosion makes Samus' face reflect in the glass

rawset(_G, "SamFaceReflect", function(s, radius)
	if not (s and s.valid) or not radius
		return
	end
	for z in players.iterate --Look for nearby Samus players.
		if z and z.mo and YouAreSamus(z.mo) and not z.sammorphed
			if (FixedHypot(FixedHypot(s.x-z.mo.x, s.y-z.mo.y), s.z-z.mo.z) < radius)
				z.mo.sam_reflectfacebig = false
				z.mo.sam_reflectface = 16
				if (radius > 190*FRACUNIT) and (FixedHypot(FixedHypot(s.x-z.mo.x, s.y-z.mo.y), s.z-z.mo.z) < (radius/2))
					z.mo.sam_reflectfacebig = true
					if (radius > 774*FRACUNIT)
						z.mo.sam_reflectface = 32
					end
				end
			end
		end
	end
end)

--Shortcut for quick camera switch. 
rawset(_G, "SamCam", function(p, var1)
if not p or not camera return end
	if var1 == 7 --Switch depending on saved preference.
		if p.sam_firstperson
			camera.chase = false
		else
			camera.chase = true
		end
	elseif (p == consoleplayer)
		if var1 == true
			camera.chase = true
		else
			camera.chase = false
		end
	end
end)

--Set charge only if morphed Samus.
rawset(_G, "SamSpiderCharge", function(p, s, num)
	if p.sammorphed and YouAreSamus(s)
		s.spiderbcharge = num
	end
end)

--Calculate if we should continue depending on player's energy, keeping difficulty and defense in mind.
rawset(_G, "SAM_Damage", function(p, zero, hyper, fusion, ignoredefense)
	--Factor in difficulty, if applicable.
	local num = zero
	if fusion and hyper
		if p.fusionmode
			num = fusion
		elseif p.crazysamusmobs
			num = hyper
		end
	end
	
	--Now optionally factor in defense. The base number assumes you're using the Varia Suit.
	--The Gravity Suit reduces the number by about 30%, while having no suit powerups boosts damage taken by 15% instead.
	if not ignoredefense
		num = ($*8)/p.gravityrd
	end
	
	if ((p.sam_energy-num) <= 0) --We would die from this. Return false.
		return false
	else --We'd live. Deal damage
		return num
	end
end)

--Return appropriate value for difficulty.
/*rawset(_G, "SAM_DifficultyNum", function(p, zero, hyper, fusion)
	if (gametype != GT_COOP)
		return zero
	end
	if p.fusionmode --Fusion Mode Difficulty. Challenge Mode.
		return fusion
	elseif p.crazysamusmobs --Hyper Mode Difficulty. Normal mode.
		return hyper
	else --Zero Mission Difficulty. Casual mode.
		return hyper
	end
end) */

--Only switches INTO Morph Ball, not out.
rawset(_G, "SamMorphSwitch", function(p, s)
		--Turn off scan visor 
		if s.sam_scanning
			s.sam_scanning = 0
			s.samusjustscanned = false
			p.scannedmons = nil
			p.scannedplays = nil
			S_StopSoundByID(s, sfx_sscan1)
		end
		--Reset a bunch of stuff	
		if s.sam_geton and s.sam_geton > 50
			s.sam_geton = 0
		end
		p.sams_beamcombocharge = 0
		p.bsblboost = 0
		p.bsblboostattack = 0
		p.sambsblchargefull = false
		p.sam_spacejumpedboost = 0
		p.thrustfactor = skins[s.skin].thrustfactor
		p.accelstart = skins[s.skin].accelstart
		p.sams_notyet = 3
		p.sams_usecd = 9
		p.sams_notyet = 3
		p.sams_firecd = 0
		p.sams_c1cd = 0
		p.sams_c2cd = 0
		p.sams_normfcd = 0
		p.sams_supermissileready = 0
		p.sams_powerbombready = 0
		
		--Morph into a ball.	
		s.state = S_PLAY_ROLL
		p.viewrollangle = 0
		s.sammorphedghs = 5		
		p.sammorphed = true
		s.scale = 42001
		if p.sam_spiderball
			if s.spiderbcharge == nil
			or (s.spiderbcharge < 58)
				s.spiderbcharge = 58
			end
		end
		
		--Ghost effect comes after.
		local ghs = P_SpawnGhostMobj(s)
		ghs.destscale = ghs.scalespeed
		
		if (CV_FindVar("chasecam").value == 0)		
			if not twodlevel
			and not (s.flags2 & MF2_TWOD)
			and not p.threedimensionalexplosion
				p.sam_firstperson = true
			end
		else
			p.sam_firstperson = false
		end
		
		SamCam(p, true)
end)

--Samus' morph ball trail styled like Prime. 

rawset(_G, "SamMorphTrail", function(p, s, tcolor)
local renderer = 1
	if SAM_displayplayer(p) --This part doesn't need to sync.
		renderer = CV_FindVar("renderer").value --2 is openGL.
	end
		
	local density = 12*FRACUNIT --Software is less powerful and can't handle as many sprites.
	if SAM_displayplayer(p) --Since OpenGL is more accurate, it benefits more from a higher density as well.
		if renderer == 2
			density = 6*FRACUNIT
		end
	end
		
	local dist = FixedDiv(FixedMul((R_PointToDist2(0, 0, R_PointToDist2(0, 0, s.momx, s.momy), (s.z-s.prevz2)) / density), FRACUNIT), s.scale)
	dist = max(1, min($,180))
		
	local xdistog = (s.momx/dist)
	local ydistog = (s.momy/dist)
	local zdistog = (s.z-s.prevz2)
		
	if zdistog == 0
		zdistog = 1
	end
	zdistog = $/dist
		
	local xdist = 0
	local ydist = 0
	local zdist = 0
	--Keep counting down by -1 until we reach 0
			for i = dist,1,-1
				if s.scale != FRACUNIT
					xdist = FixedDiv(FixedMul((s.momx/dist)*i, FRACUNIT), s.scale)
					ydist = FixedDiv(FixedMul((s.momy/dist)*i, FRACUNIT), s.scale)
					zdist = FixedDiv(FixedMul(((s.z-s.prevz2)/dist)*i, FRACUNIT), s.scale)
				else
					xdist = xdistog*i
					ydist = ydistog*i
					zdist = zdistog*i
				end
				local morphtrail = P_SpawnMobjFromMobj(s, xdist-s.momx, ydist-s.momy, zdist-(s.z-s.prevz2), MT_THOK)	
				morphtrail.sprite = SPR_BBTR
				if renderer == 2
					morphtrail.frame = B|TR_TRANS90|FF_PAPERSPRITE|FF_FULLBRIGHT
				else
					morphtrail.frame = B|TR_TRANS70|FF_PAPERSPRITE|FF_FULLBRIGHT
				end					
				morphtrail.scale = 42001
				morphtrail.angle = R_PointToAngle2(morphtrail.x, morphtrail.y, s.x, s.y)+ANGLE_90
				morphtrail.fuse = (p.speed/5)/FRACUNIT
				morphtrail.tics = 99
				morphtrail.blendmode = AST_ADD				
				morphtrail.colorized = true
				morphtrail.renderflags = $|RF_FULLBRIGHT|RF_PAPERSPRITE
				
				if p.bsblboostattack
					morphtrail.fuse = 7
					morphtrail.color = SKINCOLOR_SUPERGOLD5
					if p.bsblboostattack < 4
						morphtrail.flags2 = $|MF2_DONTDRAW
						return
					end
				elseif (morphtrail.fuse > 5) or (morphtrail.fuse < 1)
					morphtrail.fuse = 5
					morphtrail.color = tcolor
				elseif morphtrail and p.samvisorcolor and (p.sam_gravitysuit and p.sam_gravitysuit == 2)
					morphtrail.color =  p.samvisorcolor 
				end
				
				if s.morphtrailwait or (SAM_displayplayer(p)
				and not CV_FindVar("chasecam").value) --If for whatever reason you're in first person morphballing
					morphtrail.flags2 = $|MF2_DONTDRAW
					return
				end
			end
end)