--===========================SAVING AND LOADING PAGE==============================
--Functions related to loading and saving.
--================================================================================

rawset(_G, "ProfileSamusSave", function(s, p, savenum, dosave, doload, checkonly) 
--First, setup to make sure!
if (doload or dosave) and (gametype != GT_COOP) --Cannot load or save in Matches!
	return false
end
if not s or not p --Makes sure we exist first!
	return false
end
if splitscreen and players[1] == p --Player 2 doesn't need a dedicated save.
	return false 
end	
if not (gamemap)
	CONS_Printf(p, "\x87"+"No map to save!")
	return false
end
--Save File! First, we set up a table to put all our data in, or I will literally go to hell.
	if dosave
		local s1 = {
		sam_bombs = 0, --Main equipment
		samspbs = 0,
		sambsbl = 0,
		sam_spiderball = 0,
		sam_gravitysuit = 0,
		sam_screwattack = 0,
		sam_highjump = 0,
		sam_spacejump = 0,
		sam_spazerbeam = 0,
		sam_wavebeam = 0,
		sam_icebeam = 0,
		sam_plasmabeam = 0,
		sam_powerbeamcombo = 0,
		sam_spazerbeamcombo = 0,
		sam_wavebeamcombo = 0,
		sam_icebeamcombo = 0,
		sam_plasmabeamcombo = 0,
		sam_hyperbeam = 0,
						
		sam_energy = 99, --Energy
		sam_energytanksmax = 0,

		sammissiles = 0, --Ammo
		sammissilesmax = 0,
		samsupermissiles = 0,
		samsupermissilesmax = 0,
		sampw = 0,
		sampwmax = 0,
		
		sam_scanvisor = 0, --Bonus
		sam_ammodigitizer = 1,
		sam_autotank = 0,
		crystalflashchance = 0,
		sam_emeraldflags = 0,
		
		sam_fullypoweredsuit = 0, --Achievements
		sam_gamemap = gamemap,
		sam_achievement1 = 0,
		sam_achievement2 = 0,
		sam_achievement3 = 0,
		sam_achievementlock = 0,
		sam_saveddifficulty = 1,
		sam_diffusionmissiles = 0,
		sam_power_grip = 0,
		sam_chargebeam = 0,
		sam_hyperbeamammo = 0,
		sams_itemcompletion = 0
		}
--Now that the table is set, let's decide what needs to be saved!
		
			if p.sam_bombs s1.sam_bombs = 1 end
			if p.samspbs s1.samspbs = 1 end
			if p.sambsbl s1.sambsbl = 1 end
			if p.sam_spiderball s1.sam_spiderball = 1 end
		
			if p.sam_gravitysuit
				if (p.sam_gravitysuit < 3)
				s1.sam_gravitysuit = p.sam_gravitysuit
				else
				s1.sam_gravitysuit = 2
				end
			else
			s1.sam_gravitysuit = 0
			end	
			if p.sam_screwattack s1.sam_screwattack = 1 end
			if p.sam_highjump s1.sam_highjump = 1 end
			if p.sam_spacejump s1.sam_spacejump = 1 end
			if p.sam_spazerbeam s1.sam_spazerbeam = 1 end
			if p.sam_wavebeam s1.sam_wavebeam = 1 end
			if p.sam_icebeam s1.sam_icebeam = 1 end
			if p.sam_plasmabeam s1.sam_plasmabeam = 1 end
			if p.sam_powerbeamcombo s1.sam_powerbeamcombo = 1 end
			if p.sam_spazerbeamcombo s1.sam_spazerbeamcombo = 1 end
			if p.sam_wavebeamcombo s1.sam_wavebeamcombo = 1 end
			if p.sam_icebeamcombo s1.sam_icebeamcombo = 1 end
			if p.sam_plasmabeamcombo s1.sam_plasmabeamcombo = 1 end
			if p.sam_hyperbeam s1.sam_hyperbeam = 1	end


			--Ammo, health
			s1.sam_energy = p.sam_energy
			
			if p.sam_energytanksmax 
				s1.sam_energytanksmax = p.sam_energytanksmax
			else
				s1.sam_energytanksmax = 0
			end	
			
			s1.sammissiles = p.sammissiles
			s1.sammissilesmax = p.sammissilesmax
			s1.samsupermissiles = p.samsupermissiles
			s1.samsupermissilesmax = p.samsupermissilesmax
			s1.sampw = p.sampw
			s1.sampwmax = p.sampwmax
		
			if p.sam_scanvisor s1.sam_scanvisor = 1 else s1.sam_scanvisor = 0 end --Bonus
			if p.sam_ammodigitizer and p.sam_ammodigitizer != 1 s1.sam_ammodigitizer = 3 else s1.sam_ammodigitizer = 1 end
			if p.sam_autotank s1.sam_autotank = 99 else s1.sam_autotank = 0 end
			
			if p.crystalflashchance
			s1.crystalflashchance = p.crystalflashchance 
				if (s1.crystalflashchance > 999)
				s1.crystalflashchance = 999
				end
			else
			s1.crystalflashchance = 0
			end
			
			if emeralds --Which emeralds did we get?
				s1.sam_emeraldflags = emeralds
			else
				s1.sam_emeraldflags = 0
			end
			
			if p.sam_fullypoweredsuit s1.sam_fullypoweredsuit = 1 end
			
			if gamemap
			s1.sam_gamemap = gamemap
			else
			s1.sam_gamemap = 1
			end
			
			if p.sam_achievement1 s1.sam_achievement1 = p.sam_achievement1 end
			if p.sam_achievement2 s1.sam_achievement2 = p.sam_achievement2 end
			if p.sam_achievement3 s1.sam_achievement3 = p.sam_achievement3 end
			
			if p.sam_achievementlock s1.sam_achievementlock = 1 end
			
			if p.fusionmode
				s1.sam_saveddifficulty = 2
			elseif p.crazysamusmobs
				s1.sam_saveddifficulty = 1
			else
				s1.sam_saveddifficulty = 0
			end
				
			if p.sam_diffusionmissiles s1.sam_diffusionmissiles = 1 end
			
			if p.sam_power_grip s1.sam_power_grip = 1 end
			if p.sam_chargebeam s1.sam_chargebeam = 1 end	--Amazing, I forgot the CHARGE BEAM of all things.
			if p.sam_hyperbeamammo s1.sam_hyperbeamammo = p.sam_hyperbeamammo end
			if p.sams_itemcompletion s1.sams_itemcompletion = p.sams_itemcompletion end
			
	p.samussave = s1 --Okay! Table saved!
	end
	
--Okay, so what are we actually DOING with this info? Are we loading? Saving it to a savefile?
	if p.samussave or doload --The table is here!
	local s1 = p.samussave	
		if doload --We're loading!
			if (savenum == nil or savenum == 0 or not tonumber(savenum) or (tonumber(savenum) > 99)) --No save slot given? Then load whatever's in the table right now!
				if (savenum and tonumber(savenum) == 9001) --Is it 9001? Then start at the load screen.
					p.sam_initmenu = true
					p.newsamfile = true
				//	if p == consoleplayer
				//	SAM_COM_BufInsertText(p, "gr_shaders 1")
				//	end
				end
			else  --Okay, load from the designated save slot! Open Locally, then use BufInsertText to force it to re-sync
				local file = io.openlocal("client/MetroidVanguard/sav"+tostring(savenum)+".dat")
					if file 
					local code = file:read("*a")
						if code ~= nil and not (string.find(code, ";"))
						and (string.find(code, "21473647"))
							SAM_COM_BufInsertText(p, tostring(code))
							p.newsamfile = false
							if not checkonly
							CONS_Printf(p, "\x83"+"Successfully loaded from saveslot\x80 "+savenum)
							end
						else
						p.newsamfile = true
						SAM_COM_BufInsertText(p, "SamusLoad 21473647")
						end
						file:close()
						return true
					else
					SAM_COM_BufInsertText(p, "SamusLoad 21473647")
					p.newsamfile = true
					return true
					end
			end
			
		elseif dosave --We're saving!
			if not savenum or not tonumber(savenum) or (tonumber(savenum) > 99) --No save slot? Well, we just updated the table, so our job here's done!
			--
				return		
			else --Save it to a specific io slot as some kinda crazy console command.	
					if io and p == consoleplayer
						local file = io.openlocal("client/MetroidVanguard/sav"+tostring(savenum)+".dat", "w+")

							file:write("SAMUSLOAD "+tostring(21473647)+" "+tostring(savenum)+" "+s1.sam_bombs+" "
							+s1.samspbs+" "+s1.sambsbl+" "+s1.sam_spiderball+" "+s1.sam_gravitysuit+" "
							+s1.sam_screwattack+" "+s1.sam_highjump+" "+s1.sam_spacejump+" "+s1.sam_spazerbeam+" "
							+s1.sam_wavebeam+" "+s1.sam_icebeam+" "+s1.sam_plasmabeam+" "
							+s1.sam_powerbeamcombo+" "+s1.sam_spazerbeamcombo+" "+s1.sam_wavebeamcombo+" "
							+s1.sam_icebeamcombo+" "+s1.sam_plasmabeamcombo+" "+s1.sam_hyperbeam+" "
							+s1.sam_energy+" "+s1.sam_energytanksmax+" "+s1.sammissiles+" "
							+s1.sammissilesmax+" "+s1.samsupermissiles+" "+s1.samsupermissilesmax+" "
							+s1.sampw+" "+s1.sampwmax+" "+s1.sam_scanvisor+" "
							+s1.sam_ammodigitizer+" "+s1.sam_autotank+" "+s1.crystalflashchance+" "
							+s1.sam_emeraldflags+" "+s1.sam_fullypoweredsuit+" "+s1.sam_gamemap+" "
							+s1.sam_achievement1+" "+s1.sam_achievement2+" "+s1.sam_achievement3+" "
							+s1.sam_achievementlock+" "+s1.sam_saveddifficulty+" "+s1.sam_diffusionmissiles+" "
							+s1.sam_power_grip+" "+s1.sam_chargebeam+" "+s1.sam_hyperbeamammo+" "
							+s1.sams_itemcompletion)

						file:close()
						CONS_Printf(p, "\x86"+"Game has been saved to slot "+savenum+"\x86"+"!")
					end
			end
		end
	end
	
end)
			
