//SMS' reliable melee move, the triple sweepkick!

addHook("MobjThinker", function(s)
if not s.player
return end
local p = s.player
	if p.smsrdash
	p.smsrdash = $-1
	end
	if s
		if s.airboostimmune
		  s.airboostimmune = $-1
		  if P_IsObjectOnGround(s) and s.airboostimmune
		  s.airboostimmune = $-1
		  end
		  if (p.speed < 8*FRACUNIT) or (s.skin != "sms")
		  s.airboostimmune = 0
		  end
		end
		if p.starthmscombo and p.hypermysticsonic and (s.hmsspint2 and s.hmsspint2.valid and s.hmsspint2.hmscombod and s.hmsspint2.health)
		and not (p.starthmscombo == 1) 
			p.starthmscombo = $-1
		elseif p.starthmscombo
			p.starthmscombo = 0
			s.flags = $ & ~MF_NOCLIPTHING //Always restore clipping!
		end
		if s.hmscombod
			if (s.tracer and s.tracer.player and not (s.tracer.player.starthmscombo or s.tracer.player.hypermysticsonic))
			s.hmscombod = false
			P_KillMobj(s)
			end
			if not s.health
			s.hmscombod = false
			end
		end
	  if not (s.skin == "sms")
			if p.footsweepanim
			or s.state == S_SMS_ATOMLAND1
			or s.state == S_SMS_ATOMLAND2
				p.footsweep01 = 0
				p.footsweep02 = 0
				p.footsweep03 = 0
				p.footsweepanim = false
				p.sweepanimrecovery = 0
				p.smsdivetimer = 0
				p.smsdivefloat = 0
				p.smsatomicdivefail = 0
				s.height = P_GetPlayerHeight(p)
				s.state = S_PLAY_WALK
			end
	  elseif s.health 
			if p.sweepspeed == nil
			p.sweepspeed = 15*FRACUNIT
			end
			if (s.state == S_SMS_FOOTSWEEP8)
				p.sweepanimrecovery = 3
			end
			if p.sweepanimrecovery
			p.sweepanimrecovery = $-1
			end
			if (p.sweepanimrecovery and p.sweepanimrecovery == 1)
			and s.state == S_PLAY_STND and p.speed
				s.state = S_PLAY_WALK
			end

			//This is to smoothen the animation a little.

			if s.state == S_SMS_FOOTSWEEP8
			and (s.tics == 1)
			and P_IsObjectOnGround(s)
				s.state = S_PLAY_WALK
				s.fsrecov = true
			end

			// These are the speed and angle values to go with footsweep timers.
			// Lots of values for what seems like a simple attack.
		       if not ((s.state == S_PLAY_PAIN) and not (p.pflags & PF_SLIDING))
			if p.footsweep01
				p.footsweep01 = $-1
				if (s.eflags & MFE_UNDERWATER) or (p.pflags & PF_SLIDING)
					if (p.pflags & PF_SLIDING) and (s.momz < FRACUNIT)
					P_SetObjectMomZ(s, 4*FRACUNIT, true)
					end
					if not (s.momz > 6*FRACUNIT) and not (s.momz < -6*FRACUNIT) 
					P_SetObjectMomZ(s, 18500, true)
					end
				end
				if p.footsweepanim
				and not (s.state == S_PLAY_SPRING)
					if (p.footsweep01 >= 15)
					//	P_SetObjectMomZ(s, 0)
						P_InstaThrust(s, p.sweepangle, p.sweepspeed)
					elseif (p.footsweep01 < 15 and p.footsweep01 > 11)
						P_InstaThrust(s, p.sweepangle, p.sweepspeed*6/7)
					elseif (p.footsweep01 < 12 and p.footsweep01 > 7)
						P_InstaThrust(s, p.sweepangle, p.sweepspeed*6/8)
					elseif (p.footsweep01 > 4)
						P_InstaThrust(s, p.sweepangle, p.sweepspeed*6/9)
					end
					if (p.pflags & PF_JUMPED)
						p.footsweepanim = false
						s.sms_juststomped = 6
						p.footsweep01 = 0
						p.footsweep02 = 0
							if (s.eflags & MFE_UNDERWATER)
							P_SetObjectMomZ(s, 377777)
							else
							P_SetObjectMomZ(s, 655555)
							end
						s.state = S_SMS_ROLLT1
						p.lasthomingtrick = 2
						s.momx = ($*5)/9
						s.momy = ($*5)/9
						p.hometrickanim = true
						p.pflags = $ & ~PF_JUMPED
						p.homingtrickcharge = 0
					end
				end
			end
			if p.footsweep02
				p.footsweep02 = $-1
				if (p.footsweep02 > 6)
				and not (s.state == S_PLAY_SPRING)
				p.pflags = $|PF_JUMPDOWN|PF_USEDOWN
				end
				if p.footsweepanim
				and (p.sweepspeed > 2*FRACUNIT)
				and not (s.state == S_PLAY_SPRING)
					if (p.footsweep02 >= 15)
					P_InstaThrust(s, p.sweepangle, FixedMul(51*FRACUNIT, s.scale))
					P_SetObjectMomZ(s, 0)
					elseif (p.footsweep02 < 15 and p.footsweep02 > 11)
					P_InstaThrust(s, p.sweepangle, FixedMul(47*FRACUNIT, s.scale))
					P_SetObjectMomZ(s, 0)
					elseif (p.footsweep02 < 12 and p.footsweep02 > 7)
					P_SetObjectMomZ(s, 0)
					P_InstaThrust(s, p.sweepangle, FixedMul(40*FRACUNIT, s.scale))
					elseif (p.footsweep02 > 4)
					P_InstaThrust(s, p.sweepangle, FixedMul(27*FRACUNIT, s.scale))
					end
				end
			end
			if p.footsweep03
			   p.footsweep03 = $-1
			     if not (s.state == S_PLAY_SPRING)
				p.powers[pw_nocontrol] = $+1
				if p.footsweepanim
					if (p.cmd.buttons & BT_ATTACK)
					p.sms_flamebuttonhold = 3500
					end
					if (p.footsweep03 > 3)			
						if (p.footsweep03 > 5)
						s.tics = 1
							if (p.footsweep03 == 19)
							s.ghsthk = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_THOK) //New visual effect for 1.1
							s.ghsthk.color = SKINCOLOR_WHITE
							s.ghsthk.sprite = SPR_SBRT
							s.ghsthk.frame = $|TR_TRANS60
							s.ghsthk.tics = 6
							s.ghsthk.momx = s.momx
							s.ghsthk.momy = s.momy
							s.ghsthk.momz = s.momz
							s.ghsthk.scale = s.scale				
							s.ghsthk.scalespeed = $*14
							s.ghsthk.destscale = $*40
							P_SpawnGhostMobj(s.ghsthk)
							end
						end
						if (s.state == S_SMS_FOOTSWEEP8)
						s.state = S_SMS_FOOTSWEEP1
						end
					end
					if (p.footsweep03 < 15 and p.footsweep03 > 10)
						P_SetObjectMomZ(s, 4*FRACUNIT)
					elseif (p.footsweep03 == 10)
						P_SetObjectMomZ(s, 10*FRACUNIT)
						p.fadonuke77 = P_SpawnMobj(s.x, s.y, s.z, MT_SMMK)
						p.fadonuke77.target = s
							if p.fadonuke77 
							and not (G_GametypeHasSpectators())
							P_NukeEnemies(p.fadonuke77, s, 350*FRACUNIT)
							end
					end
					if ((p.sweepspeed > 2*FRACUNIT))
						if (p.footsweep03 >= 17)
							P_SpawnGhostMobj(s)
							P_InstaThrust(s, p.sweepangle, FixedMul(65*FRACUNIT, s.scale))
						elseif (p.footsweep03 < 17 and p.footsweep03 > 14)
							P_InstaThrust(s, p.sweepangle, FixedMul(59*FRACUNIT, s.scale))
						elseif (p.footsweep03 < 15 and p.footsweep03 > 10)
							P_InstaThrust(s, p.sweepangle, FixedMul(30*FRACUNIT, s.scale))
						elseif (p.footsweep03 == 10)
							P_InstaThrust(s, p.sweepangle, FixedMul(18*FRACUNIT, s.scale))
						elseif (p.footsweep03 < 10 and p.footsweep03 > 3)
							P_InstaThrust(s, p.sweepangle, FixedMul(10*FRACUNIT, s.scale))
						else
							P_InstaThrust(s, p.sweepangle, FixedMul(2*FRACUNIT, s.scale))
						end
					end
				end
			     end
			end
		       end

			// The animation needs to be turned off if you're not spinning like a dumbass.

			if p.footsweepanim
				P_RadiusAttack(s, s, 55*FRACUNIT)
				if p.footsweep01 and not (s.eflags & MFE_VERTICALFLIP)
				s.height = P_GetPlayerSpinHeight(p)
				end
				if (s.state == S_PLAY_WALK or s.state == S_PLAY_RUN or s.state == S_PLAY_STND)
				and (p.footsweep01 or p.footsweep02 or p.footsweep03)
				and not s.fsrecov
				s.state = P_RandomRange(S_SMS_FOOTSWEEP2, S_SMS_FOOTSWEEP7)
				end
				if not ((s.state >= S_SMS_FOOTSWEEP1) and (s.state <= S_SMS_FOOTSWEEP8))
				p.footsweepanim = false
				s.height = P_GetPlayerHeight(p)
				end
			end

			// Activating the footsweeps seems easy enough....oh damnit.

			if (p.cmd.buttons & BT_CUSTOM2)
			and not (p.smsmeleebutton > 1) 
			and s.health
			and (P_IsObjectOnGround(s) or p.footsweep02 or p.footsweep01)
			and not p.exiting
				if not (p.footsweep01 or p.footsweep02 or p.footsweep03 or p.sms_comethaymaker or p.knucklewaving or p.gotflag)
				and not (p.sms_dodging and p.sms_dodging > 6)
				and not p.hypermysticsonic
				and not (p.cmd.buttons & (BT_CUSTOM1|BT_TOSSFLAG))
				and not (p.sms_boostlevel >= 64)
				and not s.sms_juststomped
				and not (p.pflags & (PF_SPINNING|PF_STASIS))
				and not (p.panim == PA_ROLL)
				and not p.powers[pw_nocontrol] and not p.powers[pw_carry]
				and not (s.state == S_SMSCOMETHAYMAKER2)
				and not p.smsblastboost and not p.sms_ringburst
				and not p.sms_intoship and not s.sdodgeoh
					if (p.pflags & PF_SLIDING)
					p.sweepspeed = 25*FRACUNIT
					else
					p.sweepspeed = p.speed+FixedMul(p.cmomx, p.cmomy)
					end
					if p.smsanalogsweep and not (p.pflags & PF_ANALOGMODE)
					A_FAKEANALOGANGLE(p)
						if not (p.cmd.forwardmove > 0)
						or not (p.cmd.sidemove and p.cmd.forwardmove)
						p.powers[pw_nocontrol] = 5
						end
					end
					p.sweepangle = s.angle
					p.smsmeleebutton = $+4
					p.smsmeleebutton2 = 9000
					p.footsweepanim = true
					p.footsweep01 = 20
					p.footsweep02 = 0
					p.footsweep03 = 0
					s.state = S_SMS_FOOTSWEEP1
					if (s.eflags & MFE_UNDERWATER)
					S_StartSound(s, sfx_bubbl5)
					S_StartSound(s, sfx_s3k7d)
					else
					S_StartSound(s, sfx_sswip)
					end
				elseif (p.footsweep01 or p.sms_dodging)
				and not ((p.smsmeleebutton or p.smsmeleebutton2) > 1)
				and not (s.eflags & MFE_UNDERWATER)
				and not (p.pflags & (PF_SPINNING|PF_SLIDING))
				and not (p.footsweep02 or p.footsweep03) and not p.powers[pw_nocontrol]
				and not (G_GametypeHasSpectators() and ((p.rings < 1) and not (p.mxscap > 1)))
					if (p.cmd.forwardmove)
						p.sweepspeed = 50*FRACUNIT
					end
					p.footsweepanim = true
					if p.smsanalogsweep and not (p.pflags & PF_ANALOGMODE)
					A_FAKEANALOGANGLE(p)
						if not (p.cmd.forwardmove > 0)
						or not (p.cmd.sidemove and p.cmd.forwardmove)
						p.powers[pw_nocontrol] = 5
						end
					end
					p.sweepangle = s.angle
					p.footsweep01 = 0
					p.footsweep02 = 20
					A_SMSquake(s, 9*FRACUNIT, 2, 750, true)
					p.footsweep03 = 0
					p.smsmeleebutton = 9000
					s.state = S_SMS_FOOTSWEEP1
					P_SpawnGhostMobj(s)
					S_StartSound(s, sfx_sswip)
					S_StartSound(s, sfx_s3k64)
					if G_GametypeHasSpectators() and not (p.mxscap > 1)
						P_GivePlayerRings(p, -1)
					end
				elseif p.footsweep02
				and not (p.footsweep01 or p.footsweep03)
				and not (p.smsmeleebutton > 1)
				and not (s.eflags & MFE_UNDERWATER)
				and not (p.pflags & PF_SLIDING) and not p.powers[pw_nocontrol]
				and not (G_GametypeHasSpectators() and ((p.rings < 2) and not (p.mxscap > 1)))
					p.powers[pw_nocontrol] = 0
					p.pflags = $ & ~PF_STASIS
					p.pflags = $ & ~PF_FULLSTASIS
					p.pflags = $ & ~PF_JUMPSTASIS
					if (p.cmd.forwardmove)
						p.sweepspeed = 50*FRACUNIT
					end
					p.footsweepanim = true
					A_SMSquake(s, 9*FRACUNIT, 18, 750, true)
					if p.smsanalogsweep and not (p.pflags & PF_ANALOGMODE)
					A_FAKEANALOGANGLE(p)
						if not (p.cmd.forwardmove > 0)
						or not (p.cmd.sidemove and p.cmd.forwardmove)
						p.powers[pw_nocontrol] = 5
						end
					end
					p.sweepangle = s.angle
					p.footsweep01 = 0
					p.footsweep02 = 0
					p.footsweep03 = 21
					
					if s.z == s.floorz
						A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, 0, 0, 0, SKINCOLOR_RED)
						A_SMSSTOMPQUAKE(s, 65, 18, 2*FRACUNIT, 0, ANG20, 0, 0, SKINCOLOR_SUPERSILVER4)
					end
					s.state = S_SMS_FOOTSWEEP1
					S_StartSound(s, sfx_sswip)
					S_StartSound(s, sfx_s3k82)
					S_StartSound(s, sfx_mswing)
					if G_GametypeHasSpectators() and not (p.mxscap > 1)
						P_GivePlayerRings(p, -1)
					end
				end
			end


			//Rotating object effect, much like the 1.09.4 eggman spikeballs

			if p.footsweepanim
			and (p.footsweep01 and p.footsweep01 > 8)

			p.smsrotatespikeball3 = $ - 26*FRACUNIT
			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SUPERSPARK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*30, s.y+sin(FixedAngle(p.smsrotatespikeball3))*30, s.z-FixedMul(7*FRACUNIT, P_MobjFlip(s)))
			p.ftornadoattack.momx = $+s.momx
			p.ftornadoattack.momy = $+s.momy
			p.ftornadoattack.scale = s.scale
			p.ftornadoattack.state = S_SPINDUST2
			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SUPERSPARK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*-30, s.y+sin(FixedAngle(p.smsrotatespikeball3))*-30, s.z-FixedMul(7*FRACUNIT, P_MobjFlip(s)))
			p.ftornadoattack.momx = $+s.momx
			p.ftornadoattack.momy = $+s.momy
			p.ftornadoattack.state = S_SPINDUST2
			end
			if (p.footsweep02 and p.footsweep02 > 8)
			and p.footsweepanim

			p.smsrotatespikeball3 = $ - 24*FRACUNIT
			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SUPERSPARK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*42, s.y+sin(FixedAngle(p.smsrotatespikeball3))*42,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			p.ftornadoattack.momx = $+s.momx
			p.ftornadoattack.momy = $+s.momy
			p.ftornadoattack.eflags = s.eflags
			p.ftornadoattack.scale = s.scale
			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SUPERSPARK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*-42, s.y+sin(FixedAngle(p.smsrotatespikeball3))*-42,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
			p.ftornadoattack.momx = $+s.momx
			p.ftornadoattack.momy = $+s.momy
			p.ftornadoattack.eflags = s.eflags
			p.ftornadoattack.scale = s.scale

			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*62, s.y+sin(FixedAngle(p.smsrotatespikeball3))*62,s.z-3*FRACUNIT)
			p.ftornadoattack.momx = s.momx
			p.ftornadoattack.momy = s.momy
			p.ftornadoattack.eflags = s.eflags
			p.ftornadoattack.scale = s.scale
			p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*-62, s.y+sin(FixedAngle(p.smsrotatespikeball3))*-62,s.z-3*FRACUNIT)
			p.ftornadoattack.momx = s.momx
			p.ftornadoattack.momy = s.momy
			p.ftornadoattack.eflags = s.eflags
			p.ftornadoattack.scale = s.scale
			end
			if p.footsweep03
			and p.footsweepanim
				if (p.lddiscount == 1 or p.lddiscount == 3)
				p.smsrotatespikeball3 = $ + 1978743
				p.smsrotatespikeball4 = $ - 1978743 //Go both ways!
				p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*65, s.y+sin(FixedAngle(p.smsrotatespikeball3))*65,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
				p.ftornadoattack.target = s
				p.ftornadoattack.eflags = s.eflags
				p.ftornadoattack.scale = s.scale
				p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball3))*-65, s.y+sin(FixedAngle(p.smsrotatespikeball3))*-65,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
				p.ftornadoattack.target = s
				p.ftornadoattack.eflags = s.eflags
				p.ftornadoattack.scale = s.scale
				p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball4))*20, s.y+sin(FixedAngle(p.smsrotatespikeball4))*20,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
				p.ftornadoattack.target = s
				p.ftornadoattack.eflags = s.eflags
				p.ftornadoattack.scale = s.scale
				p.ftornadoattack = P_SpawnXYZMissile(s, s, MT_SMMK, s.x+cos(FixedAngle(p.smsrotatespikeball4))*-20, s.y+sin(FixedAngle(p.smsrotatespikeball4))*-20,s.z-FixedMul(3*FRACUNIT, P_MobjFlip(s)))
				p.ftornadoattack.target = s
				p.ftornadoattack.eflags = s.eflags
				p.ftornadoattack.scale = s.scale
				end
			end
			if s.fsrecov
			s.fsrecov = nil
			end
			
			//The legendary epic Hyper Mystic sprite code of ultimate destruction through all the timelines in EVERY omniverse!
			
			if p.hypermysticsonic
				if p.hmsrunf == nil
				p.hmsrunf = 8
				end
				if (p.hmsrunf < 1)
				p.hmsrunf = 8
				else
					if (p.speed < 52*FRACUNIT)
					p.hmsrunf = $-2
					elseif (p.speed < 70*FRACUNIT)
					p.hmsrunf = $-3
					else
					p.hmsrunf = 0					
					end
				end	
			 if (s.sprite == SPR_PLAY or s.sprite == SPR_SMSO or (s.sprite == SPR_HMSO and (s.state >= (S_PLAY_STND)) and (s.state <= (S_PLAY_MELEE_LANDING))))
			 and not (s.state >= (S_HMSTRANSFORM1)) and (s.state <= (S_HMSTRANSFORM9))	
				if (s.frame > J)
				s.frame = C
				end
				s.sprite = SPR_HMSO
				if s.hmsspinpass and not s.nohmsspin
					if s.hmsspinang == nil
					s.hmsspinang = 0
					else
						if s.hmsforcedspin
						s.hmsspinang = $+FixedAngle(45*FRACUNIT)
						elseif (s.momz > -4*FRACUNIT and s.momz < 4*FRACUNIT)
						s.hmsspinang = $+FixedAngle(5*FRACUNIT)
						else
						s.hmsspinang = $+FixedAngle(s.momz)
						end
					end
					p.drawangle = s.hmsspinang
					s.frame = H
				elseif (s.state >= (S_PLAY_STND)) and (s.state <= (S_PLAY_MELEE_LANDING))
					if s.hmsoframe
					elseif s.state == S_PLAY_SPRING
					s.frame = F
						if s.hmsroflstomped 
						s.hmsroflstomped = false
						s.rollangle = 0
						s.hmsspinpass = 0
						end
					elseif s.state == S_PLAY_EDGE
					s.frame = F
					elseif s.state == S_PLAY_STUN
					s.frame = B 
					elseif (p.speed < 35*FRACUNIT)
					s.frame = C 
					elseif (p.hmsrunf > 3) 
					s.hmsoframe = E
					else
					s.hmsoframe = D 
					end
				elseif not s.hmsoframe
					if (p.hmsrunf > 3) 
					s.hmsoframe = E
					else
					s.hmsoframe = D 
					end
				end
				if s.hmsoframe and (s.nohmsspin or not s.hmsspinpass)
				s.frame = s.hmsoframe
				end
			 end
			end
			if p.smsdivefloat or p.smsdivetimer or (p.hypermysticsonic and p.atomdiveaim)
				p.atomdiveaim = true
				A_AtomDiveAim(p)
				p.aiming = (P_MobjFlip(s)*-4850*FRACUNIT)
			end
			if ((s.color >= SKINCOLOR_SUPERSILVER1) or (p.shinyglosscoat)) and not (p.powers[pw_carry] == CR_NIGHTSMODE) //Glowing colors become fullbright
		    s.frame = $|FF_FULLBRIGHT
		    end
			
