--=============================MAIN THINKER 2===============================================
--This main thinker is usually used for misc stuff, usually for seperate states that don't usually apply.
--Like the golden shoes, shields, HMS panic event, Mystic Super, powershare, etc.
--I say usually, because there's still alot of generic gameplay stuff sprinkled here too...
--==========================================================================================

addHook("MobjThinker", function(s) if not s.player return end --
	local p = s.player			
	if p.dfflame --Diffusion Flame warning messages. Applies to all skins, naturally.
		p.dfflame = $-1
	end
	if s.bhlcamtimer
		s.bhlcamtimer = $-1
		if (s.bhlcamtimer > 36)
			if (s.bhlcamtimer > 110)
				p.camerascale = $*39/38
			else
				p.camerascale = $*100/99
			end
		else
			p.camerascale = $*11/12 --Slowly adjust...
		end
		p.camerascale = max($, FRACUNIT) --call repeatedly every frame for zoom-ins.
		if (s.bhlcamtimer <= 1)
			p.camerascale = FRACUNIT
			s.bhlcamtimer = 0
		end
	end

	//Let HMS carry infinite people, unlike regular characters
		
	if s.hmspickuptarget != nil and s.hmspickuptarget.valid and not (s.hmspickuptarget == s)
	and s.hmspickuptarget.hmspickedup and s.hmspickuptarget.player
	and not (FixedHypot(s.x-s.hmspickuptarget.x, s.y-s.hmspickuptarget.y) > 450*s.scale)//Generous check
	and not s.hmsccd
		local t = s.hmspickuptarget			
			if (t.state == S_PLAY_RIDE)
			and ((t.occupiedcarrying == nil) or (t.occupiedcarrying == s))
				if not s.hmsstacksfx
					s.hmsstacksfx = true 
					S_StartSound(t, sfx_s3k4a)
					t.occupiedcarrying = s //Keep track of who you're holding
				elseif s.tracer //Kill Tails' carry
				s.tracer = nil
				end		
				P_ResetPlayer(p) //Follow me, set me free!					
				s.hmspickedup = 3
				p.dohmscarry = true			
				s.state = S_PLAY_RIDE
				if t.player and t.player.drawangle != nil and not (p.pflags & PF_ANALOGMODE)
				p.drawangle = t.player.drawangle
				end				
				if P_PlayerInPain(p) or (s.state != S_PLAY_RIDE)
					t.occupiedcarrying = nil 
					s.occupiedcarrying = nil
					s.hmsstacksfx = false
					s.hmspickuptarget = nil
					if P_PlayerInPain(p)
					s.hmsccd = 50
					end
				elseif t and t.occupiedcarrying and P_IsObjectOnGround(t)	
					t.occupiedcarrying = nil
					s.hmspickuptarget = nil
				elseif s.hmsstacksfx
					if (p.cmd.buttons & BT_SPIN) and (p.spinhold <= 2)
						if (p.charflags & SF_NOJUMPSPIN)
						s.state = S_PLAY_FALL
						else
						s.state = S_PLAY_ROLL
						end
						p.pflags = $|PF_JUMPED & ~PF_SPINNING
						s.hmsccd = 18
						s.occupiedcarrying = nil
						t.occupiedcarrying = nil
						s.hmsstacksfx = false
						s.hmspickuptarget = nil
					elseif (p.cmd.buttons & BT_JUMP) and (p.sms_jumphold <= 2)
						s.hmsccd = 24
						P_DoJump(p, true)
						s.occupiedcarrying = nil
						t.occupiedcarrying = nil
						s.hmsstacksfx = false
						s.hmspickuptarget = nil
					end
				end
			end	
	elseif s.hmspickuptarget
		s.hmspickuptarget = nil
	end

	
	//When SMS is being carried by someone flying, give them boost powers!
	//We're also giving our carrying angels immunity to our fireblasts.
	
	if (p.powers[pw_carry] == CR_PLAYER)
	and s.health
	 if s.tracer and s.tracer.player
	   	if s.skin == "sms" and not p.gotflag 
			if not s.tracer.player.iamcarryingsms or s.tracer.player.iamcarryingsms < 3
				s.tracer.player.iamcarryingsms = 3
				SMSRglow(s.tracer)
			end
	   	end
	  	if (s.tracer.player.hypermysticsonic) and (s.tracer.player.pflags & PF_CANCARRY)
	 		if s.tracer.hmsspinpass or s.tracer.hmscarryspinpass
			p.drawangle = s.tracer.player.drawangle
			s.hmscarryspinpass = 2
			end
			s.hmspickedup = 3
	  	elseif not (s.tracer.player.hypermysticsonic)
			if (s.tracer.player.cmd.buttons & BT_CUSTOM3)
			and (s.tracer.player.charability == CA_FLY)
			and (s.tracer.player.powers[pw_tailsfly] > 5)
				if not (s.tracer.player.hmsblackhole and (s.tracer.player.hmsblackhole > 3))
				and not (s.tracer.player.cmd.forwardmove < -10)
					P_InstaThrust(s.tracer, s.tracer.angle, 55*s.tracer.scale)
					P_InstaThrust(s, s.angle, 55*s.scale)
					S_StartSound(s.tracer, sfx_zoom)
					P_SpawnMobj(s.tracer.x, s.tracer.y, s.tracer.z, MT_SMSAIRBOOST)
					s.tracer.player.hmsblackhole = 25		
					
				elseif (s.tracer.player.cmd.forwardmove < -10)
				and not s.tracer.player.hmsblackhole
					P_SetObjectMomZ(s.tracer, 14<<16, false)
					P_SetObjectMomZ(s, 14<<16, false)
					P_InstaThrust(s.tracer, s.tracer.angle, 17*s.tracer.scale)
					P_InstaThrust(s, s.angle, 17*s.scale)
					S_StartSound(s.tracer, sfx_zoom)
					P_SpawnGhostMobj(s)
					P_SpawnGhostMobj(s.tracer)
					s.tracer.player.hmsblackhole = 25
				end
			end
	   	end
	  end
	end
	
	
	
	if (s.skin == "sms")
		if s.sms_csfxtimer
			s.sms_csfxtimer = $-1
		end
		
		if not (s.eflags & MFE_UNDERWATER)
			--Welcome to the Next Generation, with real life water drip physics!
			if p.sms_steaming
			and not p.hypermysticsonic
			and not (leveltime < 3)
			
				if p.sms_steamingwait
					p.sms_steamingwait = $-1
					if not (p.pflags & (PF_SPINNING|PF_JUMPED|PF_STARTDASH)) and (s.state != S_PLAY_WAIT)
						local ghs = P_SpawnMobjFromMobj(s, 
						SMSLocalRNG(-26,26,s)*s.scale,
						SMSLocalRNG(26,26,s)*s.scale,
						SMSLocalRNG(5,45,s)*s.scale, 
						MT_WATERDROP)
						ghs.scale = $/2
						ghs.frame = ($ & ~FF_TRANSMASK)|TR_TRANS50
					end
				else
					p.sms_steaming = $-1
					if (p.speed > 70*s.scale)
					and (p.sms_steaming > 1) //Lose steam faster if you're going fast.
						p.sms_steaming = $-1 //I'm going to great lengths for such a useless feature...
					end
					if not (p.lddiscount == 3 or p.lddiscount == 1)
						A_BossScream(s, 0, MT_SMSSTEAM)
					end
				end	
			end		
		end

		if (p.pflags & PF_SPINNING)
		
			if (p.pflags & PF_STARTDASH) or p.dashspeed --Currently charging.
			
				//Let's give a fully charged blindddash an extra effect or two.			
				if (p.dashspeed > 90<<16)
				and not (p.pflags & (PF_JUMPED|PF_SLIDING))
					if (p.dashspeed >= 146<<16)
						if not s.sms_fullcharge or (s.sms_fullcharge == 1)
							local ghs = SMS_WallJumpGFX(s, true)
							ghs.color = SKINCOLOR_FLAME
							ghs.blendmode = AST_ADD
							ghs.frame = ($ & ~FF_TRANSMASK)|TR_TRANS40
						end
						s.sms_fullcharge = 3
						if (leveltime % 10 == 0)
							SMS_DustLayers(s, true, s.angle)
						end
						if (leveltime % 4 == 0) and not p.hypermysticsonic
							s.spritexscale = FRACUNIT-11100
							s.spriteyscale = FRACUNIT+13500
							s.SMS_squashtable = {timer = 4, Xspeed = 4500, Yspeed = 5000, ground = true}								
						end
					else
						s.sms_fullcharge = 1
					end
				end				
			
				if (p.pflags & PF_STARTDASH)
					if not (s.smschargedbd and s.smschargedbd > 9) and not p.hypermysticsonic
						s.spritexscale = FRACUNIT-14500
						s.spriteyscale = FRACUNIT+15000
						s.SMS_squashtable = {timer = 12, Xspeed = 3608, Yspeed = 4801, ground = true}	
					end
					s.smschargedbd = 10
					
					local ghs = P_SpawnGhostMobj(s)
					ghs.flags = $|MF_NOCLIP|MF_NOCLIPHEIGHT
					ghs.tics = 3
					ghs.destscale = s.scale*2
				
					if (p.dashspeed >= p.maxdash) 
						p.sms_boostlevel = max($, 28)
						if not p.hypermysticsonic
							if not p.lightdashenable
								p.camerascale =  FRACUNIT*2/3
								s.bhlcamtimer = 2
							end
							local dist = 30*s.scale
							if leveltime % 2 == 0
								dist = 35*s.scale
							end
							for i = 0,40 -- A little aiming reticule
								ghs = P_SpawnMobjFromMobj(s, FixedMul(dist*i ,cos(s.angle)), FixedMul(dist*i,sin(s.angle)), s.height/2, MT_THOK)
								ghs.scale = max(s.scale/2-(i*1000), 500)
								ghs.color = SKINCOLOR_SUPERSILVER1
								ghs.tics = 2
							end
						end
					end
				end
				
			else --We're going!
				
				if (s.eflags & MFE_JUSTHITFLOOR) and (p.cmd.buttons & BT_SPIN) --Fix a weird issue where no sound plays.
					if not s.SMS_squashtable and (s.momz*P_MobjFlip(s) <= 0)
						s.spritexscale = FRACUNIT-19100
						s.spriteyscale = FRACUNIT+24500
						s.SMS_squashtable = {timer = 8, Xspeed = 6000, Yspeed = 7000, ground = true}	
					end
					if not S_SoundPlaying(s, skins["sms"].soundsid[SKSSPIN])
						S_StartSound(s, sfx_spin)
					end
				end
				if s.sms_fullcharge
					if SMS_Locked(s, p, true)
						s.sms_fullcharge = 0
					else
						if (p.speed > 94*s.scale)
							SMS_DustLayers(s, true)
							if (s.sms_fullcharge != 1) --FULL charge!
								s.sms_superspin = 11						
								if s.sms_fullcharge == 2
									if (p.sms_boostlevel > 60) --Go even faster still!
									or p.powers[pw_sneakers]
									or p.hypermysticsonic
										if (p.cmd.forwardmove < -39)
											P_Thrust(s, SMS_PlayerAngle(s,p, true), 41*s.scale)
										else
											P_Thrust(s, SMS_PlayerAngle(s,p), 41*s.scale)
										end
										SMS_ElectricBody(s, 8, SKINCOLOR_SKY)
									end
									SMS_BoostStart(s, true)									
								end
								
								A_SMSquake(s, 44<<16, 9, 3000)	
								if not p.hypermysticsonic
									s.spritexscale = FRACUNIT+55000
									s.spriteyscale = FRACUNIT-27000
									s.SMS_squashtable = {timer = 22, Xspeed = 3802, Yspeed = 4000}	
								end
								SMSRSpawnGhost(s, 22, true)
							else
								if (p.sms_boostlevel < 12)
									p.sms_boostlevel = 12
								end
								if not p.hypermysticsonic --Minor charge.
								and not (s.SMS_squashtable and s.SMS_squashtable.Xspeed == 3802)
									s.spritexscale = FRACUNIT+22000
									s.spriteyscale = FRACUNIT-22000
									s.SMS_squashtable = {timer = 6}
								end
								SMS_BoostAura(s, p)
							end
						end
						s.sms_fullcharge = max($-1,0)
					end
					
				elseif not p.smsblastboost --New spin effects!
				
					if not SMS_Graphix(s)
						p.spinitem = 0
						
						if (p.speed > 38*s.scale) or (abs(s.momz) > 9*s.scale)
							if not (p.pflags & PF_JUMPED)
							and (s.SMS_DLtrail == nil or s.SMS_DLtrail.timer == 1)
								s.SMS_DLtrail = {
								timer = 2, 
								fuse = 7,
								itemtype = MT_THOK, //MT_SMSAUTOFRAME
								spritexscale = s.spritexscale,
								spriteyscale = s.spriteyscale,
								spinspecial = true,
								colorized = false,
								momx = 0,
								scale = s.scale,
								scalespeed = FRACUNIT/8,
								renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS,
								blendmode = AST_ADD,
								}
							end
						elseif P_IsObjectOnGround(s) --Slow trail?
						and (p.speed > 6*s.scale)
						and not (s.eflags & MFE_TOUCHWATER) 
							local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SPINDUST)
							ghs.frame = (SMSLocalRNG(2,4,s)-2)|FF_TRANS40						
						end
					end
					if p.hypermysticsonic or s.sms_superspin 
						if (leveltime % 2 == 0) and P_IsObjectOnGround(s) and (p.speed > 77*s.scale)
							local ghs = HMS_BigBangVortex(s, 9, nil, SMSLocalRNG(-70,70,s)*ANG1, Z+5|FF_TRANS50, (leveltime % 8 == 0) and SKINCOLOR_SUPERSKY5 or SKINCOLOR_SMS3R)	
							ghs.renderflags = RF_FULLBRIGHT
							ghs.tracer = s
							ghs.ditchtracer = 2
							ghs.GSoffsetX = 20*s.scale
							ghs.GSoffsetY = 20*s.scale
							ghs.GSoffsetZ = s.height*5/4
							ghs.momx = s.momx/2
							ghs.momy = s.momy/2
							ghs.spritexoffset = $+(SMSLocalRNG(-50,50,s)*(FRACUNIT/24))
							if (ghs.sttroll < 0)
								ghs.frame = $|FF_HORIZONTALFLIP
							end
						end
						if s.SMS_DLtrail and s.SMS_DLtrail.spinspecial and s.SMS_DLtrail.timer == 2
							s.SMS_DLtrail.scale = nil --Simple tweak makes all the difference.
						end								
					end						
				end
			
				if s.smschargedbd
			
					s.smschargedbd = $-1
				
					if (p.speed > 30*s.scale)
				
					local ghs = P_SpawnGhostMobj(s) 
					ghs.tics = 5 ghs.fuse = 4
					ghs.scale = (s.scale*10)/9
					ghs.destscale = $*99
				
						if not s.smsbdsfx and s.smschargedbd == 9 and not (s.eflags & MFE_UNDERWATER) 
							local sfxrng = P_RandomRange(1,20)
							if p.hypermysticsonic
								sfxrng = 20
							end
							s.smsbdsfx = 25
							if not (S_SoundPlaying(s, skins["sms"].soundsid[SKSZOOM])) --Double Take
								if sfxrng < 10
									S_StartSound(s, sfx_smsha1)
								elseif sfxrng < 14
									S_StartSound(s, sfx_smsha4)
								elseif sfxrng < 18 and not (s.lastbdsfx and s.lastbdsfx > 13 and s.lastbdsfx < 18)
									S_StartSound(s,sfx_smsha2) --Spamming "heh" gets annoying
								elseif sfxrng < 20
									S_StartSound(s,sfx_smsha3)
								else
									S_StartSound(s,sfx_smsha5)
								end
							end
							s.lastbdsfx = sfxrng
						end
						if (s.smschargedbd > 6)
							ghs = P_SpawnMobjFromMobj(s, s.momx, s.momy, s.momz, MT_SMSGROUNDBOOST)
							ghs.tracer = s
							ghs.scale = $/2
							ghs.blendmode = AST_ADD
						end
					end
				end
			end
		else
			s.sms_fullcharge = 0
			s.smschargedbd = 0
		end

		if (s.eflags & MFE_UNDERWATER)
		and not p.hypermysticsonic
		
			local cancel = 0
						
			--Stop blinddash sound!
			
			if not s.health
			
				cancel = 3
				
				if not s.sms_csfxtimer and cancel != s.sms_csfx
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET1] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET2] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET3] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET4] )
			
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SMSTSPARK)				
					S_StartSound(ghs, sfx_splash)
					S_StartSound(ghs, sfx_shldls)
				end					
			
			elseif (p.pflags & PF_SPINNING)	
					S_StopSoundByID(s, skins["sms"].soundsid[SKSZOOM])
					if (p.pflags & PF_STARTDASH)
						cancel = 5						
					elseif not s.sms_csfxtimer and (s.sms_csfx == 5 or cancel == 5 or s.sms_csfx != cancel)
						cancel = 1
						local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SMSTSPARK)
						S_StartSoundAtVolume(ghs, sfx_rail1, 150)
						S_StartSound(ghs, sfx_zoom)
						S_StartSoundAtVolume(ghs, sfx_rail2, 150)
					end			
			elseif P_PlayerInPain(p)
				cancel = 2
				if not s.sms_csfxtimer and cancel != s.sms_csfx
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLPAN1] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLPAN2] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLPAN3] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLPAN4] )
			
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SMSTSPARK)				
					S_StartSound(ghs, sfx_splash)
					S_StartSound(ghs, sfx_s3kb9)
					S_StartSound(ghs, sfx_s3k7d)
				end
			
			elseif (s.state == S_SMSTAUNT1) or (s.sms_tauntcooldown == 188)
				cancel = 4
				if not s.sms_csfxtimer and cancel != s.sms_csfx
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLVCT1] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLVCT2] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLVCT3] )
					S_StopSoundByID(s, skins["sms"].soundsid[SKSPLVCT4] )				
			
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SMSTSPARK)
					S_StartSound(ghs, sfx_splash)
					S_StartSound(ghs, sfx_s3k7d)
				end
			end
			
			s.sms_csfx = cancel
			if cancel != 0 and cancel != 5
				s.sms_csfxtimer = 2
			end
		end
	end

	if (p.sms_steaming or p.sms_steamingwait)
		if p.hypermysticsonic
		or (s.skin != "sms")
		or leveltime == 2
		or SMSSHIELD(p, SH_ELEMENTAL, SH_BUBBLEWRAP)
		or not s.health
			p.sms_steaming = 0
			p.sms_steamingwait = 0
		end
	end

	//Lots of MISC stuff here....

	if (gametype == GT_RACE) and p.smsnoracegame == 2
		if (s.skin != "sms") and (s.skin != "samus") and (s.skin != "basesamus")
		and not p.mysticsuper
		and P_IsObjectOnGround(s)
		and not p.exiting
		and s.health
			p.rings = 500
			A_STARTMYSTICSUPER(s)
		end
	end

	//SMS' stomp has fancy flame lines, but needs a thinkframe to work.
	//I'm essentially just faking an easy A_RotateSpikeball here for a Stomp Aura.

	if s.skin == "sms"
	or (p.sms_sontransform >= 43 and p.sms_sontransform < 72)
	
	end

	//The good old powershare. This time, more reliable than the first time in 2.0! Yay!
	//Also new, we're giving people who went super through powershare little advantages and extra abilities now!
	//We'll refer to powershared super players as "mystic supers", since they're not using the hardcoded superforms...
	//Now entering the domain of Lightspeed Attack and Mystic Super!

	if p.lightspeedchain
		p.lightspeedchain = $-1
	end
	if p.mslightspeedattack
		if (p.sms_boostlevel > 65)
			p.sms_boostlevel = 60 --Hold on, you impatient prick!
		end
		p.mslightspeedattack = $+1
	end
	if p.mysticsuper
		MysticSuperThink(s, p)
		SMSRglow(s)
	end
	
	//Here's the lightspeed dash attack, exclusive to Mystic Supers! If it works, it'll drain 3 rings!
		
	if p.mysticsuper
	
		if (p.transformstatecolors >= 26) or p.transformstatecolors == nil
		p.transformstatecolors = 0
		end
		if not s.anim3_tic or (s.anim3_tic <= 0)
			s.anim3_tic = 24
		else
			s.anim3_tic = $-1
		end
		if not s.anim2_tic or (s.anim2_tic <= 0)
			s.anim2_tic = 4
		else
			s.anim2_tic = $-1
			if (p.speed > 19*s.scale)
				s.anim2_tic = $-1
			end
			if (p.speed > 35*s.scale)
				s.anim2_tic = $-1
			end
			if (p.speed > 50*s.scale)
				s.anim2_tic = $-1
			end
		end
		if (s.skin == "sonic") //Only Sonic gets superframes
		
		//	if not (s.sprite2 > 128) 
		//	s.sprite2 = $+128
		//	end
		s.mysticssprite = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_OVERLAY)
			s.mysticssprite.target = s
			s.mysticssprite.sprite = s.sprite
			s.mysticssprite.skin = s.skin
			s.mysticssprite.sprite2 = s.sprite2|FF_SPR2SUPER
			if ((s.sprite2 == SPR2_STND) or (s.sprite2 == SPR2_WAIT))
			s.mysticssprite.sprite2 = SPR2_STND|FF_SPR2SUPER
				if (s.anim3_tic >= 18)
					s.mysticssprite.frame = A|FF_FULLBRIGHT
				elseif s.anim3_tic >= 12
					s.mysticssprite.frame = B|FF_FULLBRIGHT
				elseif s.anim3_tic >= 6
					s.mysticssprite.frame = C|FF_FULLBRIGHT
				else
					s.mysticssprite.frame = D|FF_FULLBRIGHT
				end
			elseif (s.sprite2 == SPR2_RUN_) or (s.sprite2 == SPR2_FLT_)
				if (s.anim2_tic > 2)
					s.mysticssprite.frame = A|FF_FULLBRIGHT
				else
					s.mysticssprite.frame = B|FF_FULLBRIGHT
				end	
			elseif (s.state == S_PLAY_FLOAT)
				s.mysticssprite.sprite2 = SPR2_FLT_|FF_SPR2SUPER
				if (s.anim2_tic > 2)
					s.mysticssprite.frame = A|FF_FULLBRIGHT
				else
					s.mysticssprite.frame = B|FF_FULLBRIGHT
				end	
			else				
				s.mysticssprite.frame = s.frame
			end
			s.mysticssprite.tics = 2
			s.mysticssprite.scale = s.scale
			s.mysticssprite.color = s.color
			s.flags2 = $|MF2_DONTDRAW
		end
		if p.powers[pw_sneakers]		
			p.powers[pw_sneakers] = 0
			P_RestoreMusic(p)
		end
	  if (p.mysticsuper > 25)
	 	s.smsglowticket = 2
		if not (s.color >= SKINCOLOR_SUPERSILVER1)
		A_STARTMYSTICSUPER(s, true)
		end
		if p.mysscolor
		p.transformstatecolors = $+1
			if ((p.transformstatecolors >= 0) and p.transformstatecolors < 3)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER3+p.mysscolor)
			elseif (p.transformstatecolors >= 3 and p.transformstatecolors < 6)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER4+p.mysscolor)
			elseif (p.transformstatecolors >= 6 and p.transformstatecolors < 9)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER5+p.mysscolor)
			elseif (p.transformstatecolors >= 9 and p.transformstatecolors < 12)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER4+p.mysscolor)
			elseif (p.transformstatecolors >= 12 and p.transformstatecolors < 16)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER3+p.mysscolor)
			elseif (p.transformstatecolors >= 16 and p.transformstatecolors < 21)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER2+p.mysscolor)
			elseif (p.transformstatecolors >= 21 and p.transformstatecolors < 23)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER1+p.mysscolor)
			elseif (p.transformstatecolors >= 23 and p.transformstatecolors < 27)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER2+p.mysscolor)
			end
		end
	  end
	