//Ridiculously long command for autoloading. Practically requires copy&paste.
COM_AddCommand("SAMUSLOAD", function(p, ...)

	local args = {...}
	for i = 1,45 do --Turn all these string variables into numbers. Allow 45 at max.
		args[i] = tonumber($)
	end
	
	if (args[1] != nil and (args[1] == 21473647) and not args[2])
	and p.sam_saveselect
		p.newsamfile = true --Looks like a new save, so go stop the function here.
		return
	elseif args[1] == nil or ((args[1] != 21473647) and (args[1] != -21473648)) or not p.sam_saveselect
		return --Looks like we got to something completely invalid.
	end
	if (gametype != GT_COOP)
	or not p.mo
		return
	end
	if splitscreen and (p ~= players[0]) --Splitscreen unfortunately is barely supported with these HUD elements.
		return false  --I don't want it to completely break, though...
	end
	
local s = p.mo --s to save me headaches.
p.newsamfile = false --If we got this far, this is not a new save.
			if args[2] --Which save is it we're loading here??
				p.samussavenum = args[2]
			else
				p.samussavenum = 0
			end
			if args[3] == 1
				p.sam_bombs = true
			else
				p.sam_bombs = false
			end
			if args[4] == 1
				p.samspbs = true
			else
				p.samspbs = false
			end
			if args[5] == 1
				p.sambsbl = true
			else
				p.sambsbl = false
			end
			if args[6] == 1
				p.sam_spiderball = true
			else
				p.sam_spiderball = false
			end
			--Suit one is special
			if args[7] == 1
				p.sam_gravitysuit = 1
			elseif (args[7] > 1)
				p.sam_gravitysuit = 2		
			else
				p.sam_gravitysuit = 0			
			end	
			
			if args[8] == 1
				p.sam_screwattack = true
			else
				p.sam_screwattack = false
			end
			
			if args[9] == 1
				p.sam_highjump = true
			else
				p.sam_highjump = false
			end
			if args[10] == 1
				p.sam_spacejump = true
			else
				p.sam_spacejump = false
			end
			if args[11] == 1 
				p.sam_spazerbeam = true
			else
				p.sam_spazerbeam = false
			end
			if args[12] == 1 
				p.sam_wavebeam = true
			else
				p.sam_wavebeam = false
			end
			if args[13] == 1 
				p.sam_icebeam = true
			else
				p.sam_icebeam = false
			end
			if args[14] == 1 
				p.sam_plasmabeam = true
			else
				p.sam_plasmabeam = false
			end
			if args[15] == 1 
				p.sam_powerbeamcombo = true
			else
				p.sam_powerbeamcombo = false
			end
			if args[16] == 1 
				p.sam_spazerbeamcombo = true
			else
				p.sam_spazerbeamcombo = false
			end
			if args[17] == 1 
				p.sam_wavebeamcombo = true
			else
				p.sam_wavebeamcombo = false
			end
			if args[18] == 1 
				p.sam_icebeamcombo = true
			else
				p.sam_icebeamcombo = false
			end
			if args[19] == 1 
				p.sam_plasmabeamcombo = true
			else
				p.sam_plasmabeamcombo = false
			end
			if args[20] == 1
				if ( (netgame and (IsPlayerAdmin(p) or (p == server)) ) or not netgame )
				or (players[0] and (players[0] == server) and players[0].sam_hyperbeam) --If they get it, so should you.
				p.sam_hyperbeam = true
				end
			else
				p.sam_hyperbeam = false
			end
			if p.sam_dontupdateenergy
				if args[21] and (args[21] < p.sam_energy)
				p.sam_energy = args[21]
				end
				p.sam_dontupdateenergy = false
			elseif args[21]
				p.sam_energy = args[21]
			else
				p.sam_energy = 99
			end
			if args[22] < 13 
				p.sam_energytanksmax = args[22]
			else
				p.sam_energytanksmax = 0
			end
			if args[23]
				p.sammissiles = args[23]
			else
				p.sammissiles = 0
			end
			if args[24]
				p.sammissilesmax  = args[24]
			else
				p.sammissilesmax  = 0
			end	
			
			if args[25]
				p.samsupermissiles  = args[25]
			else
				p.samsupermissiles  = 0
			end
			if args[26]
				p.samsupermissilesmax = args[26]
			else
				p.samsupermissilesmax = 0
			end
			if args[27]
				p.sampw = args[27]
			else
				p.sampw = 0
			end
			if args[28]
				p.sampwmax = args[28]
			else
				p.sampwmax = 0
			end
			
			if args[29] == 1
				p.sam_scanvisor = true
			else
				p.sam_scanvisor = false
			end
			
			if args[30] and args[30] == 3
				p.sam_ammodigitizer = 3
			else
				p.sam_ammodigitizer = 1
			end
			if args[31] and args[31] == 99
				p.sam_autotank = 99
			else
				p.sam_autotank = 0
			end
			if args[32]
				p.crystalflashchance = args[32]
			else
				p.crystalflashchance = 0
			end				
			if (netgame and (IsPlayerAdmin(p) or (p == server)) ) or not netgame
				if args[33]
					p.sam_emeraldflags = args[33]
				else
					p.sam_emeraldflags = 0
				end
			end
			if args[34] == 1
			p.sam_fullypoweredsuit = true
				if ( (netgame and (IsPlayerAdmin(p) or (p == server)) ) or not netgame )
				p.sam_hyperbeam = true
				p.sam_emeraldflags = All7Emeralds(emeralds)
				end
				p.sam_fpsmsg = 0 --Just incase.
			else
				p.sam_fullypoweredsuit = false
			end	
			if args[35]
				p.sam_savedgamemap = args[35] --Let players choose to go back to this map and continue!
			else
				p.sam_savedgamemap = 1
			end
			if args[36]
				p.sam_achievement1 = args[36] --1 is bronze(normal), 2 is silver(hard), 3 is gold(fusion) 
			else
				p.sam_achievement1 = 0 --0 of course, means you have no achievement yet.
			end
			if args[37] --Also, achievement 1 is any%, achievement 2 is 100% clear, achievement 3 is 3% clear!
				p.sam_achievement2 = args[37]
			else
				p.sam_achievement2 = 0
			end
			if args[38]
				p.sam_achievement3 = args[38]
			else
				p.sam_achievement3 = 0
			end
			if args[39] --Achievement lock.
				p.sam_achievementlock = true
			else
				p.sam_achievementlock = false
			end
			if args[40] --Difficulty
			p.sam_saveddifficulty = args[40]
				if (netgame and (IsPlayerAdmin(p) or (p == server)) ) or not netgame
					if args[40] == 1
						for z in players.iterate
						z.crazysamusmobs = true
						z.fusionmode = false
						end
					elseif args[40] == 2
						for z in players.iterate
						z.crazysamusmobs = true
						z.fusionmode = true
						end
					end
				end
			else
			p.sam_saveddifficulty = 0
				if (netgame and (IsPlayerAdmin(p) or (p == server)) ) or not netgame
					for z in players.iterate
						z.crazysamusmobs = false
						z.fusionmode = false
					end
				end			
			end
			if args[41] --Diffusion Missiles
				p.sam_diffusionmissiles = true
			else
				p.sam_diffusionmissiles = false
			end
			if args[42] --power_grip
				p.sam_power_grip = true
			else
				p.sam_power_grip = false
			end
			if args[43] --Charge Beam
				p.sam_chargebeam = true
			else
				p.sam_chargebeam = false
			end
			if args[44] --Hyper ammo
				p.sam_hyperbeamammo = args[44]
			else
				p.sam_hyperbeamammo = 0
			end
			if args[45] --Item Completion
				p.sams_realitemcompletion = args[45]
			else
				p.sams_realitemcompletion = 0
			end
			
			SetSamusColor(s, p) 
end)