//Electric discharge code, usually for HMS

			if s.hmselcharge and not (p.smsgraphix and p.smsgraphix == 2)
				if P_IsObjectOnGround(s)
					s.elofc = P_SpawnMobj(s.x+P_RandomRange(-250, 250)*FRACUNIT, s.y+P_RandomRange(-250, 250)*FRACUNIT, s.z, MT_HMSWAVEAURA)
					if s.elofc and s.elofc.valid
						s.elofc.eflags = s.eflags
						s.elofc.state = S_HMSWAVEAURAG
						s.elofc.target = s
						s.elofc.scale = $*10/P_RandomRange(4, 10)
						if (s.eflags & MFE_VERTICALFLIP)
							s.elofc.z = s.elofc.ceilingz
						else
							s.elofc.z = s.elofc.floorz						
						end
					end
					if (s.hmselcharge > 26)
						s.elofc = P_SpawnMobj(s.x+P_RandomRange(-450, 450)*FRACUNIT, s.y+P_RandomRange(-450, 450)*FRACUNIT, s.z, MT_HMSWAVEAURA)
						if s.elofc and s.elofc.valid
						s.elofc.eflags = s.eflags
						s.elofc.state = S_HMSWAVEAURAG
						s.elofc.target = s
						s.elofc.scale = $*10/P_RandomRange(2, 7)
							if (s.eflags & MFE_VERTICALFLIP)
							s.elofc.z = s.elofc.ceilingz
							else
							s.elofc.z = s.elofc.floorz						
							end
						end
					end
					if (s.hmselcharge > 40)
						s.elofc = P_SpawnMobj(s.x+P_RandomRange(-1250, 1050)*FRACUNIT, s.y+P_RandomRange(-1250, 1250)*FRACUNIT, s.z, MT_HMSWAVEAURA)
						if s.elofc and s.elofc.valid
						s.elofc.eflags = s.eflags
						s.elofc.state = S_HMSWAVEAURAG
						s.elofc.target = s
						s.elofc.scale = $*10/P_RandomRange(1, 4)
							if (s.eflags & MFE_VERTICALFLIP)
							s.elofc.z = s.elofc.ceilingz
							else
							s.elofc.z = s.elofc.floorz						
							end
						end
					end
				end
				s.hmselcharge = $-1
			end			
			
