--=============================SETUP============================================
--Lua initialization functions are here. Mostly whenever you swap character/stages, or load for the first time.
--==============================================================================

--Freeslots done! Now set up alot of main variables for later. 
--Everything here is required for SMSreborn's checks to function, so it's validated rigorously.
rawset(_G, "SetUpSMSreborn", function(p)

	--Too late in development to make an Adventure-Sonic styled exclusive table now, really...
	p.smsrtable = {
	turnang = 0,
	direct = 0,
--	timeshatter = 0,
--	timeshattercam = 0
	}
	
	p.sweepangle = 0
	p.sweepspeed = 15<<16
	p.smsnobmgame = 2
	p.srgorelvl = 0
	p.sms_shipready = 0
	p.smsrlightsec = 255
	p.smsrotatespikeball3 = 0
	p.smsrotatespikeball4 = 0
	p.sms_dodgetap = 0
	p.sms_dodging = 0
	p.sms_ringburst = 0
	p.sms_ringburstfly = 0
	p.sms_ringburstready = 0
	p.sms_comethaymaker = 0
	p.fusrodah = 0
	p.warpedtoguy = 0
	p.hmsdash = 0
	p.hmswarpcooldown = 0
	p.hms_drain = 0
	p.hms_flamehold = 0
	p.hms_explosion = 0
	p.hmstransformdisable = 0
	p.hypermysticsonic = 0
	p.transformdown = 0
	p.sms_flamedelay = 0
	p.sms_flamebuttonhold = 0
	p.novafire = 0
	p.sms_spinuc = 0
	p.sms_ringburstfalltimer = 0
	p.hmsblackhole = 0
	p.sms_ringburstdrain = 0
	p.lddiscount = 1
	p.lightdashenable = 0
	p.smsrdash = 0
	p.lightdashstart = 0
	p.elauracolors = 0
	p.spinhold = 0
	p.sms_jumphold = 0
	p.sms_c1 = 0
	p.weaponprevhold = 0
	p.sms_weaponnexthold = 0
	p.sms_nflamehold = 0
	p.transformstatecolors = 0
	p.lightspeedchain = 0
	p.mysticsuper = 0
	p.mslightspeedattack = 0
	p.speedspeedspeedspeedspeed = 0
	p.sms_transformstate = 0
	p.sms_sontransform = 0
	p.sms_wallstat = 0
	p.sms_advfall = 0
	p.sms_stompanim = 0
	p.sms_afterstompthok = false
	p.smsdivetimer = 0
	p.sweepanimrecovery = 0
	p.smsmeleebutton = 0
	p.smsmeleebutton2 = 0
	p.hms_stompbreak = 0
	p.sms_boostlevel = 0
	p.sms_boostdrain = 0
	p.mxscap = 1
	p.sms_readyairboost = 0
	p.sms_tapnothold = 0 		
	p.sms_didairboost = 0
	p.sms_tossflaghold = 0
	p.smsdontgrabme = 0
	p.autoc1mom = 2
	p.sms_instantairboost = true --New default controls.
	p.smseasyhaymaker = true		
	p.sms_autoboosthold = 0
	p.hmsmlimit = 1
		
	if p.skincolor and not (p.mo and p.mo.skin == "sms")
		p.sms_originalcolor = p.skincolor
	end
	
	--I don't trust servers to remember they can adjust graphics if the FPS is tanking, so force it until they manually change things.
	if netgame
		p.smsautographix = true
	end
	
	--Load your savefile if it exists!
	if not p.didsmsautoconfig
		SMS_LoadGame(p)		
		if netgame and (gametype != GT_COOP) and not p.smsfirstcolor
			if (A_setSMSspecialcolors(p, P_RandomRange(1,33)))
				p.smsfirstcolor = true
			end
		end
		if not p.didsmsautoconfig
			p.didsmsautoconfig = 1
		end
	end
	if p.bot --Bots always consent to being grabbed.
		p.smsdontgrabme = 2	
	end
	if (SUBVERSION < 13) and (VERSION == 202) --Use 2.2.13 or higher, pls.
		if (p == server) or IsPlayerAdmin(p)
			p.SMS_SRB2outofdate = true
		end
	end
	p.smsrebornadded = true --SMSreborn is added!
	return true --
end)