/*		if ((p.pflags & PF_JUMPED) or p.powers[pw_tailsfly])
		and (p.rings > 5) //Only let the lightspeed attack work if you have enough rings.
		and s.lightspeedpermission  and not (p.mysticsuper < 30)
		and not p.mslightspeedattack //If already active, don't activate again or you'll drain rings like crazy!
		and not P_IsObjectOnGround(s) and not p.sms_intoship
		  if not (p.transformdown > 1)
		  and (p.cmd.buttons & BT_CUSTOM3)
			local ghs = P_SpawnMobj(s.x+FixedMul(170<<16,cos(s.angle)), s.y+FixedMul(170<<16,sin(s.angle)), s.z-550<<16, MT_SMSECHECK)
			if ghs and ghs.valid
			ghs.lsasms = true
			ghs.target = s
			ghs.height = 1100<<16
			ghs.radius = 960<<16
			end
			if s.target and s.lsatarget and (s.target == s.lsatarget)
			and (s.target.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR))
			and s.target.health			
				p.mslightspeedattack = 1
				p.lightspeedchain = 2
				s.lsatarget = nil
				p.pflags = $|PF_JUMPED
				p.powers[pw_tailsfly] = 0
				S_StartSound(s, sfx_s3k83)
				s.lsaringdebt = 15
				p.transformdown = 300
			end
		  else
		  	local ghs = P_SpawnMobj(s.x+FixedMul(170<<16,cos(s.angle)), s.y+FixedMul(170<<16,sin(s.angle)), s.z-550<<16, MT_SMSECHECK)
			if ghs and ghs.valid
			ghs.target = s
			ghs.lsasms = true
			ghs.justcheckin = true
			ghs.height = 1100<<16
			ghs.radius = 960<<16
			end
		  end
		end */
	end
		
	--Light Speed Attack, the LSA! Disabled for now, don't have time to fix and maintain it.
	--	if p.mslightspeedattack
	--		SMS_LSA(s,p)
	--	end
			
	//It's SMS flashing supercolors and other custom color patterns. The SMSreborn sprites are designed with these in mind, 
	//but I'll let players pick normal colors if they want to for some reason.

	if s.skin == "sms" --SMS skin check!
	
		SMS_Colors(s, p) --Flash SMS colors
		
		if not p.hypermysticsonic	
			if (s.health <= 0) --Dead but not in death frames? Put death frames back up!
				if s.SMS_DeathFlash == nil
					local ghs = P_SpawnMobjFromMobj(s, 0,0,s.scale*32+(s.momz*2), MT_THOK)
					local ths = SMS_LightFlash(ghs, SKINCOLOR_WHITE)
					ths.tracer = ghs ths.dispoffset = 30
					HMS_AuraStorm(ghs, nil, SKINCOLOR_WHITE)
					HMS_AuraStorm(ghs, nil, SKINCOLOR_MYSTICAL5)
					ghs.flags2 = $|MF2_DONTDRAW ghs.fuse = 55 ghs.tics = 55
					s.SMS_DeathFlash = true
					SMS_SkinSwap(s, p) --Reset every value in history.
					s.spriteyscale = FRACUNIT-4500
					s.spritexscale = FRACUNIT+4500
					s.SMS_squashtable = {timer = 4, Xspeed = 1500,Yspeed = 1500}				
				end	
				if (s.state != S_PLAY_DEAD) and (s.state != S_PLAY_PAIN)
				and (abs(s.momz) > 3*s.scale)
					s.state = S_PLAY_DEAD
				end			

			else
				SMS_Shields(s, p) --Special shield behaviour?
				
			/*	if p.lightdashenable --LSA checker.
				and (p.dashspeed > 145<<16)
				and (p.pflags & PF_STARTDASH)
					p.camerascale =  FRACUNIT*3/2
					s.bhlcamtimer = 2
					local ghs = P_SpawnMobj(s.x+FixedMul(170*s.scale,cos(s.angle)), s.y+FixedMul(170*s.scale,sin(s.angle)), s.z-550*s.scale, MT_SMSECHECK)
					if ghs and ghs.valid
						ghs.target = s
						ghs.lsasms = true
						ghs.justcheckin = true
						ghs.height = 1100<<16
						ghs.radius = 960<<16
					end
					if (p.cmd.buttons & BT_CUSTOM2)
					and not (p.smsmeleebutton > 1)
						local ghs = P_SpawnMobj(s.x+FixedMul(170*s.scale,cos(s.angle)), s.y+FixedMul(170*s.scale,sin(s.angle)), s.z-550*s.scale, MT_SMSECHECK)
						if ghs and ghs.valid
							ghs.lsasms = true
							ghs.target = s
							ghs.height = 1100<<16
							ghs.radius = 960<<16
						end
						if s.target and s.target.valid and s.target.health
						and ((s.target.flags & MF_ENEMY) or (s.target.flags & MF_BOSS) or (s.target.flags & MF_MONITOR))
							p.mslightspeedattack = 1
							s.lsatarget = nil
							p.lightspeedchain = 2
							p.pflags = $|PF_JUMPED & ~PF_SPINNING
							S_StartSound(s, sfx_s3k83)
							S_StartSound(s, sfx_zoom)
							p.transformdown = 300
							p.smsmeleebutton = 850
						end
					end
				end	*/	
				
				if (s.state == S_SMSTAUNT1) --Stay in run frames when you're taunting.
			
					s.sprite2 = SPR2_RUN_
					s.frame = $|FF_ANIMATE
					if not s.anim_duration or (s.anim_duration > 2)
						s.anim_duration = 2 //Run in place
					end
					if not (s.SMS_ControlAlter and s.SMS_ControlAlter.timer > 1) 
						s.SMS_ControlAlter = {
						timer = 2,
						sidemove = 0,
						forwardmove = 0,
						freecondition = 3,
					--	turnangle = s.angle,
						removebuttons = (BT_CUSTOM2|BT_CUSTOM3|BT_TOSSFLAG|BT_WEAPONPREV|BT_WEAPONNEXT)} --You can spin and jump out
					end
					if (s.sms_tauntcooldown == 129)
						if P_IsObjectOnGround(s)
							s.state = S_PLAY_STND
						elseif not (p.pflags & PF_JUMPED)
							s.state = S_PLAY_FALL
						end
					elseif (s.sms_tauntcooldown > 140)
						local FRAME = (s.frame & FF_FRAMEMASK)
						if FRAME == B
							local RNG = SMSLocalRNG(1,9,s)
							local ghs = P_SpawnMobjFromMobj(s, FixedMul((12-RNG)*s.scale, cos(s.angle+ANGLE_90)),FixedMul((12-RNG)*s.scale, sin(s.angle+ANGLE_90)), 0, MT_SPINDUST)
							ghs.frame = SMSLocalRNG(4,2,s)-2|(FF_TRANS10+(RNG/2)<<16)
							P_Thrust(ghs, s.angle+(ANG20*7), 3*(s.scale/4*RNG))
							ghs.spriteyscale = FRACUNIT-SMSLocalRNG(5000,55555,s)
							ghs.spritexscale = ghs.spriteyscale
						elseif FRAME == D
							local RNG = SMSLocalRNG(1,9,s)
							local ghs = P_SpawnMobjFromMobj(s, FixedMul((12-RNG)*s.scale, cos(s.angle-ANGLE_90)), FixedMul((12-RNG)*s.scale, sin(s.angle-ANGLE_90)), 0, MT_SPINDUST)
							ghs.frame = SMSLocalRNG(0,2,s)|(FF_TRANS10+(RNG/2)<<16)
							P_Thrust(ghs, s.angle-(ANG20*7), 3*(s.scale/4*RNG))
							ghs.spriteyscale = FRACUNIT-SMSLocalRNG(5000,55555,s)
							ghs.spritexscale = ghs.spriteyscale
						end				
					end
				end
			end
			//If you're HMS, however, you get MULTIPLE projectiles! Let's start on his version of the flames.
			
			if p.sms_hugeflametoss
			
				p.sms_hugeflametoss = max($-1,0)		
				SMS_TossingHugeFlame(s, p)
				SMS_DiffusionChargeSparkles(s,p)
				
			elseif s.health
			
				if (p.cmd.buttons & BT_FIRENORMAL) 
				or (p.cmd.buttons & BT_ATTACK) and (p.sms_flamebuttonhold == 1) 
					if p.rings or (p.mxscap > 1) or (p.powers[pw_shield] & SH_FIREFLOWER) --Fire flower makes flames free.
						if (not p.sms_flamedelay or p.sms_flamedelay == 1)

						and not ( SMS_Locked(s, p, nil, true) 					
						and not (p.gotflag and s.battlemodsms)						
						and not (p.powers[pw_carry] and not (p.powers[pw_carry] != CR_ZOOMTUBE and p.powers[pw_carry] != CR_NIGHTSMODE) )
						)
						and not p.footsweepanim
						
						and not (p.smspickup and p.smspickup.valid)
						
						and not ((s.flags2 & MF2_DONTDRAW) and not p.powers[pw_flashing])
					
						and not ((p.sms_dodging > 9) or p.smsdivefloat or p.smsdivetimer or p.sms_ringburstfly)
						and not p.objectplacer --mod support.
						and not (p.fludd and p.fludd.enabled)
							SMS_TossSmallFlame(s, p)
							p.sms_flamedelay = max($,2)
						end
					end
				end			
			
				//A Sonic Boom from hitting mach speed!
				if (p.sms_boostlevel >= 65 and p.sms_boostlevel < 95)
					S_StartSound(s, sfx_smach)
					A_SMSquake(s, 54<<16, 4, 3400)
					s.sms_lastboost = s.sms_lastboost and $+abs(95-p.sms_boostlevel) or 0
					p.sms_boostlevel = 95
					s.hudboost = 1
					P_RadiusAttack(s, s, min(500*s.scale, max(p.speed+5*s.scale, 200*s.scale)) ) //Clear smaller enemies in your way.
				
					SMS_DustLayers(s, true)
					local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_RADIALBOOST)
					ghs.target = s
					ghs.blendmode = AST_ADD
					
					SMS_BoostStart(s, true)
				end
				
				--Wanna throw some fire?
				local FLAMETYPE = 0	
				if (p.cmd.buttons & BT_FIRENORMAL)
				or (p.cmd.buttons & BT_ATTACK) and not (p.sms_flamebuttonhold > 1) and not (p.sms_boostlevel > 64)
					FLAMETYPE = 1
				elseif (p.cmd.buttons & BT_ATTACK) and not (p.cmd.buttons & BT_FIRENORMAL)
				
					if ((p.sms_flamebuttonhold > 39) or (p.sms_boostlevel > 64))
						FLAMETYPE = 2
					elseif (p.sms_flamebuttonhold > 3)
						FLAMETYPE = 3
					end
				end
				if FLAMETYPE != 0 --Checks that apply for both!
					if p.sms_flamedelay
					or (p.smsdivefloat or p.smsdivetimer or p.sms_ringburstfly)
					or p.objectplacer
					or p.smspickup
					or ((s.state == S_SMS_ATOMLAND1) or (s.state == S_SMS_ATOMLAND2))
					or p.homing
					or not s.health
					or p.exiting 
					or p.hypermysticsonic					
					or (p.pflags & (PF_STASIS|PF_GAMETYPEOVER))
					or ((p.powers[pw_carry] == CR_ZOOMTUBE) or (p.powers[pw_carry] == CR_NIGHTSMODE))
					or (p.fludd and p.fludd.enabled)
						FLAMETYPE = 0
					elseif FLAMETYPE == 1
						if p.rings 
						or (p.mxscap > 1)
						or (p.powers[pw_shield] & SH_FIREFLOWER)
							if not (p.gotflag and s.battlemodsms)
							and not p.footsweepanim
							and not ((s.flags2 & MF2_DONTDRAW) and not p.powers[pw_flashing])
							and not (p.sms_dodging > 9)
								SMS_TossSmallFlame(s, p)
							end
						end				
					elseif FLAMETYPE >= 2
						if (p.rings >= 3) and not s.battlemodsms
						or (p.rings >= 5)
						or (p.mxscap > 1)
						or (p.powers[pw_shield] & SH_FIREFLOWER) //Meet one of these requirements to shoot fire
							if not SMS_Locked(s, p, true)
							and not p.sms_aerialfirerestrict
							and not (s.flags2 & MF2_DONTDRAW)
							and not p.sms_dodging
							and not (p.panim == PA_PAIN or (s.state == S_PLAY_RIDE))
							and not p.smsblastboost
							and not (s.silv_grabbed and s.silv_grabbed.valid)
								if FLAMETYPE == 2
									SMS_DiffusionChargeSparkles(s,p)
									if (p.pflags & PF_DIRECTIONCHAR)
										s.forcesmsangletimer = 19
										s.forcesmsangle = s.angle
									end
									p.sms_hugeflametoss = 19
									s.dfclosest = nil
									s.quickdfthrow = false
									p.pflags = $ & ~PF_JUMPED|PF_SPINNING
								else --Just render charging effects, then!
									SMS_DiffusionChargeSparkles(s,p)
												
									--Look alive there, Sonic.
									if (p.panim == PA_IDLE)
										if (s.state == S_PLAY_WAIT)
											s.state = S_PLAY_STND
										elseif (s.state == S_PLAY_STND)
											s.tics = 99 s.anim_duration = 99
										end
									end
								end
							end
						end			
					end					
				end
				if s.sms_addboostlevel
					if not (p.pflags & PF_SPINNING) and not SMS_Locked(s,p)
						p.sms_boostlevel = $+s.sms_addboostlevel
						s.sms_lastboost = s.sms_lastboost and $+s.sms_addboostlevel
					end
					s.sms_addboostlevel = 0
				end
				//Zap! Bzzzt! Shock! Oww! It's electricity!
				//....uhh, yeah. Anyway, under certain circumstances, SMS will exert electrical currents off his body
				if (p.smsdivefloat > 10)
				or ((p.pflags & PF_STARTDASH) and (p.dashspeed >= 146<<16))
				or p.hypermysticsonic
					if SMS_Graphix(s) != 2
						local ghs = P_SpawnMobjFromMobj(s, 
						SMSLocalRNG(99, 99, s)*s.scale,
						SMSLocalRNG(-99, 99, s)*s.scale,
						SMSLocalRNG(1, FixedInt(s.height)+8, s)*s.scale*P_MobjFlip(s),
						MT_HMSWAVEAURA)
						ghs.target = s
					end
				end		
			end
			if (p.powers[pw_sneakers] > 699)
			and not (p.speedspeedspeedspeedspeed > 24)
			and (not SMS_NerfedMode(p) and not s.battlemodsms)
				p.powers[pw_sneakers] = 825
				p.speedspeedspeedspeedspeed = $+1
				if (p.speedspeedspeedspeedspeed == 1)
					S_StartSound(s, sfx_s3k4e)
					S_StartSound(s, sfx_bejet1)
					P_FlashPal(p, PAL_MIXUP, 7)
					P_NukeEnemies(s, s, 0)
					
					local ghs = SMS_LightningStrike(s, SKINCOLOR_SMS1R, R|FF_TRANS10)
					ghs.tracer = s ghs.fuse = 29
					
					ghs = SMS_LightClash(s, SKINCOLOR_SMS1R)
					ghs.scalespeed = 24000
					ghs.fuse = 21
					ghs.spriteyoffset = -4<<16
					ghs.tracer =  s
				--	HMS_AuraStorm(s, nil, SKINCOLOR_SUPERSKY5, 9, nil, 2)
					HMS_BoltStorm(s, SKINCOLOR_SMS4R, 14, nil, -132)
					
				/*	ghs = P_SpawnMobjFromMobj(s, 0,0, -24*s.scale,  MT_BURSTWAVE)
					ghs.color = SKINCOLOR_FLAME
					ghs.blendmode = AST_ADD */
				
					ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_HMSLIGHTNING2)
					ghs.followsms = s
					ghs.blendmode = AST_ADD
					A_SMSquake(s, 70<<16, 5, 1050)
				
					ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_SMSSPARKLESPAWN)
					ghs.target = s
				end
			end
			if s.sms_justuncurled
				s.sms_justuncurled = $-1
			end		
		end --End of "not p.hypermysticsonic" check.

		if (p.cmd.buttons & BT_TOSSFLAG)
			p.sms_tossflaghold = $+1 or 1
		elseif p.sms_tossflaghold
			p.sms_tossflaghold = 0
		end
				
		if (p.pflags & PF_SPINNING)
			
			if (((s.state >= S_SMS_BOOST01) and (s.state <= S_SMS_BOOST04))
			or (s.state <= S_PLAY_DASH))
				s.state = S_PLAY_ROLL --Stop this nonsense, pls.
			end
			
			if (p.pflags & (PF_JUMPED|PF_STARTDASH))
			or SMS_MovingCharge(s, p) --Trying to charge on the spot instead?
			or p.smsblastboost --SMSreborn only.
			or p.gotflag
				s.sms_runspinboost = 0
				p.sms_spinuc = 0
			else
				--Increase accel. Though the game already increases spindash control if PF_THOKKED is applied
				p.acceleration = (p.pflags & PF_THOKKED) and 46 or 98 
				
				if ((p.panim == PA_ROLL) or p.hypermysticsonic)
				and (p.cmd.forwardmove > -11)
				and not (p.cmd.buttons & (BT_SPIN|BT_CUSTOM2))
					p.sms_spinuc = p.hypermysticsonic and $+2 or $+1
				end
				if (p.sms_spinuc >= 2)
			
					if (p.cmd.buttons & BT_SPIN) and not (p.hypermysticsonic and not P_IsObjectOnGround(s))
					or ((p.cmd.buttons & BT_CUSTOM2) and not (p.smsmeleebutton > 3))		
					
						p.pflags = $ & ~(PF_SPINNING|PF_THOKKED|PF_STARTDASH|PF_JUMPED|PF_STARTJUMP) //Researchers agree this is the best flag to kill.
						s.sms_justuncurled = 9
						
						if (p.cmd.buttons & BT_CUSTOM2)
							p.smsmeleebutton = 3
						end
				
						local ghs = P_SpawnGhostMobj(s)
						ghs.destscale = ghs.scalespeed+1
				
						S_StartSound(s, sfx_s3kd1s)
						--Uncurl from your roll into this anim!
						if P_IsObjectOnGround(s) or p.hypermysticsonic
							s.state = S_PLAY_RUN //Put us in the running animations
						else
							s.state = (s.momz*P_MobjFlip(s) > s.scale*7) and S_PLAY_SPRING or S_SMS_ADVFALL1
						end
					end
				end
				if s.sms_justuncurled and (P_IsObjectOnGround(s) or p.hypermysticsonic)
					s.sms_runspinboost = $+1
				else
					s.sms_runspinboost = 0
				end
			end			
				
		else --Not spinning.
		
			p.acceleration = 36
				
		--Spamdash! Well, it's an "uncurl" boost rather than a spindash boost, but hey, similar enough! Uncurlboost. Uncurl Boost.
		
			if (s.sms_runspinboost == 1 or p.hypermysticsonic and s.sms_runspinboost and s.sms_runspinboost <= 7 or p.sms_spinuc) //Spamdash script
			and ( (abs(p.cmd.sidemove) > 20) or (abs(p.cmd.forwardmove) > 20) )
			and (p.speed > 12*s.scale)
			and (P_IsObjectOnGround(s) or p.hypermysticsonic)
			and s.sms_justuncurled
		--	and not SMS_Locked(s, p, true, true)
			and not p.smsblastboost

				if not (s.eflags & MFE_UNDERWATER)	
				
					if (p.sms_boostlevel < 65)
						p.sms_boostlevel = min($+22,63)
					end
					
					if p.hypermysticsonic --Infinity speed.
					or (p.powers[pw_sneakers] and (not SMS_NerfedMode(p) and not s.battlemodsms))
						local Radial = 480*s.scale
					
						if (p.speed > 220*s.scale)
							if p.hypermysticsonic
								Radial = 2000*s.scale
								P_Thrust(s, s.angle, FixedMul(p.speed/3, s.scale)) //Aaaand we've gone absolutely bonkers....
							end
							P_Thrust(s, s.angle, 250*s.scale) 
						else
							P_Thrust(s, s.angle, 115*s.scale)
							if p.hypermysticsonic
								Radial = 1000*s.scale
							end
						end
						S_StartSound(s, sfx_smach) 
						A_SMSquake(s, 54<<16, 4, 3400)
						p.sms_boostlevel = 95
						s.hudboost = 1
						P_RadiusAttack(s, s, Radial) //Clear out smaller enemies in your way.
				
						local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_RADIALBOOST)
						ghs.target = s
						ghs.blendmode = AST_ADD
				
					else
						local speedgain = min(99, max(36, FixedInt((p.speed or (10<<16))*6/13)) )
						P_Thrust(s, s.angle, speedgain*s.scale) --Regular speedgain.
					end					
					S_StartSound(s, sfx_cdfm16)
				else
					P_Thrust(s, s.angle, 14*s.scale) //Smaller underwater boost.
				end
				if not s.bhlcamtimer or (s.bhlcamtimer < 3) --Zoom out a bit for an extra sense of speed!
					p.camerascale = FRACUNIT*3/2
					s.bhlcamtimer = 5	
				end	
				if SMS_Graphix(s) == 0
					if not s.SMS_DLtrail 
						if p.hypermysticsonic
						or p.powers[pw_sneakers] and (not SMS_NerfedMode(p) and not s.battlemodsms)
							local ghs = SMS_FollowCircle(s, SKINCOLOR_SMS3R)
							ghs.blendmode = AST_ADD ghs.fuse = $-3
							ghs = HMS_RollWaves(s, ANG1*63, 8, SKINCOLOR_SUPERSKY5, FRACUNIT+9999, nil, s)
							ghs.scalespeed = $+(FRACUNIT/4)
							ghs.sttfade = 11

							for i = -1,1
								ghs = SMS_CraterSpew(s, s.angle+(ANG1*120*i), 13)
								if ghs and ghs.valid
									ghs.spritexscale = $*3/2
									ghs.spriteyscale = $*3/2
									ghs.momx = ($*9)+FixedDiv(FixedMul(s.momx, 2),3)
									ghs.momy = ($*9)+FixedDiv(FixedMul(s.momy, 2),3)
									ghs.smsrgtimer = 23
								end
							end										
							s.SMS_DLtrail = {timer = 3, color = SKINCOLOR_RED, colorized = true, fuse = 6, spriteyscale = FRACUNIT+52000, spritexscale = FRACUNIT+52000, scalespeed = FRACUNIT/6}
						else
							s.SMS_DLtrail = {timer = 2, color = s.color, colorized = true, spriteyscale = FRACUNIT+29999, spritexscale = FRACUNIT+29999, scalespeed = FRACUNIT/7}
						end
					end
				end
				
				local ghs = P_SpawnMobjFromMobj(s, 0,0,s.height/5, MT_THOK) //visual effect for SMS v1.1+
				ghs.color = s.color
				ghs.sprite = SPR_SBRT
				ghs.renderflags = RF_PAPERSPRITE|RF_SEMIBRIGHT
				ghs.angle = s.angle+ANGLE_90
				ghs.fuse = 7
				ghs.tics = 9
				ghs.momx,ghs.momy,ghs.momz = s.momx/3,s.momy/3,s.momz/3
				ghs.scalespeed = $*4
				ghs.destscale = $*20
				
				if (p.speed > 56*s.scale)
				and (p.cmd.forwardmove > 4)
				and not (s.eflags & MFE_UNDERWATER)
					if not (p.cmd.buttons & BT_CUSTOM1)
						s.sms_tapnothold2 = 0 --Okay, but don't ringburst from tapping spin.
						p.cmd.buttons = $|BT_CUSTOM1
						p.sms_autoboosthold = 9
					end
					s.smsboostimmune = 3
				end					
			end	
		
			p.sms_spinuc = 0
			s.sms_runspinboost = 0
		end		