//Start of the boost aura code, passes it to thinkframe for spawn.
			if (((p.speed > 79*FRACUNIT) and not p.hypermysticsonic) or (((p.speed > 135*FRACUNIT) or p.hmsdash) and p.hypermysticsonic)) and (((s.state == S_SMS_AIRBOOST) and s.tics > 20)
			or p.hypermysticsonic or (p.sms_boostlevel and (p.sms_boostlevel > 64))) and s.health
			s.boostpass = 1
			/*	if not (s.state == S_SMS_AIRBOOST)
				s.baaie.color = SKINCOLOR_FLAME
				else
				s.baaie.color = SKINCOLOR_GREEN			
				end */ 
			end		
				
//Afterimage behind the boost aura.	
			if s.boostpass
				if s.rollboostangle == nil //Setup....
				s.rollboostangle = 0
				end
				if s.smboframe == nil
				s.smboframe = 3
				end
				if not (p.powers[pw_carry] == CR_MINECART)
				s.smsbaang = R_PointToAngle2(s.x, s.y, (s.x+s.momx), (s.y+s.momy))
				end
				if not s.smboframeswitch
					if not s.smboframejs
						s.smboframe = $-1
						s.smboframejs = true
					else
						s.smboframejs = false
					end
					s.smboframeswitch = true
				else 
				s.smboframeswitch = false
				end
				
				s.rollboostangle = $+FixedAngle(10*FRACUNIT)
				s.baaie = P_SpawnMobj(s.x, s.y, s.z, MT_SMSBOOSTAURA)
				s.baaie.momx = s.momx/3
				s.baaie.momy = s.momy/3
				s.baaie.momz = s.momz/2
				s.baaie.angle = s.smsbaang
				s.baaie.color = SKINCOLOR_FLAME
				s.baaie.scale = s.scale+(P_RandomRange(15,14000))
				s.baaie.scalespeed = $/2
				s.baaie.destscale = 5
				if not p.hypermysticsonic
				s.baaie.greeeeeeen = 1
				s.baaie.momz = s.momz/2
					if p.powers[pw_sneakers] and p.sms_boostlevel and (p.sms_boostlevel > 64)
					s.baaie.scale = s.scale+P_RandomRange(0, 40111)
					else
					s.baaie.scale = $*6/7
					end
				s.baaie.scale = $*3/4
			//	s.baaie.z = $+(15*FRACUNIT*P_MobjFlip(s))
				else
				s.baaie.blue = 1
			//	s.baaie.z = $+(15*FRACUNIT*P_MobjFlip(s))
					if (p.speed > 146*FRACUNIT)
					s.baaie.scale = s.scale+P_RandomRange(0, 40111)
					end
				end
				s.baaie.momz = $+FRACUNIT*2
				s.baaie.frame = E|FF_FULLBRIGHT|TR_TRANS60
				s.baaie.tics = 4
				if (s.eflags & MFE_VERTICALFLIP)
				s.baaie.z = $-FixedMul(36*FRACUNIT, s.baaie.scale)
				end
			end
	  end
	end