--Remove the p.sms_intoship value first before using this!
--Removing these eases strain on netgames a bit.
rawset(_G, "SMS_RemoveMenuValues", function(p)
	p.sms_intoship = nil
	
	p.starSMS = nil
	p.ssmenuileft = nil
	p.ssmenuiright = nil
	p.ssmenuijump = nil
	p.ssmenuiup = nil
	p.ssmenuidown = nil
	p.ssmenuiuse = nil
	p.sms_hudtransf = nil
	p.ssmenuisub = nil
	p.ssmenuisubpage = nil
	p.ssmenui1 = nil
	p.ssmenuidrop = nil
	p.smshudmenuclick = nil
	p.smstext1x = nil
	p.smstext2y = nil
	p.smsmenuanim,p.smsmenuanim2 = nil,nil
	p.smshudappearanim = nil
	p.hsh1 = nil
	p.hssh2 = nil
	p.hssh = nil	
	p.ssmenui1,p.ssmenuisub,p.ssmenuisubpage = nil,nil,nil
	p.menutpos = nil
	p.smshudtrans1n = nil 
	p.smshudtrans2n = nil
	p.smshudmessagetime = nil 
	p.smshudtrans3 = nil
	p.smshudtrans2 = nil
	p.smshudtrans1 = nil
	p.smshudmenusphere = nil
	p.smsmemeter = nil
	p.sms_shipready = nil
	p.smsmeterfiller = nil	
	if p.mo and p.mo.valid
		local s = p.mo
		s.huddiego2 = nil 
		s.huddiego = nil 
	 	s.huddiego3 = nil
		s.eshipwater = nil
	end
end)

--Alternate setup when mo is valid. This one happens EVERYTIME on spawn.
rawset(_G, "SetUpSMSrebornmo", function(p)
	local s = p.mo
	if s and s.valid
		if p.sms_intoship
			p.accelstart = skins[s.skin].accelstart
			s.flags2 = $ & ~MF2_SHADOW
		end
		if p.hypermysticsonic --Be strict about this...
			SMS_SkinSwap(s, p)
		elseif p.wasHMS or (p.jumpfactor == 133469)
			HMS_UntransformedStats(s, p) --Remove HMS stats!
		elseif not p.nohmstheme
			COM_BufInsertText(p, "tunes -default")
			P_RestoreMusic(p)
		end
		if p.mysticsuper
			A_ENDMYSTICSUPER(s)
		end	
	end
	if p.smsrtable --Reset table values.
		p.smsrtable.turnang = 0
		p.smsrtable.direct = 0
	end	
	if p.bot
		p.smsdontgrabme = 2
	end
	if p.sms_intoship --Don't start off with the menu.
		p.pflags = $|PF_USEDOWN & ~(PF_INVIS|PF_GODMODE|PF_FORCESTRAFE|PF_STARTDASH|PF_SPINNING)
		SMS_RemoveMenuValues(p)
	end
	p.sms_steaming = nil
	p.sms_steamingwait = nil
	p.sms_ringburstfly = 0
	p.sms_ringburst = 0
	p.sms_ringburstready = 0
	p.sms_ringburstfalltimer = 0
	p.sms_ringburstdrain = 0
	p.sms_comethaymaker = 0
	p.cmphdodge = 0
	p.fusrodah = 0
	p.sms_dodging = 0
	p.footsweep01 = 0
	p.footsweep02 = 0
	p.footsweep03 = 0
	p.smsdivetimer = 0
	p.smsdivefloat = 0
	p.smsdivedelay = 0
	p.smsatomicdivefail = 0
	p.smsrotatespikeball3 = 0
	p.smsrotatespikeball4 = 0
	p.sms_justuncurled = 0
	p.sms_dodgetap = 0
	p.sms_flamedelay = 0
	p.sms_hugeflametoss = 0
	p.sms_spinuc = 0
	p.sms_wallstat = 0 --Old Walljump stat.
	p.hms_instamovew = 0
	p.lightdashenable = 0
	p.smsrdash = 0
	p.lightdashstart = 0
	p.lightspeedchain = 0
	p.mysticsuper = 0
	p.mslightspeedattack = 0
	p.sms_wallstat = 0
	p.sms_advfall = 0
	p.sms_stompanim = 0
	p.sms_afterstompthok = false
	p.sms_watergrind = 0
	p.sms_boostlevel = 0
	p.sms_boostdrain = 0		
	p.sms_didairboost = 0
	p.hmswarn = 0
	p.smsrnm = 0
	p.hfear = 0
	p.hmspanic = 0
	p.mxscap = 1
	p.smsrlightsec = 255
	p.smsrebornadded = true
	p.smssc = false
	p.smsex = false
	p.smsgre = false
	p.smsat = false
	p.smsra = false
	p.smsin = false
	p.smspickup = nil
	
	--s is optional and doesn't NEED to be valid.
	if s
		if s.bhlcamtimer
			s.bhlcamtimer = 0
			p.camerascale = FRACUNIT
		end
		if mapheaderinfo[gamemap] 
			if mapheaderinfo[gamemap].startrings and not p.hmsrushactive
				s.mssprst = false
				if mapheaderinfo[gamemap].bonustype == 1
					s.smsvsboss = mapheaderinfo[gamemap].startrings
				end
				if s.skin == "sms" and p.rings and not p.sms_transformstate //Less rings to discourage flamespam
					p.rings = max(1, (mapheaderinfo[gamemap].startrings)/2)
				end
			elseif mapheaderinfo[gamemap].lvlttl == "Industrial Valley" --Remembered this after the wolf...
				p.banned = nil p.powers[pw_nocontrol] = 0
				for SEC in sectors.iterate --Change tags
					if SEC.tag == 148 SEC.tag = 3999 end
				end
			end
			if (mapheaderinfo[gamemap].typeoflevel >= 1025)
				s.mssprst = false
			end
		end		
		if p.sms_originalcolor == nil --Original color isn't nil, right?
			p.sms_originalcolor = ((s.skin != "sms") and p.skincolor) and p.skincolor or SKINCOLOR_BLUE
		end
		--Undo NiGHTS rollangle.
		if s.nrollanga
			if s.rollangle
				if not ((s.state >= S_PLAY_NIGHTS_STUN) and (s.state <= S_PLAY_NIGHTS_ATTACK))
					s.rollangle = 0
				end
			end
			s.fboostgfx = 0
			s.nrollanga = false
		end
		if s.SMS_lastZ == nil
			s.SMS_lastZ = s.z
		end
		s.starthmscombo = 0
		s.sms_runspinboost = 0
		s.smsgbs = 0
		s.hmsgalaxystorm = 0
		s.smsdropdash = false
		s.lastcaptureamountsms = 0
		s.lastcaptureamounthms = 0
		s.smsmsdelay = true
		s.cmphdelayjump = 0
		if s.mssprst and leveltime and not multiplayer
			s.mssprst = false
		end
		s.hmspowerbombcam = 0
		s.smsflagrgpermission = 0
		s.smsflagrg = 0
		s.eyesareuponyou = nil
		s.sprst = false
		s.hmscombod = nil
		s.gravbu = nil
		
		if s.SMS_walltable == nil
			s.SMS_walltable = {}
			if s.SMS_hitwall == nil
				s.SMS_hitwall = {}
			end
		end
		
		if s.skin == "sms"
			p.camerascale = FRACUNIT
			if not s.abilitytogive or s.abilitytogive != -8
				s.abilitytogive = -8
				s.smskability = true
			end	
	
			if p.superkey != "off"
				if mmtINTHEPK3
					CONS_Printf(p, "\x85"+"Turned off superkey for"+"\x82 SMS.\x85 Remember to turn it on again if you switch characters!")
				end
				p.superkey = "off"
			end
			
	  		if p.isclassic or p.isclassic == nil  //No Classic physics for SMS.
				p.isclassic = false
				p.isclassicsms = true
			end
			p.thrustfactor = skins[s.skin].thrustfactor
			p.jumpfactor = skins[s.skin].jumpfactor
		end
	end		
	return true --
end)

