//SMS' palette, Mystic Super, steam, etc!
//skins[s.skin].normalspeed == 60*FRACUNIT

local function hmspanic(s)
	for z in players.iterate
		if not z.nohmstheme
		S_ChangeMusic(935, false, z)
		end
	end
end

local function MysticSuperThink(s, p)
			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.powers[pw_tailsfly] and (p.charability == CA_FLY)
			p.powers[pw_tailsfly] = 250
			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.climbing and (p.charability == CA_GLIDEANDCLIMB)
				if (p.cmd.buttons & BT_CUSTOM3)
				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
					if (p.cmd.forwardmove)
					s.momz = $*2
					P_SpawnGhostMobj(s)
					end
					if (p.cmd.sidemove)
					s.momx = $*2
					s.momy = $*2
					end
				end
			end
			if (p.charability == CA_HOMINGTHOK) 
				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_SPINNING
				s.state = S_PLAY_ROLL
				end
				if p.homing
				s.homingfremove = true
				end
				if s.homingfremove and not p.homing
					if (p.pflags & PF_NOJUMPDAMAGE) and ((s.state == S_PLAY_SPRING) or (s.state == S_PLAY_FALL))
					p.pflags = $|PF_JUMPED & ~PF_THOKKED & ~PF_NOJUMPDAMAGE
					s.state = S_PLAY_ROLL
					s.homingfremove = nil
						if (s.momz > 11*FRACUNIT)
						P_SetObjectMomZ(s, 10*FRACUNIT)
						s.momx = 0
						s.momy = 0
						end
					end
					if P_IsObjectOnGround(s)
					s.homingfremove = nil
					end
				end 
			end
			if (p.cmd.buttons & BT_USE)
				if (p.charability2 == CA2_GUNSLINGER) and (p.weapondelay == 14) and (p.panim == PA_ABILITY2) and P_IsObjectOnGround(s)
				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.pflags & PF_GLIDING) and (p.charability == CA_GLIDEANDCLIMB)
					P_InstaThrust(p.mo, p.mo.angle, p.actionspd*40/19)
					p.mo.momz = 0
					if not (p.spinhold and (p.spinhold > 1))
					S_StartSound(p.mo, sfx_zoom)
					p.spinhold = 3
					end
				P_SpawnSpinMobj(p, MT_THOK)
				elseif ((p.charability == CA_THOK) or (p.charability == CA_JUMPTHOK) or (p.charability == CA_HOMINGTHOK) or s.skin == "shadow")
				and (p.pflags & PF_JUMPED) and (s.momz*P_MobjFlip(s) < (gravity)) and (p.speed >= FixedMul(5*FRACUNIT, 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
				elseif (p.charability == CA_FLOAT) and (p.pflags & PF_THOKKED) and not (p.pflags & PF_JUMPED)
					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)
							s.smswd = P_SpawnMobj(s.x+((P_RandomRange(FixedMul(-300, s.scale), FixedMul(300, s.scale)))*FRACUNIT), s.y+((P_RandomRange(FixedMul(-300, s.scale), FixedMul(300, s.scale)))*FRACUNIT), s.z+((P_RandomRange(FixedMul(300, s.scale), FixedMul(-300, s.scale)))*FRACUNIT), MT_MSGATHER)
							s.smswd.scale = s.scale
							s.smswd.fuse = P_RandomRange(10,20)
							s.smswd.flags = $|MF_SPECIAL
							s.smswd.frame = $|FF_FULLBRIGHT|TR_TRANS50
							P_HomingAttack(s.smswd, s)
							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
				elseif (p.charability == CA_BOUNCE) and (p.pflags & PF_THOKKED) and not s.myssbacd and not (p.pflags & PF_JUMPED)
					if not (p.spinhold and (p.spinhold > 1))
					S_StartSound(s, sfx_alart)
					P_SpawnGhostMobj(s)
					if not ((s.momz*P_MobjFlip(s)) < -20*FRACUNIT)
					P_SetObjectMomZ(s, -20*FRACUNIT)
					else
					P_SetObjectMomZ(s, -4*FRACUNIT, true)
					end
					p.spinhold = 3
					s.myssbacd = 35
					end
				elseif (p.charability == CA_FALLSWITCH) and (p.pflags & PF_JUMPED) and not (p.spinhold and (p.spinhold > 1)) and not P_IsObjectOnGround(s)
					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 and (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 and (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*FRACUNIT)
					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 and (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 < 0)
					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 
				if (p.charability != CA_SWIM) or not (p.panim == PA_ABILITY)
				s.myssswim = nil
				end
				if not (s.eflags & MFE_UNDERWATER) and s.myssswim
				p.pflags = $|PF_JUMPED & ~PF_THOKKED
				P_SpawnGhostMobj(s)
				P_DoJump(p, true)
				s.momz = $*2
				s.myssswim = nil
				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_USE)
						if (s.metalcharge < 11)
						P_InstaThrust(s, s.angle, 15*FRACUNIT)
						s.metalafterimage = 2
						S_StopSound(s)
						S_StartSound(s, sfx_kc3c)
						elseif (s.metalcharge < 70)
						P_InstaThrust(s, s.angle, 27*FRACUNIT)
						s.metalafterimage = 7
						S_StopSound(s)
						S_StartSound(s, sfx_kc3c)
						elseif (s.metalcharge < 175)
						P_InstaThrust(s, s.angle, 45*FRACUNIT)
						s.metalafterimage = 20
						S_StopSound(s)
						S_StartSound(s, sfx_kc3c)
						else
						P_InstaThrust(s, s.angle, (s.metalcharge-140)*FRACUNIT)
						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_USE) or not P_IsObjectOnGround(s)
				S_StopSound(s)
				s.metalcharge = 0
				end
			end
			if s.skin == "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) and (p.cmd.buttons & BT_JUMP) and (p.pflags & PF_THOKKED) and (p.pflags & PF_JUMPED)
				P_SetObjectMomZ(s, 6*FRACUNIT)
			end
			if ((p.charability2 == CA2_MELEE) or (p.charability == CA_TWINSPIN)) // and (p.panim == PA_ABILITY2)
			  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
			  end
			  if ((s.state == S_PLAY_MELEE_FINISH) or (s.state == S_PLAY_MELEE_LANDING) or (s.state == 45))
			  and P_IsObjectOnGround(s) // and not s.noamybadamy
				if s.skin == "amy" and (s.tics == 1)
					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_WHIRLWIND
							P_SpawnShieldOrb(z)
							S_StartSound(z.mo, sfx_wirlsg) //Upgrade their shield!
							end
						end
					end				
				end
				if (p.cmd.buttons & BT_JUMP)
					A_SMSSTOMPQUAKE(s)
					A_SMSSTOMPQUAKE(s, 64, 12)
					S_StartSound(s, sfx_sprong)
					P_SpawnGhostMobj(s)
					P_DoJump(p, false)
					if (p.speed < 20*FRACUNIT)
					P_Thrust(s, s.angle, 20*FRACUNIT-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
			end
			if (p.charability == CA_TWINSPIN)
				if s.twinrefreshonce
					if not (p.panim == PA_ABILITY)
					s.state = S_PLAY_TWINSPIN
					s.twinrefreshonce = false
					end
				elseif not (p.panim == PA_ABILITY)
				p.pflags = $ & ~PF_THOKKED
				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!)
			end
			if not p.rings or p.powers[pw_super] or p.exiting
			A_ENDMYSTICSUPER(s)
			elseif (leveltime % 35 == 0)
			P_GivePlayerRings(p, -1)
			end
			if (p.cmd.buttons & BT_CUSTOM3) //Let Mystic Supers untransform whenever they like!
			and (p.cmd.buttons & BT_USE)
			and (p.cmd.forwardmove < 0)
			and not ((gametype == GT_RACE) and (p.smsnoracegame and p.smsnoracegame == 2))
			and (p.speed < 10*FRACUNIT)
			and (P_IsObjectOnGround(s) or (p.panim == PA_ABILITY2))
				P_NukeEnemies(s, s, 450*FRACUNIT)
				A_ENDMYSTICSUPER(s)
			end
end