end, MT_PLAYER)

addHook("MobjThinker", function(s)
	if s.blue
		if (s.tics == 2)
		s.color = SKINCOLOR_SKY
		s.frame = E|FF_FULLBRIGHT|TR_TRANS70
		s.scale = $*5/6
		end
	elseif s.greeeeeeen and (s.tics == 2)
		s.color = SKINCOLOR_EMERALD
		s.frame = E|FF_FULLBRIGHT|TR_TRANS70
		s.scale = $*5/6
	end
end, MT_SMSBOOSTAURA)

//Set up SMS' quake for the thinkframe. SMS' quake is slightly different from regular P_StartQuake, having an epicenter.
//Var1 = Intensity, Var2 = Duration, Var3 = Distance(optional), Var4 = Low Priority Quake

function A_SMSquake(s, var1, var2, var3, var4)
if not (var1 and var2)
return end
if var4 and s.smsqtime //Already a quake active? Don't start another if var4 is there.
return end
	if s and s.valid
		s.smsqtime = var2
		s.smsqlvl = var1
		if var3
		s.smsqdist = var3
		else
		s.smsqdist = 850
		end
	end
end
local smsp
hud.add(function(v, p)
	smsp = p
end)

local SwitchSMSBattleScript = false

addHook("ThinkFrame", do
	for p in players.iterate
		if p.mo	and p.mo.smsqtime and p.mo.smsqlvl and p.mo.smsqdist
			if smsp and smsp.valid and smsp.mo and not smsp.nosmsquakespls and not splitscreen
			or (splitscreen and not (players[(0)].nosmsquakespls or players[(1)].nosmsquakespls)) 
				if splitscreen or FixedHypot(FixedHypot(smsp.mo.x-p.mo.x, smsp.mo.y-p.mo.y), smsp.mo.z-p.mo.z) < p.mo.smsqdist*FRACUNIT
				P_StartQuake(p.mo.smsqlvl, 1)
				p.mo.smsqtime = $-1
					if (p.mo.smsqtime < 0)
					p.mo.smsqtime = 0
					end
				end
			end
		end
		if p.dohmscarry
			if p.mo and p.mo.valid and p.mo.hmspickuptarget and p.mo.hmspickuptarget.valid
			local t = p.mo.hmspickuptarget
			local s = p.mo
			s.momx = t.momx
			s.momy = t.momy
			s.momz = t.momz
				if t.player and t.player.drawangle != nil
				p.drawangle = t.player.drawangle
				end
			P_TeleportMove(s, t.x, t.y, t.z-(43*t.scale))
			end
			p.dohmscarry = false
		end
		if p.hfear and p.spectator
			for sector in sectors.iterate
				sector.lightlevel = ($+31)
			end
			P_SetupLevelSky(p.hfear)
			for z in players.iterate
				z.hmshascome = nil
				P_FlashPal(z, PAL_MIXUP, 3)
			end
			S_StartSound(nil, sfx_s3k66)
			p.hfear = nil
			p.powers[pw_invulnerability] = 2
			p.powers[pw_shield] = SH_NONE	
		end
		if p.ffdelaycs and p.sms_originalcolor
			if p.mo
			p.skincolor = p.sms_originalcolor
			p.mo.color = p.sms_originalcolor
			end
			p.ffdelaycs = $-1
		end
		if (p.mo and p.mo.skin == "sms")
local s = p.mo


	//Fix some bugs transforming Sonic's sprites into Super Mystic ones in NiGHTs
	
			if (p.powers[pw_carry] == CR_NIGHTSMODE) 
				if ((s.state >= S_PLAY_NIGHTS_STUN) and (s.state <= S_PLAY_NIGHTS_ATTACK))
				s.state = S_PLAY_NIGHTS_PULL
					if s.nrollangle != nil
					s.rollangle = s.nrollangle
					s.nrollanga = true
					end
				end
				if not s.fboostgfx
				s.frame = $ & ~FF_FULLBRIGHT
				end
			end
//The Super Mystic boost aura	

			if s.boostpass
				if s.smsbaang == nil
				s.smsbaang = s.angle
				end
				if s.smboframe == nil
				s.smboframe = 3
				end
				s.smsboost = P_SpawnMobj((s.x)+FixedMul(3*FRACUNIT, cos(s.smsbaang)),(s.y)+FixedMul(3*FRACUNIT, sin(s.smsbaang)), s.z, MT_SMSBOOSTAURA)
				s.smsboost.sprite = SPR_SMBO
				s.smsboost.tics = 1
				s.smsboost.momx = s.momx
				s.smsboost.momy = s.momy
				s.smsboost.momz = s.momz
				s.smsboost.angle = s.smsbaang
				if (leveltime % 2 == 0) and s.smboframe != nil
				s.smsboost.frame = (s.smboframe)|FF_FULLBRIGHT|(TR_TRANS40+P_RandomRange(0,3)*FRACUNIT)
				else
				s.smsboost.frame = A|FF_FULLBRIGHT|(TR_TRANS40+P_RandomRange(0,3)*FRACUNIT)
				end
				if p.hypermysticsonic
				s.smsboost.color = P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERSILVER5)
				else
					if SMSisyellow(s) or (s.color == SKINCOLOR_BLACK) or ((s.color >= SKINCOLOR_RUBY) and (s.color <= SKINCOLOR_FLAME))
					s.smsboost.color = SKINCOLOR_SUPERGOLD3
					else
					s.smsboost.color = s.color
					end
				end
			//	s.smsboost.rollangle = s.rollboostangle+FixedAngle(10*FRACUNIT)
				if (p.hypermysticsonic and (p.speed > 146*FRACUNIT)) or (p.powers[pw_sneakers] and (p.sms_boostlevel > 64))
				s.smsboost.scale = (s.scale*2)+P_RandomRange(-20000, 20000)
				s.smsboost.z = $-((20*FRACUNIT)*P_MobjFlip(s))
				else
				s.smsboost.scale = s.scale+P_RandomRange(-11000, 17000)
				end
				if (s.eflags & MFE_VERTICALFLIP)
				s.smsboost.z = $-FixedMul(29*FRACUNIT, s.smsboost.scale)
				end
				