//Swapped Skin? Reset a whole bunch of nonsense, then. You could also call this manually to safely reset basically anything.
//Alot of HMS values are handled seperately.
rawset(_G, "SMS_SkinSwap", function(s, p)

	SMS_WallJumpDelete(s, true) --Remove all these tables.
	s.HayMakerGFXTable = nil
	s.SMS_ControlAlter = nil
	s.SMS_DLtrail = nil
	
	if p.hypermysticsonic or p.wasHMS or (p.jumpfactor == 133469)
		HMS_UntransformedStats(s, p) --Remove HMS stats!
	elseif not p.nohmstheme
		local MUSIC = S_MusicName()
		if p.powers[pw_sneakers] or MUSIC == "HMS" or MUSIC == "MAPX7M" or MUSIC == "MAPZYM"
			COM_BufInsertText(p, "tunes -default")
			P_RestoreMusic(p)
		end
		p.powers[pw_sneakers] = 0
	elseif p.powers[pw_sneakers]
		p.powers[pw_sneakers] = 0
		P_RestoreMusic(p)
	end
	
	if s.SMS_squashtable or s.sms_squashy
		s.SMS_squashtable,s.spriteyoffset,s.spritexscale,s.spriteyscale = nil,0,FRACUNIT,FRACUNIT
		s.spritexoffset = 0
		s.sms_squashy = nil
	end	
	s.SMS_WJauto = nil
	
	p.speedspeedspeedspeedspeed = 0
	p.lightdashstart = 0
	
	p.sms_ringburstfly = 0
	p.sms_ringburst = 0
	p.sms_ringburstready = 0
	p.sms_ringburstfalltimer = 0
	p.sms_ringburstdrain = 0
	
	p.sms_dodgetap = 0
	p.sms_dodging = 0
	
	p.sms_comethaymaker = 0
	
	p.footsweep01 = 0
	p.footsweep02 = 0
	p.footsweep03 = 0
	p.footsweepanim	= false
	
	p.smsdivetimer = 0
	p.smsdivefloat = 0
	p.smsdivedelay = 0
	p.smsatomicdivefail = 0
	
	p.sms_justuncurled = 0
	
	p.sms_flamedelay = 0
	p.sms_hugeflametoss = 0
	
	p.sms_spinuc = 0
	p.hms_instamovew = 0
	p.sms_wallstat = 0
	p.sms_advfall = 0
	p.sms_stompanim = 0
	p.sms_afterstompthok = false
	p.sms_watergrind = 0
	p.sms_boostlevel = 0
	s.sms_boostloss = 0
	p.sms_didairboost = 0
	p.mxscap = 1
	
	p.atomdivetargetspin = nil
	p.smsrlightsec = 255
	p.hmsdash = 0
	p.hmswarpcooldown = 0
	p.hms_drain = 0
	p.hms_flamehold = 0
	p.hms_explosion = 0
	p.transformdown = 0
	p.sms_flamedelay = 0
	p.sms_flamebuttonhold = 0
	p.novafire = 0
	p.sms_ringburstfalltimer = 0
	p.hmsblackhole = 0
	p.elauracolors = 0
	p.sms_wallstat = 0
	p.sms_advfall = 0
	p.sms_spinuc = 0
	p.readyforpowershare = 0
	p.sms_steaming = nil
	s.sms_runspinboost = 0
	p.sms_autoboosthold = 0
	
	--Reset Buttons.
	p.spinhold = 0
	p.sms_jumphold = 0
	p.sms_c1 = 0
	p.weaponprevhold = 0
	p.sms_weaponnexthold = 0
	p.smsmeleebutton = 0
	p.smsmeleebutton2 = 0
	p.hms_stompbreak = 0
	p.cmphspamreduce = 0
	p.homecamfly = 0
	
	--s values
	s.useatommethod = false
	s.atomdiveusebuffer	= 0
	

	s.SMS_wallready = 0
	s.SMS_wallwait = 0
	s.SMS_removeWD = 0
	s.readyforonemoreplant = 0
	s.smsboostimmune = 0
	s.smshmcheck = 0
	s.smscmphret = 0
	s.smspkuret = 0
	s.cmphdelayjump = 0
	
	--The pile of random stuff to turn to nil....
	s.smsmenunote = nil
	s.sms_spintrickspeed = nil
	s.sms_superspin = nil
	s.sms_lastboost = nil
	s.sms_boostplus = nil
	s.sms_boostplustimer = nil	
	s.SMS_stompmom = nil
	s.sms_stompspin = nil
	s.stompanimburst = nil	
	s.sdodgeoh = nil
	s.dcadsms = nil
	s.SMS_LoseC1Hold = nil
	s.SMS_MineCarting = nil
	s.SMS_lastwallANG = nil
	s.SMS_lastwallNUM = nil
	s.SMS_tossready = nil
	
	--Just being experimental for shits and giggles...
	s.smsaurablastivate,s.tnospina,s.cmphtarget2,s.cmphclosest,s.cmphtarget, s.HayMakerPunch,
	s.SMS_oldspeed,s.smsatombounced,s.NoSMSGlow,s.boostpass, s.ssxaticket, s.smsdropdash, s.hmsrotateright,s.rglowticket,
	s.HMS_FireCoords,s.HMS_FireCoords,s.HMS_FireCoords2, s.HMS_7flame,s.HMS_SkipHBnext,s.SMSLASTANGLE,s.SMSDELAYRENDER = nil

	s.atomdiveheld = 0
	s.atomdiveusebuffer = 0
	s.smsframejump = 0
	s.smsglowticket = 0
	s.sms_addboostlevel = 0
	s.sms_juststomped = 0
	s.cmphlanded = 0
	s.starthmscombo = 0
	s.smsgbs = 0
	s.hmsgalaxystorm = 0
	s.smsboostimmune = 0
	s.smstrickroll = false
	s.smsbdsfx = 0
	s.hmsccd = 0
	s.smsarmablow = 0
	s.smsstompcd = 0
	s.hudboost = 0
	s.sms_painr = 0
	s.sdodgecd = 0
	s.sdodgelvl = 0	
	s.atomdiveheld = 0
	s.smpkclosest = nil
	s.smsatombounced = nil
	s.sliderollang = nil	
	s.hmspowerbombcam = nil
	s.hmsroflstomped = false
	s.hmsspinpass = 0
	s.hmsroflstompcd = 0	
	s.hmsmwh = 0
	s.hmsrunquake = 0
	s.farnovaview = nil
	s.hmsforcedspin = 0
	s.haltthespam = 0
	s.SMS_CrashRoll = nil
	
	s.rollangle = 0 --May as well reset rollangle always.
	
	/*	if p.shinyglosscoat == 1
		and not SMSisyellow(s)
		and not p.hypermysticsonic
		and not G_GametypeHasTeams()
		and not (p.powers[pw_shield] & SH_FIREFLOWER)
		and not ((mariomode) and p.powers[pw_invulnerability])
		p.shinyglosscoat = 0 --Player trying to switch. Let them.
		end */	
		
	if s.bhlcamtimer --SMS' camera timer. Originally meant for Black Hole, therefore the name "bhl"camtimer.
		s.bhlcamtimer = 0
	end
	p.camerascale = FRACUNIT
	if s.suddenquickspeed
		s.suddenquickspeed = 0
		s.flags2 = $ & ~MF2_DONTDRAW
	end
	if s.DeyCURollin
		s.DeyCURollin = 0
		if p.powers[pw_carry] == CR_ROLLOUT
			p.powers[pw_carry] = 0
		end
	end
	s.airboostroll = 0
	if s.hmscchange --This would be reaaal bad if left as is.
		p.viewrollangle = 0
		s.hmscchange = nil
	end	
	if p.smsrtable --Reset table values.
		p.smsrtable.turnang = 0
		p.smsrtable.direct = 0
	end	
	---====================================
	--		SMS exclusive changes.
	--=====================================
	
	if s.skin == "sms"
		if s.prehmscolor
			s.color = s.prehmscolor
			p.skincolor = s.prehmspcolor
		end
		s.prehmscolor = nil
		s.prehmspcolor = nil
		if not p.homing
		and not p.powers[pw_carry]
			s.target = nil
			s.tracer = nil
		end
		if not p.smsfirstcolor 
			if (not p.shinyglosscoat or p.shinyglosscoat > 1)
			or p.nosmscolorspls
				if p.nosmscolorspls
					A_setSMSspecialcolors(p, 0)
				end
				p.smsfirstcolor = true
			elseif p.smsfcc == nil or (p.smsfcc != p.skincolor)	
		  		p.smsfcc = p.skincolor
			end
		end				
		
		s.cooldownlight = 10
		s.SMS_Locked = true --Crucial frame.
		p.mysticsuper = 0
		s.renderflags = $|RF_FULLBRIGHT
		if p.powers[pw_super]
			p.powers[pw_super] = 0
			P_RestoreMusic(p)
		end
		if ((s.sprite == SPR_SMSO) or (s.sprite == SPR_HMSO)) --Huh?
		and not p.hypermysticsonic
			s.sprite = SPR_PLAY
			s.state = S_PLAY_FALL
		end
		if P_IsObjectOnGround(s)
			if (p.speed < 4*s.scale) or (p.panim == PA_IDLE)
				s.state = S_PLAY_STND
			else
				s.state = S_PLAY_RUN
			end
		elseif not p.sms_sontransform
			if (s.state != S_PLAY_ROLL) and (s.state != S_PLAY_JUMP)
				s.state = S_PLAY_FALL
			end
		end
		if not s.abilitytogive or s.abilitytogive != -8
			s.abilitytogive = -8
			s.smskability = true
		end		
		if p.superkey != "off"
			if mmtINTHEPK3
				CONS_Printf(p, "\x85"+"Turned off superkey for"+"\x82 SMS.\x85 Remember to turn it on again if you switch characters!")
			end
			p.superkey = "off"
		end
		if p.isclassic or p.isclassic == nil  //No Classic physics for SMS.
			p.isclassic = false
			p.isclassicsms = true
		end	
		p.thrustfactor = skins[s.skin].thrustfactor
		p.jumpfactor = skins[s.skin].jumpfactor		

	else 
		--==========================================================
		--Changed from SMS into someone else! (Possibly base Sonic)
		--==========================================================
		s.prehmscolor = nil
		s.prehmspcolor = nil
		s.cooldownlight = nil
		s.SMS_WJpenalty = 0
		s.HayMakerRoll = nil
		s.SMS_lastz = nil
		s.SMS_tempRF = nil
		s.renderflags = $ & ~RF_FULLBRIGHT
		if s.hmsgodmode
			p.pflags = $ & ~PF_GODMODE
			s.hmsgodmode = nil
		end
		if p.sms_transformstate
			A_SMSTOSONIC(s)
			p.sms_transformstate = 0
		end	
		if s.smskability
			if s.abilitytogive != nil
				s.abilitytogive = 0
			end
			s.smskability = false
		end
		if p.smssonicbattle
			if (s.skin != "sonic" and not (s.skin == "sms" and p.sms_transformstate))
				p.smssonicbattle = false
			end
		end
		if (s.sprite == SPR_SMSO) or (s.sprite == SPR_HMSO) --You're not allowed to use these sprites!
			s.sprite = SPR_PLAY
			s.state = S_PLAY_SPRING
		end		
		if p.isclassicsms and not p.mysticsuper
			p.isclassic = nil
			p.isclassicsms = nil
		end
		p.pflags = $ & ~PF_CANCARRY
		
		--What state to carry the player to?
		if (s.state == S_PLAY_DEAD) or (p.panim == PA_PAIN)
			--Keep it.
		elseif (s.state == SMSHayMakerState(p, 1)) --Change things up!
			s.target = nil
			s.state = S_PLAY_FALL
			p.panim = PA_FALL
			p.charflags = $ & ~SF_NOSKID
		elseif (s.sprite == SPR_SMSO) or (s.sprite == SPR_HMSO) --Don't use these sprites!
			s.state = S_PLAY_FALL
			p.panim = PA_FALL
		elseif P_IsObjectOnGround(s)
			if (p.speed < 4*s.scale) or (p.panim == PA_IDLE)
				s.state = S_PLAY_STND
			else
				s.state = S_PLAY_RUN
			end
		elseif not p.sms_sontransform
			if (s.state != S_PLAY_ROLL) and (s.state != S_PLAY_JUMP)
				s.state = S_PLAY_FALL
			end
		end
		if (s.state == S_PLAY_FALL)
		and (p.powers[pw_flashing] > 99)
		and not P_IsObjectOnGround(s)
			s.state = S_PLAY_PAIN
		end
		HMS_UntransformedStats(s, p, true) 
		p.sms_boostlevel = 0
		s.AmSuperMysticSonic = false
	end
	return true --
end)