addHook("MobjThinker", function(s)
if not s.player
return end
local p = s.player
		if p.shinyglosscoat
		and G_GametypeHasTeams()
			p.shinyglosscoat = false
		end
		if p.dfflame
		p.dfflame = $-1
		end
		if p.homecamfly
			if (s and s.skin == "sms") and not p.hypermysticsonic
			p.drawangle = s.angle
			end
			p.homecamfly = $-1
		end
		if s.bhlcamtimer
		s.bhlcamtimer = $-1
		p.smschangedcamera = true
				if (s.bhlcamtimer > 110)
				p.camerascale = $*30/29
				elseif (s.bhlcamtimer > 36)
				p.camerascale = $*100/99
				elseif not (s.bhlcamtimer == 1)
				p.camerascale = $*11/12
				end
				if (s.bhlcamtimer <= 1)
				p.camerascale = FRACUNIT//s.scale
				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*FRACUNIT)//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_USE) and not (p.spinhold and p.spinhold > 1)
							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 not (p.sms_jumphold and p.sms_jumphold > 1)
							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 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
    			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 < 0)
						P_InstaThrust(s.tracer, s.tracer.angle, 55*FRACUNIT)
						P_InstaThrust(s, s.angle, 55*FRACUNIT)
						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 < 0)
					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*FRACUNIT)
						P_InstaThrust(s, s.angle, 17*FRACUNIT)
						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 and s.skin == "sms")
		
			if (p.powers[pw_carry] == CR_PTERABYTE) and s.state == S_PLAY_FALL
				s.state = S_SMS_ADVFALL1
			end
		
			if ((s.state == S_SMS_AIRBOOST) or (s.state == S_SMS_ADVFALL1) or (s.state == S_SMS_ADVFALL2))
			and (P_IsObjectOnGround(s) or (s.eflags & MFE_JUSTHITFLOOR))
			s.state = S_PLAY_WALK
			end

			if p.hypermysticescort and not p.hypermysticsonic
			p.hypermysticescort = false // Completely random and not supposed to be here!
			end

			//Warn the players someone went Hyper Mystic. Don't want them to
			//them to try attacking a completely invincible player.

			if G_GametypeHasSpectators()
				if p.hmspanic
				p.hmspanic = $-1
				end
				if (p.hypermysticsonic == 2)
				print("\x82* "+p.name+" just went Hyper Mystic! Run for your life!")
				p.hypermysticsonic = 3
				p.hmspanic = 965
				end
			end
			if p.hmspanic
				if (p.hmspanic == 964)
					if not p.nohmstheme
					S_ChangeMusic(935, false, p)
					end
				hmspanic(s)
				if not p.hypermysticsonic
				p.hmspanic = 2
				end
				if (p.hmspanic == 2)
					P_RestoreMusic(p)
					for z in players.iterate
					P_RestoreMusic(z)
					z.hmspanic = 0
					end
				elseif (p.hmspanic > 10)
				and not p.hypermysticsonic
					p.hmspanic = 1
					P_RestoreMusic(p)
					for z in players.iterate
					P_RestoreMusic(z)
					end
				end
			end
		end

		if s.player.lightdashenable
		  	if not G_PlatformGametype()
		  	p.lightdashenable = 0
			end
			if not p.hypermysticsonic and not s.smsldcheck and not p.lightdashstart
		  	and not p.powers[pw_carry]
			and not ( (p.powers[pw_shield] == (SH_ATTRACT) or p.powers[pw_shield] == (SH_ATTRACT|SH_FIREFLOWER))
			or (p.powers[pw_shield] == (SH_THUNDERCOIN) or p.powers[pw_shield] == (SH_THUNDERCOIN|SH_FIREFLOWER)) )
			and not (s.state == S_PLAY_PAIN)
			and s.health //Don't lightdash when you're dead!
			and not p.homing and not p.sms_intoship
				s.eymon = P_SpawnMobj(s.x+FixedMul(158*FRACUNIT,cos(s.angle)), s.y+FixedMul(158*FRACUNIT,sin(s.angle)), s.z-160*FRACUNIT, MT_SMSECHECK)
				if s.eymon and s.eymon.valid
				s.eymon.justcheckin = true
				s.eymon.target = s
				s.eymon.height = 320*FRACUNIT
				s.eymon.radius = 190*FRACUNIT
				end
				if ((p.cmd.buttons & BT_CUSTOM1) and not (p.sms_tapnothold > 1) and not p.smsldtf) or ((p.cmd.buttons & BT_TOSSFLAG) and not (p.sms_tossflaghold and p.sms_tossflaghold > 1)) //waaaaaaa
					s.smsldcheck = 2
					s.eymon = P_SpawnMobj(s.x+FixedMul(158*FRACUNIT,cos(s.angle)), s.y+FixedMul(158*FRACUNIT,sin(s.angle)), s.z-160*FRACUNIT, MT_SMSECHECK)
					if s.eymon and s.eymon.valid
					s.eymon.target = s
					s.eymon.height = 320*FRACUNIT
					s.eymon.radius = 190*FRACUNIT
					end
				end
			end
			if s.smsldcheck and s.smsrdash
					if s.target // and (s.target.type == MT_RING or (s.target.type == MT_COIN))
					and s.target.valid and s.target.health and P_CheckSight(s, s.target) and s.target == s.smsrdash
					and ( (FixedHypot(FixedHypot(s.target.x-s.x, s.target.y-s.y), s.target.z-s.z)) < (500*FRACUNIT) )
						s.momz = 0
						s.state = S_SMS_LIGHTDASH
						p.powers[pw_flashing] = 0
						p.sms_stompanim = 0
						p.pflags = $ & ~PF_JUMPED
						p.sms_afterstompthok = false
						s.ldclosest = nil
						if not (s.momz > FRACUNIT*50) and not (s.momz < FRACUNIT*-50)
							if s.lastldrx and s.lastldry and (R_PointToAngle2(s.lastldrx, s.lastldry, s.target.x, s.target.y))
							and not (p.lightdashstart <= 1) and s.target and s.target.valid
								s.angle = R_PointToAngle2(s.lastldrx, s.lastldry, s.target.x, s.target.y)
								s.lastldrx = s.target.x //Look in the same direction as the ring-lines, not relative to your own angle.
								s.lastldry = s.target.y
								if (s.target.z < (s.target.floorz+60*FRACUNIT))
								s.z = s.target.z
								s.momz = 0
								P_TryMove(s, s.target.x, s.target.y)
								end
							elseif s.target
								s.lastldrx = s.target.x
								s.lastldry = s.target.y
								s.angle = R_PointToAngle2(s.x, s.y, s.target.x, s.target.y)
							end 
						end
						if (p.pflags & (PF_DIRECTIONCHAR|PF_ANALOGMODE))
							s.forcesmsangletimer = 2
							s.forcesmsangle = R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy)
						end
						s.smsldcheck = 3 //Extend lightdash!
						if (p.lightdashstart < 6) or (p.lightdashstart % 2 == 0)
						A_SMSSTOMPSMOKE(s, P_RandomRange(7, 24), MT_IVSP)
						end
					elseif not s.target or s.target and not s.target.valid or s.target and not s.target.health
						s.eymon = P_SpawnMobj(s.x+FixedMul(158*FRACUNIT,cos(s.angle)), s.y+FixedMul(158*FRACUNIT,sin(s.angle)), s.z-310*FRACUNIT, MT_SMSECHECK)
						if s.eymon and s.eymon.valid
						s.eymon.target = s
						s.eymon.height = 620*FRACUNIT
						s.eymon.radius = 190*FRACUNIT
						end
					end				
					if (s.state == S_SMS_LIGHTDASH)
						s.sprintlin = P_SpawnGhostMobj(s)
						s.sprintlin.rollangle = s.rollangle
						p.smsrdash = 5
						p.lightdashstart = $+1
						p.pflags = $ & ~PF_SPINNING 
					end
			end
			if (p.smsrdash or p.lightdashstart) //p.smsrdash and s.smsrdash are different! The former's a timer, the latter a target failsafe.
				if P_PlayerInPain(p) or p.powers[pw_carry] or (p.smspickup and s.target and (s.target == p.smspickup))
				p.smsrdash = 0
				p.lightdashstart = 0
				s.smsrdash = 0
				s.smsldcheck = 0
				p.pflags = $ & ~PF_JUMPED
				s.lastldrx = 0
				s.lastldry = 0
				s.ldclosest = nil
				elseif not s.smsldcheck
				p.smsrdash = 0
				p.lightdashstart = 0
				s.smsrdash = 0
				s.lastldrx = 0
				s.lastldry = 0
				s.ldclosest = nil
					if P_IsObjectOnGround(s)
						s.state = S_PLAY_RUN
						p.pflags = $ & ~PF_JUMPED & ~PF_SPINNING & ~PF_STARTJUMP
					else
						if (s.z < s.floorz+60*FRACUNIT)
						P_SetObjectMomZ(s, FRACUNIT)
						
						elseif (s.momz >= ((FRACUNIT*27)*P_MobjFlip(s))) //You can fly high, sure! Is cool, dawg.
							s.state = S_SMS_SIDET
							p.hometrickanim = true
							p.pflags = $ & ~PF_JUMPED
							p.homingtrickcharge = 0
							s.airboostroll = 0
							s.rollangle = 0
							s.smstrickroll = true
							s.smstrickrollang = 0
						P_SetObjectMomZ(s, FRACUNIT*26) //...but let's at least make it manageable for the player, instead of smashing their head into the skybox.
						end
						s.momx = $*2/3
						s.momy = $*2/3
						if not (s.state == S_SMS_SIDET)
						s.state = S_PLAY_ROLL
						p.pflags = $|PF_JUMPED & ~PF_SPINNING & ~PF_STARTJUMP
						end
					end
				end
			end
		end

			//Failsafe so you can exit lightdash at will.

			if (p.smsrdash or p.lightdashstart)
			and ((p.cmd.buttons & BT_USE) and not (p.spinhold and p.spinhold > 1))
				p.smsrdash = 0
				p.lightdashstart = 0
				p.pflags = $ & ~PF_SPINNING
				p.pflags = $ & ~PF_JUMPED
				s.momx = $/2
				s.momy = $/2
				P_SetObjectMomZ(s, FRACUNIT*4)
				S_StartSound(s, sfx_s1a2)
				s.state = S_PLAY_FALL
				s.smsldcheck = 0
				s.smsrdash = 0
			end

			if ((s.color == SKINCOLOR_YELLOW) or (s.color == 0) or (p.shinyglosscoat and not p.hypermysticsonic))
			and not (s.ctfteam and G_GametypeHasTeams()) and not (p.powers[pw_shield] & SH_FIREFLOWER)
			and not (mariomode and p.powers[pw_invulnerability])
  				s.color = SKINCOLOR_SUPERGOLD5 //Purposely not changing the skincolor.
    			p.sms_truesms = 1
			else
    			p.sms_truesms = 0
			end
			
			//Water vaporizes off SMS' body if he steps in it.

			if not p.hypermysticsonic
			and not (p.powers[pw_shield] == SH_ELEMENTAL)
				if ((s.eflags & MFE_UNDERWATER)
				or ((s.eflags & MFE_TOUCHWATER) and (p.pflags & PF_SPINNING)))
				and not P_PlayerTouchingSectorSpecial(p, 1, 3)
				p.sms_steaming = 200
				p.sms_steamingwait = 35
				end
				if P_PlayerTouchingSectorSpecial(p, 1, 3)
				p.sms_steaming = 200
				p.sms_steamingwait = 0 //You can't drip water from lava, dipshit.
				end
			end
			if p.sms_steaming
			and not p.hypermysticsonic
			and not (s.eflags & MFE_UNDERWATER)
			and not (leveltime < 3)
				if p.sms_steamingwait
				p.sms_steamingwait = $-1
					if not (s.state == S_PLAY_WAIT)
					and not ((p.pflags & PF_SPINNING) and not (p.pflags & PF_JUMPED))
					p.waterdrip = P_SpawnMobj(s.x+((P_RandomRange(FixedMul(-26, s.scale), FixedMul(26, s.scale)))*FRACUNIT), s.y+((P_RandomRange(FixedMul(-26, s.scale), FixedMul(26, s.scale)))*FRACUNIT), s.z+((P_RandomRange(FixedMul(5, s.scale), FixedMul(45, s.scale)))*FRACUNIT), MT_WATERDROP)
					p.waterdrip.scale = s.scale/2
					p.waterdrip.frame = $|TR_TRANS50
					end
				else
				p.sms_steaming = $-1
					if (p.speed > 70*FRACUNIT)
					and (p.sms_steaming 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 and (p.lddiscount == 3 or p.lddiscount == 1))
					A_BossScream(s, 0, MT_SMSSTEAM)
					end
				end	
			end
			
		//Don't shout "GO!!" underwater

			if not (s.eflags & MFE_UNDERWATER)
				if ((S_SoundPlaying(s, skins["sms"].soundsid[SKSZOOM]))
				or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN1])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN2])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN3])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN4])))
					p.dontcancelmysfx = 100
				end
			end

			if p.dontcancelmysfx
			p.dontcancelmysfx = $-1
			end

			if p.startcharge and not (p.pflags & PF_SPINNING)
			p.startcharge = $-1
			end

			if (p.pflags & PF_SPINNING)
				if ((p.pflags & PF_STARTDASH) or p.dashspeed)
					if (p.pflags & PF_STARTDASH)
					s.smschargedbd = 10
					s.spinsmsgr3 = P_SpawnGhostMobj(s)
					s.spinsmsgr3.flags = $|MF_NOCLIP|MF_NOCLIPHEIGHT
					s.spinsmsgr3.tics = 3
					s.spinsmsgr3.destscale = s.scale*2
					
						if (p.dashspeed >= p.maxdash)
							if not p.lightdashenable and not p.hypermysticsonic
							p.camerascale =  FRACUNIT*2/3
							s.bhlcamtimer = 2
							end
							if (p.sms_boostlevel < 28)
							p.sms_boostlevel = 28
							end
							for i = 0,40 // A little aiming reticule
							s.asph = P_SpawnMobj(s.x+FixedMul(30*FRACUNIT*i ,cos(s.angle)), s.y+FixedMul(30*FRACUNIT*i,sin(s.angle)), s.z+s.height/2, MT_THOK)
							if (s.scale/2-(i*1000) > 0)	//Avoid sigsevs, thx			
							s.asph.scale = s.scale/2-(i*1000)
							else
							s.asph.scale = 500
							end
							s.asph.color = s.color
							s.asph.tics = 2
							end	
						end
					end
					p.startcharge = 0
					p.dontcancelmysfx = 0
				elseif s.smschargedbd
				s.smschargedbd = $-1				
					if (p.speed > FixedMul(30*FRACUNIT, s.scale))
					s.spinsmsgr = P_SpawnGhostMobj(s) 
					s.spinsmsgr.tics = 4
					s.spinsmsgr.scale = s.scale*10/P_RandomRange(8,9)
						if not s.smsbdsfx and s.smschargedbd == 9 and not (s.eflags & MFE_UNDERWATER) 
						and (S_SoundPlaying(s, skins["sms"].soundsid[SKSZOOM])) --Double Take
							local sfxrng = P_RandomRange(1,20)
							if p.hypermysticsonic
							sfxrng = 20
							end
							s.smsbdsfx = 25
							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
							s.lastbdsfx = sfxrng
						end
						if (s.smschargedbd > 6)
						s.smsgrboost = P_SpawnMobj(s.x+s.momx, s.y+s.momy, s.z+s.momz, MT_SMSGROUNDBOOST)
						s.smsgrboost.tracer = s
						s.smsgrboost.scale = $/2
						end
					end
				end
			elseif s.smschargedbd
			s.smschargedbd = 0
			end

			if (s.eflags & MFE_UNDERWATER)
			and not p.hypermysticsonic
				if not p.dontcancelmysfx
				and (S_SoundPlaying(s, skins["sms"].soundsid[SKSZOOM]))
					S_StopSound(s)
					if not p.startcharge
						s.ghs2 = P_SpawnMobj(s.x, s.y, s.z, MT_SMSTSPARK)				
						S_StartSound(s.ghs2, sfx_rail1)
						S_StartSound(s.ghs2, sfx_zoom)
						S_StartSound(s.ghs2, sfx_rail2)
						p.startcharge = 150
					end
				end
				if P_PlayerInPain(p)
					if not p.dontcancelmysfx
						if (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN1])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN2])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN3])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLPAN4]))
						S_StopSound(s)
						s.ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SMSTSPARK)				
						S_StartSound(s.ghs, sfx_splash)
						S_StartSound(s.ghs, sfx_s3kb9)
						S_StartSound(s.ghs, sfx_s3k7d)
						end
					end
				end
				if not s.health
				and (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLDET1])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLDET2])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLDET3])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLDET4]))
					S_StopSound(s)
					s.ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SMSTSPARK)				
					S_StartSound(s.ghs, sfx_splash)
					S_StartSound(s.ghs, sfx_shldls)
				end
				if S_OriginPlaying(s)
				and (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLVCT1])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLVCT2])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLVCT3])) or (S_SoundPlaying(s, skins["sms"].soundsid[SKSPLVCT4]))
				S_StopSound(s)
					s.ghs = P_SpawnMobj(s.x, s.y, s.z, MT_SMSTSPARK)
					S_StartSound(s.ghs, sfx_splash)
					S_StartSound(s.ghs, sfx_s3k7d)
				end
			end
		end

		if (p.sms_steaming or p.sms_steamingwait)
		and ((p.hypermysticsonic or not (s and s.skin == "sms") or leveltime == 2 or (p.powers[pw_shield] == SH_ELEMENTAL) or not s.health))
		p.sms_steaming = 0
		p.sms_steamingwait = 0
		end