//Boostframe number 2!
		
			s.smsboost = P_SpawnMobj((s.x)+FixedMul(3*FRACUNIT, cos(s.smsbaang)),(s.y)+FixedMul(3*FRACUNIT, sin(s.smsbaang)), s.z, MT_SMSBOOSTAURA)
				s.smsboost.sprite = SPR_SMBO
				s.smsboost.tics = 3
				if P_RandomRange(0,1)
				s.smsboost.momx = s.momx/4*-1
				s.smsboost.momy = s.momy/4*-1
				s.smsboost.momz = s.momz/4*-1
				s.baatr2 = TR_TRANS70
				else
				s.smsboost.momx = s.momx/5*-1
				s.smsboost.momy = s.momy/5*-1
				s.smsboost.momz = s.momz/5*-1
				s.baatr2 = TR_TRANS90
				end
				s.smsboost.angle = s.smsbaang
				if (leveltime % 2 == 0)
				s.smsboost.frame = (s.smboframe)|FF_FULLBRIGHT|(s.baatr2)
				else
				s.smsboost.frame = A|FF_FULLBRIGHT|(s.baatr2)
				end
				if p.hypermysticsonic
				s.smsboost.color = P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERSILVER5)
				else
					if SMSisyellow(s)
					s.smsboost.color = SKINCOLOR_SUPERGOLD3
					else
					s.smsboost.color = s.color
					end
				end 

				if (p.hypermysticsonic and (p.speed > 146*FRACUNIT)) or (p.powers[pw_sneakers] and (p.sms_boostlevel > 64))
				s.smsboost.scale = (s.scale*2)+P_RandomRange(-20000, 20000)
				s.smsboost.z = $-((20*FRACUNIT)*P_MobjFlip(s))
				else
				s.smsboost.scale = s.scale+P_RandomRange(-11000, 17000)
				end 
				
				if (s.smboframe <= 1) and not s.smboframeswitch
				s.smboframe = 3
				s.smboframeswitch = true
				end
				if (s.eflags & MFE_VERTICALFLIP)
				s.smsboost.z = $-FixedMul(29*FRACUNIT, s.smsboost.scale)
				end
				s.boostpass = 0
			end