--Switch stuff out when changing maps.
addHook("MapChange", function()
	for z in players.iterate
		if z.sweepangle == nil --This needs to be setup at all times....
			SetUpSMSreborn(z)
		end
	end
end)

--Give Kirby extra abilities depending on SMS' projectile
if not (kirbyabilitytable)
	rawset(_G, "kirbyabilitytable", {})
end
kirbyabilitytable[MT_HMSNOVABLAST] = 12 //Screaming
kirbyabilitytable[MT_SMMK] = -1 //Tornado
kirbyabilitytable[MT_HMSLIGHTNING1] = 5 //Spark
kirbyabilitytable[MT_SPINFIRE] = 1 //Fire
kirbyabilitytable[MT_HMS_NAPALM_FLAMES] = 1
kirbyabilitytable[MT_HMSFLAMEREST] = 1
kirbyabilitytable[MT_HMSFIREBLAST] = 1
kirbyabilitytable[MT_SMSFIREBLAST] = 1
kirbyabilitytable["sms"] = -8

--These functions are used by the setup, hence need to be present here.

//Shortcut to set all of SMS' colors at once for laziness. The colors count backwards, but the arguments won't.
rawset(_G, "SMSpulsecolorset", function(p, c1, c2, c3, c4, c5)
	if tonumber(c1) == nil
		CONS_Printf(p, "\x85"+"ERROR:\x80 Invalid color! Using default SMSreborn color to prevent crash!")
		SMSpulsecolorset(p, SKINCOLOR_MYSTICAL1) return false --	
	end
	
	local MAXCOLORS = (#skincolors-1) --If we go past this, the game crashes! Can't let that happen, ofc.
	if (c1 > MAXCOLORS)
		CONS_Printf(p, "\x85"+"ERROR:\x80 Going over color limit! Using default SMSreborn color to prevent crash!")	
		SMSpulsecolorset(p, SKINCOLOR_MYSTICAL1) return false --
	else
		p.smscoatc5 = c1
		if c2 == nil --Not specified? Count up by 1 for convenience and hope the colors allign!
			p.smscoatc4 = min(c1+1, MAXCOLORS)
			p.smscoatc3 = min(c1+2, MAXCOLORS)
			p.smscoatc2 = min(c1+3, MAXCOLORS)
			p.smscoatc1 = min(c1+4, MAXCOLORS)
		else --Specifically chosen colors!
			p.smscoatc4 = c2
			p.smscoatc3 = c3
			p.smscoatc2 = c4
			p.smscoatc1 = c5
		end
		return true --
	end
end)

--======================================
-- The great list of shiny SMS colors!
--======================================
function A_setSMSspecialcolors(p, var1, var2)
	if not (p and p.valid and p.mo and p.mo.valid) return end --
	
	if G_GametypeHasTeams() 
		if s.skin == "sms"
			local COLOR = (p.ctfteam == 1) and SKINCOLOR_BLUE or SKINCOLOR_RED
			SMSpulsecolorset(p, COLOR, COLOR, COLOR, COLOR, COLOR)
			if not p.sms_transformstate
				p.skincolor = COLOR
			end
			if not p.hypermysticsonic --These aren't allowed here!
				s.color = COLOR
			end
		end
		p.shinyglosscoat = 0
		return 0 --
	end
	
	local s = p.mo
	local sc = tonumber(var1) --Special color is...?
	if sc != nil p.shinyglosscoat = sc end
	
	--Mystical! The Canonical SMS colors I could never use until custom skincolors were introduced.
	if sc == 1 or sc == nil
		SMSpulsecolorset(p, SKINCOLOR_MYSTICAL1)
		p.shinyglosscoat = 1
	--This one's "NO special color". It lets SRB2's default coloring code take over!	
	elseif sc == 0 
	or p.nosmscolorspls
		if p.nosmscolorspls and s.color != SKINCOLOR_COBALT and not p.sms_transformstate
			CONS_Printf(p, "\x84"+"Cannot use pulsing colors at this moment!")
		end
		if s.skin == "sms"
			if not p.sms_transformstate
				p.skincolor = SKINCOLOR_COBALT
			end
			s.color = SKINCOLOR_COBALT 
		end	
		SMSpulsecolorset(p, SKINCOLOR_COBALT, SKINCOLOR_COBALT, SKINCOLOR_COBALT, SKINCOLOR_COBALT, SKINCOLOR_COBALT)
		p.shinyglosscoat = 0
	--Now for the rest!	
	elseif sc == 2 //Super Yellow - Super Sonic
		SMSpulsecolorset(p, SKINCOLOR_SUPERGOLD5, SKINCOLOR_SUPERGOLD4, SKINCOLOR_SUPERGOLD3, SKINCOLOR_SUPERGOLD2, SKINCOLOR_SUPERGOLD1)
	elseif sc == 3 //Super Orange
		SMSpulsecolorset(p, SKINCOLOR_SUPERORANGE5, SKINCOLOR_SUPERORANGE4, SKINCOLOR_SUPERORANGE3, SKINCOLOR_SUPERORANGE2, SKINCOLOR_SUPERORANGE2)
	elseif sc == 4 //Super Red
		SMSpulsecolorset(p, SKINCOLOR_SUPERRED5, SKINCOLOR_SUPERRED4, SKINCOLOR_SUPERRED3, SKINCOLOR_SUPERRED2, SKINCOLOR_SUPERRED2)		
	elseif sc == 5 //Super Green
		SMSpulsecolorset(p, SKINCOLOR_SUPERPERIDOT5, SKINCOLOR_SUPERPERIDOT4, SKINCOLOR_SUPERPERIDOT3, SKINCOLOR_SUPERPERIDOT2, SKINCOLOR_SUPERPERIDOT2)
	elseif sc == 6 //Super Blue
		SMSpulsecolorset(p, SKINCOLOR_SUPERSKY5, SKINCOLOR_SUPERSKY4, SKINCOLOR_SUPERSKY3, SKINCOLOR_SUPERSKY2, SKINCOLOR_SUPERSKY2)
	elseif sc == 7 //Super Purple
		SMSpulsecolorset(p, SKINCOLOR_SUPERPURPLE5, SKINCOLOR_SUPERPURPLE4, SKINCOLOR_SUPERPURPLE3, SKINCOLOR_SUPERPURPLE2, SKINCOLOR_SUPERPURPLE2)
	elseif sc == 8 //Super Rust
		SMSpulsecolorset(p, SKINCOLOR_SUPERRUST5, SKINCOLOR_SUPERRUST4, SKINCOLOR_SUPERRUST3, SKINCOLOR_SUPERRUST2, SKINCOLOR_SUPERRUST2)
	elseif sc == 9 //Super Tan
		SMSpulsecolorset(p, SKINCOLOR_SUPERTAN5, SKINCOLOR_SUPERTAN4, SKINCOLOR_SUPERTAN3, SKINCOLOR_SUPERTAN2, SKINCOLOR_SUPERTAN2)
	elseif sc == 10 //Crisis flame
		SMSpulsecolorset(p, SKINCOLOR_CRIMSON, SKINCOLOR_RED, SKINCOLOR_FLAME, SKINCOLOR_KETCHUP, SKINCOLOR_SUPERORANGE5)
	elseif sc == 11 //Dark SMS
		SMSpulsecolorset(p, SKINCOLOR_BLACK, SKINCOLOR_CARBON, SKINCOLOR_BLACK, SKINCOLOR_JET, SKINCOLOR_GREY)
	elseif sc == 12 //Priest
		SMSpulsecolorset(p, SKINCOLOR_GREY, SKINCOLOR_SILVER, SKINCOLOR_SUPERSILVER5, SKINCOLOR_SUPERSILVER3, SKINCOLOR_SUPERSILVER1)
	elseif sc == 13 //Hyper Sonic
		SMSpulsecolorset(p, SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERPERIDOT1, SKINCOLOR_SUPERRED1, SKINCOLOR_SUPERGOLD1, SKINCOLOR_SUPERPURPLE1)
	elseif sc == 14 //Bluewave
		SMSpulsecolorset(p, SKINCOLOR_COBALT, SKINCOLOR_BLUE, SKINCOLOR_CORNFLOWER, SKINCOLOR_BLUEBELL, SKINCOLOR_AZURE)
	elseif sc == 15 //Arctic Chi
		SMSpulsecolorset(p, SKINCOLOR_ICY, SKINCOLOR_AETHER, SKINCOLOR_BONE, SKINCOLOR_WHITE, SKINCOLOR_SUPERSILVER5)
	elseif sc == 16 //Ranger
		SMSpulsecolorset(p, SKINCOLOR_FOREST, SKINCOLOR_GREEN, SKINCOLOR_PERIDOT, SKINCOLOR_SUPERPERIDOT5, SKINCOLOR_SUPERPERIDOT2)
	elseif sc == 17 //Pink Menace
		SMSpulsecolorset(p, SKINCOLOR_LILAC, SKINCOLOR_ROSY, SKINCOLOR_PINK, SKINCOLOR_BUBBLEGUM, SKINCOLOR_BUBBLEGUM)
	elseif sc == 18 //Metallic
		SMSpulsecolorset(p, SKINCOLOR_SUPERRUST4, SKINCOLOR_COPPER, SKINCOLOR_SUNSET, SKINCOLOR_GOLD, SKINCOLOR_GOLD)
	elseif sc == 19 //HazelGlow
		SMSpulsecolorset(p, SKINCOLOR_CARBON, SKINCOLOR_BRONZE, SKINCOLOR_BROWN, SKINCOLOR_BEIGE, SKINCOLOR_BEIGE)
	elseif sc == 20 //UltraDrive
		SMSpulsecolorset(p, SKINCOLOR_WHITE, SKINCOLOR_SUPERSILVER3, SKINCOLOR_SUPERSILVER2, SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERSILVER1)
	elseif sc == 21 //Lapis Vapor
		SMSpulsecolorset(p, SKINCOLOR_DUSK, SKINCOLOR_CERULEAN, SKINCOLOR_BLUE, SKINCOLOR_SAPPHIRE, SKINCOLOR_BLUEBELL)
	elseif sc == 22 //Azure Breaker
		SMSpulsecolorset(p, SKINCOLOR_AZURE, SKINCOLOR_WAVE, SKINCOLOR_TEAL, SKINCOLOR_AQUA, SKINCOLOR_MOSS)
	elseif sc == 23 //Emperor
		SMSpulsecolorset(p, SKINCOLOR_EMPEROR1)
	elseif sc == 24 //Base Sonic
		SMSpulsecolorset(p, SKINCOLOR_SONIC1)	
	elseif sc == 25  --Pre 3.0 SMSreborn colors.
		SMSpulsecolorset(p, SKINCOLOR_SMS1R)
	elseif sc == 26 //Transformation
		SMSpulsecolorset(p, SKINCOLOR_TRANSFORMATION1)
	elseif sc == 27 //FlameBreaker
		SMSpulsecolorset(p, SKINCOLOR_FLAMEBREAKER1)			
	elseif sc == 28 //Infinity's End
		SMSpulsecolorset(p, SKINCOLOR_ZEEJIN1)	
		
	--Now for some anon fan-submitted custom colors for SMS 3.0+
	elseif sc == 29 //Solar Billow
		SMSpulsecolorset(p, SKINCOLOR_SOLAR1)	
	elseif sc == 30 //Moonslammer
		SMSpulsecolorset(p, SKINCOLOR_MOONSLAMMER1)	
	elseif sc == 31 //Galactic
		SMSpulsecolorset(p, SKINCOLOR_GALACTIC1)	
	elseif sc == 32 //Breezy (Though tempted to call it Broly, lol)
		SMSpulsecolorset(p, SKINCOLOR_BREEZY1)	
	elseif sc == 33 //Zenith (Terraria's final blade?)
		SMSpulsecolorset(p, SKINCOLOR_ZENITH1)			
	end
	return p.shinyglosscoat --
end



