--=============================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*FRACUNIT, false)
						P_SetObjectMomZ(s, 14*FRACUNIT, 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*FRACUNIT)
					and not (p.pflags & (PF_JUMPED|PF_SLIDING))
						if (p.dashspeed >= 146*FRACUNIT)
							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*FRACUNIT, 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*FRACUNIT,cos(s.angle)), s.y+FixedMul(170*FRACUNIT,sin(s.angle)), s.z-550*FRACUNIT, MT_SMSECHECK)
				if ghs and ghs.valid
				ghs.lsasms = true
				ghs.target = s
				ghs.height = 1100*FRACUNIT
				ghs.radius = 960*FRACUNIT
				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*FRACUNIT,cos(s.angle)), s.y+FixedMul(170*FRACUNIT,sin(s.angle)), s.z-550*FRACUNIT, MT_SMSECHECK)
				if ghs and ghs.valid
				ghs.target = s
				ghs.lsasms = true
				ghs.justcheckin = true
				ghs.height = 1100*FRACUNIT
				ghs.radius = 960*FRACUNIT
				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*FRACUNIT)
				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*FRACUNIT
						ghs.radius = 960*FRACUNIT
					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*FRACUNIT
							ghs.radius = 960*FRACUNIT
						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)*FRACUNIT)
							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)*FRACUNIT)
							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*FRACUNIT, 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*FRACUNIT))
				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 (G_PlatformGametype() 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*FRACUNIT
					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*FRACUNIT, 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 = $+1
					end
					if (p.sms_spinuc >= 2)
				
						if (p.cmd.buttons & BT_SPIN) and not p.hypermysticsonic
						or ((p.cmd.buttons & BT_CUSTOM2) and not (p.smsmeleebutton > 2))		
						
							p.pflags = $ & ~PF_SPINNING & ~PF_THOKKED //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 P_IsObjectOnGround(s)
					and s.sms_justuncurled
						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.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 (G_PlatformGametype() 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*FRACUNIT, 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*FRACUNIT))*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 (G_PlatformGametype() 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*FRACUNIT)
					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*FRACUNIT, 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*FRACUNIT)
						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*FRACUNIT) --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*FRACUNIT)
					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)))*FRACUNIT), 
									((P_RandomRange(FixedMul(-300, s.scale), FixedMul(300, s.scale)))*FRACUNIT),
									((P_RandomRange(FixedMul(300, s.scale), FixedMul(-300, s.scale)))*FRACUNIT),
									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*FRACUNIT)
							else
								P_SetObjectMomZ(s, -4*FRACUNIT, 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*FRACUNIT)+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*FRACUNIT)
						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*FRACUNIT)			
				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*FRACUNIT
							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*FRACUNIT)
				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*FRACUNIT )
								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*FRACUNIT) //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)