//You have a thokaura active.
			
			if s.thokaurapass
				s.smsboost = P_SpawnMobj(s.x,s.y, s.z, MT_SMSAURATRAIL)
				s.smsboost.aftertrail = 40
				s.smsboost.eflags = s.eflags
				if (s.eflags & MFE_VERTICALFLIP)	
				s.smsboost.z = $+FixedMul(18*FRACUNIT, s.scale)
				end
				if s.lasttrailra
				s.smsboost.rollangle = s.lasttrailra
				end
				s.smsboost.target = s
				s.smsboost.sprite = SPR_AURA
				s.smsboost.tics = 8
				
				if s.thokaurapass >= 7
				s.smsboost.color = SKINCOLOR_FLAME
				s.smsboost.frame = B|FF_FULLBRIGHT|TR_TRANS40
				elseif s.thokaurapass == 6
				s.smsboost.color = SKINCOLOR_ORANGE
				s.smsboost.frame = B|FF_FULLBRIGHT|TR_TRANS50				
				elseif s.thokaurapass == 5
					if SMSisyellow(s) or s.color == SKINCOLOR_BLACK or s.color == SKINCOLOR_CRIMSON
					s.smsboost.color = SKINCOLOR_GOLD
					else
					s.smsboost.color = s.color
					end
				s.smsboost.frame = B|FF_FULLBRIGHT|TR_TRANS60
				elseif s.thokaurapass >= 2
				s.smsboost.color = s.color
				s.smsboost.frame = B|FF_FULLBRIGHT|TR_TRANS70
				elseif s.thokaurapass == 1
				s.smsboost.color = SKINCOLOR_EMERALD
				s.smsboost.frame = B|FF_FULLBRIGHT|TR_TRANS80
				elseif not s.smsboost.color
				s.smsboost.color = SKINCOLOR_FLAME
				end
				
				if (s.smsboost.color == SKINCOLOR_FLAME and s.tics > 6)
				s.smsboost.sprite = SPR_SMBO
				s.smsboost.scale = s.scale*4/5
				else
				s.smsboost.scale = s.scale*4/3
				end
				s.smsboost.scalespeed = $*2/3
				s.smsboost.destscale = 9
			//	P_SetObjectMomZ(s.smsboost, 193401, true)
				s.thokaurapass = $-1
			end
			
			if s.ringburstticket //Special ghostmobjs for ringburstflight

				if (leveltime % 2 == 0)
					if P_RandomRange(0,2)
					s.spinsmsgr = P_SpawnMobj(s.x, s.y, s.z, MT_THOK)
					s.spinsmsgr.angle = p.drawangle
					s.spinsmsgr.color = s.color
					s.spinsmsgr.sprite = SPR_SMSO
					s.spinsmsgr.frame = 26|FF_FULLBRIGHT|TR_TRANS60
					else
					s.spinsmsgr = P_SpawnGhostMobj(s) 
					s.spinsmsgr.sprite2 = SPR2_ROLL
					s.spinsmsgr.frame = 3|FF_FULLBRIGHT|TR_TRANS50
					s.spinsmsgr.scale = $*3/2
					
					end
				s.spinsmsgr.rollangle = P_RandomRange(0,359)*ANG1
				s.spinsmsgr.tics = 6
				s.spinsmsgr.scalespeed = $*2
				s.spinsmsgr.destscale = s.scale*4
				s.spinsmsgr.momx = s.momx/2
				s.spinsmsgr.momy = s.momy/2
				s.spinsmsgr.momz = s.momz/4*-1
				end			
				s.spinsmsgr = P_SpawnGhostMobj(s) 
				s.spinsmsgr.tics = 5
				s.spinsmsgr.sprite2 = SPR2_ROLL
				s.spinsmsgr.frame = 3|FF_FULLBRIGHT|TR_TRANS50
				s.spinsmsgr.scalespeed = $*2
				s.spinsmsgr.destscale = s.scale*4
				s.spinsmsgr.momx = s.momx
				s.spinsmsgr.momy = s.momy
				s.spinsmsgr.momz = s.momz+32320
				s.ringburstticket = false
			end
			if s.ringburstticket2 //Golden shine when initiating a ringburst!
				if (s.ringburstticket2 >= 17)
						s.hshinelin = P_SpawnMobj(s.x, s.y, s.z+(s.height/2)+FixedMul((11*FRACUNIT*P_MobjFlip(s)), s.scale), MT_THOK)
						s.hshinelin.sprite = SPR_AURA
						s.hshinelin.frame = S|((TR_TRANS80)+(P_RandomRange(0,1)*FRACUNIT))|FF_FULLBRIGHT
				 		s.hshinelin.color = s.color
						s.hshinelin.flags = $|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP
						if s.sqaang != nil
				  		s.hshinelin.rollangle = s.sqaang*ANG1
						end
					  	s.hshinelin.scale = s.scale*4/P_RandomRange(1,5)
						s.hshinelin.destscale = s.scale*6
				  		s.hshinelin.tics = 2
				  		s.hshinelin.momx = s.momx
				 		s.hshinelin.momy = s.momy
				  		s.hshinelin.momz = s.momz
				end
				if (s.ringburstticket2 % 4 == 0)
				s.gshine = P_SpawnMobj(s.x, s.y, s.z, MT_GOLDENSHINE)
				s.gshine.target = s
				s.gshine.color = s.color
				s.gshine.rollangle = FixedAngle(P_RandomRange(0,160)*FRACUNIT)
				s.gshine.frame = U|((TR_TRANS10)+(P_RandomRange(4,8)*FRACUNIT))|FF_FULLBRIGHT
				s.gshine.scale = s.scale/10
				s.gshine.scalespeed = $*P_RandomRange(1,5)
					if (s.ringburstticket2 > 35)
					s.gshine.scalespeed = $*20
					end
				s.gshine.destscale = s.scale*P_RandomRange(2,6)
				end			
				s.ringburstticket2 = $-1
				if not (p.sms_ringburstfly and (p.sms_ringburstfly < 3))
				or (p.smsgraphix and p.smsgraphix == 2)
				s.ringburstticket2 = 0
				end
			end
			if p.hypermysticsonic
			  if (s.sprite == SPR_PLAY or s.sprite == SPR_SMSO or (s.sprite == SPR_HMSO and (s.state >= (S_PLAY_STND)) and (s.state <= (S_PLAY_MELEE_LANDING))))
			  and not (s.state >= (S_HMSTRANSFORM1)) and (s.state <= (S_HMSTRANSFORM9))			
				if (s.frame > J)
				s.frame = C
				end
				s.sprite = SPR_HMSO
				if s.hmsspinpass and not s.nohmsspin//and s.hmsspinang
					s.hmsspinpass = $-1 //Spin!
					if s.hmsspinang != nil
					p.drawangle = s.hmsspinang
					end
					s.frame = H
				elseif (s.state >= (S_PLAY_STND)) and (s.state <= (S_PLAY_MELEE_LANDING))
					if s.state == S_PLAY_SPRING
					s.frame = H
					elseif s.state == S_PLAY_EDGE
					s.frame = F
					elseif s.state == S_PLAY_STUN
					s.frame = B
					elseif p.speed < 35*FRACUNIT or (s.state == S_PLAY_STND) or p.skidtime
						if not s.hmsidleanim or (s.hmsidleanim < 6)
						s.frame = C
						elseif (s.hmsidleanim < 12)
						s.frame = K
						elseif (s.hmsidleanim < 18)
						s.frame = L
						else
						s.frame = K				
						end
					end
				end
				if s.hmsoframe and (s.nohmsspin or not s.hmsspinpass)
				s.frame = s.hmsoframe
				s.hmsoframe = nil
				end
				if p.hmssrecover
				p.pflags = $ & ~PF_SLIDING
				p.hmssrecover = false
				end
			  end
			  if (s.hmsgalaxystorm > 105) and (s.hmsgalaxystorm < 121)
			    if s.hmstrickrollang == nil
				s.hmstrickrollang = 0
				end
			  s.hmstrickrollang = $+FixedAngle(24*FRACUNIT)
			  s.rollangle = s.hmstrickrollang
			  end
			end
			if p.smsdivefloat or p.smsdivetimer or (p.hypermysticsonic and p.atomdiveaim)
				p.atomdiveaim = true
				A_AtomDiveAim(p)
				if p.mo and (P_MobjFlip(p.mo) == 1)
				p.aiming = -4850*FRACUNIT
				else
				p.aiming = 4850*FRACUNIT
				end
			end


		   if p.smsblastboost
		  	p.charability = CA_HOMINGTHOK
			if not p.homing
		  	p.actionspd = 142*FRACUNIT //Emulate SMS' 1.09.4 multithok.
			else
			p.actionspd = skins[s.skin].actionspd
			end
			if (p.cmd.buttons & BT_CUSTOM1)
			and P_IsObjectOnGround(p.mo)
			and p.mo.health and not (G_GametypeHasSpectators() and not p.rings)
			and not (p.mo.eflags & MFE_UNDERWATER and not p.hypermysticsonic)
			and not (p.pflags & (PF_STARTDASH|PF_JUMPED))
			and not (p.cmd.forwardmove < 0)
			and not p.powers[pw_carry]
				if G_GametypeHasSpectators()
					if not p.sblastrd
					P_GivePlayerRings(p, -1)
					p.sblastrd = 15
					elseif p.sblastrd
					p.sblastrd = $-1
					end
				end
				if not p.smsblastboost1
					if G_GametypeHasSpectators()			
					P_GivePlayerRings(p, -1)
					p.sblastrd = 18
					end
				S_StartSound(s, sfx_smsha1)
				S_StartSound(p.mo, sfx_zoom)
				s.hudboost = 1
				p.speed = 160*FRACUNIT
				s.boostpass = 1
				p.smsradialboosteffect = P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_RADIALBOOST)
				p.smsradialboosteffect.target = p.mo
					if not (p.pflags & PF_SPINNING)
					p.mo.state = S_PLAY_RUN
					end
				end
				s.ghosttt = P_SpawnGhostMobj(s)
				s.ghosttt.tics = 2
				s.ghosttt.rollangle = s.rollangle
				if (p.pflags & PF_DIRECTIONCHAR) and not (p.pflags & PF_ANALOGMODE)
				p.drawangle = s.angle
				end
				p.smsblastboost1 = true

				if p.hypermysticsonic
				P_InstaThrust(p.mo, p.mo.angle, 121*FRACUNIT)
				p.pflags = $ & ~PF_SPINNING
				else
				P_InstaThrust(p.mo, p.mo.angle, 82*FRACUNIT)
				end
				if s.state == S_PLAY_RUN and not p.hypermysticsonic
					s.state = S_SMS_BOOST01
				end
				if not p.hypermysticsonic
				p.normalspeed = 40*FRACUNIT
				end
				s.spinrundust = P_SpawnMobj(s.x+FixedMul(24*FRACUNIT, cos(s.angle+ANGLE_90)),s.y+FixedMul(24*FRACUNIT, sin(s.angle+ANGLE_90)), s.z, MT_SPINDUST)
				s.spinrundust.frame = P_RandomRange(0,2)
				s.spinrundust = P_SpawnMobj(s.x+FixedMul(24*FRACUNIT, cos(s.angle-ANGLE_90)),s.y+FixedMul(24*FRACUNIT, sin(s.angle-ANGLE_90)), s.z, MT_SPINDUST)
				s.spinrundust.frame = P_RandomRange(0,2)
			else
			p.smsblastboost1 = false
			end
			if (p.pflags & PF_THOKKED) and (p.pflags & PF_JUMPED) and not p.sms_wallstat
				if p.smsblastboost --SMSunleashed walljump
				P_SpawnSpinMobj(p, MT_SMSWALLJUMP)
		 		end
			p.pflags = $ & ~PF_THOKKED
			end
		   elseif s.changedmyrsd
		   p.runspeed = skins[s.skin].runspeed
		   p.actionspd = skins[s.skin].actionspd
		   end
		   if (p.charflags & SF_SUPER)
		   p.charflags = $ & ~SF_SUPER
		      if (p.pflags & PF_JUMPED) and not (p.powers[pw_invulnerability] or p.powers[pw_shield])
		      p.pflags = $|PF_USEDOWN //Fighting these pesky "all super" addons that dare conceive Super Super Mystic Sonic
			  end
		   end
		   if p.powers[pw_super]
		   p.powers[pw_super] = 0 //You're already super enough. It's in your darn name.
		   p.powers[pw_emeralds] = 0
		   p.charflags = $ & ~SF_SUPER
		   		if p.mo and (p.mo.state >= S_PLAY_SUPER_TRANS1) and (p.mo.state <= S_PLAY_SUPER_TRANS6)
				P_FlashPal(p, PAL_NUKE, 4)
				S_StartSound(p.mo, sfx_lose)
				p.mo.state = S_PLAY_FALL
				CONS_Printf(p, "\x85"+"You're already super! What are you trying to pull?")
				end
		   end
		   if p.hmsrushactive and (gametype == GT_COOP) //SMSchallenges related.
		      if p.hmsenoughdeath and ((p.hmsenoughdeath < 370) and (p.hmsenoughdeath > 0))
			  p.mo.sprite = SPR_HMSO
			  p.mo.frame = B
			  p.mo.tics = 500
			  end
		   end
		elseif (p.mo and p.mo.skin == "sonic")
		local s = p.mo