//Lots of MISC stuff here....

	if (gametype == GT_RACE)
	and p.smsnoracegame == 2
		if s
		and s.health
		and P_IsObjectOnGround(s)
		and not p.mysticsuper
		and not (s.skin == "sms") and not (s.skin == "samus")
		and not (p.exiting)
			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.

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

		if p.smsrotatespikeball == nil
		or p.smsrotatespikeball2 == nil
		p.smsrotatespikeball = 0
		p.smsrotatespikeball2 = 0
		end
		if p.shieldready
		p.shieldready = false
		end
		if ((p.sms_stompanim or (p.smsdivetimer and p.smsdivetimer >= 37) or (s.state == S_HMS_INSTANTWARP2) or (p.dashspeed > FixedMul(490*FRACUNIT, s.scale))
		or (p.sms_sontransform and p.sms_sontransform >= 43 and p.sms_sontransform < 72) or p.sms_afterstompthok)
		and not (s and s.eflags & MFE_UNDERWATER)
		and not (s.state == S_PLAY_STND))
		or p.starthmscombo and (p.starthmscombo < 63 and p.starthmscombo > 20)
			s.hmgodmticket = true
			p.smsrotatespikeball = $ + 1278743
			p.smsrotatespikeball2 = $ - 1278743
			P_SpawnXYZMissile(s, s, MT_SMSSTOMPLINE, s.x+cos(FixedAngle(p.smsrotatespikeball))*42, s.y+sin(FixedAngle(p.smsrotatespikeball))*42,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			P_SpawnXYZMissile(s, s, MT_SMSSTOMPLINE, s.x+cos(FixedAngle(p.smsrotatespikeball))*-42, s.y+sin(FixedAngle(p.smsrotatespikeball))*-42,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			P_SpawnXYZMissile(s, s, MT_SMSSTOMPLINE, s.x+cos(FixedAngle(p.smsrotatespikeball2))*20, s.y+sin(FixedAngle(p.smsrotatespikeball2))*20,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			P_SpawnXYZMissile(s, s, MT_SMSSTOMPLINE, s.x+cos(FixedAngle(p.smsrotatespikeball2))*-20, s.y+sin(FixedAngle(p.smsrotatespikeball2))*-20,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			end
	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
			end
			p.mslightspeedattack = $+1
		end
		if p.mysticsuper and s
			MysticSuperThink(s, p)
		end
		//Here's the lightspeed dash attack, exclusive to Mystic Supers! If it works, it'll drain 3 rings!
			
		if p.mysticsuper and s
		
			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*FRACUNIT)
				s.anim2_tic = $-1
				end
				if (p.speed > 35*FRACUNIT)
				s.anim2_tic = $-1
				end
				if (p.speed > 50*FRACUNIT)
				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_SpawnMobj(s.x, s.y, s.z, 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 and p.transformdown > 1)
			  and (p.cmd.buttons & BT_CUSTOM3)
				s.eymon = 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 s.eymon and s.eymon.valid
				s.eymon.lsasms = true
				s.eymon.target = s
				s.eymon.height = 1100*FRACUNIT
				s.eymon.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.lsaclosest = nil
					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
			  	s.eymon = 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 s.eymon and s.eymon.valid
				s.eymon.target = s
				s.eymon.lsasms = true
				s.eymon.justcheckin = true
				s.eymon.height = 1100*FRACUNIT
				s.eymon.radius = 960*FRACUNIT
				end
			  end
			end
		end



			if s and p.mslightspeedattack and not (p.mysticsuper and p.mysticsuper < 30)
			and (p.lightspeedchain and p.lightspeedchain > 2) and not p.sms_intoship
				s.eymon = 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 s.eymon and s.eymon.valid
				s.eymon.lsasms = true
				s.eymon.target = s
				s.eymon.height = 1100*FRACUNIT
				s.eymon.radius = 960*FRACUNIT
				end		
				p.lightspeedchain = 2
				p.mslightspeedattack = 1
				p.pflags = $|PF_JUMPED
				if not (s.state == S_PLAY_ROLL)
				s.state = S_PLAY_ROLL
				end
			end
			if s and p.mslightspeedattack
			and not p.lightspeedchain
				if not s.target 
				or (s.target and s.target.health)
				or (s.target and not (s.target.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR)))
					p.mslightspeedattack = 0
				end
			end
			if s and p.mslightspeedattack
			P_SpawnGhostMobj(s)
 			P_RadiusAttack(s, s, 30*FRACUNIT)
				if s.target and s.target.health // and (s.lsatarget and (s.target == s.lsatarget))
				and (s.target.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR)) and not (s.target.flags2 & MF2_FRET)
				and ((FixedHypot(s.target.x-s.x, s.target.y-s.y)) < 1400*FRACUNIT)
				and (P_CheckSight(s, s.target))
				p.lightspeedchain = 2
				p.lsdeadjump = 0
				p.pflags = $|PF_JUMPED
				s.lsaclosest = nil
				s.lsatarget = nil
				s.angle = (R_PointToAngle2(s.x, s.y, s.target.x, s.target.y))
				s.momx = FixedMul(FixedDiv(s.target.x-s.x, 512*FRACUNIT), FixedDiv(261*FRACUNIT, 3*FRACUNIT/2))
				s.momy = FixedMul(FixedDiv(s.target.y-s.y, 512*FRACUNIT), FixedDiv(261*FRACUNIT, 3*FRACUNIT/2))
				P_SpawnSpinMobj(p, p.spinitem)
					if p.mslightspeedattack == 1
					P_SetObjectMomZ(s, 32*FRACUNIT)
					elseif p.mslightspeedattack == 2
					P_SetObjectMomZ(s, 17*FRACUNIT)
					elseif p.mslightspeedattack == 3
					P_SetObjectMomZ(s, 3*FRACUNIT)
					else
					s.momz = FixedMul(FixedDiv(s.target.z-s.z, 512*FRACUNIT), FixedDiv(261*FRACUNIT, 3*FRACUNIT/2))
					end
					if (s.target.type == MT_SPRINGSHELL) //Oh, these bastards! Use P_Radius so we don't just recoil from their springs
					or (s.target.type == MT_YELLOWSHELL)
					P_RadiusAttack(s, s, 70*FRACUNIT)
					end


					if (p.speed > FixedMul(24*FRACUNIT, s.scale))
					or (s.momz > 16*FRACUNIT)
					or (s.momz < -16*FRACUNIT)
					P_SpawnMobj(s.x, s.y, s.z, MT_SMSAIRBOOST) //Attaaack!
					end
				else
					if not (p.lsdeadjump and p.lsdeadjump == 2)
					p.lsdeadjump = 1
					end
				end
			end
			if p.mslightspeedattack
			and (p.lsdeadjump and (p.lsdeadjump == 1))
			and ((s.target and not s.target.health) or (s.target and (s.target.flags2 & MF2_FRET)) or (s.target and not s.target.valid) or not s.target)
				s.lsaclosest = nil
				s.lsatarget = nil
				p.lightspeedchain = 4
				p.lsdeadjump = 2
				p.pflags = $|PF_JUMPED
				P_SetObjectMomZ(s, 14*FRACUNIT)
				s.eymon = 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 s.eymon and s.eymon.valid
				s.eymon.lsasms = true
				s.eymon.target = s
				s.eymon.height = 1100*FRACUNIT
				s.eymon.radius = 960*FRACUNIT
				end
			end

			// This party can't go on forever! Here's some cases where it's gotta stop!

			if p.mslightspeedattack
				if (p.pflags & (PF_GLIDING|PF_STASIS|PF_SPINNING))
				and not (p.powers[pw_carry])
					p.mslightspeedattack = 0
				end

				if (p.target and (p.target.flags2 & MF2_FRET))
				or (p.mslightspeedattack > 30)
					p.mslightspeedattack = 0
					p.pflags = $|PF_JUMPED
					P_SetObjectMomZ(s, 14*FRACUNIT)
				end
				if not (p.panim == PA_ROLL)
				P_SetMobjStateNF(s, S_PLAY_ROLL)
				p.pflags = $|PF_JUMPED				
				end
			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 and s.skin == "sms")
		  if p.smscoatc5 == nil
		  A_setSMSspecialcolors(s, 1)
		  end
		  if (p.skincolor == SKINCOLOR_YELLOW)
		  and not p.shinyglosscoat and not p.hypermysticsonic
		  and not G_GametypeHasTeams()
		  A_setSMSspecialcolors(s, 1)
		  p.shinyglosscoat = 1
		  p.skincolor = SKINCOLOR_YELLOW
		  end 
		  if (p.hypermysticsonic > 30)
		  	if (p.transformstatecolors >= 26)
			p.transformstatecolors = 0
			s.color = SKINCOLOR_SUPERGOLD3
			end
			p.transformstatecolors = $+1
				if ((s.color < SKINCOLOR_SUPERGOLD1) or (s.color > SKINCOLOR_SUPERGOLD5))
				s.color = SKINCOLOR_SUPERGOLD2
				else			
					if (p.transformstatecolors == 3)
						s.color = SKINCOLOR_SUPERGOLD4
					elseif (p.transformstatecolors == 6)
						s.color = SKINCOLOR_SUPERGOLD5
					elseif (p.transformstatecolors == 9)
						s.color = SKINCOLOR_SUPERGOLD4
					elseif (p.transformstatecolors == 12)
						s.color = SKINCOLOR_SUPERGOLD3
					elseif (p.transformstatecolors == 16)
						s.color = SKINCOLOR_SUPERGOLD2
					elseif (p.transformstatecolors == 21)
						s.color = SKINCOLOR_SUPERGOLD1
					elseif (p.transformstatecolors == 23)
						s.color = SKINCOLOR_SUPERGOLD2
					end
				end
				
		  elseif (p.sms_transformstate or p.shinyglosscoat)
		  and not G_GametypeHasTeams()
		  and not (p.powers[pw_shield] & SH_FIREFLOWER)
		  and not ((mariomode) and p.powers[pw_invulnerability])
			if (p.transformstatecolors >= 52)
			p.transformstatecolors = 0
			end
			p.transformstatecolors = $+1
				if ((p.transformstatecolors >= 0) and p.transformstatecolors < 6)
					if s.color != p.smscoatc3
					s.color = p.smscoatc3
					end
				elseif (p.transformstatecolors >= 6 and p.transformstatecolors < 12)
					if s.color != p.smscoatc2
					s.color = p.smscoatc2
					end
				elseif (p.transformstatecolors >= 12 and p.transformstatecolors < 18)
					if s.color != p.smscoatc1
					s.color = p.smscoatc1
					end
				elseif (p.transformstatecolors >= 18 and p.transformstatecolors < 27)
					if s.color != p.smscoatc2
					s.color = p.smscoatc2
					end
				elseif (p.transformstatecolors >= 27 and p.transformstatecolors < 33)
					if s.color != p.smscoatc3
					s.color = p.smscoatc3
					end
				elseif (p.transformstatecolors >= 33 and p.transformstatecolors < 44)
					if s.color != p.smscoatc4
					s.color = p.smscoatc4
					end
				elseif (p.transformstatecolors >= 44 and p.transformstatecolors < 47)
					if s.color != p.smscoatc5
					s.color = p.smscoatc5
					end
				elseif (p.transformstatecolors >= 47 and p.transformstatecolors < 53)
					if s.color != p.smscoatc4
					s.color = p.smscoatc4
					end
				end
				if p.nosmscolorspls and not s.color == SKINCOLOR_COBALT //p.sms_transformstate
				A_setSMSspecialcolors(s, 0)
				end
		  end