-------------------------------------------------		
	  end  //Warning: "if sms" check is removed from here on out. All skins apply now.
-------------------------------------------------

	//Creating a new function called flamedelay, which will act as our firing timer.
	//It may even affect other players later, for reasons having to do with the aura.

	if p.sms_flamedelay //If your flametimer isn't 0, then....
		p.sms_flamedelay = max($-1,0) //Minus 1 each frame untill back at 0.
	end	
	
	//When holding SMS, you become intangible to his attacks so he
	//can bomb enemies from above without his flames hitting you.

	if p.iamcarryingsms
		p.iamcarryingsms = $-1
	end
	if p.aurarefresh
		p.aurarefresh = $-1
	end
	if not p.hypermysticsonic --HMS doesn't use these.
		if p.sms_sontransform
			p.sms_sontransform = $+1
		end	
		--NOTE: Other characters use this too to avoid SMS' haymaker in match!
		if p.sms_dodging
			p.sms_dodgetap = 0
			p.sms_dodging = $-1
		
			if p.sms_dodging == 12 //This part is here so it'll work with all skins in SkillStrip
				if not ((p.panim == PA_PAIN) or (p.panim == PA_SPRING) )
				and not (p.pflags & PF_JUMPED)
					if s.sdodgelvl and (s.sdodgelvl > 2)
						s.momx = $*3/4
						s.momy = $*3/4
						P_SetObjectMomZ(s, -6<<16)
					else
						s.momx = $/3
						s.momy = $/3
						if not (s.eflags & MFE_UNDERWATER)
							P_SetObjectMomZ(s, -FRACUNIT)
						end
					end
				end
			elseif (p.sms_dodging == 1)
				if P_IsObjectOnGround(s)
					if s.sdodgelvl and (s.sdodgelvl > 2)
						s.momx = $*4/5
						s.momy = $*4/5
					else
						s.momx = $/2
						s.momy = $/2
					end
					p.smsmeleebutton = 2
				elseif s.sdodgelvl and (s.sdodgelvl > 2)
					if ((s.state == S_PLAY_ROLL) or (p.panim == PA_ROLL) or (p.panim == PA_JUMP))
						local ghs = P_SpawnGhostMobj(s)
						ghs.fuse = 8 ghs.tics = 9
						ghs.scalespeed = FRACUNIT/9
						ghs.destscale = ghs.scalespeed+1
					
						s.state = S_PLAY_FALL
						p.pflags = $ & ~PF_JUMPED
						p.sms_dodging = 0
					end
					P_SetObjectMomZ(s, -2<<16, true)		
				end
			end
		else
			if p.sms_dodgetap or (p.sms_dodgetap == 0)
				if (abs(p.cmd.sidemove) > 8)
				or (abs(p.cmd.forwardmove) > 8) and not (s.flags2 & MF2_TWOD)
					p.sms_dodgetap = $+1
				else
					p.sms_dodgetap = 0
				end
			end
			//We must set a walljump-only multithok limit to prevent abuse..

			if p.sms_wallstat
				p.charflags = $ & ~SF_MULTIABILITY
				P_ResetScore(p)
				p.sms_wallstat = $-1 //Minus everytime!
				if (p.sms_wallstat > 50) and (p.speed > 11*s.scale)
				and p.lddiscount == 1
					P_SpawnMobj(s.x, s.y, s.z+(s.height/2), MT_SPARK)
				end
			end	
			if p.smsrdash --Rdash is "ring dash", aka LightDash.
				p.smsrdash = $-1
			end
			if p.lightdashstart == 1 //Let's make a sound when you start lightdashing.
			S_StartSound(s, sfx_s3kb6)
				if s.skin == "sms" and not s.airboostroll
					if s.hmsrotateright
						s.hmsrotateright = false
					else
						s.hmsrotateright = true
					end
					p.sms_stompanim = 0 
					s.airboostroll = 9
					s.rollangle = 0
				end
			end
		end
	end
	if p.readyforpowershare
		p.readyforpowershare = $-1
		SMSRglow(s)
	end	
	p.lddiscount = p.lddiscount and $+1 or 1 --my original (leveltime % 2) wannabe.
	if (p.lddiscount > 3)
		p.lddiscount = 0
	end
	if p.elauracolors != nil
		p.elauracolors = $+1
		if (p.elauracolors >= 280)
			p.elauracolors = 0
		end
	end	
	if (p.cmd.buttons & BT_SPIN)
		p.spinhold = $+1
	else
		p.spinhold = 0
		if s.hmsspinfreeze
			s.hmsspinfreeze = nil
		end
	end