//Start Battle Script. This'll never initialize if SMS is disabled from the start, just FYI
			if p.smssonicbattle
			  if not SwitchSMSBattleScript and CBW_Battle
			  	if CBW_Battle.SkinVars --7.0+ support.
					CBW_Battle.SkinVars["sms"] = {
 						weight = 110,
						flags = 0,
 						shields = 0,
						special = CBW_Battle.Action.SMSTransform,
 						guard_enabled = false,
 						guard_frame = 2,
 						func_guard_trigger = CBW_Battle.GuardFunc.Parry,
 						func_priority = CBW_Battle.Priority_FullCommon,
 						func_priority_ext = nil
					}			
				end
			  	--Don't display shield gauge, SMS can't use them anyway.
				CBW_Battle.Action.SMSTransform = function(mo,doaction)	
			
				
			  	if mo.player.hypermysticsonic
					mo.player.actiontext = nil
			  		mo.player.actionrings = nil
			  	elseif mo.skin == "sms"
			  		mo.player.actiontext = "Hyper Mystic Sonic"
			  		mo.player.actionrings = 300		
				
			  	elseif mo.player.smssonicbattle
			  		mo.player.actiontext = "Super Mystic Sonic"
			  		mo.player.actionrings = 30
					if mo.skin == "sonic"
					mo.player.actionspd = 37*FRACUNIT 
					end
			  	elseif P_IsObjectOnGround(mo)
			  		mo.player.actiontext = "Super Jump"
			  		mo.player.actionrings = 10
			  	else
			  		mo.player.actiontext = "Ground Pound"
			  		mo.player.actionrings = 10
			  	end
			  	mo.player.action2text = nil
			  	if mo.player.smssonicbattle or mo.skin == "sms"
			  	return
			  	end
			  	doaction = CBW_Battle.CheckRings(mo.player,$)
	
			  	local water = CBW_Battle.WaterFactor(mo)
			  	local thrust
			  	local jumpflags = (mo.player.pflags|PF_JUMPED|PF_THOKKED)&~(PF_STARTJUMP|PF_NOJUMPDAMAGE|PF_GLIDING|PF_BOUNCING|PF_SPINNING)
			  	if mo.player.actionstate == 0
			  		if doaction == 1 then
			  			CBW_Battle.PayRings(mo.player)
			  			if P_IsObjectOnGround(mo) then
			  				mo.player.actionstate = 2 
			  				thrust = 18*FRACUNIT/water
			  				P_SetObjectMomZ(mo,thrust,true) 
			  				S_StartSound(mo,sfx_s3k3c)
			  				S_StartSound(mo,sfx_kc5b)
			  				mo.player.pflags = jumpflags
			  				mo.state = S_PLAY_ROLL
			  				mo.player.secondjump = 0
			  			else
			  				thrust = 24*FRACUNIT/water
			  				mo.player.actionstate = 1 
			  				P_SetObjectMomZ(mo,-thrust,false) 
			  				S_StartSound(mo,sfx_zoom)
			  				mo.state = S_PLAY_ROLL
			  				mo.player.pflags = jumpflags
			  				mo.player.secondjump = 0
			  			end
			  		end
			  	elseif mo.player.actionstate == 1 
			  		mo.player.actioncooldown = TICRATE/2
			  		if mo.momz*P_MobjFlip(mo) > 0
			  			mo.player.actionstate = 0
			  			mo.state = S_PLAY_SPRING
			  			mo.player.pflags = $&~(PF_JUMPED)
			  		else
			  			if P_IsObjectOnGround(mo) then
			  				thrust = 10*FRACUNIT/water
			  				P_SetObjectMomZ(mo,thrust,true) 
			  				S_StartSound(mo,sfx_s3k5f)
			  				mo.player.state = S_PLAY_SPRING
			  				P_InstaThrust(mo,R_PointToAngle2(0,0,mo.momx,mo.momy),FixedHypot(mo.momx,mo.momy)/4)
			  				for n = 0, 23
			  					local p = P_SPMAngle(mo,MT_GROUNDPOUND,mo.angle+n*ANG15,0)
			  					if p and p.valid then
			  						p.momz = mo.scale*P_MobjFlip(mo)*2/water
			  						p.fuse = TICRATE/3
					  			end
					  		end
					  	end
				  	end
			  	elseif mo.player.actionstate == 2
			  		if mo.momz*P_MobjFlip(mo) < 0 then
			  			mo.state = S_PLAY_FALL
			  			mo.player.pflags = $&~(PF_JUMPED)
			  			mo.player.actionstate = 0
			  		end
			  		if P_IsObjectOnGround(mo) then
			  			mo.player.actionstate = 0
			  		end
			  	end
			  	if mo.player.actionstate and mo.player.pflags&PF_JUMPED then
				  	P_SpawnThokMobj(mo.player)
			  	end
			   end
			  	SwitchSMSBattleScript = true
				if CBW_Battle.ActionChar
				CBW_Battle.ActionChar["sonic"] = CBW_Battle.Action.SMSTransform
				CBW_Battle.ActionChar["sms"] = CBW_Battle.Action.SMSTransform	
				elseif CBW_Battle.SkinVars
					CBW_Battle.SkinVars["sonic"] = {
						special = CBW_Battle.Action.SMSTransform,
					}	
				end
					

			  end
			  if (p.rings > 29) and (p.cmd.buttons & (BT_ATTACK|BT_FIRENORMAL)) and not p.powers[pw_nocontrol]
			  and not p.exiting and not P_PlayerInPain(p) and not (p.charmed and p.charmedtime)
			  and s.health
				p.sms_originalcolor = p.skincolor //Remember the player's original color.
				P_FlashPal(p, PAL_MIXUP, 7)
				
				if p.powers[pw_super]
				p.powers[pw_super] = 0
				P_RestoreMusic(p)
				end
				p.presmsskin = 0
				s.skin = "sms"	
				R_SetPlayerSkin(p, "sms") //For the life icon.
				
				if not (p.powers[pw_shield] & SH_FIREFLOWER)
				and not ((mariomode) and p.powers[pw_invulnerability])
					s.color = 0
				end
				if not p.smscoatc5 or not p.shinyglosscoat
				p.skincolor = SKINCOLOR_YELLOW
				end
				
				S_StartSound(s, sfx_s3k9f)
				p.sms_transformstate = 2
				s.state = S_PLAY_SPRING
				p.pflags = $ & ~PF_JUMPED
				p.sms_hugeflametoss = 0
				p.powers[pw_flashing] = 85 //Some invincibility upon transforming.
				s.flags2 = $|MF2_DONTDRAW
				p.sms_flamedelay = 10
				p.powers[pw_nocontrol] = 2
				P_GivePlayerRings(p, -30)
					for d = 0,15
						P_SpawnParaloop(s.x, s.y, s.z+FixedMul(20*FRACUNIT, s.scale), 10*FRACUNIT, 16, MT_NIGHTSPARKLE, d*ANGLE_22h, S_SMSTSPARK1, false)
					end
					if G_GametypeHasTeams()
						if p.ctfteam == 1
						p.sms_originalcolor = SKINCOLOR_RED
						s.color = SKINCOLOR_RED
						p.skincolor = SKINCOLOR_RED
						elseif p.ctfteam == 2
						p.sms_originalcolor = SKINCOLOR_BLUE
						s.color = SKINCOLOR_BLUE
						p.skincolor = SKINCOLOR_BLUE						
						end				
					end
				return
			  end
			end
			//End Battle Script
		end
	  if p.mo
		if p.mo.resetsongtodayok
			p.mo.resetsongtodayok = nil
				if p.mysticsuper
				COM_BufInsertText(p, "tunes -default")
				end
		end
		if  ( (((p.mo.color >= SKINCOLOR_SUPERSILVER1) or (p.shinyglosscoat)) and p.mo.skin == "sms") or p.mo.smsglowticket) and p.mo.health and not (p.powers[pw_carry] == CR_NIGHTSMODE) //Glowing colors become fullbright
			p.mo.frame = $|FF_FULLBRIGHT
		end
		if p.mo.nuuuuuuuuu
			p.mo.frame = A
			p.mo.nuuuuuuuuu = false
		end
		if p.smspickup and p.smspickup.valid and p.mo and p.mo.health
				p.smspickup.z = p.mo.z+FixedMul(27*FRACUNIT,p.mo.scale)*(P_MobjFlip(p.mo))
				if not p.smspickup.player
				p.smspickup.angle = p.drawangle
				else
				p.smspickup.player.drawangle = p.drawangle //Let players rotate their camera
				end
				p.smspickup.iampickedupbysmshelp = 2
				p.smspickup.eflags = p.mo.eflags
				p.smspickup.momz = 0
				p.smspickup.pmomz = p.mo.pmomz
				p.smspickup.momx = p.mo.momx
				p.smspickup.momy = p.mo.momy
				p.smspickup.rollangle = p.mo.rollangle
				if p.smspickup.fuse
				p.smspickup.fuse = $+1 //Infinitely extend fuse of whatever you're holding
				end

				if ((FixedHypot(p.smspickup.x-p.mo.x, p.smspickup.y-p.mo.y)) > 130*FRACUNIT)
				P_TeleportMove(p.smspickup, p.mo.x+FixedMul(p.smspickup.info.radius*20/9, cos (p.drawangle)), p.mo.y+FixedMul(p.smspickup.info.radius*20/9, sin(p.drawangle)), p.mo.z+FixedMul(27*FRACUNIT,p.mo.scale)*(P_MobjFlip(p.mo)))
				else
				P_TryMove(p.smspickup, p.mo.x+FixedMul(p.smspickup.info.radius*20/9, cos (p.drawangle)), p.mo.y+FixedMul(p.smspickup.info.radius*20/9, sin(p.drawangle)), true)
				end
		end
	   end	
		
		
		
		
		
		
		
	/*	if p.mysticsuper
			p.mo.sprite2 = $|FF_SPR2SUPER
		//	p.mo.mysstics = states[p.mo.state].tics
			if not p.mo.mysstics
			end
			if not p.mo.mysstics
			p.mo.mysstics = states[p.mo.state].tics
				if framechecknext and p.mo.lastmframe != nil
				p.mo.frame = p.mo.lastmframe+1
				else
				p.mo.frame = A
				end
			else
			p.mo.mysstics = $-1
			end
			p.mo.lastmframe = p.mo.frame */
		/*	if (p.mo.tics < 3) and not p.mo.justfchecked // and not framechecknext 
			p.mo.justfchecked = p.mo.frame+1
			elseif p.mo.justfchecked and framechecknext
			p.mo.frame = $+1
			p.mo.justfchecked = nil
			elseif not framechecknext
			p.mo.frame = A 
			end */
			
			//	print(skins[s.skin].sprites[s.frame|FF_SPR2SUPER])
			//	s.mysticssprite.sprite2 = s.sprite2|FF_SPR2SUPER	
	//	framecheck = nil
	//	framechecknext = nil
	//	end
		
		
		
		
		
		
		
		
		
		
		
		
		
	//	p.powers[pw_super] = 2
	//	if p.mo.sprite2 != nil // and not (p.mo.sprite2 > 128)
	//	p.mo.sprite2 = $+128
	//	p.mo.newtics = p.mo.tics 
	//	p.mo.sprite2 = $|FF_SPR2SUPER
	//	p.mo.tics = p.mo.newtics
	//	p.mo.newtics = nil
	//	print(p.mo.anim_duration+" tics = "+p.mo.tics)
	//	print("state = :"+p.mo.state+"   sprite2 = "+p.mo.sprite2)
	//	end
		
	end