COM_AddCommand("SAMUSLOADCONFIG", function(p, ...)
if splitscreen and (p ~= players[0])
	return false 
end

local sargs = {...} --String Arguments
local args = {...}
	for i = 1,16 do --Turn all these string variables into numbers.
		args[i] = tonumber($)
	end
	
if args[1] != nil
	if (args[1] == 21473636)
		p.samusfirstsetupdone = true -- Welcome back.
	return false
	elseif (args[1] == 21473632)
		p.samusfirstsetupdone = false -- First time, boys?
	return false
	end
end
if args[1] == nil
--637 for personal, 539 for admin
or ((args[1] != 21473539) and (args[1] != 21473637))
CONS_Printf(consoleplayer, "\x88"+"This command isn't meant for general use!")
return
end
  if (args[1] == 21473637) --Personal version 
 			if sargs[2]
			
				if tonumber(sargs[2]) == nil --Filter the string first off spaces.
					sargs[2] = string.gsub(sargs[2] , "blurwhyPLZ", " ")
				end
				--Skincolor conversion if needed.		
				if (R_GetColorByName(sargs[2]))			
					sargs[2] = R_GetColorByName(sargs[2])
				else --It's a number then? Old save version or a supercolor, probably.
					sargs[2]= tonumber(sargs[2])
				end
				
				if sargs[2] --Sanity check.
					--Get our converted color!
					if not (sargs[2] > (#skincolors - 1)) --This would crash the game.
						p.customsuitc1 = sargs[2]							
					else
						p.customsuitc1 = nil
						CONS_Printf(p, "\x85"+"Failed to load custom suit color. Missing color mods occasionally mess this up. Using default.")
					end
				end
			end
			--Now repeat for the other custom suit colors
 			if sargs[3]
			
				if tonumber(sargs[3]) == nil --Filter the string first off spaces.
					sargs[3] = string.gsub(sargs[3], "blurwhyPLZ", " ")
				end
				--Skincolor conversion if needed.		
				if (R_GetColorByName(sargs[3]))			
					sargs[3] = R_GetColorByName(sargs[3])
				else --It's a number then? Old save version or a supercolor, probably.
					sargs[3] = tonumber(sargs[3])
				end		

				if sargs[3] and not (sargs[3] > (#skincolors - 1))
					p.customsuitc2 = sargs[3]
				else
					p.customsuitc2 = false --why
				end
			end	
 			if sargs[4]
				if tonumber(sargs[4]) == nil --Filter the string first off spaces.
					sargs[4] = string.gsub(sargs[4], "blurwhyPLZ", " ")
				end
				--Skincolor conversion if needed.		
				if (R_GetColorByName(sargs[4]))			
					sargs[4] = R_GetColorByName(sargs[4])
				else --It's a number then? Old save version or a supercolor, probably.
					sargs[4] = tonumber(sargs[4])
				end	
				if sargs[4] and not (sargs[4] > (#skincolors - 1))
					p.customsuitc3 = sargs[4]
				else
					p.customsuitc3 = nil
				end
			end
			
			
			if args[5]
				p.autospeedbooster = 1
			else
				p.autospeedbooster = 0
			end			
			if args[6]
				p.swapfire = true
			else
				p.swapfire = false
			end
			if args[7]
				p.nosamustutorials = true
			else
				p.nosamustutorials = false
			end
			
 			if sargs[8] --Visor color
				if tonumber(sargs[8]) == nil --Filter the string first off spaces.
					sargs[8] = string.gsub(sargs[8], "blurwhyPLZ", " ")
				end
				--Skincolor conversion if needed.		
				if (R_GetColorByName(sargs[8]))			
					sargs[8] = R_GetColorByName(sargs[8])
				else --It's a number then? Old save version or a supercolor, probably.
					sargs[8] = tonumber(sargs[8])
				end	
				if sargs[8] and not (sargs[8] > (#skincolors - 1))
					p.samvisorcolor = sargs[8]
				else
					p.samvisorcolor = SKINCOLOR_SKY
				end
			else
				p.samvisorcolor = SKINCOLOR_SKY
			end			
			
			if args[9]
				p.sam_scrollswap = true
			else
				p.sam_scrollswap = false
			end
			if args[10]
				p.sam_visorhidden = true
			else
				p.sam_visorhidden = false
			end
			if args[11]
				if args[11] == 1
				p.sam_lockonpower = 1
				else
				p.sam_lockonpower = 2
				end
			else
			p.sam_lockonpower = 0
				if p.mo
				SamusTutorial(p.mo, "lockon", true)
				end
			end
			if args[12]
			p.sam_lockontoggle = true
			else
			p.sam_lockontoggle = false
			end
			if args[13]
			p.sam_lockonnomon = true
			else
			p.sam_lockonnomon = false
			end
			if args[14]
				if args[14] == 1
				p.sam_noautoscan = 1
				else
				p.sam_noautoscan = 2
				end
			else
			p.sam_noautoscan = 0
			end
			if args[15]
				if not p.samusmusicadd2
				p.samusmusicadd2 = 3 --wait 3 tics.
				end
			else
			p.sam_autoaddmusic = false
			end
			if args[16] --Screen Tilt option
				if args[16] == 1
				p.sam_noscreentilt = 1
				else
				p.sam_noscreentilt = 2
				end
			else
				p.sam_noscreentilt = 0
			end
			
			if p.mo
			SetSamusColor(p.mo, p)
			end
			
  elseif (p == server) --Admin version
 	for z in players.iterate
 			if args[2] --Which save is it we're loading here??
			z.samusmatch = args[2]
			else
			z.samusmatch = 0
			end
			if args[3] == nil --Are joiners allowed to load any of their savefiles in COOP?
			z.sam_netsaves = true
			elseif not args[3]
			z.sam_netsaves = false
			else
			z.sam_netsaves = true
			end
			if args[4] --How many energy tanks to start with in Match?
			z.sam_energytanksstart = args[4]
			else
			z.sam_energytanksstart= 0
			end			
			if args[5] --Is Samus allowed in standard ringslinger or not?
			z.sammatchchars = args[5]
			else
			z.sammatchchars = 0
			end			
			if args[6] --Spawn monitors in Match with Samus' balance in mind, or with SRB2's standard algorithm?
			z.sammatchmonitors = true
			else
			z.sammatchmonitors = false
			end
			if args[7] --Respawn per Player, per timer, or not at all?
			z.coopboxrespawn = args[7]
			else
			z.coopboxrespawn = 0
			end
			if args[8] --Metroid style skins for objects like rings and starposts?
			z.metroidvisuals = true
			/*
				if z.mo and not netgame and not multiplayer
					if YouAreSamus(z.mo)
						z.metroidvisuals = true
					else
				//		z.metroidvisuals = false
					end
				else
					z.metroidvisuals = true
				end */
			end
			if args[9] --Can you toss players with morph ball?
			z.morphcoop = true
			else
			p.morphcoop = false
			end	
			if args[10] --Are powerbombs and Super Missiles available in match modes?
			z.nosuperpowert = true
			else
			z.nosuperpowert = false
			end		
			if args[11] --Can the Hyper Beam be used in netgames?
			z.hypernetgo = true
			else
			z.hypernetgo = false
			end
			if args[12] -- Can players use beam combos in match modes?
			z.sam_beamcombosrestrict = true
			else
			z.sam_beamcombosrestrict = false
			end	
			if args[13] --Metroid Vanguard story mode active, or are we playing the unaltered campaign?
				z.samworldevents = true
			else
				z.samworldevents = false
			end
			if args[14] --No Damage Challenge for emeralds or SRB2 vanilla behaviour?
			z.tokensrb2style = a13
			else
			z.tokensrb2style = 0
			end		
			if args[15] and tonumber(args[15]) --How long until boxes respawn in match? Never make this one 0.
			z.sam_respawnboxer = tonumber(args[15])
			else
			z.sam_respawnboxer = 30
			end	
			if args[16] --Spawn gunship?
			z.nogunshipspawn = true
			else
			z.nogunshipspawn = false
			end
			SetMetroidVisuals(nil) --Call this at the end.
	end
  end
end)

local function LoadSamusStage(p, mapnum)
	if not (p == server) and not netgame
	return false
	end
	if splitscreen and players[1] == p
	return false 
	end	
	p.sam_dontsave = true --Don't immediately save upon loading.
	if netgame and not (IsPlayerAdmin(p) or (p == server))
		p.pflags = $ & ~PF_INVIS & ~PF_GODMODE & ~PF_FORCESTRAFE		
		if p.mo
		p.mo.flags = $|MF_SHOOTABLE & ~MF_NOCLIP & ~MF_NOCLIPHEIGHT & ~MF_NOGRAVITY
		p.mo.flags2 = $ & ~MF2_DONTDRAW & ~MF2_SHADOW
		end	
	return
	end
	S_StopMusic(p)
		if not mapheaderinfo[mapnum].lvlttl or (mapheaderinfo[mapnum].lvlttl == "")
			if not mapheaderinfo[mapnum].skynum or (mapheaderinfo[mapnum].skynum == 1)
				if not mapheaderinfo[mapnum].typeoflevel or (mapheaderinfo[mapnum].typeoflevel == nil) 
				p.sam_wrongmap = true --Okay, we can say fairly certainly this map doesn't exist.
				return false --Or at least, the creator didn't bother with some VERY crucial mapheader info....
				end
			end
		end
		for z in players.iterate
		z.score = 0
		end

		p.pflags = $ & ~PF_INVIS & ~PF_GODMODE & ~PF_FORCESTRAFE
		
		if p.mo
		p.mo.flags = $|MF_SHOOTABLE & ~MF_NOCLIP & ~MF_NOCLIPHEIGHT & ~MF_NOGRAVITY
		p.mo.flags2 = $ & ~MF2_DONTDRAW & ~MF2_SHADOW
		end
		G_SetCustomExitVars(mapnum, 1)		
		G_ExitLevel()
end
rawset(_G, "FinishSamusSaveSelect", function(p, currentstage, truereset)
	if p.sam_saveselect
	local samestage = true
		
		--Reload the stage, or move to the last stage you were at.
		samestage = false
		if truereset
			LoadSamusStage(p, 1)
				if p.sam_achievementlock
				p.sam_setachievementlock = true
				p.sam_achievementlock = false
				end
				CollectSamusTax(p, true)
		elseif currentstage
			LoadSamusStage(p, SAM_map(nil))
		else
			LoadSamusStage(p, (p.sam_saveselect.chosenstage))
		end
		
		if p.sam_wrongmap --This map didn't exist, it seems.
		p.sam_wrongmap = false
		P_FlashPal(p, PAL_NUKE, 5)
		S_StartSound(nil, sfx_sdenid, p)
		CONS_Printf(p, "\x85"+"This map does not exist!")
		p.sam_saveselect.menuvertical = 2
		p.sam_saveselect.submenu = 1
		SAM_COM_BufInsertText(p, "tunes SAMMU1")
	--	S_ChangeMusic("SAMMU1", true, p, 0, 0, 699, 699)
			if p.sam_setachievementlock
			p.sam_achievementlock = true
			end
		p.sam_setachievementlock = false
		return false
		end
		
		--Reset flags incase of netgame or some weird failure.
		p.pflags = $ & ~PF_INVIS & ~PF_GODMODE & ~PF_FORCESTRAFE
		
		if p.mo
		p.mo.flags = $|MF_SHOOTABLE & ~MF_NOCLIP & ~MF_NOCLIPHEIGHT & ~MF_NOGRAVITY
		p.mo.flags2 = $ & ~MF2_DONTDRAW & ~MF2_SHADOW
		end

		
		p.sam_saveselect = nil
			if not p.sam_powerbeamequip --Fix beam bug.
			p.sam_wantstoswitch = 1 A_SAMBEAMSWITCH(p)
			end
		P_FlashPal(p, PAL_RECYCLE, 5)
		S_StartSound(nil, sfx_samtm7, p)
		S_StartSound(nil, sfx_samjin, p)
		
		if samestage or (p != server)
		SAM_COM_BufInsertText(p, "tunes -default")
		S_FadeMusic(0, 1, p)
		S_FadeMusic(100, 999, p)
		end
		
		return true
	else
	return false
	end
end)

--Careful. Starting this immediately ditches previous data. It's only meant for the start of new games!
rawset(_G, "StartSamusSaveSelect", function(p)
if gametype != GT_COOP
return
end
if splitscreen and players[1] == p
return false 
end
		if io and p == consoleplayer
			local file = io.openlocal("client/MetroidVanguard/firstsetup.dat")
			if file			
				local code = file:read("*a")	
					if code ~= nil and (string.find(code, "21473636")) and not (string.find(code, "RESET"))
						SAM_COM_BufInsertText(p, "SAMUSLOADCONFIG 21473636")
						--Set first time menu to done. 'cause you've got this already.
					else
						SAM_COM_BufInsertText(p, "SAMUSLOADCONFIG 21473632")
					end		
				file:close()
			else
				SAM_COM_BufInsertText(p, "SAMUSLOADCONFIG 21473632")
			end
		end
		
		if (p.samusfirstsetupdone == nil) --You didn't get an answer....
		p.samuschosefile = nil
		p.sam_saveselect = nil
		return
		end
		
		p.samuschosefile = true
		
		p.sam_saveselect = {
		fadein = 20*FRACUNIT,
		transfadebg = V_90TRANS,
		transfadebuttons = V_90TRANS,
		transfadebuttons2 = V_90TRANS,
		begintrans = 3,
		textbgfade = V_90TRANS,
		scale = 65356,
		menuvertical = 2,
		menuhorizontal = 1,
		submenu = 1,
		backgroundx = 0,
		backgroundy = 0,
		randomsparkx = 0,
		randomsparky = 0,
		randomsparkt = 0,
		randomsparkscale = 0,
		left = 5,
		right = 5,
		up = 0, 
		down = 0,
		jump = 5,
		spin = 5,
		custom1 = 0,
		arrowanim = 0,
		cursoranim = "SAMSAVS3",
		tempsavenum = 1,
		chosenstage = 1,
		firsttrans1 = V_70TRANS,
		firsttrans2 = V_70TRANS,
		firsttrans3 = V_70TRANS,
		runanim = A,
		runanim2 = A,
		huddash1 = 0,
		huddash2 = 0,
		huddash3 = 0,
		noloadsave = 0,
		delaycrash = 150}
		
		S_StartSound(nil, sfx_sscan2, p)
		
		if (p.samusfirstsetupdone == false)
			p.sam_saveselect.submenu = 10
			p.samuschosefile = true
				if p.samusmusicadded
					SAM_COM_BufInsertText(p, "tunes SAMUSG")
				--	S_ChangeMusic("SAMUSG", true, p)
				else
					SAM_COM_BufInsertText(p, "tunes SAMMU1")
				--	S_ChangeMusic("SAMMU1", true, p)
				end	
			S_StartSound(nil, sfx_samtm6, p)
		elseif (p.samusfirstsetupdone == true)
		SAM_COM_BufInsertText(p, "tunes SAMMU1")
	--	S_ChangeMusic("SAMMU1", true, p, 0, 0, 699, 699)
		end
end)

--Config version of Samus' save. Loads automatically.
rawset(_G, "ConfigSamusSave", function(s, p, dosave, doload) 
if not (doload or dosave)
	return false
end
if splitscreen and players[1] == p
return false 
end
if not s or not p --Make sure we exist
	return false
end
	if dosave
		local s1 = {
			customsuitc1 = SKINCOLOR_POWERSUIT,
			customsuitc2 = SKINCOLOR_VARIASUIT,
			customsuitc3 = SKINCOLOR_GRAVITYSUIT,
			autospeedbooster = 0,
			swapfire = 0,
			nosamustutorials = 0,
			samvisorcolor = SKINCOLOR_SKY,
			sam_scrollswap = 0,
			sam_visorhidden = 0,
			sam_lockonpower = 0,
			sam_lockontoggle = 0,
			sam_lockonnomon = 0,
			sam_noautoscan = 0,
			sam_autoaddmusic = 1,
			sam_noscreentilt = 0,
		}
			if p.customsuitc1 s1.customsuitc1 = (string.gsub(tostring(R_GetNameByColor(p.customsuitc1)), " ", "blurwhyPLZ")) else	s1.customsuitc1 = nil end
			if p.customsuitc2 s1.customsuitc2 = (string.gsub(tostring(R_GetNameByColor(p.customsuitc2)), " ", "blurwhyPLZ")) else	s1.customsuitc2 = nil end
			if p.customsuitc3 s1.customsuitc3 = (string.gsub(tostring(R_GetNameByColor(p.customsuitc3)), " ", "blurwhyPLZ")) else	s1.customsuitc3 = nil end	
			
			if p.autospeedbooster s1.autospeedbooster = 1 else s1.autospeedbooster = 0 end
			if p.swapfire s1.swapfire = 1 else s1.swapfire = 0 end
			if p.nosamustutorials s1.nosamustutorials = 1 else s1.nosamustutorials = 0 end
			
			if p.samvisorcolor s1.samvisorcolor = (string.gsub(tostring(R_GetNameByColor(p.samvisorcolor)), " ", "blurwhyPLZ")) else s1.samvisorcolor = SKINCOLOR_SKY end
			
			if p.sam_scrollswap s1.sam_scrollswap = 1 else s1.sam_scrollswap = 0 end
			if p.sam_visorhidden s1.sam_visorhidden = 1 else s1.sam_visorhidden = 0 end
			
			if p.sam_lockonpower and p.sam_lockonpower == 1
				s1.sam_lockonpower = 1
			elseif p.sam_lockonpower
				s1.sam_lockonpower = 2
			else
				s1.sam_lockonpower = 0
			end
			
			if p.sam_lockontoggle s1.sam_lockontoggle = 1 else s1.sam_lockontoggle = 0 end
			if p.sam_lockonnomon s1.sam_lockonnomon = 1 else s1.sam_lockonnomon = 0 end
			
			if p.sam_noautoscan and p.sam_noautoscan == 1
				s1.sam_noautoscan = 1
			elseif p.sam_noautoscan
				s1.sam_noautoscan = 2
			else
				s1.sam_noautoscan = 0
			end
			
			if p.sam_autoaddmusic s1.sam_autoaddmusic = 1 else s1.sam_autoaddmusic = 0 end
			if p.sam_noscreentilt s1.sam_noscreentilt = p.sam_noscreentilt else s1.sam_noscreentilt = 0 end
			
		p.samuspersonalsettings = s1 --Okay! Table saved!
	end
	
--Okay, so what are we actually DOING with this info? Are we loading? Saving it to a savefile?

	if p.samuspersonalsettings or doload --The table is here!
		local s1 = p.samuspersonalsettings
	
		if doload and not p.samuspsettingload --We're loading!		
		
				local file = io.openlocal("client/MetroidVanguard/samuspersonalsettings.dat")
					if file 
					local code = file:read("*a")
						if code ~= nil and not (string.find(code, ";"))
						and (string.find(code, "21473637"))
							SAM_COM_BufInsertText(p, tostring(code))
							CONS_Printf(p, "\x86"+"Loaded Metroid Vanguard personal settings.")
						end				
						file:close()
					end
					p.samuspsettingload = true --Only ONCE!
					p.samuspersonalsettings = nil
			
		elseif dosave --We're saving!
		
					if io and p == consoleplayer
						local file = io.openlocal("client/MetroidVanguard/samuspersonalsettings.dat", "w+")
							file:write("SAMUSLOADCONFIG "+tostring(21473637)+" "+s1.customsuitc1+" "
							+s1.customsuitc2+" "+s1.customsuitc3+" "+s1.autospeedbooster+" "+s1.swapfire+" "
							+s1.nosamustutorials+" "+s1.samvisorcolor+" "+s1.sam_scrollswap+" "
							+s1.sam_visorhidden+" "+s1.sam_lockonpower+" "+s1.sam_lockontoggle+" "
							+s1.sam_lockonnomon+" "+s1.sam_noautoscan+" "+s1.sam_autoaddmusic+" "
							+s1.sam_noscreentilt)
						file:close()
						CONS_Printf(p, "\x86"+"Saved Metroid Vanguard personal settings!")
					end
					p.samuspersonalsettings = nil
					
		end
	end	
end)


--Saves ADMIN-only features.

rawset(_G, "AdminSamusSave", function(p, dosave, doload) 
if not (p == server) --Server only
	return false
end
if not (doload or dosave) 
	return false
end
if not p --Make sure we exist
	return false
end
	if dosave
		local s1 = {
			nogunshipspawn = 0,
			sam_respawnboxer = 30,
			tokensrb2style = 0,
			samworldevents = 1,
			sam_beamcombosrestrict = 0,
			hypernetgo = 0,
			nosuperpowert = 0,
			morphcoop = 0,
			metroidvisuals  =  0,
			coopboxrespawn = 2,
			boxammospawns = 0,
			sammatchmonitors = 0,
			sammatchchars = 0,
			sam_energytanksstart = 2,
			sam_netsaves = 1,
			samusmatch = 0
		}
			if p.samusmatch s1.samusmatch = p.samusmatch end
			if not p.sam_netsaves s1.sam_netsaves = 0 end
			if p.sam_energytanksstart s1.sam_energytanksstart = p.sam_energytanksstart end
			if p.sammatchchars s1.sammatchchars = p.sammatchchars end
			if p.sammatchmonitors s1.sammatchmonitors = 1 end
			if p.coopboxrespawn s1.coopboxrespawn = p.coopboxrespawn end
			if p.metroidvisuals s1.metroidvisuals = 1 end
			if p.morphcoop s1.morphcoop = 1 end
			if p.nosuperpowert s1.nosuperpowert = 1 end
			if p.hypernetgo s1.hypernetgo = 1 end
			if p.sam_beamcombosrestrict s1.sam_beamcombosrestrict = 1 end
			if p.samworldevents s1.samworldevents = 1 end
			if p.tokensrb2style s1.tokensrb2style = p.tokensrb2style end
			if p.sam_respawnboxer s1.sam_respawnboxer = p.sam_respawnboxer end
			if p.nogunshipspawn s1.nogunshipspawn = 1 end
			
			
						
	p.samusadminsettings = s1
	end
	
--Are we loading? Or saving?

	if p.samusadminsettings or doload --The table is here!
	local s1 = p.samusadminsettings
	
		if doload and not p.samusasettingload --We're loading!			
				local file = io.openlocal("client/MetroidVanguard/samusadminsettings.dat")
					if file 
					local code = file:read("*a")
						if code ~= nil and not (string.find(code, ";"))
						and (string.find(code, "21473539"))
							SAM_COM_BufInsertText(p, tostring(code))
							CONS_Printf(p, "\x86"+"Loaded Metroid Vanguard admin settings.")
						end		
						file:close()
					else --Lazy patch.
						p.sam_netsaves = true
					end
					p.samusasettingload = true --Only ONCE!
					p.samusadminsettings = nil
			
		elseif dosave --We're saving!
		
					if io and p == consoleplayer
						local file = io.openlocal("client/MetroidVanguard/samusadminsettings.dat", "w+")

							file:write("SAMUSLOADCONFIG "+tostring(21473539)+" "+s1.samusmatch+" "
							+s1.sam_netsaves+" "+s1.sam_energytanksstart+" "+s1.sammatchchars+" "+s1.sammatchmonitors+" "
							+s1.coopboxrespawn+" "+s1.metroidvisuals+" "+s1.morphcoop+" "+s1.nosuperpowert+" "
							+s1.hypernetgo+" "+s1.sam_beamcombosrestrict+" "+s1.samworldevents+" "
							+s1.tokensrb2style+" "+s1.sam_respawnboxer+" "+nogunshipspawn)


						file:close()
						CONS_Printf(p, "\x86"+"Saved Metroid Vanguard admin settings!")
					end
					p.samusadminsettings = nil	
		end
	end
end)