end, MT_PLAYER)

--The Mystic Super thinker, AKA SMS' "powershare" forms in action!
rawset(_G, "MysticSuperThink", function(s, p, yu)
	s.ssxaticket = true
	p.mysticsuper = $+1

	if (p.powers[pw_invulnerability] < 1450)
	or p.powers[pw_sneakers]
	or p.powers[pw_extralife]
		p.powers[pw_extralife] = 0
		p.powers[pw_sneakers] = 0
		s.resetsongtodayok = true //Wait for thinkframe or else the game will fight you.
	end
	
	p.powers[pw_invulnerability] = 7777
	p.superinvulnerable = true
	P_ResetScore(p) //Needed to prevent infinite lives
	
	if (p.charability == CA_FLY) and p.powers[pw_tailsfly]
		p.powers[pw_tailsfly] = 250 --Infinite flight.
	end
	
	if (p.mysticsuper < 24)
		s.momx = 0
		s.momy = 0
		s.momz = 0
		p.pflags = $|PF_THOKKED & ~PF_GLIDING			
	elseif (p.mysticsuper == 24)
		p.pflags = $ & ~PF_GLIDING & ~PF_THOKKED
	end
	
	if (p.charability == CA_GLIDEANDCLIMB) --Superfast climbing!
		if p.climbing
			if (p.cmd.buttons & BT_CUSTOM3) --Super jump off the wall!
				P_DoJump(p)
				p.pflags = $|PF_JUMPED & ~PF_THOKKED
				s.state = S_PLAY_SPRING
				S_StartSound(s, sfx_bljp)
				P_SetObjectMomZ(s, 30<<16)
				P_SpawnGhostMobj(s)
				s.angle = $+ANGLE_180 //Keep facing that wall.
			else --Speed climbing!
				if (abs(p.cmd.forwardmove) > 20)
					s.momz = $*2
					P_SpawnGhostMobj(s)
				end
				if (abs(p.cmd.sidemove) > 20)
					s.momx = $*2
					s.momy = $*2
				end
			end
		end
		
	elseif (p.charability == CA_HOMINGTHOK) --Multi homing for everyone!
	
		if (p.pflags & PF_THOKKED) and not p.homing and ((s.state == S_PLAY_SPRING) or (s.state == S_PLAY_FALL))
			p.pflags = $|PF_JUMPED & ~(PF_THOKKED|PF_NOJUMPDAMAGE|PF_SPINNING)
			s.state = S_PLAY_ROLL
		end
		if p.homing
			s.homingfremove = true
		elseif s.homingfremove --Reset state after homing attack!
			if (p.pflags & PF_NOJUMPDAMAGE)
			and ((p.panim == PA_SPRING) or (p.panim == PA_FALL) or (p.panim == PA_IDLE))
				if (abs(s.momz) > 11*s.scale)
				or (s.momz*P_MobjFlip(s) > 9) and (s.momz*P_MobjFlip(s) < 4*s.scale)
					P_SetObjectMomZ(s, 10<<16) --Anti-jank.
					s.momx = 0
					s.momy = 0
				end
			--	if (p.speed > 50*s.scale) --That's not right...
			--		P_InstaThrust(s, R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy), 50*s.scale)
			--	end
				p.pflags = $|PF_JUMPED & ~PF_THOKKED & ~PF_NOJUMPDAMAGE & ~PF_SPINNING & ~PF_STARTDASH & ~PF_SLIDING
				s.state = S_PLAY_ROLL
			end
			s.homingfremove = nil
		end
	end
	
	if (p.cmd.buttons & BT_SPIN)
	
		if (p.charability2 == CA2_GUNSLINGER) and (p.weapondelay == 14) 
		and (p.panim == PA_ABILITY2) and P_IsObjectOnGround(s) --Machine Gun Fang?!
			A_FireShot(s, MT_CORK, 40<<16)
			s.state = S_PLAY_SPRING
			s.newshootframe = nil
			p.weapondelay = 0
			p.pflags = $ & ~PF_USEDOWN
		end
		
		if (p.charability == CA_GLIDEANDCLIMB)
			if (p.pflags & PF_GLIDING) 
				P_InstaThrust(s, s.angle, p.actionspd*40/19)
				s.momz = 0
				if not (p.spinhold > 1)
					S_StartSound(s, sfx_zoom)
					p.spinhold = 3
				end
				P_SpawnSpinMobj(p, MT_THOK)
			end
			
		--Multithok for all!
		
		elseif ((p.charability == CA_THOK) or (p.charability == CA_JUMPTHOK) or (p.charability == CA_HOMINGTHOK) or s.skin == "shadow")
			if (p.pflags & PF_JUMPED) and (s.momz*P_MobjFlip(s) < (gravity)) and (p.speed >= 5*s.scale) and not p.homing
				s.momz = 2*P_MobjFlip(s)
				if s.skin == "sonic"
					s.sprite2 = SPR2_FLT_|FF_SPR2SUPER //Only Sonic is guaranteed to have these...
					if (p.speed < p.runspeed)
						s.state = S_PLAY_FLOAT
					elseif (p.speed > p.runspeed)
						s.state = S_PLAY_FLOAT_RUN
					end
				elseif not (s.state == S_PLAY_ROLL)
					s.state = S_PLAY_ROLL
				end
			end
			
		elseif (p.charability == CA_FLOAT)
		
			if (p.pflags & PF_THOKKED) and not (p.pflags & PF_JUMPED) --Gain a charge boost!			
				s.momx = $*20/21
				s.momy = $*20/21
				if s.metalcharge == nil
					s.metalcharge = 0
				end
				if not (s.metalcharge > 219)
					s.metalcharge = $+1
					if (s.metalcharge == 217)
						S_StartSound(s, sfx_kc3d)
						S_StartSound(s, sfx_kc3d)
						S_StartSound(s, sfx_kc3d)
						s.metalcharge = 218
					end
				end
				s.metalcharge = $+1
				if s.skin == "metalsonic"
					if (p.mysticsuper % 2 == 0)
					s.sprite = SPR_METL
					s.sprite2 = 0
					s.frame = S|FF_FULLBRIGHT
						if not (s.metalcharge > 219)
							P_SpawnSpinMobj(p, MT_THOK)
							local ghs = P_SpawnMobjFromMobj(s, ((P_RandomRange(FixedMul(-300, s.scale), FixedMul(300, s.scale)))<<16), 
							((P_RandomRange(FixedMul(-300, s.scale), FixedMul(300, s.scale)))<<16),
							((P_RandomRange(FixedMul(300, s.scale), FixedMul(-300, s.scale)))<<16),
							MT_MSGATHER)
							if ghs and ghs.valid
								ghs.fuse = P_RandomRange(10,20)
								ghs.flags = $|MF_SPECIAL
								ghs.frame = $|TR_TRANS50
								ghs.renderflags = RF_FULLBRIGHT
								P_HomingAttack(ghs, s)
							end
						end
					else
						s.sprite = SPR_METL
						s.sprite2 = 0
						s.frame = T|FF_FULLBRIGHT
					end
					s.anim_duration = 3
					s.tics = 3
				elseif not (s.state == S_PLAY_ROLL)
				s.state = S_PLAY_ROLL
				end
			end
			
		elseif (p.charability == CA_BOUNCE) --SUPER bounce!
		
			if (p.pflags & PF_THOKKED) and not s.myssbacd and not (p.pflags & PF_JUMPED)
				if not (p.spinhold > 1)
					S_StartSound(s, sfx_alart)
					P_SpawnGhostMobj(s)
					if not ((s.momz*P_MobjFlip(s)) < -20*s.scale)
						P_SetObjectMomZ(s, -20<<16)
					else
						P_SetObjectMomZ(s, -4<<16, true)
					end
					p.spinhold = 3
					s.myssbacd = 35
				end
			end
			
		elseif (p.charability == CA_FALLSWITCH) and (p.pflags & PF_JUMPED) and not (p.spinhold > 1)
		and not P_IsObjectOnGround(s) --Fallswitch horizontally as well!
		
			S_StartSound(s, sfx_s1b4)
			P_SpawnGhostMobj(s)
			P_SpawnThokMobj(p)
			s.momx = $*-1
			s.momy = $*-1
			p.spinhold = 3
			
		elseif (p.charability == CA_AIRDRILL) and (p.pflags & PF_JUMPED) and (p.pflags & PF_THOKKED) 
		
			if not (p.spinhold > 1) //Already one of the most overpowered abilities without this.
			S_StartSound(s, sfx_s3k82)
			p.spinhold = 3
			end
			P_SpawnGhostMobj(s)
			if not (p.speed >= p.normalspeed*4/3)
			P_InstaThrust(s, s.angle, p.speed+FRACUNIT)
			else
			P_InstaThrust(s, s.angle, p.normalspeed*4/3)
			end
			
		elseif (p.charability == CA_SWIM) and (s.eflags & MFE_UNDERWATER) and (p.panim == PA_ABILITY)
		
			if not (p.spinhold > 1)
			S_StartSound(s, sfx_s3k7d) S_StartSound(s, sfx_splash)
			p.spinhold = 3
			end
			A_BossScream(s, 0, MT_SMALLBUBBLE)
			if (s.anim_duration > 1)
			s.anim_duration = 1
			end					
			if not (p.speed >= p.normalspeed*2)
			P_InstaThrust(s, s.angle, p.speed+2*s.scale)
			else
			P_InstaThrust(s, s.angle, p.normalspeed*2)
			end
			if (p.cmd.buttons & BT_JUMP)
				P_SetObjectMomZ(s, (4<<16)+25355)
			else
				P_SetObjectMomZ(s, -25355, true)
			end
			s.myssswim = true
			
		elseif (p.charability == CA_TELEKINESIS) and (p.pflags & PF_THOKKED) and (p.pflags & PF_JUMPED)
		and not (p.spinhold > 1) and not (s.flags2 & MF2_DONTDRAW)
		
			P_NukeEnemies(s, s, 0)
			s.state = S_PLAY_RUN
			s.anim_duration = 5
			s.tics = 5
			s.flags2 = $|MF2_DONTDRAW
			s.tkteleport = 6
			p.spinhold = 3
			S_StartSound(s, sfx_zoom)
			P_InstaThrust(s, s.angle, (p.normalspeed*2))
			if (p.cmd.buttons & BT_JUMP) and (p.cmd.forwardmove < -10)
				P_SetObjectMomZ(s, 55<<16)
				s.tkteleportup = true
			end
		end
	end
	if s.tkteleport
	s.tkteleport = $-1
		if (s.state == S_PLAY_SPRING or s.state == S_PLAY_PAIN or s.state == S_PLAY_FALL)
			s.tkteleport = 0
		else
			s.momz = 0
			s.anim_duration = 5
			s.tics = 5
			s.flags2 = $|MF2_DONTDRAW
			P_InstaThrust(s, s.angle, (p.normalspeed*2))
		end
		if s.tkteleportup
			P_SetObjectMomZ(s, 55<<16)			
		end
		if not (p.charability == CA_TELEKINESIS) or P_IsObjectOnGround(s)
			s.tkteleport = 0
			s.tkteleportup = nil
			p.pflags = $ & ~PF_SPINNING & ~PF_JUMPED & ~PF_USEDOWN
		end
		if not P_IsObjectOnGround(s) and (s.tkteleport == 1)
			s.state = S_PLAY_SPRING
			p.pflags = $ & ~PF_JUMPED & ~PF_SPINNING
			P_NukeEnemies(s, s, 0)
			s.flags2 = $ & ~MF2_DONTDRAW
			P_SpawnGhostMobj(s)
			s.momx = $/7
			s.momy = $/7
			s.momz = $/7
			s.tkteleportup = nil
			s.tkteleport = 0
		end
	end
	if s.myssswim --Swimming?
		if (p.charability != CA_SWIM) or not (p.panim == PA_ABILITY)
			s.myssswim = nil
		else
			if not (s.eflags & MFE_UNDERWATER)
				p.pflags = $|PF_JUMPED & ~PF_THOKKED
				P_SpawnGhostMobj(s)
				P_DoJump(p, true)
				s.momz = $*2
				s.myssswim = nil
			end
		end
	end
	if s.myssbacd
		s.myssbacd = $-1
	 	if (s.myssbacd > 27)
			P_SpawnGhostMobj(s)
			if not P_IsObjectOnGround(s)
				p.pflags = $|PF_THOKKED & ~PF_JUMPED
				s.state = S_PLAY_ROLL
			end
		end
		if (s.myssbacd == 26) and (s.state == S_PLAY_ROLL) and not P_IsObjectOnGround(s)
			if (p.cmd.buttons & BT_JUMP) and (p.charability == CA_BOUNCE)
				s.state = S_PLAY_BOUNCE
			else
				s.state = S_PLAY_SPRING
			end
			s.myssbacd = 25
		end
			if P_IsObjectOnGround(s) or p.powers[pw_carry]
		s.myssbacd = 0
		end
	end
	if s.metalcharge
		if (p.charability == CA_FLOAT) and not (P_IsObjectOnGround(s))
			if (s.metalcharge == 2)
				S_StartSound(s, sfx_trpowr)
			end
			if not (p.cmd.buttons & BT_SPIN)
				if (s.metalcharge < 11)
					P_InstaThrust(s, s.angle, 15*s.scale)
					s.metalafterimage = 2
					S_StopSound(s)
					S_StartSound(s, sfx_kc3c)
				elseif (s.metalcharge < 70)
					P_InstaThrust(s, s.angle, 27*s.scale)
					s.metalafterimage = 7
					S_StopSound(s)
					S_StartSound(s, sfx_kc3c)
				elseif (s.metalcharge < 175)
					P_InstaThrust(s, s.angle, 45*s.scale)
					s.metalafterimage = 20
					S_StopSound(s)
					S_StartSound(s, sfx_kc3c)
				else
					P_InstaThrust(s, s.angle, (s.metalcharge-140)*s.scale)
					S_StopSound(s)
					S_StartSound(s, sfx_cdfm35)
					s.metalafterimage = 50
					if (p.charflags & SF_DASHMODE)
						p.dashmode = 105
						p.normalspeed = 80<<16
					end
				end
				s.metalcharge = 0
			end
		elseif (p.charability != CA_FLOAT) or not (p.cmd.buttons & BT_SPIN) or not P_IsObjectOnGround(s)
			S_StopSound(s)
			s.metalcharge = 0
		end
	end
	if s.skin == "silver" --Infinite energy for Silver.
		if s.silv_energy != nil
			s.silv_energy = 350
		end
	end
	if s.metalafterimage
		s.metalafterimage = $-1
		P_SpawnGhostMobj(s)
	end
	if (p.charability == CA_SLOWFALL)
		if (p.cmd.buttons & BT_JUMP) 
		and (p.pflags & PF_THOKKED) and (p.pflags & PF_JUMPED)
			P_SetObjectMomZ(s, 6<<16)
		end
	end
	if (p.charability2 == CA2_MELEE) or (p.charability == CA_TWINSPIN)
	
	  if not P_IsObjectOnGround(s)
	  and ((s.state == S_PLAY_SPRING) or (s.state == S_PLAY_FALL))
	  and not (p.pflags & PF_JUMPED)
	  
	  	p.pflags = $|PF_JUMPED & ~PF_THOKKED & ~PF_STARTJUMP & ~PF_JUMPDOWN
		
	  elseif ((s.state == S_PLAY_MELEE_FINISH) or (s.state == S_PLAY_MELEE_LANDING) or (s.state == 45))
	  and P_IsObjectOnGround(s)
		if s.skin == "amy" and (s.tics == 1) //Upgrade everyone's shield!
			for z in players.iterate
				if (z.powers[pw_shield] == SH_PINK) or (z.powers[pw_shield] == SH_PITY)
					if z.mo and z.mo.skin != "amy" and z.mo.health and ( (FixedHypot(FixedHypot(z.mo.x-s.x, z.mo.y-s.y), z.mo.z-s.z)) < 200<<16 )
						z.powers[pw_shield] = ($ & ~(SH_PINK|SH_PITY))|SH_WHIRLWIND
						P_SpawnShieldOrb(z)
						S_StartSound(z.mo, sfx_wirlsg) 
					end
				end
			end				
		end
		if (p.cmd.buttons & BT_JUMP) --Super Hammer Jump like in SA1!
			A_SMSSTOMPQUAKE(s)
			A_SMSSTOMPQUAKE(s, 64, 12)
			S_StartSound(s, sfx_sprong)
			P_SpawnGhostMobj(s)
			P_DoJump(p, false)
			if (p.speed < 20*s.scale)
			P_Thrust(s, s.angle, 20*s.scale-p.speed)
			end
			p.pflags = $|PF_THOKKED
			if (p.charability == CA_TWINSPIN)
				s.state = S_PLAY_TWINSPIN
				s.twinrefreshonce = true
				P_SpawnSpinMobj(p, skins[s.skin].thokitem)
			else
				s.state = S_PLAY_ROLL
				p.pflags = $|PF_JUMPED
			end
			s.momz = $*2
		end
	  end
	  if (p.charability == CA_TWINSPIN)
		if s.twinrefreshonce
			if not (p.panim == PA_ABILITY)
				s.state = S_PLAY_TWINSPIN
				s.twinrefreshonce = nil
			end
		elseif not (p.panim == PA_ABILITY)
			p.pflags = $ & ~PF_THOKKED
		end
	  end			  
	end
	if (p.charflags & SF_DASHMODE)
		if not (p.dashmode >= 105)
			p.normalspeed = (skins[s.skin].normalspeed)*24/15
			p.jumpfactor = (skins[s.skin].jumpfactor)*69/51
		else
			if (p.normalspeed < 120<<16) //Gotta imitate the ability altogether.				
				p.normalspeed = $+(FRACUNIT/5)
			end
			if (p.jumpfactor < 118000)
				p.jumpfactor = $+(FRACUNIT/300)
			end
		end
	end
	if (p.myssskin and (p.myssskin != s.skin)) //Skin change! Uh oh....let's not, this could cause serious issues.
		A_ENDMYSTICSUPER(s, true) //Setting var1 to true means skin stats won't get reset.(Skinswitching itself already did this!)
		return --
	elseif not p.rings or p.powers[pw_super] or p.exiting --Cancel conditions.
		A_ENDMYSTICSUPER(s)
		return --
	elseif (leveltime % 35 == 0) --Ring drain every second when Mystic Super
		if p.rings
			P_GivePlayerRings(p, -1)
		end
	end
	
	if (p.cmd.buttons & BT_CUSTOM3) //Let Mystic Supers untransform whenever they like!
	and (p.cmd.buttons & BT_SPIN)
	and (p.cmd.forwardmove < -10)
	and (p.speed < 10*s.scale)
	and not ((gametype == GT_RACE) and p.smsnoracegame == 2) --Can't untransform in Mystic Super event races.
	and (P_IsObjectOnGround(s) or (p.panim == PA_ABILITY2))
		P_NukeEnemies(s, s, 450*s.scale)
		A_ENDMYSTICSUPER(s)
		return --
	end
end)