//The whirlwind shield will interfere with SMS' walljump/homing thok.
//So let's make it have him jump higher instead.

//Also, set the toss position here because mobjcollide won't be able to deal with that.

			if p.sms_attracttl
			and not ( (p.powers[pw_shield] == (SH_ATTRACT) or p.powers[pw_shield] == (SH_ATTRACT|SH_FIREFLOWER))
			or (p.powers[pw_shield] == (SH_THUNDERCOIN) or p.powers[pw_shield] == (SH_THUNDERCOIN|SH_FIREFLOWER)) )
			p.sms_attracttl = 0
			end
		//	if p.powers[pw_shield] 
		//	and ((p.pflags & PF_JUMPED) or (p.hypermysticsonic and not P_IsObjectOnGround(s))) and not (p.powers[pw_shield] == SH_PITY or p.powers[pw_shield] == SH_PINK)
		//		p.pflags = $|PF_USEDOWN // & ~PF_SHIELDABILITY
		//	end
		   if not p.hypermysticsonic
			if p.powers[pw_shield] == (SH_WHIRLWIND) or p.powers[pw_shield] == (SH_WHIRLWIND|SH_FIREFLOWER)
			p.jumpfactor = 87250 //Get slightly less than double jumpheight.
				if (p.pflags & PF_JUMPED) or (p.pflags & PF_SPINNING and not P_IsObjectOnGround(s) or s.smsframejump)
					if not s.whirljumpgfx and (p.pflags & PF_JUMPED) and not p.powers[pw_sneakers]
						if not (s.z > s.floorz+17*FRACUNIT)
						A_SMSSTOMPSMOKE(s, 11, MT_SPINDUST)
						P_SpawnGhostMobj(s)
						end
					s.whirljumpgfx = true
					end
		//		p.pflags = $|PF_USEDOWN
					if (p.pflags & PF_SHIELDABILITY) and ((s.momz*P_MobjFlip(s)) >= 11*FRACUNIT ) and ((s.momz*P_MobjFlip(s)) <= 13*FRACUNIT )
					s.state = S_PLAY_FALL
					p.pflags = $ & ~PF_JUMPED & ~PF_SPINNING & ~PF_SHIELDABILITY & ~PF_THOKKED
					end
				elseif s.whirljumpgfx 
				s.whirljumpgfx = false
    			end
				if (p.sms_didairboost) or p.hometrickanim or (s.state == S_PLAY_FALL) or (p.sms_dodging and not P_IsObjectOnGround(s))
				or (s.state == S_SMS_ADVFALL1 or s.state == S_SMS_ADVFALL2)
				p.pflags = $|PF_JUMPDOWN
    			end
    			if p.sms_stompanim
				p.pflags = $|PF_THOKKED
    			end
    		elseif (p.powers[pw_shield] == SH_ARMAGEDDON)
				if (p.powers[pw_shield] & SH_ARMAGEDDON) and ((p.pflags & PF_JUMPED) or p.hometrickanim)
				and (p.cmd.buttons & BT_USE) and not p.spinhold
					if not s.smsarmablow
					s.smsarmablow = 6
					elseif s.smsarmablow
					P_BlackOw(p)
					end
				end
				
			elseif ( (p.powers[pw_shield] == (SH_ATTRACT) or p.powers[pw_shield] == (SH_ATTRACT|SH_FIREFLOWER))
			or (p.powers[pw_shield] == (SH_THUNDERCOIN) or p.powers[pw_shield] == (SH_THUNDERCOIN|SH_FIREFLOWER)) )
				if p.sms_attracttl
    			    p.sms_attracttl = $-1
					if (p.sms_attracttl == 1)
					p.powers[pw_shield] = SH_PITY
					P_SpawnShieldOrb(p)
					S_StartSound(s, sfx_shield)
					P_FlashPal(p, PAL_MIXUP, 3)
					P_NukeEnemies(s, s, 0)
					p.sms_attracttl = 0
					end
				elseif G_GametypeHasSpectators()
    			    p.sms_attracttl = 390 //Roughly 10 seconds for matches.
				else
					p.sms_attracttl = 725 //Roughly 20 for other gamemodes.
				end
    		end
		   end  
			if ( (p.cmd.buttons & BT_TOSSFLAG) or ((p.cmd.buttons & BT_WEAPONPREV) and not p.hypermysticsonic) )
			and not p.speed
			and P_IsObjectOnGround(s)
				if not p.footsweepanim
				and not (p.footsweep01 or p.footsweep02 or p.footsweep03)
				and not (p.pflags & PF_SPINNING)
				and not (p.cmd.buttons & BT_CUSTOM2)
				and not p.powers[pw_nocontrol] and not p.powers[pw_carry]
				and not (s.state == S_SMS_ATOMLAND1 or s.state == S_SMS_ATOMLAND2 or s.state == S_SMSTOSSING)
					p.camerascale =  FRACUNIT*5/6
					s.bhlcamtimer = 2
					s.state = S_SMSTOSSREADY
					s.height = P_GetPlayerSpinHeight(p)
					if p.hypermysticsonic
					s.hmsoframe = F
					end
				end
			end

		//Zap! Bzzzt! Shock! Oww! It's electricity!
		//....uhh, yeah. Anyway, under certain circumstances, SMS will exert electrical currents off his body
		if not (p.smsgraphix and p.smsgraphix == 2)
			if ((p.smsdivefloat and p.smsdivefloat > 10) or ((p.pflags & PF_STARTDASH)
			and (p.dashspeed and p.dashspeed >= 146*FRACUNIT)) and not p.hypermysticsonic)
			or p.hypermysticsonic
			s.hmwau = P_SpawnMobj(s.x+FixedMul(P_RandomRange(-99, 99)*FRACUNIT, s.scale), s.y+FixedMul(P_RandomRange(-99, 99)*FRACUNIT, s.scale), s.z+FixedMul((P_RandomRange(1, ((s.height/FRACUNIT)+8))*FRACUNIT)*P_MobjFlip(s), s.scale), MT_HMSWAVEAURA)
			s.hmwau.eflags = s.eflags
			s.hmwau.scale = s.scale
			s.hmwau.target = s
			end
    	end

		if p.lightdashenable
		and (p.dashspeed > 145*FRACUNIT)
		and (p.pflags & PF_STARTDASH)
		and not p.hypermysticsonic
			p.camerascale =  FRACUNIT*3/2
			s.bhlcamtimer = 2
			s.eymon = 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 s.eymon and s.eymon.valid
			s.eymon.target = s
			s.eymon.lsasms = true
			s.eymon.justcheckin = true
			s.eymon.height = 1100*FRACUNIT
			s.eymon.radius = 960*FRACUNIT
			end
			if (p.cmd.buttons & BT_CUSTOM2)
			and not (p.smsmeleebutton and (p.smsmeleebutton > 1))
				s.eymon = 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 s.eymon and s.eymon.valid
				s.eymon.lsasms = true
				s.eymon.target = s
				s.eymon.height = 1100*FRACUNIT
				s.eymon.radius = 960*FRACUNIT
				end
					if s.target 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
						s.lsaclosest = nil
						p.lightspeedchain = 2
						p.pflags = $|PF_JUMPED
						p.pflags = $ & ~PF_SPINNING
						S_StartSound(s, sfx_s3k83)
						S_StartSound(s, sfx_zoom)
						p.transformdown = 300
				    end
			end
		end
			if p.smsaurablastivatecd
			p.smsaurablastivatecd = $-1
			end
			if p.smsaurablastivate
			and not (p.cmd.buttons & BT_CUSTOM3)
			and not p.sms_flamedelay
			and not p.smsaurablastivatecd
				p.smsaurablastivate = false
			end
			if ((p.cmd.buttons & BT_CUSTOM3) or p.dobotpowershare and p.bot)
			and (p.speed < 5*FRACUNIT)
			and P_IsObjectOnGround(s)
			and not p.powers[pw_carry]
				if (gametype == GT_COOP)
				and not (p.powersharerestrict and ((p.powersharerestrict == 2) or ((p.powersharerestrict == 1) and not All7Emeralds(emeralds))))
					if p.dashspeed >= 500*FRACUNIT and p.hypermysticsonic
					p.camerascale =  FRACUNIT*20 //Gaze into the depths of particle hell
					s.bhlcamtimer = 2
					else
					p.camerascale =  FRACUNIT*3/2
					s.bhlcamtimer = 2
					end
					
					s.smsglowticket = 2
					P_SpawnMobj(s.x+90*FRACUNIT, s.y+90*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					P_SpawnMobj(s.x+0*FRACUNIT, s.y+100*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					P_SpawnMobj(s.x+100*FRACUNIT, s.y+0*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					P_SpawnMobj(s.x-90*FRACUNIT, s.y-90*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					P_SpawnMobj(s.x+0*FRACUNIT, s.y-100*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					P_SpawnMobj(s.x-100*FRACUNIT, s.y+0*FRACUNIT, s.z+32*FRACUNIT, MT_POWERSHARE)
					
					if not s.sms_auradelay
					and not p.smsaurablastivate
					S_StartSound(s, sfx_s3ka0)
					p.smsaurablastivatecd = 29
					p.smsaurablastivate = true
					p.smsaurablastspawn = P_SpawnMobj(s.x, s.y, s.z-25*FRACUNIT, MT_BURSTWAVE)
						if s.color == SKINCOLOR_CRIMSON
						p.smsaurablastspawn.color = SKINCOLOR_RED
						elseif not p.hypermysticsonic and SMSisyellow(s)
						p.smsaurablastspawn.color = SKINCOLOR_BONE
						else
						p.smsaurablastspawn.color = s.color
						end
					end
					if not s.sms_auradelay
						s.pwshare = P_SpawnMobj(s.x, s.y, s.z, MT_SMSPOWERAURA)
						if s.pwshare and s.pwshare.valid and p.hypermysticsonic s.pwshare.scale = $*5/3 end
						s.sms_auradelay = 16 //We're using SMS' flame delay to spawn SMS' poweraura in rhythm.
					end
					if (s.state == S_PLAY_WAIT or s.state == S_PLAY_STND)
					and not p.hypermysticsonic
						s.state = S_PLAY_STND //Stop laying on the floor, you lazy ass!
					end
				elseif p.dashspeed >= 500*FRACUNIT and p.hypermysticsonic
					p.camerascale =  FRACUNIT*20 //Gaze into the depths of particle hell
					s.bhlcamtimer = 2
				end
			end

//For competitive gametypes, SMS gets to do a Smash-styled taunt
//with CUSTOM3, which would do otherwise nothing in such gametypes.
//However, let's put a cooldown to keep things from getting TOO trollish.

		if (s.state == S_SMSTAUNT1)
		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 (p.sms_tauntcooldown == 129)
			s.state = S_PLAY_STND
			end
		elseif p.speed == 0
		and P_IsObjectOnGround(s)
		and not p.footsweepanim
		and not (p.footsweep01 or p.footsweep02 or p.footsweep03)
		and not (p.pflags & PF_SPINNING)
		and not p.hypermysticsonic //Now that would just be cruel.
			if (((p.cmd.buttons & BT_CUSTOM3) and  G_GametypeHasSpectators())
			or ((p.cmd.buttons & BT_CUSTOM2) and (p.cmd.buttons & BT_TOSSFLAG) and not netgame))
			and (p.sms_tauntcooldown == 0 or not netgame)
			and not p.powers[pw_nocontrol]
			p.powers[pw_nocontrol] = 61
			s.state = S_SMSTAUNT1
			p.sms_tauntcooldown = 190
			end
			if p.powers[pw_nocontrol] == 61 //This script is brought to you by Super Mystic duct tape
			and (s.state == S_SMSTAUNT1)
				if (s.eflags & MFE_UNDERWATER)
				S_StartSound(s, sfx_splash)
				S_StartSound(s, sfx_s3k7d)
				P_SpawnMobj(s.x+10*FRACUNIT, s.y+6*FRACUNIT, s.z+14*FRACUNIT, MT_SMALLBUBBLE)
				P_SpawnMobj(s.x-10*FRACUNIT, s.y-6*FRACUNIT, s.z+29, MT_SMALLBUBBLE)
				P_SpawnMobj(s.x+14*FRACUNIT, s.y+5*FRACUNIT, s.z+23*FRACUNIT, MT_MEDIUMBUBBLE)
				P_SpawnMobj(s.x-5*FRACUNIT, s.y-11*FRACUNIT, s.z+15*FRACUNIT, MT_MEDIUMBUBBLE)
				return nil
				elseif (p.lddiscount == 0)
				S_StartSound(s, sfx_victr1)
				return nil
				elseif (p.lddiscount == 1)
				S_StartSound(s, sfx_victr2)
				return nil
				elseif (p.lddiscount == 2)
				S_StartSound(s, sfx_victr3)
				return nil
				else
				S_StartSound(s, sfx_victr4)
				return nil
				end
			end
		end

//SMS' fire bracelets let him shoot condensed flames from his palms!
//Let's start our ability.

			if (s.health <= 0) //Dead but not in death frames? Put death frames back up!
			and not p.hypermysticsonic
			and not (s.state == S_PLAY_DEAD)
			s.state = S_PLAY_DEAD
			end

			//This disables the use of weapon rings as SMS entirely in Match/CTF.
			//SMS will also always have weapon delay, never able to use weapons other than
			//his own powers, even if he DID somehow obtain weapons.

			if p.sms_aerialfirerestrict
			and (P_IsObjectOnGround(s) or (p.pflags & PF_JUMPED))
				p.sms_aerialfirerestrict = false
			end
			if (p.cmd.buttons & BT_ATTACK)
				p.sms_flamebuttonhold = $+1
			elseif p.sms_flamebuttonhold
				p.sms_flamebuttonhold = 0
			end
			if (p.cmd.buttons & BT_FIRENORMAL)
				if not p.sms_nflamehold
				p.sms_nflamehold = 1
				else
				p.sms_nflamehold = $+1
				end
			elseif p.sms_nflamehold
			p.sms_nflamehold = 0
			end
			if p.sms_hugeflametoss
			p.sms_hugeflametoss = $-1
			end
			if G_RingSlingerGametype()
				if (p.ringweapons & RW_SCATTER)
				p.smssc = true
				elseif (p.ringweapons & RW_EXPLODE)
				p.smsex = true
				elseif (p.ringweapons & RW_GRENADE)
				p.smsgre = true
				elseif (p.ringweapons & RW_AUTO)
				p.smsat = true
				elseif (p.ringweapons & RW_RAIL)
				p.smsra = true
				elseif p.powers[pw_infinityring]
				p.smsin = true
				end
			p.ringweapons = 0 // Do not move this! Be careful!
			p.powers[pw_infinityring] = 0
			p.currentweapon = 0
			end
			p.weapondelay = 9
			if ((p.cmd.buttons & BT_FIRENORMAL) or ((p.cmd.buttons & BT_ATTACK) and not (p.sms_flamebuttonhold > 1)) )
			and not p.hypermysticsonic
				if p.rings or (p.mxscap > 1) or (p.powers[pw_shield] & SH_FIREFLOWER)
					if (p.knucklewaving and not p.sms_flamedelay)
					or not p.sms_flamedelay
					and not ((p.powers[pw_carry] == CR_ZOOMTUBE) or (p.powers[pw_carry] == CR_NIGHTSMODE))
					and not p.objectplacer and not p.exiting and s.health
					and not p.smspickup and not (p.gotflag and s.battlemodsms)
					and not p.footsweepanim
					and not (p.pflags & (PF_GAMETYPEOVER|PF_STASIS)) //Stasis is when you can't move. I believe like pw_nocontrol or pw_goop
					and not ((s.flags2 & MF2_DONTDRAW) and not p.powers[pw_flashing])
					and not ((p.sms_dodging and p.sms_dodging > 9) or p.smsdivefloat or p.smsdivetimer or p.sms_ringburstfly)
					and not (s.state == S_SMS_ATOMLAND1 or s.state == S_SMS_ATOMLAND2)
					and not p.homing
					and not (p.fludd and p.fludd.enabled)
						if (p.cmd.buttons & BT_ATTACK) and not p.smsblastboost
						p.smsflm = P_SpawnPlayerMissile(s, MT_SMSFIREBLAST)
						
							if p.smsflm
								if s.color == SKINCOLOR_GOLD or SMSisyellow(s)
								p.smsflm.color = SKINCOLOR_SKY
								else
								p.smsflm.color = s.color
								end
								if not (p.mxscap > 1)
									if not (p.powers[pw_shield] & SH_FIREFLOWER) //Infinite fire with fireflowers!
									P_GivePlayerRings(p, -1) 
									end
								end
								if (s.eflags & MF2_TWOD) or twodlevel
								p.smsflm.smfltwod = true
								end
								p.smsflm.twoshot = true
								P_TeleportMove(p.smsflm, s.x+FixedMul(8*FRACUNIT, cos(s.angle+ANGLE_90)),s.y+FixedMul(8*FRACUNIT, sin(s.angle+ANGLE_90)), p.smsflm.z)
							end
							
							p.smsflm = P_SpawnPlayerMissile(s, MT_SMSFIREBLAST)
								if p.smsflm
									if s.color == SKINCOLOR_GOLD or SMSisyellow(s)
									p.smsflm.color = SKINCOLOR_SKY
									else
									p.smsflm.color = s.color
									end
									if (s.eflags & MF2_TWOD) or twodlevel
									p.smsflm.smfltwod = true
									end
									p.smsflm.twoshot2 = true
									p.smsflm.twoshot = true
									P_TeleportMove(p.smsflm, s.x-FixedMul(8*FRACUNIT, cos(s.angle+ANGLE_90)),s.y-FixedMul(8*FRACUNIT, sin(s.angle+ANGLE_90)), p.smsflm.z)
								end
							
						else
						p.smsflm = P_SpawnPlayerMissile(s, MT_SMSFIREBLAST)
						end
						if p.smsflm and p.smsflm.valid
							if s.color == SKINCOLOR_GOLD or SMSisyellow(s)
							p.smsflm.color = SKINCOLOR_SKY
							else
							p.smsflm.color = s.color
							end
						end
						if (p.cmd.buttons & BT_ATTACK)
						p.sms_flamedelay = 8
						else
						p.sms_flamedelay = 9 //This sets our weapon delay timer.
						end
						if not (p.mxscap > 1)
							if (p.powers[pw_shield] & SH_FIREFLOWER)
							S_StartSound(s, sfx_mario7)
							else
							P_GivePlayerRings(p, -1)
							end
						end
						if (p.pflags & (PF_DIRECTIONCHAR|PF_ANALOGMODE))
						s.forcesmsangle = s.angle
						s.forcesmsangletimer = 8
						end
						if s.battlemodsms //Attacks have more deliberate openings in battlemod. SMS can't just spam flames when nobody else has projectiles
						p.sms_flamedelay = $*3
							if not p.powers[pw_carry] and (((s.state == S_SMS_ADVFALL1) or (s.state == S_SMS_ADVFALL2)) or not (p.panim == PA_ETC))
							P_SpawnGhostMobj(s)
							S_StartSound(s, sfx_s3k47)
							s.momx = $/2
							s.momy = $/2
							p.pflags = $ & ~PF_JUMPED & ~PF_THOKKED & ~PF_SPINNING & ~PF_STARTDASH
							p.dashspeed = 0
							p.powers[pw_nocontrol] = 8
							s.state = S_SMSHUGEFLAMETOSS
							if (p.pflags & PF_DIRECTIONCHAR)
							s.forcesmsangletimer = 9
							s.forcesmsangle = s.angle
							end
							P_Thrust(s, s.angle, -6*FRACUNIT)
							P_SetObjectMomZ(s, 3*FRACUNIT, true)
							end
						end
					end
				end
			end
			if ((p.cmd.buttons & BT_ATTACK) and (p.sms_flamebuttonhold > 39)) and not (p.cmd.buttons & BT_FIRENORMAL)
				if (((p.rings >= 3) and not s.battlemodsms) or ((p.rings >= 5) and s.battlemodsms) or (p.mxscap > 1) or (p.powers[pw_shield] & SH_FIREFLOWER)) //Meet one of these requirements to shoot fire
				and not p.hypermysticsonic //HMS has a different attack.
					if not p.sms_flamedelay
					and not p.footsweepanim
					and not p.powers[pw_carry]
					and not p.sms_aerialfirerestrict
					and not p.objectplacer
					and not p.smspickup and not (p.gotflag and s.battlemodsms)
					and not (p.pflags & (PF_STASIS|PF_GAMETYPEOVER))
					and not (s.flags2 & MF2_DONTDRAW)
					and not (p.sms_dodging or p.smsdivefloat or p.smsdivetimer or p.sms_ringburstfly)
					and not p.knucklewaving 
					and not (s.state == S_SMS_ATOMLAND1 or s.state == S_SMS_ATOMLAND2 or s.state == S_PLAY_PAIN or (s.state == S_PLAY_RIDE))
					and not p.homing and not p.smsblastboost
					and not (p.fludd and p.fludd.enabled)
					and not (s.silv_grabbed and s.silv_grabbed.valid)
							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
					end
				end
			end
			if p.sms_hugeflametoss
			and not p.hypermysticsonic
			and s.health
				p.camerascale =  FRACUNIT*5/4
				s.bhlcamtimer = 2
				if not s.quickdfthrow and ((p.cmd.buttons & BT_ATTACK) and (p.sms_flamebuttonhold == 1))
				s.quickdfthrow = true
				end
				p.powers[pw_nocontrol] = $+1

				if P_PlayerInPain(p) //You got knocked out of it.
					p.sms_hugeflametoss = 0
					s.state = S_PLAY_PAIN
				end

				if (p.sms_hugeflametoss == 18)
				p.sms_boostlevel = 0
				S_StartSound(s, sfx_s3k6d)
				end

				if (p.sms_hugeflametoss >= 2)
				s.momz = s.momz*10/15
				s.momx = s.momx*10/11
				s.momy = s.momy*10/11
				p.sms_flamedelay = 18
				p.pflags = $ & ~PF_JUMPED
					if not (s.state == S_SMSGRINDPOSE1) and not (s.state == S_SMSGRINDPOSE2)
					s.state = S_SMSGRINDPOSE1
					end

					if P_IsObjectOnGround(s)
					and (p.sms_hugeflametoss >= 2)
					P_SetObjectMomZ(s, 26*FRACUNIT)
					S_StartSound(s, sfx_jump)
					s.state = S_PLAY_SPRING
					P_SpawnGhostMobj(s)
					end
				end
				if (p.sms_hugeflametoss == 1) or s.quickdfthrow //Diffusion Flame fire!
				S_StartSound(s, sfx_s3k4b)
				S_StartSound(s, sfx_s3k82)
				S_StartSound(s, sfx_fire)
					if not s.quickdfthrow 
						A_SMSFindTarget(s, 7000*FRACUNIT, 25) //Let the player force manual aim if they want, with homing turned off. An advantage is that you can throw the flame quicker
						if s.target and s.dfclosest
						p.smssuperflame = P_SpawnPointMissile(s, s.target.x, s.target.y, s.target.z+(34*FRACUNIT*(P_MobjFlip(s.target))), MT_SMSFIREBLAST, s.x, s.y, s.z+(15*FRACUNIT*(P_MobjFlip(s))))
						s.angle = R_PointToAngle2(s.x, s.y, s.target.x, s.target.y)
						else
						p.smssuperflame = P_SpawnPlayerMissile(s, MT_SMSFIREBLAST)
						end

					else
						p.smssuperflame = P_SpawnPlayerMissile(s, MT_SMSFIREBLAST)
					end
					if p.smssuperflame and p.smssuperflame.valid
						if s.target and s.target.valid and s.target.health and not s.quickdfthrow
						p.smssuperflame.smspointer = s.target
						end
						p.smssuperflame.mysticflame = true
						p.smssuperflame.flags2 = $|MF2_SUPERFIRE
						p.smssuperflame.momx = p.smssuperflame.momx*7/6
						p.smssuperflame.momy = p.smssuperflame.momy*7/6
						p.smssuperflame.momz = p.smssuperflame.momz*7/6
							if (s.color == SKINCOLOR_GOLD or SMSisyellow(s))
							p.smssuperflame.color = SKINCOLOR_SKY
							else
							p.smssuperflame.color = s.color
							end
					end
					if not (p.mxscap > 1)
						if (p.powers[pw_shield] & SH_FIREFLOWER)
							S_StartSound(s, sfx_mario7)
						else
							P_GivePlayerRings(p, -3) //Expensive!
							if s.battlemodsms
							P_GivePlayerRings(p, -2)
							end
						end
					end
					if (p.pflags & PF_DIRECTIONCHAR)
						s.forcesmsangletimer = 9
						s.forcesmsangle = s.angle
					end
				s.dfclosest = nil
				p.sms_aerialfirerestrict = true
				p.sms_flamebuttonhold = 2
				s.state = S_SMSHUGEFLAMETOSS
				A_SMSquake(s, 60*FRACUNIT, 5, 1000, true)
				p.sms_hugeflametoss = 0
				P_Thrust(s, s.angle, -6*FRACUNIT)
				P_SetObjectMomZ(s, 6*FRACUNIT, true)
				end
			end

			//If you're HMS, however, you get MULTIPLE projectiles! Let's start on his version of the flames.
			if (p.hypermysticsonic > 30) //Only HMS can do this!
				if (p.cmd.buttons & BT_FIRENORMAL)
					if (p.knucklewaving and not p.sms_flamedelay and not (p.novafire > 37))
					or not (((p.cmd.buttons & BT_ATTACK) or (p.cmd.buttons & BT_FIRENORMAL)) and (p.pflags & PF_ATTACKDOWN))
					and not p.sms_flamedelay
					and not p.objectplacer
					and not (p.novafire > 37)
					and not p.smsdivetimer
					and not (p.hmsblackhole > 60)
					and not p.starthmscombo
					and not (p.pflags & PF_GAMETYPEOVER)
					and not (p.powers[pw_carry] == CR_ZOOMTUBE)
					s.hmgodticket = true
						if p.sms_nflamehold and p.sms_nflamehold == 1
						S_StartSound(s, sfx_s3k48)
						S_StartSound(s, sfx_s3k7d)
						s.novawave = P_SpawnMobj(s.x+FixedMul(-20*FRACUNIT, cos(s.angle+ANGLE_90)), s.y+FixedMul(-20*FRACUNIT, sin(s.angle+ANGLE_90)), s.z+s.height/2, MT_HMSNOVAWAVE)
						s.novawave.scale = s.scale/10
						s.novawave.destscale = s.novawave.scalespeed+1 s.novawave.tics = 1
						s.novawave.rollangle = FixedAngle(120*FRACUNIT)
							if (p.aiming and not (p.aiming/FRACUNIT == 0) and not (p.aiming/FRACUNIT/2200 == 0))
							s.novawave.momz = FixedMul(FixedMul(80*FRACUNIT, FRACUNIT), sin(p.aiming))
							P_InstaThrust(s.novawave, s.angle, 80*FRACUNIT/((p.aiming/FRACUNIT)/2200))
							else
							P_InstaThrust(s.novawave, s.angle, 80*FRACUNIT)
							end
						P_Thrust(s.novawave, s.angle+ANGLE_90, 22*FRACUNIT)
						s.novawave = P_SpawnMobj(s.x+FixedMul(-20*FRACUNIT, cos(s.angle-ANGLE_90)), s.y+FixedMul(-20*FRACUNIT, sin(s.angle-ANGLE_90)), s.z+s.height/2, MT_HMSNOVAWAVE)
						s.novawave.scale = s.scale/10
						s.novawave.destscale = s.novawave.scalespeed+1 s.novawave.tics = 1
						s.novawave.rollangle = FixedAngle(240*FRACUNIT)
							if (p.aiming and not (p.aiming/FRACUNIT == 0) and not (p.aiming/FRACUNIT/2200 == 0))
							s.novawave.momz = FixedMul(FixedMul(80*FRACUNIT, FRACUNIT), sin(p.aiming))
							P_InstaThrust(s.novawave, s.angle, 80*FRACUNIT/((p.aiming/FRACUNIT)/2200))
							else
							P_InstaThrust(s.novawave, s.angle, 80*FRACUNIT)
							end
						P_Thrust(s.novawave, s.angle-ANGLE_90, 22*FRACUNIT)
						end
						if (s.z > s.ceilingz-100*FRACUNIT) and (s.floorz < s.ceilingz-300*FRACUNIT) //Not in extremely tight spaces.
						s.z = $-19*FRACUNIT
						end
						if s.hmsspinpass and s.hmsspinang
						s.hmstsang = s.hmsspinang
						else
						s.hmstsang = s.angle
						end
						if s.hmsspinpass 
						p.hmfl = P_SpawnPlayerMissile(s, MT_HMSFIREBLAST, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						else
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang+ANG10 - 10, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang-ANG10 - 10, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang+ANG2 - 2+ANG2 - 2, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang-ANG2 - 2-ANG2 - 2, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang+ANG15 - 15, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						p.hmfl = P_SPMAngle(s, MT_HMSFIREBLAST, s.hmstsang-ANG15 - 15, 1, MF2_RAILRING)
						if p.hmfl p.hmfl.color = SKINCOLOR_SKY end
						S_StartSound(s, sfx_s3kbcs)
						p.sms_flamedelay = 3 //This small detail makes all the difference.
					end
				end
			end

//Now here's a crazy attack for you; HMS' Hypernova blast!
//He fires a stream of concentrated energy spheres with incredible explosive power

			if (p.hypermysticsonic > 38) //Only HMS can do this!
				if (p.cmd.buttons & BT_ATTACK) 
				and not (p.pflags & PF_ATTACKDOWN) and not (p.cmd.buttons & BT_FIRENORMAL)
					if not p.sms_flamedelay
					and not (p.sms_flamebuttonhold > 1)
					and not P_IsObjectOnGround(s)
					and not p.novafire
					and not p.smsdivetimer
					and not p.hmswarpcooldown
					and not (p.hmsblackhole > 60)
					and not p.starthmscombo
					and not (p.pflags & (PF_STASIS|PF_GAMETYPEOVER))
					and not (p.powers[pw_carry])
					and not (p.smspickup and p.smspickup.valid)
					s.farnovaview = 0
					s.novazaim = false
					s.state = S_HMSNOVAFIRE1
					p.pflags = $|PF_ATTACKDOWN
					S_StartSound(s, sfx_beeyow)
					s.hmgodticket = true
					p.novafire = 125
					s.novawave = P_SpawnMobj(s.x, s.y, s.z, MT_HMSNOVAWAVE)
					s.novawave.color = SKINCOLOR_CRIMSON
					s.novawave.followmenoz = s
					s.novawave.scale = s.scale
					s.hmsl2d = P_SpawnMobj(s.x, s.y, s.z, MT_HMSLIGHTNING2)
					s.hmsl2d.followsms = s
					s.hmsl2d.ltimershort = true 
					s.hmsl2d.color = SKINCOLOR_CRIMSON
					p.pflags = $|PF_JUMPED
					end
					
				//D-did he just....yep, HMS just summoned a goddamn black hole!
				//This move has some serious cooldown.
					
				elseif (p.cmd.buttons & BT_ATTACK) 
				and (p.cmd.buttons & BT_FIRENORMAL)
					if (p.pflags & PF_JUMPED)
					and not p.novafire
					and not p.hmsblackhole
					and not p.hmswarpcooldown
					and not (p.pflags & PF_STASIS)
					and not p.smsdivetimer
					and not p.starthmscombo
					and not P_IsObjectOnGround(s)
					and not (p.powers[pw_carry] == CR_ZOOMTUBE)
						s.state = S_HMSBLACKHOLE
						p.hmsblackhole = 175
						s.bhlcamtimer = 150
						P_SpawnPlayerMissile(s, MT_HMSBLACKHOLE)
					end
				end
				if s.state == S_HMSNOVAFIRE1
					if (s.z >= s.ceilingz-150*FRACUNIT) and (s.floorz < s.ceilingz-150*FRACUNIT)
					s.momz = -10*FRACUNIT
					else
					s.momz = 0
					end
					if (p.novafire == 124 or p.novafire == 117)
					P_NukeEnemies(s, s, 200*FRACUNIT) //Nuke-stars are mostly for show.
					end
					
					if not s.farnovaview
						if (p.cmd.buttons & BT_ATTACK) and not (p.pflags & PF_ATTACKDOWN)
						s.farnovaview = 1 p.pflags = $|PF_ATTACKDOWN
						end
					elseif s.farnovaview
						if (p.cmd.buttons & BT_ATTACK) and not (p.pflags & PF_ATTACKDOWN)
						s.farnovaview = 0 p.pflags = $|PF_ATTACKDOWN
						end
					p.camerascale =  FRACUNIT*5/2 s.bhlcamtimer = 2
					end
				elseif s.state == S_HMSNOVAFIRE2
					if (p.cmd.buttons & BT_USE) --Keyboard/gamepad-only aiming assist buttons
						p.aiming = -2800*FRACUNIT*P_MobjFlip(s)
						s.novazaim = true
						elseif (p.cmd.buttons & BT_JUMP)
						p.aiming = 2800*FRACUNIT*P_MobjFlip(s)
						s.novazaim = true
						elseif s.novazaim
						s.novazaim = false
						p.aiming = 0
					end
					if (s.tics == 60)
					S_StartSound(s, sfx_hmsnof)
					P_FlashPal(p, 4, 7) //Do only 1 flash to prevent seizures.
					elseif (s.tics == 1)
						if s.novazaim
						s.novazaim = false
						p.aiming = 0
						end
					end
					if not s.farnovaview
						if (p.cmd.buttons & BT_ATTACK) and not (p.pflags & PF_ATTACKDOWN)
						s.farnovaview = 1 p.pflags = $|PF_ATTACKDOWN
						end
					elseif s.farnovaview
						if (p.cmd.buttons & BT_ATTACK) and not (p.pflags & PF_ATTACKDOWN)
						s.farnovaview = 0 p.pflags = $|PF_ATTACKDOWN
						end
					p.camerascale =  FRACUNIT*5/2 s.bhlcamtimer = 2
					end
					if (s.z >= s.ceilingz-150*FRACUNIT) and (s.floorz < s.ceilingz-150*FRACUNIT)
					s.momz = -10*FRACUNIT
					else
					s.momz = 0
					end
					if not (p.sms_flamedelay > 0)
						s.hmsnb = P_SpawnPlayerMissile(s, MT_HMSNOVABLAST, MF2_RAILRING)
						if s.hmsnb and s.hmsnb.valid //Did it spawn correctly?
						s.hmsnb.scale = s.scale*3
						s.hmsnb.destscale = 285000 //Roughly 4.3
						s.hmsnb.color = SKINCOLOR_GOLD
						end
					A_SMSquake(s, 8*FRACUNIT, 3, 8901)
						if (p.smsgraphix and p.smsgraphix == 2)
						p.sms_flamedelay = 5 //Slow it down so our poorly optimized engine can keep up
						else
						p.sms_flamedelay = 3						
						end
					end
				elseif (s.state == S_HMSBLACKHOLE)
				  if not (p.smsgraphix and p.smsgraphix == 2)
					if p.hmsblackhole == 124
					A_SMSSTOMPSMOKE(s, 30, MT_HMSLIGHTNING2, 0, 20*FRACUNIT, FRACUNIT/2, SKINCOLOR_JET)
					elseif p.hmsblackhole == 117
					S_StartSound(s, sfx_s3k45)
					A_SMSSTOMPSMOKE(s, 28, MT_HMSLIGHTNING2, 0, -20*FRACUNIT, FRACUNIT/2, SKINCOLOR_JET)
					elseif p.hmsblackhole == 76
					A_SMSSTOMPSMOKE(s, P_RandomRange(12, 27), MT_HMSLIGHTNING2, -5, P_RandomRange(-20, 20)*FRACUNIT, FRACUNIT/P_RandomRange(1,4), SKINCOLOR_JET)
					elseif p.hmsblackhole == 65
					S_StartSound(s, sfx_kc4d) 
					A_SMSSTOMPSMOKE(s, 50, MT_HMSLIGHTNING2, 0, 0, nil, SKINCOLOR_JET)
					end
				  end
				s.hmgodticket = true
				P_SetObjectMomZ(s, 0*FRACUNIT)
				P_InstaThrust(s, s.angle, 0)
				P_LookForEnemies(p, 4000, true, false)
					if p.hmsblackhole == 174
					P_FlashPal(p, 4, 10) //Temporary red flash.
					A_SMSquake(s, 44*FRACUNIT, 140, 6901)
					end
					if p.lddiscount and (p.lddiscount == 1 or p.lddiscount == 3)
					p.waterdrip = P_SpawnMobj(s.x+((P_RandomRange(FixedMul(-1700, s.scale), FixedMul(1700, s.scale)))*FRACUNIT), s.y+((P_RandomRange(FixedMul(-1700, s.scale), FixedMul(1700, s.scale)))*FRACUNIT), s.z+((P_RandomRange(FixedMul(-750, s.scale), FixedMul(750, s.scale)))*FRACUNIT), MT_HMSPBC)
					p.waterdrip.bkhl = true
					p.waterdrip.target = s
					end
				end
			end

//A ton of countdown related things from the previous LUA_SMFL!

			//A Sonic Boom from hitting mach speed!

			if (p.sms_boostlevel and p.sms_boostlevel >= 65 and p.sms_boostlevel < 95)
			S_StartSound(s, sfx_smach)
			A_SMSquake(s, 54*FRACUNIT, 4, 3400)
				p.sms_boostlevel = 95
				s.hudboost = 1
				P_RadiusAttack(s, s, FixedMul(480*FRACUNIT, s.scale)) //Clear out smaller enemies in your way.
				p.smsradialboosteffect = P_SpawnMobj(s.x, s.y, s.z, MT_RADIALBOOST)
				p.smsradialboosteffect.target = s
			end

			if (p.cmd.buttons & BT_TOSSFLAG)
				p.sms_tossflaghold = p.sms_tossflaghold and $+1 or 1
			elseif p.sms_tossflaghold
				p.sms_tossflaghold = 0
			end

			if (s.state == S_SMS_ATOMLAND1)
			or (s.state == S_SMS_ATOMLAND2)
			or (s.state == S_HMS_ATOMLAND)
			p.powers[pw_nocontrol] = $+1
			end

			if (p.powers[pw_sneakers] > 699)
			and not p.hypermysticsonic
			and not (p.speedspeedspeedspeedspeed and (p.speedspeedspeedspeedspeed > 24))
			and (G_PlatformGametype() and not s.battlemodsms)
				p.powers[pw_sneakers] = 825
				if p.speedspeedspeedspeedspeed != nil
				p.speedspeedspeedspeedspeed = $+1
				end
				if (p.speedspeedspeedspeedspeed == 1)
				S_StartSound(p.mo, sfx_s3k4e)
				S_StartSound(p.mo, sfx_bejet1)
				P_FlashPal(p, PAL_MIXUP, 7)
				P_NukeEnemies(p.mo, p.mo, 0)
				P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_BURSTLIGHT)
				p.mo.burstwave = P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z-24*FRACUNIT,  MT_BURSTWAVE)
				p.mo.burstwave.color = SKINCOLOR_FLAME
				s.hmsl2d = P_SpawnMobj(s.x, s.y, s.z, MT_HMSLIGHTNING2)
				s.hmsl2d.followsms = s
				A_SMSquake(s, 70*FRACUNIT, 5, 1050)
					p.smssparkspawn = P_SpawnMobj(s.x, s.y, s.z, MT_SMSSPARKLESPAWN)
					p.smssparkspawn.target = s
				end
			end


			//Press spin or custom 2 to uncurl from a spindash!

			if p.sms_justuncurled
				p.sms_justuncurled = $-1
			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
				end
				if (p.pflags & PF_THOKKED)
				p.acceleration = 46 //Game already increases spindash control if PF_THOKKED is applied, so limit the boost a little.
				else
				p.acceleration = 98 //Increase SMS' spindash control.
				end
			else
				p.acceleration = 36
			end
			if ((p.panim == PA_ROLL) or p.hypermysticsonic)
			and (p.pflags & PF_SPINNING)
			and not (p.pflags & (PF_JUMPED|PF_STARTDASH))
			and not (p.cmd.forwardmove < 0)
			and not p.homing
			and not (p.cmd.buttons & (BT_USE|BT_CUSTOM2))
			and not p.powers[pw_carry]
				p.sms_spinuc = $+1
			else
				if not ((p.cmd.buttons & BT_USE) or (p.cmd.buttons & BT_CUSTOM2))
				p.sms_spinuc = 0
				end
			end

			if (p.sms_spinuc >= 2)
				if (p.pflags & PF_SPINNING)
				and ((p.panim == PA_ROLL) or p.hypermysticsonic)
				and not (p.pflags & (PF_JUMPED|PF_STARTDASH))
				and not (p.smsmeleebutton and p.smsmeleebutton > 2)
				and not p.homing
				and not p.powers[pw_carry] and not p.smsblastboost
					if ((p.cmd.buttons & BT_USE) and not p.hypermysticsonic) or (p.cmd.buttons & BT_CUSTOM2)
					p.pflags = $ & ~PF_SPINNING & ~PF_THOKKED //Researchers agree this is the best flag to kill.
					p.sms_justuncurled = 8
					p.smsmeleebutton = 3
					P_SpawnGhostMobj(s)
					S_StartSound(s, sfx_s3kd1s)
						if P_IsObjectOnGround(s) or p.hypermysticsonic
						s.state = S_PLAY_RUN //Put us in the running animations
						else
							if (s.momz*P_MobjFlip(s) > FRACUNIT*7)
							s.state = S_PLAY_SPRING
							else						
							s.state = S_SMS_ADVFALL1
							end
						end
					end
				end
			end
			
			if (p.pflags & PF_SPINNING)
			and P_IsObjectOnGround(s)
			and p.sms_justuncurled
				p.sms_runspinboost = $+1
			elseif p.sms_runspinboost
				p.sms_runspinboost = 0
			end
			if p.sms_runspinboost == 1 //Spamdash script
			and p.sms_justuncurled
			and not p.gotflag and not p.smsblastboost
				if not (s.eflags & MFE_UNDERWATER)
					if p.sms_boostlevel != nil and (p.sms_boostlevel < 43)
					p.sms_boostlevel = $+22
					end
					if p.hypermysticsonic or (p.powers[pw_sneakers] and (G_PlatformGametype() and not s.battlemodsms))
						if (p.speed > 220*FRACUNIT)
							if p.hypermysticsonic
							P_RadiusAttack(s, s, 2000*FRACUNIT)
							end
						P_Thrust(s, s.angle, FixedMul(255*FRACUNIT, s.scale)) //Aaaand we've gone absolutely bonkers....
						else
						P_Thrust(s, s.angle, FixedMul(115*FRACUNIT, s.scale))
							if p.hypermysticsonic
							P_RadiusAttack(s, s, 1000*FRACUNIT)
							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, FixedMul(480*FRACUNIT, s.scale)) //Clear out smaller enemies in your way.
					p.smsradialboosteffect = P_SpawnMobj(s.x, s.y, s.z, MT_RADIALBOOST)
					p.smsradialboosteffect.target = s
					
					elseif (p.speed < 70*FRACUNIT)
					P_Thrust(s, s.angle, FixedMul(24*FRACUNIT, s.scale)) //Give a tiny boost each time.
					elseif (p.speed < 92*FRACUNIT)
					P_Thrust(s, s.angle, FixedMul(31*FRACUNIT, s.scale))
					else
					P_Thrust(s, s.angle, FixedMul(41*FRACUNIT, s.scale))
					end
					S_StartSound(s, sfx_cdfm16)
				else
				P_Thrust(s, s.angle, FixedMul(12*FRACUNIT, s.scale)) //Smaller underwater boost.
				end
				s.ghsthk = P_SpawnMobj(s.x, s.y, s.z+s.height/5, MT_THOK) //New lil' visual effect for 1.1
				s.ghsthk.color = s.color
				s.ghsthk.sprite = SPR_SBRT
				s.ghsthk.tics = 6
				s.ghsthk.momx = s.momx/3
				s.ghsthk.momy = s.momy/3
				s.ghsthk.momz = s.momz/3
				s.ghsthk.scale = s.scale
				s.ghsthk.scalespeed = $*4
				s.ghsthk.destscale = $*20
			end
			if (p.pflags & PF_SPINNING) //Let's allow SMS a moving spindash charge!
			and P_IsObjectOnGround(s) and not p.smsblastboost
				if (p.cmd.buttons & BT_USE)
				p.sms_doubleblinddash = $+1
					if (p.sms_doubleblinddash > 2)  //If you're holding back on the control stick, charge!
					and ((p.cmd.forwardmove < 0) and not (p.pflags & PF_ANALOGMODE)) or ((p.pflags & PF_ANALOGMODE) and not p.cmd.forwardmove and not p.cmd.sidemove)
					and not p.gotflag
					p.pflags = $|PF_STARTDASH
						if p.cmomx or p.cmomy
						s.momx = 0
						s.momy = 0
						p.cmomy = 0
						p.cmomx = 0
						elseif (p.speed > FixedMul(4*FRACUNIT+30055, s.scale))
						s.momx = $/30
						s.momy = $/30
						end
						if p.dashspeed < p.mindash
						p.dashspeed = p.mindash
						end
					end
				else
				p.sms_doubleblinddash = 0
				end
			end


		//Weird to be using Tailsfly to make the walljump controls, but hey, it works.

		if p.powers[pw_tailsfly] //If Tailsfly is on...
			if p.speed >= 10*FRACUNIT //But if you're also fast enough...
			and (s.momz >= 0 and P_MobjFlip(s) == 1) or (s.momz <= 0 and P_MobjFlip(s) == -1) //And you're RISING...aka, doing a walljump...
			p.powers[pw_nocontrol] = 6 //Then continue with the walljump stats.
			end
		end


		if p.hms_instamove
			p.hms_instamove = $-1
		end
		if p.hmswarpcooldown
		and not (p.cmd.buttons & (BT_WEAPONPREV|BT_WEAPONNEXT))
			p.hmswarpcooldown = $-1
		end

		//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 = $-1 //Minus 1 each frame untill back at 0.
		end
		if p.sms_addboostlevel
		and not (p.pflags & PF_SPINNING)
		p.sms_boostlevel = $+1
		end
		if p.sms_addsuperboostlevel
		and not (p.pflags & PF_SPINNING)
		p.sms_boostlevel = $+2
		end
		
	  end  //Warning: "if sms" check is removed from here on out. All skins apply now.


	//When holding SMS, you become intangible to his attacks so he
	//can bomb enemies from above with his flames without hitting you.

	if p.iamcarryingsms
	p.iamcarryingsms = $-1
	end
	if p.aurarefresh
	p.aurarefresh = $-1
	end
	if p.sms_sontransform
	p.sms_sontransform = $+1
	end
	if p.sms_dodging
		p.sms_dodging = $-1
		
		if p.sms_dodging == 12 //This part is here so it'll work with all skins in SkillStrip
		and not ((s.state == S_PLAY_PAIN) or (s.state == S_PLAY_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
		elseif (p.sms_dodging == 1) and s
			if P_IsObjectOnGround(s) and (s.eflags & MFE_ONGROUND)
				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))
				P_SpawnGhostMobj(s)
				s.state = S_PLAY_FALL
				p.pflags = $ & ~PF_JUMPED
				p.sms_dodging = 0
				end
				P_SetObjectMomZ(s, -2*FRACUNIT, true)		
			end
		end	
	elseif p.sms_dodging == nil
		p.sms_dodging = 0
	end
	if p.sms_dodgetap or (p.sms_dodgetap == 0)
		if ((p.cmd.sidemove > 0) or (p.cmd.sidemove < 0) or ((p.cmd.forwardmove > 0 or p.cmd.forwardmove < 0) and not (s and s.flags2 & MF2_TWOD)))
			p.sms_dodgetap = $+1
		elseif p.sms_dodgetap
			p.sms_dodgetap = 0
		end
	end
	if p.sms_tauntcooldown
	p.sms_tauntcooldown = $-1
	end
	if p.novafire
	p.novafire = $-1
		if p.powers[pw_carry]
		p.novafire = 0
		end
		if s
		s.hmgodticket = true
		end
	end

	//God tell me why pw_nocontrol won't work in SOCs. x.x;

	if p.smsdivefloat and ( (p.cmd.buttons & (BT_TOSSFLAG|BT_WEAPONPREV)) or (p.cmd.buttons & BT_USE) and s.useatommethod)
	and (p.smsdivefloat > 0)
	p.smsdivefloat = $-1
	elseif p.smsdivefloat
	p.smsdivefloat = 0
	end
	if p.smsatomicdivefail
	p.powers[pw_nocontrol] = $+1
	p.smsatomicdivefail = $-1
	end
	if p.smsdivetimer
	and not p.smsdivedelay
	p.smsdivetimer = $+1
		if p.hypermysticsonic and s
		and not (p.smsdivetimer == 36 or p.smsdivetimer == 57)
			if (s.z > s.ceilingz-600*FRACUNIT)
			p.smsdivetimer = $+1
			end
			if (s.z > s.ceilingz-300*FRACUNIT)
			and not (p.smsdivetimer == 36 or p.smsdivetimer == 57)
			p.smsdivetimer = $+1
			end
		end
	end
	if p.readyforpowershare
	p.readyforpowershare = $-1
	end
	if p.selectcooldown
	p.selectcooldown = $-1
	end
	if p.sms_ringburst
	p.sms_ringburst = $-1
	end
	if p.sms_ringburstready
	p.sms_ringburstready = $-1
	end
	if p.sms_ringburstfly
		p.sms_ringburstfalltimer = $+1
	end
	if p.sms_ringburstdrain
		if not p.sms_ringburstfly
		p.sms_ringburstdrain = 0
		else
		p.sms_ringburstdrain = $+1
			if (p.sms_ringburstdrain > 4)
			p.sms_ringburstdrain = 1
			elseif (p.sms_ringburstdrain == 2)
			and p.rings 
			P_GivePlayerRings(p, -1)
			end
		end
	end
	if p.hmsblackhole
	p.hmsblackhole = $-1
	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*FRACUNIT)
		and (p.lddiscount and (p.lddiscount < 2))
		P_SpawnMobj(s.x, s.y, s.z+(s.height/2), MT_SPARK)
		end
	end

	//A timer for SMS' comet punch.

	if p.sms_comethaymaker
	p.sms_comethaymaker = $-1
	end

		//Failsafe! Stop lightdashing if you press spindash during a lightdash.
		
		//Here's a recreated version of the lightdash script.
		//We'll be using it for an easter egg since I don't intend SMS to have the lightdash by default.

		if p.smsrdash
			p.smsrdash = $-1
		end
		if p.lightdashstart == 1 //Let's make a sound when you start lightdashing.
		S_StartSound(s, sfx_s3kb6)
			if s and 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
		if (p.lddiscount >= 0)
			p.lddiscount = $+1
			if (p.lddiscount > 3)
				p.lddiscount = 0
			end
		end
		if (p.elauracolors >= 0)
		p.elauracolors = $+1
			if (p.elauracolors >= 280)
			p.elauracolors = 0
			end
		end
		if (p.cmd.buttons & BT_USE)
			p.spinhold = $+1
		elseif p.spinhold
			p.spinhold = 0
			if s.hmsspinfreeze
			s.hmsspinfreeze = false
			end
		end
		if (p.cmd.buttons & BT_WEAPONPREV)
			p.weaponprevhold = $+1
		elseif p.weaponprevhold
			p.weaponprevhold = 0
		end
	/*	if p.shinyglosscoat == 1
		and not SMSisyellow(s)
		and not p.hypermysticsonic
		and not G_GametypeHasTeams()
		and not (p.powers[pw_shield] & SH_FIREFLOWER)
		and not ((mariomode) and p.powers[pw_invulnerability])
		p.shinyglosscoat = 0 --Player trying to switch. Let them.
		end */
end, MT_PLAYER)