end)

addHook("MobjThinker", function(s)
	if s and s.target and s.target.health
		if not s.abilitytogive
		s.abilitytogive = -1 //Get it? Dust bunnies? ...no? Ok.
		end
		if s.target.player and s.target.player.footsweepanim
			if (s.eflags & MFE_VERTICALFLIP)
			and not (s.correctiontp)
			P_TeleportMove(s, s.x, s.y, s.z+34*FRACUNIT)
			s.correctiontp = true
			end
			if s.target.player.footsweep03
			P_SetObjectMomZ(s, 8*FRACUNIT)
			s.momx = (s.x-s.target.x)/16
			s.momy = (s.y-s.target.y)/16
			s.flags2 = $|MF2_EXPLOSION
			elseif s.target.player.footsweep02
			s.momz = 0
			end
		end
		if (s.state == S_SMMK0)
			s.color = SKINCOLOR_BONE

		elseif (s.state == S_SMMK2)
			if (s.target.color == 0 or s.target.color == SKINCOLOR_YELLOW or (s.target.color >= SKINCOLOR_SUPERSILVER1))
			s.color = SKINCOLOR_CRIMSON
			else
			s.color = s.target.color
			end
			if s.smssmmk
				P_SetObjectMomZ(s, 15000)
			end

		elseif (s.state == S_SMMK3)
			s.color = SKINCOLOR_BONE
			if s.smssmmk
				P_SetObjectMomZ(s, 2*FRACUNIT)
			end

		elseif (s.state == S_SMMK4)
			if (s.target.color == 0 or s.target.color == SKINCOLOR_YELLOW or (s.target.color >= SKINCOLOR_SUPERSILVER1))
			s.color = SKINCOLOR_CRIMSON
			else
			s.color = s.target.color
			end
			if s.smssmmk
				P_SetObjectMomZ(s, 4*FRACUNIT)
				s.momx = s.momx*3/4
				s.momy = s.momy*3/4
			end

		elseif (s.state == S_SMMK5)
			s.color = SKINCOLOR_WHITE
			if s.smssmmk
				P_SetObjectMomZ(s, 6*FRACUNIT)
				s.momx = s.momx*3/4
				s.momy = s.momy*3/4
			end
		end
	end
end, MT_SMMK)

addHook("MobjThinker", function(s)
	if s and s.valid
		P_SetObjectMomZ(s, 4500)
		if (s.state == S_HMSLIPILLAR0)
			A_SetScale(s, s.scale+50*FRACUNIT, 1)
			P_InstaThrust(s, s.angle, 0)
				if not s.fuse
				s.fuse = 70
				end
				if (s.scalespeed <= FRACUNIT/10)
				s.scalespeed = P_RandomRange(24000, 37000)
				end
				if not s.color //Why not choose a random color if Lua doesn't specify one?
				s.color = P_RandomRange(SKINCOLOR_WHITE, SKINCOLOR_SUPERGOLD5)
				end
		end
		if s.fuse and (s.fuse == 10)
		s.flags2 = $|MF2_SHADOW
		end
	end
end, MT_HMSLIPILLAR)
