--=============================HYPER MYSTIC SONIC=======================================
--Everything related to Hyper Mystic Sonic, the ultimate transformation. Some of his moves
--are a different version of SMS',so they might be located in other thinkers, however.
--======================================================================================

local function Pdelet(p,s, t, pfft) local z = t.player
	z.powers[pw_carry],z.powers[pw_nocontrol],z.powers[pw_shield],z.powers[pw_flashing] = CR_GENERIC,9999,0,0
	z.lives,z.continues,z.powers[pw_super],z.rings = 0,0,0,0
	z.target,z.tracer = nil,nil
	P_FlashPal(z, PAL_NUKE, 18)
	t.angle = R_PointToAngle2(t.x, t.y, s.x, s.y)
	t.health,t.momx.t.momy,t.momz = 0,0,0,16*t.scale*P_MobjFlip(t)
	t.state,z.playerstate,p.banned,s.sdlfhkgsdfjlhkflsjhglkdfjshglsdkjfhgldfjh = S_PLAY_DEAD,PST_DEAD,nil,nil
	t.flags = MF_SHOOTABLE|MF_SOLID|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT
	z.pflags = $|PF_FULLSTASIS|PF_GAMETYPEOVER|PF_THOKKED|PF_JUMPDOWN|PF_USEDOWN & ~(PF_JUMPED|PF_GODMODE|PF_SPINNING|PF_STARTDASH)
	if z.deadtimer z.deadtimer = 2 end
	delet(p,s,t,pfft)
end
local function ResetW(s, facc)
	if (s.state == S_FACCIOLO_HIT or s.state == S_FACCIOLO_BARRIER) and not s.DidEnding
		s.state = S_FACCIOLO_IDLE
	end
	facc.active = (facc.active==1) and 2 or facc.active
	s.health = 10000
	s.flags,s.flags2 = s.info.flags, $&~(MF2_FRET|MF2_INVERTAIMABLE|MF2_DONTDRAW)
	s.colorized,facc.invincible,facc.isntseen = false,false,false
	if s.fusrodah	
		facc.barrier = {} facc.statetimer = min($,99)
	end
end
local function End(m) if (m.sprite == SPR_MNRV) and not (m.state == S_FACCIOLO2_INTO) and not m.DidEnding 
	m.DidEnding,m.health,m.facc.health,m.facc.hittime = 1,9,0,35 
	m.fusrodah = nil
	if m.cmphtracker 
		if m.cmphtracker.valid
			m.cmphtracker.state = S_NULL
		end m.cmphtracker = nil
	end Silverhorn.Phase2Destruction(m)
end end
local function delet(p,s, m, pfft) if not s.valid or (s.player and s.skin == "sms") return end
	if m.facc and SilverHorn
		if m.DidEnding return end --
		ResetW(m, m.facc) End(m)
		local SFX,SFX2 = P_RandomRange(sfx_fahit1, sfx_fahit8), (leveltime%2) and sfx_dbboom or sfx_kboom1
		if not S_SoundPlaying(m, sfx_kboom1)
			S_StartSound(m, SFX) S_StartSound(m, SFX2)
		end
	elseif m.info.deathsound or m.info.painsound
		S_StartSound(m, m.info.deathsound or m.info.painsound)			
	end
	if (m.flags & MF_BOSS)
		SMS_AngledLightning(m) SMS_FlameWalls(m) SMS_SmokeCircle(m) SMS_FireCircle(m) SMS_FlamingImpact(m)
	end
	for i = 0,9
		if not (m and m.valid and m.health) break end m.flags2 = $ & ~MF2_FRET  m.flags = $|MF_SHOOTABLE
		if m.info.deathstate m.state = m.info.deathstate end	
				
		local DMGTYPE = (i>4) and (DMG_INSTAKILL+i)-5 or (DMG_WATER+i) 
		P_DamageMobj(m, (i%2) and pfft or nil, (i%3==0) and m or nil, (i%3==0) and 1 or i, DMGTYPE)				
	end
	for i = 0,5
		if not (m and m.valid and m.health) break end m.flags2 = $ & ~MF2_FRET m.flags = $|MF_SHOOTABLE
		local DMGTYPE = (i!=0) and i or nil 
		P_KillMobj(m, (i%2) and pfft or nil, (i%3==0) and m or nil, DMGTYPE)
	end
	if m and m.valid
		if m.state != m.info.deathstate or m.state == m.info.spawnstate or (m.facc and (m.facc.health > 2))
			if (m.player and (userdataType(m.player)) == "player_t")
				Pdelet(p,s,z.mo, pfft)
			else
				m.fuse,m.height,m.radius,m.sprite = 1,1,1,SPR_NULL
				m.state = S_NULL 
			end
		end
	end
end
local function HMS_Rewrite(s, p, i, so)
	if (p.rings < 2) p.rings = 300 end
	if (s.health <= 0) s.health = 1000 end
	if (p.lives <= 0) p.lives = 7 end
	if s.state == S_PLAY_DEAD or p.panim == PA_PAIN P_ResetPlayer(p) s.state = S_PLAY_FALL end
	
	p.playerstate = PST_LIVE
	p.pflags = $|PF_GODMODE|PF_JUMPED & ~(PF_THOKKED|PF_SPINNING|PF_STARTDASH|PF_STARTJUMP|PF_STASIS|PF_FULLSTASIS|PF_JUMPSTASIS|PF_SLIDING|PF_NOJUMPDAMAGE)
	p.powers[pw_nocontrol],p.deadtimer,p.awayviewtics,p.aiming = 0,0,0,nil,0
	s.scale = max($,FRACUNIT)
	s.eflags = $ & ~(MFE_SPRUNG|MFE_APPLYPMOMZ|MFE_JUSTHITFLOOR)
	P_NukeEnemies(s, s, 4004*s.scale)
	P_RadiusAttack(s, s, 4004*s.scale, DMG_SPIKE, false)

	S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET1])
	S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET2])
	S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET3])
	S_StopSoundByID(s, skins["sms"].soundsid[SKSPLDET4])
	S_StopSoundByID(s, sfx_dmpain)
	if s.sprite != SPR_HMSO
		s.sprite,s.frame = SPR_HMSO, ($ & ~FF_FRAMEMASK)|C|FF_FULLBRIGHT
	end	
	if s.info.deathsound
		S_StopSoundByID(s, s.info.deathsound)
	end

	if (s.momz*P_MobjFlip(s) <= 0) 
		P_SetObjectMomZ(s, FRACUNIT/2) 
	end
	if (abs(p.cmd.forwardmove) > 20) 
		P_InstaThrust(s, s.angle, s.scale*p.cmd.forwardmove)
	end
	
	local pfft
	if i and i.valid
		P_TryMove(i, i.x+FixedMul(55*s.scale, cos(p.drawangle)), i.y+FixedMul(55*s.scale, sin(p.drawangle)), true)
		delet(p,s, i, pfft)
	end
	if so and so != i and so.valid
		P_TryMove(so, so.x+FixedMul(55*s.scale, cos(p.drawangle)), so.y+FixedMul(55*s.scale, sin(p.drawangle)), true)
		delet(p,s, so, pfft)
	end
	for z in players.iterate
		if z.mo and z.mo.movefactor == 0 and not z.mo.skin != "sms"
			Pdelet(p,s,z.mo, pfft)
			if z.mo and z.mo.valid
				delet(p,s,z.mo, pfft)
			end
		end
	end	
	for m in mobjs.iterate(mobjs)
		if m.valid
			if (m.flags & (MF_BOSS|MF_PAIN|MF_SHOOTABLE|MF_MISSILE|MF_ENEMY|MF_SPECIAL|MF_FIRE))
			or m.facc or m.facciolo or (m.type == MT_THOK) or m.target == s or m.tracer == s
				if (FixedHypot(FixedHypot(s.x-m.x, s.y-m.y), s.z-m.z) > 2500<<16)
				or (m.flags & (MF_NOSECTOR|MF_NOTHINK))
					continue --
				end
				delet(p,s, m, pfft)
			end
			pfft = m
		end
	end
end

addHook("MobjThinker", function(s) if not s.player return end local p = s.player
	p.transformdown = (p.cmd.buttons & BT_CUSTOM3) and $+1 or 0
	if p.superinvulnerable
		if not p.mysticsuper
		p.superinvulnerable = nil
			if (p.powers[pw_invulnerability] > 7771 and p.powers[pw_invulnerability] < 7799)
				p.powers[pw_invulnerability] = 1
			end
		end
	end
	if p.hfear and not p.hypermysticsonic
		for sector in sectors.iterate
			sector.lightlevel = ($+31)
		end
		for z in players.iterate
			z.hmshascome = nil
			P_FlashPal(z, PAL_MIXUP, 3)
			if not z.nohmstheme
				COM_BufInsertText(z, "tunes -default")
				P_RestoreMusic(z)
			end
		end
		S_StartSound(nil, sfx_s3k66)
		P_SetupLevelSky(p.hfear)
		p.hfear = nil
	end
	-------------------------------------------------------------------
	--The great MATCH mode checks, alot of which is dedicated to HMS
	-------------------------------------------------------------------
	
	if SMS_NerfedMode(p)
		if s.skin == "sms"
			if G_RingSlingerGametype() --Adjust weapon rings to be inaccessible, but keep them in a table so you can drop them for others.
				if p.ringweapons
					if s.sms_ringweapons == nil s.sms_ringweapons = 0 end
					if (p.ringweapons & RW_SCATTER)
						s.sms_ringweapons = $|RW_SCATTER
					end
					if (p.ringweapons & RW_EXPLODE)
						s.sms_ringweapons = $|RW_EXPLODE
					end
					if (p.ringweapons & RW_GRENADE)
						s.sms_ringweapons = $|RW_GRENADE
					end
					if (p.ringweapons & RW_AUTO)
						s.sms_ringweapons = $|RW_AUTO
					end
					if (p.ringweapons & RW_RAIL)
						s.sms_ringweapons = $|RW_RAIL
					end
				end
				if p.powers[pw_infinityring]
					s.sms_infinityring = true
					p.powers[pw_infinityring] = 0
				end
				p.ringweapons = 0 --Keep this code order right here.
				p.currentweapon = 0
				p.weapondelay = 9
			end	
			if p.shinyglosscoat
				if G_GametypeHasTeams() 
					local COLOR = (p.ctfteam == 1) and SKINCOLOR_BLUE or SKINCOLOR_RED
					SMSpulsecolorset(p, COLOR, COLOR, COLOR, COLOR, COLOR)
					p.skincolor = COLOR
					if not p.hypermysticsonic --These aren't allowed here!
						s.color = COLOR
					end
					p.shinyglosscoat = 0
				end
			end
		end	
		if s.hmsfearmessage --HMS is here.
			s.hmsfearmessage = $-1
		end
		if s.eyesareuponyou --HMS is about to teleport to you.
			s.eyesareuponyou = $-1
		end
		if p.hmshascome --Glow in the dark, becoming a target for HMS.
			s.smsglowticket = 2
		end
		if p.cmphspamreduce --To negate timers for this stuff.
			p.cmphspamreduce = $-1
		end
		if p.hmspanic --Someone went HMS!
			if (p.hmspanic == 964)
				for z in players.iterate --Play panic music.
					if not z.nohmstheme
						COM_BufInsertText(z, "tunes MAPX7M")
					--	S_ChangeMusic("MAPX7M", false, z)
					end
				end
				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.skin != "sms") --Save that we weren't HMS.
			if not s.notsms
				s.notsms = true
			end
		else
			//Warn the players someone went Hyper Mystic. Don't want them to
			//them to try attacking a completely invincible player.
			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	
			if s.notsms
				s.notsms = false
				p.rings = min($,100) --Can't smuggle rings from other characters back to SMS.
			end
			if SMS_NerfedMode(p)
				if p.hmswarn
					if not (p.hmswarn == 1)
						p.hmswarn = $-1
					end
					if (p.hmswarn == 1) and (p.rings < 200)
						p.hmswarn = 0
					end
				else
					if p.hypermysticsonic
						if p.gotflag --No HMS flag carrying for an automatic victory.
							P_PlayerFlagBurst(p)
						end
						s.hmgodmticket = true			
					elseif (p.rings > 199)
						S_StartSound(nil, sfx_litng4)
						print("\x85 -"+p.name+"\x85 has collected 200 rings! Be careful!")
						p.hmswarn = 825
					end
				end
				if s.health			
					if (p.powers[pw_emeralds] == 0) and (p.powers[pw_invulnerability] == 700 and p.powers[pw_sneakers] == 700)
						p.powers[pw_invulnerability] = 0 //Give 100 rings instead of that shitty fake match "super form".
						p.powers[pw_sneakers] = 0 //Incase you're in Match/CTF, add ring draining abilities.
						P_GivePlayerRings(p, 100)
						P_RestoreMusic(p)
						S_StartSound(s, sfx_token)
					end	
					if s.smsflagrgpermission and not p.gotflag //Delay in picking up CTF flag
						s.smsflagrg = s.smsflagrg and $+1 or 1
						if (s.smsflagrg > 24)
							s.smsflagrg = 21
						elseif (s.smsflagrg % 6 == 0)
							s.flagsmssfx = true
						end
						s.smsflagrgpermission = $-1	
					elseif s.smsflagrg
						s.smsflagrgpermission = 0
						s.smsflagrg = 0
						s.flagsmssfx = false
					end
					if not p.rings
						p.sms_boostlevel = 0
					else
						if (p.rings > 199) and not p.hypermysticsonic //Add a beacon stolen--err, borrowed from Samus.
							s.smsglowticket = 2
							local rng = SMSLocalRNG(1,5,s)
							local ghs = P_SpawnMobjFromMobj(s, 0,0, s.height*10/12, MT_THOK)
							ghs.destscale = s.scale/rng
							ghs.momx = s.momx
							ghs.momy = s.momy
							ghs.momz = s.momz+( 20*rng*s.scale*P_MobjFlip(s) )
							ghs.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS
							ghs.tics = 9 ghs.fuse = 8
							ghs.color = SKINCOLOR_SUPERGOLD1-1+rng
						end					
						if (((p.cmd.buttons & BT_CUSTOM1) or p.sms_autoboosthold) or (p.sms_boostlevel >= 65))
						and (p.speed >= 70*s.scale)
						and not (s.eflags & (MFE_UNDERWATER|MFE_GOOWATER))
						and not (p.pflags & (PF_SPINNING|PF_STARTDASH))
						and not p.powers[pw_carry]
						and not p.smsblastboost
							if not (s.hmsspinpass and p.hypermysticsonic)
								p.sms_boostdrain = $+1
								SMSRSpawnGhost(s)
								s.smsspeedticket = true
							end
						end
						if (p.sms_boostdrain > 12)
							p.sms_boostdrain = 0						
						elseif p.sms_boostdrain == 3
							if not p.hypermysticsonic
							and not p.ringburstfly
								P_GivePlayerRings(p, -1) //Take rings when the timer resets.
								p.sms_boostdrain = $+1
							end
						end
					end
				end
			end
		end
	end
	--If SMS but not HMS!
	if (s.skin == "sms")
			if (gametype == GT_RACE) or G_TagGametype()
				if (p.smsnoracegame == 1)
					p.powers[pw_carry] = CR_BRAKGOOP 
				end
				if (p.smsnoracegame == 2 or (p.pflags & PF_GAMETYPEOVER))
				and p.mysticsuper and not G_TagGametype() //Mystic super cancel
					p.rings = 0
				end
			else
				if leveltime == 135 and s.smsmenunote == nil 
					if not modeattacking
					and (gametype == GT_COOP)
					and not (p.powers[pw_carry] == CR_NIGHTSMODE)
						if p.didsmsautoconfig != 2
						and not s.smsvsboss
							s.smsmenunote = 455 
						end
					end
				elseif s.smsmenunote
					s.smsmenunote = $-1
				end
			end
			if s.HMSlr and not p.hypermysticsonic 
				p.hypermysticsonic = 1
			end
			if (p.cmd.buttons & BT_CUSTOM3)
				if not (p.transformdown > 1) //Custom 3 wasn't held, right?
				and ((p.pflags & PF_JUMPED) or p.hometrickanim)
				and not p.hypermysticsonic
				and not P_IsObjectOnGround(s)
					if ( (((p.rings > 49) and not SMS_NerfedMode(p) ) and not s.battlemodsms) --Ring check.
					or ((p.rings > 299) and (s.battlemodsms or SMS_NerfedMode(p))) ) --Need 300 for match!
						if not (p.cmd.buttons & BT_JUMP)
						and not p.sms_ringburstfly
						and not p.sms_stompanim
						and not SMS_Locked(s, p, true)
						and not p.homing
						and not (p.pflags & (PF_GAMETYPEOVER|PF_STASIS))
						and not p.powers[pw_super]
							A_TOGOEVENFURTHERBEYOND(s) //Become Hyper Mystic Sonic!
						end
					end
				elseif (p.hypermysticsonic and not (s.state >= S_HMSTRANSFORM1 and s.state <= S_HMSTRANSFORM9))
				or p.sms_transformstate			
					//Untransform from HMS at anytime by pressing Custom 3 on the ground.
					//Also, automaticly untransform when time's over in any contest.

					if (p.cmd.buttons & BT_SPIN)
					and (p.cmd.forwardmove < -5)
					and (p.speed < 3*s.scale)
					and P_IsObjectOnGround(s)
					and not p.hmsrushactive and not (p.dashspeed > 259<<16)
						A_TOGOBACKTOTHEWAYYOUWERE(s, nil) return --Don't continue the hook or it'll give all of HMS' stats back!
					end
				end
			end	
			
			//Add a little flair to the transformation animation!
			if (s.state >= S_HMSTRANSFORM1) and (s.state <= S_HMSTRANSFORM9)
				s.boostpass = false		
				if (p.hypermysticsonic > 1) and SMS_Graphix(s) == 0	
					if (s.z < s.floorz+420*s.scale)
						local ghs = P_SpawnMobjFromMobj(s, 0,0,0, MT_GARGOYLE) --Spawn a temporary invisible gargoyle.
						ghs.flags = $|MF_NOCLIPTHING & ~MF_PUSHABLE
						ghs.z = s.floorz+1
						ghs.fuse = 1 ghs.flags2 = $|MF2_DONTDRAW
						ghs.color = s.color
						if (p.hypermysticsonic%5==0)
							local HMSPOW = (p.hypermysticsonic<<16)
							A_SMSSTOMPQUAKE(ghs, 45, SMSLocalRNG(5,10,s), HMSPOW, 0, leveltime*ANG1, 0, 20, SKINCOLOR_SUPERRED4)
							A_SMSSTOMPQUAKE(ghs, 85, SMSLocalRNG(7,12,s), HMSPOW, 0, ANG10+leveltime*ANG1, 0, 20)
							A_SMSSTOMPQUAKE(ghs, 125, P_RandomRange(8,14), HMSPOW*2, 0, ANG20+leveltime*ANG1, 0, 20)
							A_SMSSTOMPQUAKE(ghs, 165, SMSLocalRNG(10,16,s), HMSPOW*3, FRACUNIT*2, ANG30+leveltime*ANG1, 0, 20, SKINCOLOR_SUPERSILVER4)
						end	
						local ANGLE = s.angle+leveltime*ANG30
						if (leveltime % 2)
							ANGLE = $+ANGLE_180
						end
						--Try to move the reference statue?
						for d = 1,5
							if not P_TryMove(ghs, ghs.x+FixedMul(23*s.scale, cos(ANGLE)), ghs.y+FixedMul(23*s.scale, sin(ANGLE)), true)
								break --
							end
						end
						for i = 1,41,10
							local ths = SMS_CraterSpew(ghs, s.angle+ANGLE_180, 17)
							if ths and ths.valid
								local EXTRAPOWER = max(s.scale, min(16*s.scale, (p.hypermysticsonic/2)*s.scale))
								P_Thrust(ths, R_PointToAngle2(s.x, s.y, ths.x, ths.y)+(SMSLocalRNG(-30, 30, ths)*ANG1), EXTRAPOWER/2) 
								ths.ROCK = 777
								ths.gentrgsfx = true
								ths.flags = $ & ~MF_GRENADEBOUNCE & ~MF_BOUNCE
								if (s.state < S_HMSTRANSFORM8)
									ths.smsrgtimer = 64
									break --
								else
									ths.momz = $ + ( (EXTRAPOWER+(i*s.scale)) *P_MobjFlip(s))
									P_SetObjectMomZ(ths, SMSLocalRNG(7, 24, ths)<<16, true)
									ths.smsrgtimer = 32
								end
							end
						end
						ghs.state = S_NULL
					end
				end
				if not p.powers[pw_carry]
					p.pflags = $|PF_JUMPED & ~PF_SPINNING & ~PF_NOJUMPDAMAGE & ~PF_STARTDASH & ~PF_THOKKED
				end			
				if not s.hmsspinpass
				and not s.hms_jumprisen
				and not p.starthmscombo
					p.powers[pw_nocontrol] = 2
					s.momx = 0 s.momy = 0 s.momz = 0
					p.powers[pw_ignorelatch] = 32769
					if (s.state > S_HMSTRANSFORM7) and (not s.bhlcamtimer or s.bhlcamtimer == 1)
						p.camerascale = FRACUNIT*4/3
						s.bhlcamtimer = 2
					end
				else
					s.state = S_PLAY_SPRING
				end
				if (s.state < S_HMSTRANSFORM8)
					if (s.state > S_HMSTRANSFORM4)
						if (s.state > S_HMSTRANSFORM6)
							HMS_NegativeZone(s, s, true, nil, A|FF_TRANS50)
						else
							HMS_NegativeZone(s, s, true, SKINCOLOR_BLACK, A|FF_TRANS60)
						end
					end
					if (s.tics == 1) --Only on the single tic.
						if (s.state == S_HMSTRANSFORM2)
							SMS_ElectricBody(s, 16, SKINCOLOR_RED)
							local ghs = SMS_LightFlash(s, SKINCOLOR_SMS5R, FRACUNIT-20000, 6, Z+3|FF_TRANS10)
							ghs.fuse = 11
							ghs.dispoffset = -40
						elseif (s.state == S_HMSTRANSFORM3)
							for i = 1,2
								local ghs = SMS_LightningStrike(s)
								if i == 2
									ghs.mirrored = true
								end
								ghs.color = SKINCOLOR_RED+i
								ghs.frame = ($ & ~FF_TRANSMASK)
								
								--Green eyes flashing with overwhelming energy!
								for d = 1,2
									local ghs = SMS_SparkleFlash(s, (-6*s.scale)+(9*i*s.scale), 18*s.scale, FRACUNIT/5)
									ghs.colorized = true
									ghs.color = SKINCOLOR_EMERALD
									ghs.scalespeed = FRACUNIT/3
									ghs.destscale = FRACUNIT*99
									ghs.spriteyoffset = 20<<16
									ghs.fuse = 11
									ghs.sttspeed = 3
									ghs.dispoffset = 12
									ghs.sttfirstframe = nil
									ghs.spritexscale = $/d
									ghs.spriteyscale = $/d
								end
							end	
						elseif (s.state == S_HMSTRANSFORM4)
							if (s.z < s.floorz+400*s.scale)
								local ghs = SMS_FlatWave(s, SKINCOLOR_ZEEJIN5, 12, nil, 420*s.scale)
								ghs.blendmode = AST_TRANSLUCENT
								ghs.frame = U|FF_TRANS40
								ghs.z = s.floorz+FRACUNIT
							end
						elseif (s.state == S_HMSTRANSFORM5)
							SMS_LensFlare(s) //, COLOR, CROLL, FUSE, CSCALE, OFFSETXY, OFFSETZ)
						elseif (s.state == S_HMSTRANSFORM6)	
							S_StartSound(nil, sfx_smsfx7)
							SMS_WallJumpGFX(s, true)
						elseif (s.state == S_HMSTRANSFORM7)	
							local ghs = SMS_GroundWindBlast(s)
							ghs.blendmode = AST_ADD
							ghs.color = SKINCOLOR_MYSTICAL5
							for i = 1,2
								ghs = SMS_ElectricBody(s, (10*i))
								ghs.blendmode = (i == 1) and AST_SUBTRACT or $
								ghs.frame = $+i
								ghs.mirrored = (i == 1) and true
							end
							HMS_BoltStorm(s, SKINCOLOR_KETCHUP, 20)
						end
					end
				else --The big shouting frames
				
					if (not s.bhlcamtimer or s.bhlcamtimer == 1)
						p.camerascale = FRACUNIT*4/3
						s.bhlcamtimer = 2
					end
					
					if (s.state == S_HMSTRANSFORM8)
						if (s.tics == 1) or (p.cmd.buttons & BT_ATTACK)
							P_FlashPal(p, PAL_MIXUP, 6)
							A_SMSquake(s, 40<<16, 24, 6922)
						
							P_SpawnMobjFromMobj(s, 
							FixedMul(-2*s.scale, cos(s.angle)), 
							FixedMul(-2*s.scale, sin(s.angle)), 
							-5*s.scale, MT_BURSTWAVE)
							
							if SMS_Graphix(s) != 2
								SMS_GoldWaves(s,p)
								SMS_Embers(s, s)					
								local ghs = P_SpawnMobjFromMobj(s, 0, 0, -12*s.scale, MT_BURSTLIGHT)
								ghs.color = SKINCOLOR_YELLOW
								for i = 1,2
									ghs = SMS_LightningStrike(s)
									if i == 2
										ghs.mirrored = true
									end
									ghs.color = SKINCOLOR_RED+i
									ghs.frame = ($ & ~FF_TRANSMASK)
								end	
								A_SMSSTOMPQUAKE(s, SMSLocalRNG(40,90,s), P_RandomRange(7,12), SMSLocalRNG(-8,8,s)<<16, 13<<16, leveltime*ANG1, SMSLocalRNG(-25, 15,s)<<16, 14)
								A_SMSSTOMPQUAKE(s, SMSLocalRNG(30,85,s), SMSLocalRNG(7,12,s), -3<<16, SMSLocalRNG(5, 35,s)<<16, leveltime*-ANG1, SMSLocalRNG(-10,30,s)<<16, 26)
								A_SMSSTOMPQUAKE(s, SMSLocalRNG(50, 110,s), P_RandomRange(8,14), 0, 6<<16, ANG20+leveltime*ANG1, P_RandomRange(-44, 2)<<16, 14)
							end
							if (p.cmd.buttons & BT_ATTACK)
								HMS_FireNovaBlast(s, p, true)
							end
						end
						local COLORTABLE = {SKINCOLOR_SMS1R, SKINCOLOR_SMS3R, SKINCOLOR_SMS5R, SKINCOLOR_ORANGE, SKINCOLOR_RED, SKINCOLOR_LIME, SKINCOLOR_EMERALD, SKINCOLOR_MINT, SKINCOLOR_WHITE}
						HMS_BoltStorm(s, COLORTABLE[SMS_TimeFrame(9, 1)], 7, SMSLocalRNG(1,37, s)*ANG1, SMSLocalRNG(-120,50, s))
					elseif (s.state == S_HMSTRANSFORM9)
						if (s.tics < 7) and SMS_Graphix(s) != 2
							HMS_AuraStorm(s)
							if (s.tics == 1)
								local ghs = P_SpawnMobjFromMobj(s, 0,0, s.height/2, MT_THOK)
								ghs.sprite = SPR_AURA
								ghs.frame = S|FF_TRANS80|FF_FULLBRIGHT
								ghs.color = SKINCOLOR_SUPERGOLD3
								ghs.scale = s.scale*2
								ghs.momz = 24*s.scale
								ghs.scalespeed = $*10				  
								ghs.destscale = $*40
								for d = 0,7
									P_SpawnParaloop(s.x, s.y, s.z, 80*s.scale, 8, MT_NIGHTSPARKLE, d*(ANG20*2), S_SMSTSPARK1, true)
								end
							end	
						end
					else
						HMS_AuraStorm(s)
					end	
				end
			end	
	end

	//This transforms you straight from HMS down to Sonic.
	//The ONLY reason this works is because of the Lua's order, so don't mess with it.

	if p.sms_transformstate
	and p.hypermysticsonictstate
	and not p.hypermysticsonic
		local ghs = P_SpawnGhostMobj(s)
		ghs.blendmode = AST_ADD
		ghs.color = SKINCOLOR_SILVER
		ghs.colorized = true
		
		s.state = S_PLAY_FALL
			if p.presmsskin
				R_SetPlayerSkin(p, p.presmsskin)
				s.skin = p.presmsskin					
			else
				R_SetPlayerSkin(p, "sonic")
				s.skin = "sonic"
			end
			if p.sms_originalcolor != nil
				s.color = p.sms_originalcolor
				p.skincolor = p.sms_originalcolor
			end
		p.hypermysticsonic = 0
		p.sms_transformstate = 0
		
		if not (p.powers[pw_shield] & SH_FIREFLOWER)
		and not ((mariomode) and p.powers[pw_invulnerability])
			s.color = p.sms_originalcolor
		else
			s.color = SKINCOLOR_WHITE
		end
		if p.sms_originalcolor != nil --Again!
			p.skincolor = p.sms_originalcolor
		end
		if not p.nohmstheme
			COM_BufInsertText(p, "tunes -default")
		end
	end
	if p.hypermysticsonictstate
		if not p.hypermysticsonic
		or not (p.sms_transformstate)
			p.hypermysticsonictstate = false
		end
		if (s.skin != "sms")					
			p.pflags = $ & ~PF_GODMODE
			s.flags = $|MF_SHOOTABLE
			p.hypermysticsonic = 0
			p.ffdelaycs = 3 
			if not p.nohmstheme
				COM_BufInsertText(p, "tunes -default")
			end
		end
	end
		
--	======HYPER MYSTIC SONIC=======
--	You are now Hyper Mystic Sonic!
--	===============================

	if p.hypermysticsonic

		p.wasHMS = true

			if (s.skin == "sms") --Makes sense...

				p.hypermysticsonic = $+1
				p.charflags = $|SF_CANBUSTWALLS
			--	s.flags = $ & ~MF_SHOOTABLE
				s.flags2 = $|MF2_FRET
				p.powers[pw_flashing] = -1

				--S Timers and P Timers.
				if p.hms_gravburstcd
					p.hms_gravburstcd = $-1
				end
				if p.hms_explosion
					p.hms_explosion = $-1
				end
				if s.HMS_warpselectcooldown
					s.HMS_warpselectcooldown = nil
				end	
				if p.hms_instamove
					p.hms_instamove = $-1
				end					
				if p.hms_instamovew
					p.hms_instamovew = $-1
				end
				if s.HMS_airboostspeedtimer --Lose speed after a bit.
					if not s.HMS_airboostspeed
						s.HMS_airboostspeedtimer = nil
						s.HMS_airboostspeed = nil
					elseif (p.speed-(99*s.scale) < s.HMS_airboostspeed)
						s.HMS_airboostspeedtimer = $-1
						if not s.HMS_airboostspeedtimer --You lost it...				
							if (s.HMS_airboostspeed > 333*s.scale)
								local ghs = SMSRSpawnGhost(s, 11, true)
								ghs.color = SKINCOLOR_SMSROVERGLOWRED
								ghs.colorized = true
								ghs.destscale = $*99
								for i = 3,7,2
									ghs = SMS_WallJumpGFX(s, true)
									ghs.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS & ~RF_PAPERSPRITE
									ghs.spriteyscale = $/(i-1)
									ghs.spritexscale = $/(i-1)
									ghs.color = SKINCOLOR_RED-3+i
									ghs.colorized = true
									ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS30
								end
								S_StartSound(nil, sfx_smsfx9, p)
							end
							s.HMS_airboostspeedtimer = nil
							s.HMS_airboostspeed = nil
						end
					end
				end
				if p.novafire
					p.novafire = $-1
					if p.powers[pw_carry]
						p.novafire = 0
					end
					s.hmgodticket = true
				end				
				if p.hmsblackhole
					p.hmsblackhole = $-1
				end						
				if s.hmsusebuffer
					if not (p.cmd.buttons & BT_SPIN)
						s.hmsusebuffer = $-1
					end
				end
				if s.hmsccd --Carry cooldown for HMS.
					s.hmsccd = $-1
				end
				if s.hmsdashDOWN
					s.hmsdashDOWN = $-1
				end							
				if s.hmsforcedspin
					s.hmsforcedspin = $-1
				end
				p.banned,s.sdlfhkgsdfjlhkflsjhglkdfjshglsdkjfhgldfjh = nil,nil				
				if s.hmsidleanim == nil or (s.hmsidleanim > 23) //HMS idle animation timer.
					s.hmsidleanim = 0
				else
					s.hmsidleanim = $+1
					if (p.speed > 6*s.scale)
					or (abs(s.momz) > 5*s.scale)
						s.hmsidleanim = $+1
						if (p.speed > 18*s.scale)
						or (abs(s.momz) > 18*s.scale)
							s.hmsidleanim = $+1
						end	
						if (s.hmsidleanim > 23)
							s.hmsidleanim = 0
						end							
					end
				end
				--Kirby, pls.
				if s.beingsucked
					for z in players.iterate
						if z.mo and z.mo.skin == "kirby" and z.kvars.suckstate
						and (FixedHypot(FixedHypot(z.mo.x-s.x, z.mo.y-s.y), z.mo.z-s.z) <= 500*z.mo.scale)
							P_FlashPal(z, PAL_MIXUP, 5)
							A_SMSquake(z.mo, 92<<16, 14, 2)
							P_SpawnMobjFromMobj(z.mo, 0,0,0, MT_BURSTWAVE)
							if SMS_Graphix(s) != 2
								HMS_BigBangVortex(z.mo)
								HMS_BoltStorm(z.mo)
								HMS_GigaJetBolt(z.mo, nil, 45)
							end
							S_StartSound(z.mo, sfx_nerf)
							S_StartSound(z.mo, sfx_smscrt)
							z.powers[pw_nocontrol] = 8
							P_DoPlayerPain(z)
							z.kvars.suckstate = 0
							P_KillMobj(z.mo)
							if s.oldflags and not (s.oldflags & MF_NOCLIPHEIGHT)
								s.flags = s.oldflags
							end
						end
					end
				end
				--Silver, pls.
				if s.silv_grabbed and s.silv_grabbed.valid
				local t = s.silv_grabbed
					if t.mo and (t.mo.type == MT_PLAYER)
						local die = t //Bad touch, Silver. VERY bad touch.
						die.powers[pw_nocontrol] = 30 
						if die.powers[pw_invulnerability]
							die.powers[pw_invulnerability] = 0 
							P_RestoreMusic(die)
						end
						P_RemoveShield(die)
						die.losstime = 2000
						P_FlashPal(die, PAL_MIXUP, 5)
						P_DamageMobj(die.mo, s, s)
						P_SpawnMobj(die.mo.x, die.mo.y, die.mo.z, MT_BURSTWAVE)
						P_InstaThrust(die.mo, s.angle, 125<<16)
						S_StartSound(die.mo, sfx_nerf)
						if die.mo.health
							P_SetObjectMomZ(die.mo, 12<<16)
							die.mo.state = S_PLAY_PAIN
							die.hmsbpunch = true
						end
						if die.mo.skin == "silver" //How often is this NOT going to be Silver...?
							S_StartSound(s, sfx_silrip)
							S_StartSound(die.mo, sfx_silrip)
						end
				  	end
				end
				
				//Shiny HUD section
				if not s.hmslivesc or (s.hmslivesc >= SKINCOLOR_SUPERTAN1)
					s.hmslivesc = SKINCOLOR_SUPERSILVER2
				else
					s.hmslivesc = $+5
				end
				if s.tniy == nil or (s.tniy < -7<<16) 
					s.tnix = (SMSLocalRNG(0,30,s)<<16) 
					s.tniy = (SMSLocalRNG(2,12,s)<<16)
				else
					s.tniy = $-15355
				end
				if s.tniy2 == nil or (s.tniy2 < -7<<16) 
					s.tnix2 = (SMSLocalRNG(30,0,s)<<16) 
					s.tniy2 = (SMSLocalRNG(12,2,s)<<16)
				else 
					s.tniy2 = $-15800
				end
				if s.tniy3 == nil or (s.tniy3 < -7<<16) 
					s.tnix3 = (SMSLocalRNG(31,0,s)<<16) 
					s.tniy3 = (SMSLocalRNG(2,13,s)<<16)
				else 
					s.tniy3 = $-16300
				end
				if s.tniy4 == nil or (s.tniy4 < -7<<16) 
					s.tnix4 = (SMSLocalRNG(1,30,s)<<16)
					s.tniy4 = (SMSLocalRNG(13,2,s)<<16)
				else 
					s.tniy4 = $-15900
				end
				if s.tniy5 == nil or (s.tniy5 < -7<<16) 
					s.tnix5 = (SMSLocalRNG(0,31,s)<<16) 
					s.tniy5 = (SMSLocalRNG(2,14,s)<<16)
				else 
					s.tniy5 = $-15470
				end
				if s.tniy6 == nil or (s.tniy6 < -7<<16) 
					s.tnix6 = (SMSLocalRNG(30,1,s)<<16) 
					s.tniy6 = (SMSLocalRNG(14,2,s)<<16)
				else 
					s.tniy6 = $-15470
				end
				--Save music position. s.HMSmusicposition
				if s.hmsmpos
					s.hmsmpos = $+30
					if (s.hmsmpos > 107700) //89000 for the old song.
						s.hmsmpos = 1
					end
				end
				if p.powers[pw_shield] //HMS consumes shields to gain 5 rings
					if not SMSSHIELD(p, SH_PINK, SH_PITY)
						P_GivePlayerRings(p, 5)
						s.hmsshieldconsume = 18
					end
					P_RemoveShield(p)
					p.powers[pw_shield] = 0
				end
				if p.sms_transformstate
					p.hypermysticsonictstate = true
				else
					p.hypermysticsonictstate = false
				end
					
				p.hms_drain = $+1
				
				if (p.pflags & PF_SPINNING) 
				and not (p.pflags & (PF_JUMPED|PF_THOKKED|PF_STARTDASH))
				and not (s.eflags & MFE_UNDERWATER|MFE_JUSTHITFLOOR)
					p.thrustfactor = 34
				or (p.speed < s.scale) or (s.eflags & MFE_UNDERWATER)
					p.thrustfactor = 9 --Tweak accel a little.
				elseif not P_IsObjectOnGround(s) or p.thrustfactor == 34
					p.thrustfactor = 8
				end

				if p.timestop
					p.timestop = false
				end
				if not (p.pflags & (PF_GODMODE|PF_GAMETYPEOVER))
					p.pflags = $|PF_GODMODE //Though already unkillable without godmode, it's still added to HMS to negate some weird effects
					s.hmsgodmode = true
				end	
				
				P_ResetScore(p)
				p.maxdash = max($, 500<<16)
				p.jumpfactor = max($, 133469)
				p.accelstart = max($, 140)

				if s.hypermysticdash and not p.dashspeed -- When you charged up a full HMS spindash, get 3 seconds of ridiculous speed potentially ignoring colissions
					if not (p.pflags & (PF_JUMPED|PF_STARTDASH))
					and not p.powers[pw_carry] 
					and not p.cmd.buttons
					and ((p.speed > 4*s.scale) or p.cmd.angleturn or p.cmd.sidemove)
					and not (p.cmd.forwardmove < -37)
					and not p.skidtime
						if p.cmd.angleturn or p.cmd.sidemove
							P_InstaThrust(s, s.angle, 500*s.scale)
							if P_IsObjectOnGround(s)
							p.pflags = $|PF_SPINNING
							end
						end
						s.hypermysticdash = $-1
					else
						if (p.cmd.forwardmove < -37)
							p.pflags = $ & ~PF_SPINNING
							s.momx = $/3
							s.momy = $/3
						end
						s.hypermysticdash = 0
					end
				end
				
				--He gets cooler stuff when he's spinning.
				if not (p.pflags & PF_SPINNING)
				and not (s.state == S_HMSCOMETHAYMAKER1 or s.state == S_HMSCOMETHAYMAKER2 or p.sms_comethaymaker)
				and not s.starthmscombo
					P_RadiusAttack(s, s, 192*s.scale, DMG_ELECTRIC, false) --Always deal death like so!
					//Take away PF_SLIDING every tic to let you fight against the currents.
					if (p.pflags & PF_SLIDING)
						p.pflags = $ & ~PF_SLIDING
						p.hmssrecover = true
						p.novafire = 5 --Don't let player fire novablast in sliding conditions. Too glitchy.
					end
				else
					--Spawn invincibility sparkles.
					if (leveltime % (TICRATE/7) == 0) and (p.speed < 120*s.scale)
						local ghs = P_SpawnMobjFromMobj(s, 0, 0, 0, MT_IVSP)
						if (s.eflags & MFE_VERTICALFLIP)
							ghs.z = $-36*s.scale
						end
						if (p.speed < 2*s.scale)
							ghs.scale = s.scale*3/2
						else
							ghs.momx = s.momx/2 
							ghs.momy = s.momy/2
						end
					end				
				end	

				//Give HMS infinite time in space and water

				p.powers[pw_spacetime] = 0
				p.powers[pw_underwater] = 0
				
				if p.powers[pw_sneakers]
					p.powers[pw_sneakers] = 0
					P_RestoreMusic(p)
				end
				if p.powers[pw_invulnerability]
					p.powers[pw_invulnerability] = 0
					P_RestoreMusic(p)
				end	

				if (p.cmd.buttons & BT_FIRENORMAL)
					p.hms_flamehold = $+1
           		else
					p.hms_flamehold = 0
           		end		
				if (p.hypermysticsonic > 29)
				
					if s.EvilGlare and s.EvilGlare.valid
						if not p.hms_instamovew
							s.EvilGlare = nil
						else
							if not (s.state == S_HMS_INSTANTMOVE2)
								s.state = S_HMS_INSTANTMOVE2
							end 
							HMS_InstantMovement(s, p)
						end
					elseif not HMS_AirAttacks(s, p) --Allow air attacks a few frames early.
						if s.HMS_FireCoords
							s.HMS_FireCoords = nil
							s.HMS_FireCoords2 = nil
							s.HMS_FireCoords3 = nil
							s.HMS_7flame = nil
						end					
					end
					local DIDGFX = false
				
					if not SMS_Graphix(s)
					
						if (p.speed >= 140*s.scale) 
						and (s.z < s.floorz+200*s.scale) --SPEEDING flamedust effects.
						and not (p.pflags & PF_SPINNING)
						and not p.novafire
				
							s.wvqs = s.wvqs and min($+8,220) or 1
							for d = -1,1
								if d != 0
								local ghs = P_SpawnMobj(
								s.x+FixedMul(SMSLocalRNG(10,24,s)<<16, cos(s.angle+(ANGLE_90*d))),
								s.y+FixedMul((SMSLocalRNG(-10,-24,s)*-FRACUNIT), sin(s.angle+ANGLE_90*d)),
								s.floorz+1, MT_HMSWAVEAURA)
								ghs.sprite = SPR_SMMK
								ghs.dustwave2 = 1
								ghs.frame = 8
								ghs.fuse = 30
								ghs.target = s
								ghs.momx = s.momx*60/SMSLocalRNG(55,65,s)
								ghs.momy = s.momy*60/P_RandomRange(55,65)
								ghs.scale = (s.scale*4)/SMSLocalRNG(1,10,s)
								ghs.scalespeed = $*8/SMSLocalRNG(8,20,s)
								ghs.destscale = s.scale*4
								ghs.angle = s.angle+ANGLE_90*d
								P_SetObjectMomZ(ghs, -2<<16)
								P_Thrust(ghs, s.angle+ANGLE_90*d, SMSLocalRNG(-20,-50,s)<<16)
								P_Thrust(ghs, s.angle, (s.wvqs*-FRACUNIT)+SMSLocalRNG(0,10,s)<<16)
								ghs.eflags = s.eflags
								end
							end
							DIDGFX = true
							
						--Waving dustclouds circling around you from your flight power, if you're near the ground!	
							
						elseif (((p.speed < 44*s.scale) and (s.z < s.floorz+350*s.scale))
						or (p.novafire and (s.z < s.floorz+600*s.scale))) //Add dustclouds to make the power feel a bit more dynamic
				
							s.wvqs = 0
							if s.wvspwncd and not (s.eflags & MFE_JUSTHITFLOOR)
								s.wvspwncd = $-1
							else
								if not p.speed 
								and ((p.cmd.buttons & BT_CUSTOM1) or ((p.cmd.buttons & BT_CUSTOM3) and P_IsObjectOnGround(s)) or (p.pflags & PF_STARTDASH))
									local ghs = P_SpawnMobjFromMobj(s, 
									s.momx+SMSLocalRNG(-100,100,s)*s.scale,
									s.momy+P_RandomRange(-100,100)*s.scale,
									SMSLocalRNG(-20,10,s)*s.scale, MT_HMSSTOMPAURA)
									ghs.scale = (s.scale*2)*10/SMSLocalRNG(3,12,s)
									ghs.tics = 10
									P_SetObjectMomZ(ghs, SMSLocalRNG(10, 30,s)<<16)
									if (s.eflags & MFE_VERTICALFLIP)
										ghs.z = $-20*s.scale
									end
									ghs.target = s
									ghs.color = SMSLocalRNG(SKINCOLOR_SUPERRED1, SKINCOLOR_SUPERGOLD5,s)
									ghs.frame = T|FF_FULLBRIGHT|FF_TRANS50
									ghs.scalespeed = $*10/SMSLocalRNG(10,20,s)
									ghs.destscale = ghs.scalespeed+1
								end
							
								if not (P_IsObjectOnGround(s) and not ((s.eflags & MFE_JUSTHITFLOOR) or (p.cmd.buttons & BT_CUSTOM1) or (p.cmd.buttons & BT_CUSTOM3) or (p.pflags & PF_STARTDASH)) )
								and not ((p.pflags & PF_STARTJUMP) and s.momz*P_MobjFlip(s) > 0)
						
								local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
								ghs.z = s.floorz+FRACUNIT
								ghs.fuse = 1
								ghs.color = s.color
								ghs.sprite = SPR_NULL
								A_SMSSTOMPQUAKE(ghs, SMSLocalRNG(30, 50,s), SMSLocalRNG(12,18,s), SMSLocalRNG(8,30,s)<<16, 0, leveltime*ANG1*SMSLocalRNG(1,3,s), 0, 30, 0, MT_HMSWAVEAURA)
								A_SMSSTOMPQUAKE(ghs, SMSLocalRNG(40, 70,s), SMSLocalRNG(-12,-18,s)*-1, SMSLocalRNG(15,25,s)<<16, 0, leveltime*ANG1*SMSLocalRNG(-1,-3,s), 0, 30, 0, MT_HMSWAVEAURA)
									if p.novafire or (p.dashspeed > 499<<16)
										A_SMSSTOMPQUAKE(ghs, SMSLocalRNG(100, 300,s), SMSLocalRNG(6,11,s), SMSLocalRNG(40,90,s)<<16, 0, leveltime*ANG1*45, 0, 30, 0, MT_HMSWAVEAURA)
									end
									if (p.dashspeed >= 300<<16)
										s.wvspwncd = 3			
									else
										s.wvspwncd = 5
									end
									DIDGFX = true
								end
							end
						end
					end	
					if s.wvspwncd and DIDGFX
						s.wvqs = 0
						s.wvspwncd = $-1
					end
				end

				if (p.pflags & PF_STARTDASH) //HMS' spammable armagedon blast that spreads flames as well.
					if (p.cmd.buttons & BT_FIRENORMAL)
					and not (p.hms_flamehold > 1)
						S_StartSound(s, sfx_bkpoof)
						P_FlashPal(p, 4, 10)
						A_SMSquake(s, 56<<16, 6, 2922)
						P_NukeEnemies(s, s, 1500*s.scale)
						HMS_GigaJetBolt(s)
						for i = -3,3
							if i != 0
							local ghs = P_SPMAngle(s, MT_HMSFIREBLAST, s.angle+((ANG1*52)*i), 1, MF2_RAILRING)
								if ghs and ghs.valid 
									ghs.color = SKINCOLOR_SILVER
									ghs.blendmode = AST_ADD
								end
							end
							HMS_AuraStorm(s, nil, SKINCOLOR_RED, nil, nil, 2, (i*128<<16))
						end
						HMS_BoltStorm(s, SKINCOLOR_RED, 15, ANG2, 60)
						--Cause an armagedon flash for other players too!
						if SMS_NerfedMode(p)
							for z in players.iterate
								if z.mo and z.health
								and (FixedHypot(FixedHypot(z.mo.x-s.x, z.mo.y-s.y), z.mo.z-s.z) <= 1500*s.scale)
								and not (p.ctfteam and (p.ctfteam == z.ctfteam))
									P_FlashPal(z, 4, 10)
									P_DamageMobj(z.mo, s, s)
									P_InstaThrust(z.mo, z.mo.angle, -45*z.mo.scale)
								end
							end
						end
					end
				end
				
				if s.hmsgalaxystorm //Actually doing the Galaxy Storm
					s.hmsgalaxystorm = $-1
					
					if s.hmsgalaxystorm == 135
						s.momx = 0 s.momy = 0 s.momz = 0
						p.aiming = 0
						P_NukeEnemies(s, s, 160<<16)
						s.hmsgaxf = P_SpawnPlayerMissile(s, MT_HMSGAX, MF2_RAILRING)
						s.hmsgaxf.color = SKINCOLOR_JET
						s.hmsgaxf.scale = s.scale/2
						s.state = S_HMSGAXANIM
						p.powers[pw_nocontrol] = 15
						p.drawangle = s.hmsspinang
						P_FlashPal(p, 4, 12)
						
						SMS_WindJumpGFX(s)
						SMS_FlatWave(s, SKINCOLOR_ZEEJIN5, 11, 12)
						
						local ghs = HMS_GigaJetBolt(s, FRACUNIT-9500, 25)
						ghs.tracer = s
						ghs.dispoffset = 1
						ghs.GSoffsetX = -15*s.scale
						ghs.GSoffsetY = -15*s.scale
						ghs.GSoffsetZ = 0
						
						ghs = SMS_LightFlash(s, SKINCOLOR_DUSK, FRACUNIT)
						ghs.tracer = s
						ghs.fuse = $+8
						ghs.GSoffsetX = -20*s.scale
						ghs.GSoffsetY = -20*s.scale
						ghs.GSoffsetZ = s.height/4					
					
					elseif (s.hmsgalaxystorm > 135)
						s.flags2 = $|MF2_DONTDRAW
						P_SetObjectMomZ(s, 5<<16, false)
						P_InstaThrust(s, s.angle, -60<<16)
						p.powers[pw_nocontrol] = 2
						
						local ghs = P_SpawnMobjFromMobj(s,s.momx*2,s.momy*2,s.momz, MT_SMSAUTOFRAME)
						ghs.sprite = SPR_SMMK
						ghs.fuse = 6
						ghs.spritexscale = FRACUNIT-12000
						ghs.frame = D|FF_TRANS10
						ghs.sttfinalframe = H
						local TIMER = abs((135-s.hmsgalaxystorm)*3)/4
						local TRANS = min(FF_TRANS90, max(FF_TRANS20, TIMER<<16))
						HMS_NegativeZone(s, s, true, SKINCOLOR_BLACK, A|(TRANS))
						SMS_FootSweepEffects(s, p)
					
					elseif (s.hmsgalaxystorm > 105)
						if (s.hmsgalaxystorm > 120)
							if (s.hmsgalaxystorm > 129)
								s.frame = A|FF_FULLBRIGHT
							else
								s.frame = B|FF_FULLBRIGHT
							end
							P_SetObjectMomZ(s, 0, false)
							P_InstaThrust(s, s.angle, 0)
							if (s.hmsgalaxystorm % 6 == 0) and SMS_Graphix(s) == 0
								SMS_DustLayers(s, nil, s.angle)
							end
							HMS_NegativeZone(s, s, true)
						else
							P_SetObjectMomZ(s, 4<<16, false)
							P_InstaThrust(s, s.angle, -20<<16)
							s.hmsspinpass = 6
							s.hmsforcedspin = 6
						end
					elseif (s.hmsgalaxystorm == 105)
						p.powers[pw_nocontrol] = 0
						s.rollangle = 0
						p.pflags = $|PF_JUMPED & ~PF_THOKKED & ~PF_SPINNING
						if SMS_Graphix(s) != 2
							SMS_BoostAura(s, p)
							SMS_ElectricRecoil(s)
						end
					end
					
				elseif (p.cmd.buttons & BT_ATTACK)
				and P_IsObjectOnGround(s) //Gravity Burst, shortened to gravbu. Also, hmsgalaxystorm.
				and not (p.sms_flamebuttonhold > 1)
				
					if (p.pflags & PF_STARTDASH) and not s.hmsgalaxystorm //Or alternatively, use the Galaxy Storm when charging a spindash!
					
						S_StartSound(s, sfx_hmsgax)
						P_FlashPal(p, 3, 3)
						s.hmsgalaxystorm = 145
						p.novafire = 45 p.hmsblackhole = 45 p.sms_flamedelay = 50
						A_SMSquake(s, 24<<16, 31, 5000)
						s.bhlcamtimer = 15
						p.camerascale = FRACUNIT*3
						s.hmsspinpass = 12
						s.hmsforcedspin = 12
						SMS_DustLayers(s, nil, s.angle+ANGLE_180)
					
						SMS_GoldWaves(s,p)
						local ghs = SMS_GroundWindBlast(s)
						ghs.spriteyscale = FRACUNIT/2
						ghs.blendmode = AST_SUBTRACT
					
						local ghs = P_SpawnMobjFromMobj(s, 0,0, s.height/2, MT_HMSNOVAWAVE)
						if ghs and ghs.valid
							ghs.scale = $*SMSLocalRNG(2,4,ghs)
							ghs.color = SMSLocalRNG(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERGOLD5,ghs)
						end
					
						ghs = P_SpawnMobjFromMobj(s, 0,0, -20*s.scale, MT_HMSWAVEAURA)
						ghs.dustwave = 1
						ghs.sprite = SPR_SMMK
						ghs.frame = 3
						ghs.target = s
						ghs.fuse = 15
						ghs.scale = s.scale
						ghs.destscale = $*2
						A_SMSSTOMPSMOKE(s, 60, MT_SPINDUST, nil, nil, 2<<16)
						A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, 0, 0, 0, SKINCOLOR_SUPERGOLD3)
						A_SMSSTOMPQUAKE(s, 80, 18, 2<<16, 0, ANG20, 0, 0, SKINCOLOR_SUPERSILVER4)
						
						ghs = P_SpawnGhostMobj(s)
						ghs.sprite = SPR_HMSO //Use the spring frame specifically for this.
						ghs.frame = H|FF_FULLBRIGHT|FF_TRANS50
					
						p.pflags = $ & ~(PF_STARTDASH|PF_SPINNING)
						P_SetObjectMomZ(s, 50<<16, false)
						P_InstaThrust(s, s.angle, -200<<16)
		
					--Shoot foes skywards by pressing FIRE on the ground, the Anti Gravity Burst
					
					elseif not p.hms_gravburstcd and not p.smspickup //Rev up the gravity burst!		
					
						S_StartSound(s, sfx_s3k4b)
						S_StartSound(s, sfx_telept)
						S_StartSound(s, sfx_bexpld)
						A_SMSSTOMPSMOKE(s, 90, MT_SPINDUST, nil, nil, 3<<16)
						if not p.smsgraphix
						--	A_SMSSTOMPSMOKE(s, 30, MT_HMSLIGHTNING1, nil, nil, nil, SKINCOLOR_SKY)
							A_SMSSTOMPSMOKE(s, 70, MT_HMSLIGHTNING2, nil, nil, nil, SKINCOLOR_FLAMEBREAKER5)
							SMS_FlamingImpact(s, SKINCOLOR_SUPERSKY5, 2, FRACUNIT+25000, nil, 36)
							--SMS_FlameWalls(s, SCALE, SPEED, OFFSETS, ALTFRAME, COLOR, FUSE, TRACER)
							for i = -5,0
								SMS_FlameWalls(s, nil, 61<<16, ((256*i)+46)<<16, A, SKINCOLOR_SKY, 47)
							end
						end
						
						local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_HMSLIPILLAR)
						ghs.color = SKINCOLOR_MYSTICAL5
						ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS80
						ghs.blendmode = AST_ADD
						ghs.dispoffset = 3
						ghs.fuse = 25
						
						P_SetObjectMomZ(s, 9<<16, true)
						s.hmsspinpass = 12
						s.hmsforcedspin = 12
						s.momx = $/2 
						s.momy = $/2
						s.bhlcamtimer = 15
						p.camerascale = FRACUNIT*3
						p.hms_gravburstcd = 100
						HMS_GigaJetBolt(s)	
					
						P_FlashPal(p, PAL_MIXUP, 3)
						P_NukeEnemies(s, s, 333*s.scale)
						A_SMSquake(s, 33<<16, 10, 8500)
						p.pflags = $ & ~(PF_STARTDASH|PF_SPINNING)
						
						local ghs = P_SpawnMobjFromMobj(s, 0,0,0, MT_HMSNOVAWAVE)
						ghs.color = SKINCOLOR_ORANGE
						ghs.followmenoz = s
						ghs.scale = s.scale
						
						--Just once, a mobj scan should be okay!
						for m in mobjs.iterate(mobjs)
							if (m.flags & (MF_ENEMY|MF_BOSS)) or (m.type == MT_MINUS)
							
							or m.player and SMS_NerfedMode(p)
							and not m.player.hypermysticsonic and not (p.ctfteam and p.ctfteam == m.player.ctfteam)
							
								if m.health
								and ((FixedHypot(FixedHypot(m.x-s.x, m.y-s.y), m.z-s.z)) <= 5100*s.scale)
									if (m.type == MT_MINUS) --Get out of the damn ground!
										m.z = $+20<<16
										m.state = S_MINUS_AERIAL2
										m.flags = $|MF_SHOOTABLE|MF_SPECIAL & ~MF_NOCLIPTHING
									end
									m.momx = $/4
									m.momy = $/4
									S_StartSound(m, sfx_mswing)
									m.gravbu = 36
									local ghs = P_SpawnMobj(m.x, m.y, m.z, MT_CMPHTRACKER)
									ghs.target = m
									if m.player
										m.state = S_PLAY_STUN
										P_FlashPal(m.player, 2, 6)
										if P_PlayerInPain(m.player) and not p.powers[pw_carry]
											m.player.pflags = $|PF_JUMPED
										end
									end
								end
							end
						end
					end
				end
				if not p.rings
				or p.exiting or (p.powers[pw_carry] == CR_NIGHTSMODE) //Nope, no Hyper Mystic NiGHTS
					if (s.health <= 0) or (not s.HMSlr or (s.HMSlr < 0)) or (p.lives <= 0)
					or s.sdlfhkgsdfjlhkflsjhglkdfjshglsdkjfhgldfjh or p.playerstate != PST_LIVE
					or p.deadtimer or p.banned or not (p.pflags & PF_GODMODE) or (s.state == S_PLAY_DEAD)
						HMS_Rewrite(s, p)
					else
						A_TOGOBACKTOTHEWAYYOUWERE(s, true, true)
					end
				end
				
			else //Disables HMS when switching to other chars.
				SMS_SkinSwap(s, p)
				p.pflags = $ & ~PF_GODMODE
				p.charflags = $ & ~SF_CANBUSTWALLS
				s.flags = $|MF_SHOOTABLE
				p.hypermysticsonic = 0
				p.ffdelaycs = 3
				if not p.nohmstheme
					COM_BufInsertText(p, "tunes -default")
				end	
			end
		--p.hypermysticsonic still active, just don't care about the skincheck anymore.								

			if P_IsObjectOnGround(s) //When going really fast, blow up shit uuuup!
				if (p.pflags & PF_STARTDASH)
				
					if (leveltime % 6 == 0)
						if (p.dashspeed > 200<<16 and p.dashspeed < 300<<16) --Spam every 6 tics.
							A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, 0, 0, 0)
							A_SMSSTOMPQUAKE(s, 65, 18, 2<<16, 0, ANG20, 0, 0, SKINCOLOR_SUPERSILVER4)
						end
						if (leveltime % 12 == 0)
							S_StartSound(s, sfx_spndsh)
						end
					end

					if (p.dashspeed >= 260<<16)
						if (p.cmd.buttons & BT_CUSTOM3) --Tornado camera! (take 2...)
							p.camerascale = FRACUNIT*20 
							s.bhlcamtimer = 5 
						end
						if (leveltime % 5 == 0)				
							if (p.dashspeed > 300<<16 and p.dashspeed < 400<<16)
							
								A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, (ANG1*leveltime), 0, 0, SMSLocalRNG(70, 100,s))
							--	A_SMSSTOMPQUAKE(s, 65, 16, 2<<16, 0, (ANG1*leveltime)*-1, P_RandomRange(70, 100))
								A_SMSSTOMPQUAKE(s, 85, 18, 3<<16, 0, (ANG1*leveltime), 0, 0, SMSLocalRNG(101, 70,s))
								if (leveltime % 10 == 0)	
									local COLORTABLE = {SKINCOLOR_SMS5R, SKINCOLOR_RED, SKINCOLOR_CRIMSON, SKINCOLOR_ORANGE, SKINCOLOR_FLAME, SKINCOLOR_RUBY, SKINCOLOR_RED}
									SMS_FlameWalls(s, nil, 53<<16, -46<<16, A|FF_TRANS20, COLORTABLE[SMSLocalRNG(1, 7,s)], 21)
								end
								
							elseif (p.dashspeed > 400<<16 and p.dashspeed < 499<<16)
							
								local ghs = P_SpawnMobjFromMobj(s, 
								s.momx+SMSLocalRNG(101,-100,s)*s.scale,
								s.momy+SMSLocalRNG(-100,100,s)*s.scale, 
								SMSLocalRNG(-20,10,s)*s.scale,
								MT_HMSSTOMPAURA)
								
								ghs.scale = (s.scale*2)*10 / SMSLocalRNG(3,12,s)
								ghs.tics = 10
								P_SetObjectMomZ(ghs, SMSLocalRNG(10, 30,s)<<16)
								if (s.eflags & MFE_VERTICALFLIP)
									ghs.z = $-20*s.scale
								end
								ghs.target = s
								ghs.color = SMSLocalRNG(SKINCOLOR_SUPERRED1, SKINCOLOR_SUPERGOLD5,s)
								ghs.frame = T|FF_FULLBRIGHT|FF_TRANS60
								ghs.scalespeed = $*10/SMSLocalRNG(19,10,s)
								ghs.destscale = 1
								if (leveltime % 2 == 0)
									if not SMS_Graphix(s)
										if (leveltime % 12 == 0)	
											local COLORTABLE = {SKINCOLOR_SMS5R, SKINCOLOR_RED, SKINCOLOR_CRIMSON, SKINCOLOR_ORANGE, SKINCOLOR_FLAME, SKINCOLOR_RUBY, SKINCOLOR_RED, SKINCOLOR_PURPLE, SKINCOLOR_SMS4R, SKINCOLOR_SMS3R, SKINCOLOR_SMS2R, SKINCOLOR_SMS1R}
											for i = -2,0
												SMS_FlameWalls(s, nil, 55<<16, ((256*i)+46)<<16, A, COLORTABLE[SMSLocalRNG(1, 12-i,s)], 30)
											end
										end
										A_SMSSTOMPQUAKE(s, 45, 6, 8<<16, 0, ANG1*leveltime, 0, 20, SKINCOLOR_SUPERRED4)
									end
								--	A_SMSSTOMPQUAKE(s, 85, 8, 15<<16, 0, (ANG1*leveltime)*-1, 0, 20)
								else
									A_SMSSTOMPQUAKE(s, 118, 10, 25<<16, 0, ANG10*leveltime, 0, 20, SMSLocalRNG(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERTAN5,s))
									A_SMSSTOMPQUAKE(s, 175, 14, 35<<16, FRACUNIT*2, -ANG2*leveltime, 0, 20, SKINCOLOR_SUPERSILVER4)
								end
							end
						end		
						
						HMStornado(s, p) --Create a tornado!
						
						if (p.cmd.forwardmove > 25)
							P_InstaThrust(s, s.angle, 313708) //Move just below the SRB2 spindash police threshold
						end						
						if (p.dashspeed >= p.maxdash-99) --MAX charge!
							s.hypermysticdash = 105
							SMS_StompGFX(s, p, true, true)
						elseif p.dashspeed == 300<<16 --
							A_SMSquake(s, 4<<16, 50, 300, true)
						elseif p.dashspeed == 350<<16 --
							A_SMSquake(s, 12<<16, 35, 300)
						elseif p.dashspeed == 385<<16 --
							A_SMSquake(s, 64<<16, 114, 300)
							SMS_FlamingImpact(s, "prism", 2, FRACUNIT*2, nil, 20)
							if p == displayplayer
								S_StartSound(nil, sfx_s3ka3, p)
								S_StartSound(nil, sfx_s3k53, p)
								S_StartSound(nil, sfx_bejet1, p)					
							else
								S_StartSound(s, sfx_s3ka3)
								S_StartSound(s, sfx_s3k53)
								S_StartSound(s, sfx_bejet1)
							end
						elseif p.dashspeed == 499<<16
							A_SMSSTOMPQUAKE(s, 85, 1, 16<<16, 0, ANG10, 0, 22, SKINCOLOR_RED)
						--	A_SMSSTOMPQUAKE(s, 95, 4, 70<<16, 0, ANG30, 0, 19, SKINCOLOR_SUPERSILVER4)
						--	A_SMSSTOMPQUAKE(s, 75, 1, 32<<16, 0, (ANG10*5), 0, 22)
							A_SMSSTOMPQUAKE(s, 105, 3, 78<<16, 0, (ANG30*2), 0, 19, SKINCOLOR_SILVER)
							P_FlashPal(p, PAL_MIXUP, 3)
							s.hudboost = 1
							if not p.smsgraphix
								SMS_FlamingImpact(s, "prism", 2, FRACUNIT+SMSLocalRNG(23456,98765,s), nil, 38)
								A_SMSSTOMPSMOKE(s, 40, MT_HMSLIGHTNING1, nil, nil, nil, SKINCOLOR_SUPERGOLD5)
								A_SMSSTOMPSMOKE(s, 20, MT_HMSLIGHTNING2, nil, nil, nil, SKINCOLOR_RED)
							end
					
							A_SMSquake(s, 94<<16, 3, 3522)
							if p == displayplayer
								S_StartSound(nil, sfx_s3ka0, p)
								S_StartSound(nil, sfx_s3k9c, p)					
							else
								S_StartSound(s, sfx_s3ka0)
								S_StartSound(s, sfx_s3k9c)
							end
							s.hmselcharge = 100	
						end
					else --Smaller tornado as a buildup!
						
						p.dashspeed = max($, 190<<16)				
						local SKIP = (p.dashspeed < 235<<16) and 2 or 1
						local ANGLE = (s.angle)+leveltime*ANG20
						for i = 1,4,SKIP
							local ghs = P_SpawnMobjFromMobj(s, 
							FixedMul((40+(SKIP*5))*s.scale, cos(ANGLE+(ANGLE_90*i))),
							FixedMul((40+(SKIP*5))*s.scale, sin(ANGLE+(ANGLE_90*i))),
							0, MT_THOK)
							ghs.sprite = SPR_TAZD
							if (SKIP == 1)
								ghs.blendmode = AST_ADD
								ghs.colorized = true
								ghs.color = SKINCOLOR_SMS5R-i
								ghs.frame = A|FF_TRANS80
								ghs.fuse = 12
								P_SetObjectMomZ(ghs, 40<<16, true)
							else
								ghs.frame = A|FF_TRANS70
								ghs.fuse = 13
								P_SetObjectMomZ(ghs, 24<<16, true)
							end
							ghs.renderflags = RF_PAPERSPRITE|RF_SEMIBRIGHT|RF_NOCOLORMAPS
							ghs.angle = R_PointToAngle2(s.x, s.y, ghs.x, ghs.y)+ANGLE_90
							ghs.scalespeed = $*2
							ghs.destscale = $*99
						end
					end
				end
				--Create lightning from braking!
				if p.skidtime
					if p.skidtime == 16 
						S_StartSound(s, sfx_ngskid)
						if not s.hmselcharge
							s.hmselcharge = 70
						end
					end
					if (p.speed > 15*s.scale)
						A_SMSSpinFire(s, MT_SMSSPINFIRE, 65357)
						A_SMSSpinFire(s, MT_SMSSPINFIRE, 65357, 5<<16)
						if (p.speed > 40*s.scale) and not p.smsgraphix and p.skidtime == 16 
							S_StartSound(s, sfx_kc4d)
							A_SMSSTOMPSMOKE(s, 40, MT_HMSLIGHTNING1, nil, nil, nil, SKINCOLOR_SUPERGOLD5)
						end		
					end
				else
					//This makes HMS leave sparks and firetrails wherever he goes			
					if (leveltime % 3 == 0)
						if SMS_Graphix(s) != 2
							HMS_GroundSparks(s, p)	
						end					
					end
					if (p.speed == 0 or p.panim == PA_IDLE) and (abs(s.momz) < 7*s.scale)
						SMS_IdleBehaviour(s, p) --Do your idle behaviour.
						if (s.state == S_PLAY_STND) --Keep this state up as HMS.
							s.tics = 99 s.anim_duration = 99
						elseif P_IsObjectOnGround(s)
							s.state = S_PLAY_STND
						end
					end	
					if (p.pflags & PF_CANCARRY)
						p.pflags = $ & ~PF_CANCARRY
						s.hmscarryset = false
					end						
				end				
				if (p.pflags & PF_SPINNING) and (p.pflags & PF_JUMPED) --We're grounded, so...no.
					p.pflags = $ & ~PF_JUMPED	
				end
				s.hmsstompsfx = false
				p.hmsdash = 0
				
				--Speed is over 6?
				if (p.speed > 6*s.scale)
					HMS_SpeedingBehaviour(s, p) --Spawn flames among other things.
				elseif s.hmsfsfx
					s.hmsfsfx = false
				end
				
			else --if not P_IsObjectOnGround(s)
			
				if s.hmsfsfx
					s.hmsfsfx = false
				end
				if p.powers[pw_carry] and (p.pflags & PF_JUMPED)
					p.pflags = $ & ~PF_JUMPED
				elseif not (p.pflags & PF_CANCARRY)		
					p.pflags = $|PF_CANCARRY
					s.hmscarryset = true
				end
				//Midair version is less powerfull, but works too.

				if (p.speed >= 165*s.scale)
					local GORELVL = SMS_Gore(s)
					s.hmsmwh = 1
					
					if (leveltime % 2 == 0)				
						if (leveltime % 8 == 0) and not (GORELVL > 222)
							P_NukeEnemies(s, s, 325*s.scale)
						else
							P_RadiusAttack(s, s, 325*s.scale, DMG_ELECTRIC, false)
						end
						
					elseif SMS_Graphix(s) != 2 --Spawn sparkles when going speedy!
					and not (GORELVL > 222) 
					
							if GORELVL < 100
								SMS_Gore(s,1)
							end
							
							local RNG = SMSLocalRNG(1,360,s)
							local RNG2 = SMSLocalRNG(-20,20,s)
							
							local HMSSPARKTABLE = {SKINCOLOR_CRIMSON, SKINCOLOR_SMS5R, SKINCOLOR_MINT, SKINCOLOR_RED, SKINCOLOR_BLUEBELL,
							SKINCOLOR_SKY, SKINCOLOR_MYSTICAL2, SKINCOLOR_SMS4R, SKINCOLOR_PURPLE, SKINCOLOR_LAVENDER, SKINCOLOR_WHITE, SKINCOLOR_FLAME}
							
							for i = 3,3 --Ahh yes, the 3,3 loop.
								local OFFSETX = FixedMul(p.speed/3, cos(s.angle+(ANG30*i)))
								local OFFSETY = FixedMul(p.speed/3, sin(s.angle+(ANG30*i)))
								local OFFSETZ = SMSLocalRNG(-290+i,-35+i, s)*s.scale
							
								local ghs = P_SpawnMobjFromMobj(s, s.momx+OFFSETX, s.momy+OFFSETY, s.momz+OFFSETZ, MT_SMSAUTOFRAME)
								ghs.state = S_IVSP
								ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
								ghs.frame = $| (RNG/60) | ((abs((RNG2 or 1))/7)<<16)  --RNG framestate.
								ghs.fuse = max(24, RNG/3)
								ghs.sttfade = min(52, ghs.fuse/2)		
								ghs.tracer = s
								ghs.ditchtracer = 6
								ghs.GSoffsetX = OFFSETX
								ghs.GSoffsetY = OFFSETY
								ghs.GSoffsetZ = OFFSETZ
								ghs.spritexoffset = $+(180-RNG)*39356
								ghs.color = HMSSPARKTABLE[SMSLocalRNG(1,11,ghs)]
								ghs.colorized = true
								ghs.spriteyscale = max(FRACUNIT*2, $+((RNG*(777*abs(i)) or 555))) --Up to 5 extra FRACs, about.
								ghs.spritexscale = ghs.spriteyscale
							end
					end
				end
			end

		//Spindashing? Then doom awaits all those around you!

			if (p.pflags & PF_SPINNING)
			and (p.speed > 49*s.scale) --You do need a litle bit of speed.
			and not (p.pflags & (PF_STARTDASH|PF_JUMPED|PF_GAMETYPEOVER))
			and not p.powers[pw_carry]
				if not p.hms_explosion
					A_SMSquake(s, 14<<16, 1, 2122, true)
					s.NoSMSGlow = true
					
					if P_IsObjectOnGround(s)
						s.hmsrunquake = 1
						if (p.speed >= 136*s.scale) and (leveltime % 2)
						or (leveltime % 4 == 0) and (p.speed < 136*s.scale)
							if (s.state == S_PLAY_STND) or (s.state == S_PLAY_WALK)
								s.state = S_PLAY_RUN
							end
							local ANGLE = R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy)
							local RNGANGLE = (50+SMSLocalRNG(0,40,s))*ANG1
							for i = -1,1,2 --Shoot electric orbs that exploding into giant bolts to your sides!
								local ghs = P_SpawnMobjFromMobj(s, 
								FixedMul(8*s.scale, cos(ANGLE+(RNGANGLE*i))),
								FixedMul(8*s.scale, sin(ANGLE+(RNGANGLE*i))),
								s.scale, MT_HMSLIGHTNING1)
								ghs.target = s
								ghs.flags = $|MF_NOCLIPHEIGHT
								ghs.spriteyscale = $+SMSLocalRNG(0,50000/abs(i), ghs)
								ghs.spritexscale = $+SMSLocalRNG(50001/abs(i), 0, ghs)
								ghs.smssmmk = true
								P_InstaThrust(ghs, ANGLE+(RNGANGLE*i), (p.speed > 136*s.scale) and 35<<16 or 30<<16)
								ghs.momx = $+(s.momx*2/3)
								ghs.momy = $+(s.momy*2/3)
								ghs.color = (p.speed > 136*s.scale) and SMSLocalRNG(70, 102,s) or SKINCOLOR_SUPERGOLD5
								P_SetObjectMomZ(ghs, 2<<16, true)
								S_StartSound(s, sfx_s3k7c) 
							end
						end
					end
					
					if (leveltime % 10 == 0)
						local ghs = SMS_ElectricBody(s, 10, SKINCOLOR_RED)
						ghs.sttfade = nil
						if SMSLocalRNG(0,2,s) == 1
							local ghs = SMS_FollowCircle(s, s.color, 2)
							ghs.scalespeed = $*3 ghs.fuse = $/3								
							for i = 1,2
								ghs = HMS_BigBangVortex(s, 13, nil, nil, T|(i<<16), s.color)
								ghs.tracer = s
								if i == 2
									ghs.ditchtracer = 1
									ghs.color = SKINCOLOR_MYSTICAL3
									ghs.momx,ghs.momy = s.momx/2,s.momy/2
								end
							end
						else
							local ghs = HMS_GigaJetBolt(s, FRACUNIT-31000, 10)
							ghs.tracer = s
							ghs.frame = $+FF_TRANS10
							ghs.sttfade = nil
							ghs.dispoffset = -11
							
							ghs = HMS_BigBangVortex(s, 12, nil, nil, T|FF_TRANS10, s.color)
							ghs.tracer = s								
						end
					elseif (leveltime % 2) or (p.speed > 136*s.scale)
						local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_SMSGROUNDBOOST)
						ghs.tracer = s
						if ghs and ghs.valid and (p.speed > 136*s.scale)
							A_SMSquake(s, 55<<16, 1, 3522)
							s.hmsrunquake = 1
							ghs.prism = true
						end				
						if (leveltime % 2)
							local HEIGHT = 800*s.scale
							local RADIUS = 350*s.scale
							local ghs
							if (p.speed < 27*s.scale)
								ghs = P_SpawnMobj(s.x+FixedMul(150*s.scale,cos(s.angle)), s.y+FixedMul(150*s.scale,sin(s.angle)), s.z-400*s.scale, MT_SMSECHECK)
							elseif (p.speed < 52*s.scale)
								ghs = P_SpawnMobj(s.x+FixedMul(400*s.scale,cos(s.angle)), s.y+FixedMul(200*s.scale,sin(s.angle)), s.z-475*s.scale, MT_SMSECHECK)
								ghs.target = s
								HEIGHT = 950*s.scale
								RADIUS = 550*s.scale
							else
								ghs = P_SpawnMobj(s.x+FixedMul(700*s.scale,cos(s.angle)), s.y+FixedMul(700*s.scale,sin(s.angle)), s.z-600*s.scale, MT_SMSECHECK)
								HEIGHT = 1200*s.scale
								RADIUS = 800*s.scale
							end
							if ghs and ghs.valid
								ghs.hmsspincheck = true
								ghs.target = s
								ghs.height = HEIGHT
								ghs.radius = RADIUS
							end
						end							
					end
					
					--Anyone in our path, rapid-flurry them to death when spinning!
					
					if s.hmsspint and s.hmsspint.valid --This will be the target MT_SMSECHECK found.
					
						local t = s.hmsspint
						
						if (t.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR)) 
						and (t.health or (t.flags & MF_BOSS)) --Leaving in a fun bug on purpose. Fly skywards, boss man!
						
						or t.player and SMS_NerfedMode(p) and not t.player.powers[pw_flashing]
						and not (G_GametypeHasTeams() and (p.ctfteam == t.player.ctfteam))
						
							if not (t.z > s.z+1000*s.scale)
							and not (t.z < s.z-1000*s.scale)
							
								if (t.type == MT_EGGGUARD) 
									if t.tracer and t.tracer.valid and (t.tracer.type == MT_EGGSHIELD)
										t.tracer.state = S_NULL
									end
									t.flags = $|MF_SHOOTABLE|MF_ENEMY
								end
	
								P_SpawnMobjFromMobj(t, 0,0,0, MT_CYBRAKDEMON_VILE_EXPLOSION)
								if not SMS_Graphix(s) --Attack enemy with violent ghost-attacks.
									for d = 1,12
										local ghs = P_SpawnMobjFromMobj(t, 
										SMSLocalRNG(-250, 250,s)*t.scale, 
										SMSLocalRNG(-250, 250, t)*t.scale, 
										SMSLocalRNG(-99, 250,t)*t.scale, MT_THOK)
										ghs.sprite = SPR_HMSO
										ghs.scale = s.scale
										if SMSLocalRNG(0,1,t) == 1
											ghs.frame = G|FF_TRANS20
										elseif SMSLocalRNG(0,3,t) == 0
											ghs.frame = B|FF_TRANS30
											if SMSLocalRNG(0,1,ghs)
												ghs.destscale = ghs.scale*9
											end
										else
											ghs.frame = (s.frame & ~FF_TRANSMASK)|FF_TRANS50
										end
										P_HomingAttack(ghs, t)
										ghs.color = s.color
										ghs.eflags = s.eflags
										ghs.tics = SMSLocalRNG(3,18,ghs)
										ghs.angle = R_PointToAngle2(ghs.x, ghs.y, t.x, t.y)
									end
								end
								
								--Manipulate their speed!
								p.speed = max($, 120<<16)
								p.hms_explosion = 2 --Enemy slaughter cooldown!
								if abs(t.momx) < abs(s.momx/3)
									t.momx = s.momx/3
								end
								if abs(t.momy) < abs(s.momy/3)
									t.momy = s.momy/3
								end
								P_Thrust(t, s.angle, 18*s.scale)
								
								local SfX = P_SpawnMobjFromMobj(t,0,0,0, MT_THOK)
								SfX.flags = MF2_DONTDRAW SfX.tics = 166 SfX.fuse = 166
								SfX.RNG = SMSLocalRNG(0,2, t)
								if SfX.RNG == 1
									S_StartSoundAtVolume(SfX, sfx_brakrx, 50)
									S_StartSoundAtVolume(SfX, sfx_litng4, 255)
									S_StartSoundAtVolume(s, sfx_kc40, 115)
									S_StartSoundAtVolume(s, sfx_rail1, 90)								
								elseif SfX.RNG == 2
									S_StartSound(SfX, sfx_brakrx)
								else
									S_StartSound(SfX, sfx_smscrt)
									S_StartSoundAtVolume(s, sfx_nerf, 75)
								end
								
								P_SetObjectMomZ(t, 10<<16, true)
								P_DamageMobj(t, s, s)
								if t.valid and t.health
									if t.player
										if t.player.powers[pw_invulnerability] --Won't work.
											t.player.powers[pw_invulnerability] = 0
											P_RestoreMusic(t.player)
											P_DamageMobj(t, s, s)
										end
										P_FlashPal(t.player, PAL_NUKE, 4)
										P_DoPlayerPain(t.player)
										P_SetObjectMomZ(t, 13<<16, true)
										P_Thrust(t, R_PointToAngle2(s.x, s.y, t.x, t.y), 20*s.scale)										
									elseif not (t.info.mass == 2006)
										P_KillMobj(t)
									end
								end
							end
						end
					end
					s.hmsspint = nil
				end
			end

			//Want overkill? Here it is, in all it's DBZ-like glory.
			//HMS finds you, knocks you around, stops time, and blows you to hell in a blazing light.
			//This turned out to be one humongous script for a "simple" combo attack...

			//Something about the conversion from XWE to SLADE misalligned these terribly...
			
			if s.starthmscombo and s.hmsspint2 and s.hmsspint2.valid and s.hmsspint2.health and s.hmsspint2.hmscombod
				HMS_GodBreaker(s, p)
			else
				if s.starthmscombo
					s.state = S_PLAY_FALL
					s.flags = $ & ~(MF_NOCLIPTHING|MF_BOUNCE)
					p.powers[pw_ignorelatch] = 0
				end
				s.starthmscombo = 0
				s.hmsspint2 = nil	
				
				--Did input?
				if (p.smsmeleebutton < 2)
				and (p.cmd.buttons & BT_TOSSFLAG) and (p.cmd.buttons & BT_CUSTOM2)
				and not (p.pflags & (PF_STASIS|PF_SLIDING)) and not (s.state == S_HMSBLACKHOLE) 
				and not p.powers[pw_carry] and not p.knucklewaving
			 	 	--Spawn finder object.
				 	local ghs = P_SpawnMobj(s.x+FixedMul(250<<16,cos(s.angle)), s.y+FixedMul(250<<16,sin(s.angle)), s.z-500<<16, MT_SMSECHECK)
				 	if ghs and ghs.valid
					 	ghs.hmsspincheck = true
					 	ghs.hmsspincheck2 = true
					 	ghs.target = s
					 	ghs.height = 1000<<16
					 	ghs.radius = 300<<16
				 	end
				end
				
				if s.hmsspint2
					local t = s.hmsspint2					
					if t.valid and t.health and not t.hmscombod //and t.hmscombod != s)
						if not t.player
						or t.player
						and ((gametyperules & GTR_RINGSLINGER) or s.battlemodsms) 
						and not (G_GametypeHasTeams() and (p.ctfteam == t.player.ctfteam))
							s.starthmscombo = 160
							t.hmscombod = true
							HMS_GodBreaker(s, p)
						end							
					end
				end
		    end 

			//This is HMS' boost-flight.
			//Thank you for joining Hyper Mystic airlines!

			--Let's use this for convenience.
			if p.hmswarpcooldown
				for i = 1,2
					if not ((p.cmd.buttons & BT_WEAPONPREV) and p.hmswarpcooldown == 1) //No constant warping!
						p.hmswarpcooldown = max($-1, 0)
					end
				end
			end
			if (p.hypermysticsonic > 40) //Past the transformation animation first...
			
			//Ok, pay attention, game! When you're HMS in match or CTF, drain rings at x12 speed!
			//If in any other gametype, drain rings at double speed!
			
				if p.hmsthrownnorise
					if not (p.cmd.buttons & BT_TOSSFLAG) and not (p.cmd.buttons & BT_WEAPONPREV)
						p.hmsthrownnorise = false
					end
				end
				if (p.pflags & PF_JUMPED) --Jump effect!
					if not s.hmsjumpgfx
					and not (s.z > s.floorz+27*s.scale+s.momz)
					and (s.momz*P_MobjFlip(s) > 8*s.scale)
						if not p.smsgraphix
							local ghs = P_SpawnMobj(s.x, s.y, s.z-20<<16, MT_HMSWAVEAURA)
							ghs.dustwave = 1
							ghs.sprite = SPR_SMMK
							ghs.frame = 3
							ghs.target = s
							ghs.fuse = 15
							ghs.scale = s.scale
							ghs.destscale = $*2
						end
						A_SMSSTOMPSMOKE(s, 60, MT_SPINDUST, nil, nil, 2<<16)
						A_SMSSTOMPQUAKE(s, 45, 14, FRACUNIT, 0, 0, 0, 0, SKINCOLOR_SUPERGOLD3)
						A_SMSSTOMPQUAKE(s, 80, 18, 2<<16, 0, ANG20, 0, 0, SKINCOLOR_SUPERSILVER4)
						local ghs = P_SpawnGhostMobj(s)
						ghs.sprite = SPR_HMSO //Use the spring frame specifically for this.
						ghs.frame = H|FF_FULLBRIGHT|FF_TRANS50
					end
					s.hmsjumpgfx = true
				else
					s.hmsjumpgfx = false
    			end

				if p.rings and (leveltime % 35 == 0)
					P_GivePlayerRings(p, -1)
				end
				if not SMS_NerfedMode(p) and not s.battlemodsms --In generic Coop, just drain 2x rings for the sake of fun.
				and not (p.hmsrushactive and (gametype == GT_COOP))
					if (leveltime % 35 == 18)
						P_GivePlayerRings(p, -1)
						p.hms_drain = 0
					end
				elseif (p.hms_drain > 2) --In all other gamemodes, drain 12 rings per second.
					if (p.rings > 300) 
					and not (p.hmsrushactive and (gametype == GT_COOP))
						p.rings = 300
					end
					P_GivePlayerRings(p, -1)
					p.hms_drain = 0
				end

				if (p.cmd.buttons & BT_SPIN) //Press spin in midair to boost!
				
					if not P_IsObjectOnGround(s) //If we could use it on the ground, it'd collide with the spindash.
					and not (p.pflags & (PF_STARTDASH))
					and not ((p.cmd.buttons & BT_WEAPONPREV) and (p.speed < 3*s.scale) and (abs(s.momz) < 3*s.scale))
					and not SMS_Locked(s, p)		
						if (s.frame == 1048577) or (s.state == S_PLAY_SPRING)
							s.state = S_PLAY_RUN
						end
						local EXTRATURN = s.angle-( p.cmd.sidemove*(ANG1*2/3) )
						if (p.pflags & PF_ANALOGMODE) --Analog controls.
							local moveang = R_PointToDist2(s.x, s.y, s.x+s.momx, s.y+s.momy)
							local TURNANG = (p.cmd.angleturn<<16)+(R_PointToAngle2(0, 0, p.cmd.forwardmove<<16, -(p.cmd.sidemove<<16)))
							local xadd = P_ReturnThrustX(s, TURNANG, moveang)
							local yadd = P_ReturnThrustY(s, TURNANG, moveang)
							EXTRATURN = R_PointToAngle2(s.x-s.momx,s.y-s.momy, s.x+xadd, s.y+yadd)	
						end	
						
						--Slow airboost!
						if not (p.cmd.buttons & BT_CUSTOM1)
						and not (s.hmsusebuffer and s.hmsusebuffer < 4)
						and not s.hmsdashDOWN
							if not p.hmsdash
								s.hmsspinpass = 0
								s.hmsspinfreeze = true
								s.hmsroflstomped = false
								A_SMSquake(s, 15<<16, 8, 1022, true)
								S_StartSound(s, sfx_hmsfly)
								P_InstaThrust(s, EXTRATURN, (55*s.scale)+35<<16)
								SMS_DustLayers(s, true)
								p.hmsdash = 1
								s.hmsusebuffer = 4
								if not s.airboostroll
									if s.hmsrotateright
										s.hmsrotateright = false
									else
										s.hmsrotateright = true
									end
									s.airboostroll = 9
									s.rollangle = 0
								end
								HMS_RollWaves(s, nil, 11, SKINCOLOR_MYSTICAL2, FRACUNIT-31000, nil, s)
							else
								p.hmsdash = 1
								if (leveltime % 2 == 0)
									P_InstaThrust(s, EXTRATURN, (55*s.scale)+35<<16)
									if not SMS_Graphix(s)
										HMS_airdashGFX(s, p, "prism")
									end
								end
							end
							
						 //Press custom1 WHILE airboosting to----OHGOD!!!(Maybe don't?)	
						 
						else 
							if p.sms_c1 == 1 and s.hmsdashDOWN and (p.cmd.buttons & BT_CUSTOM1)
							or not p.hmsdash
								S_StartSound(s, sfx_hmsfly)
								p.hmsdash = 1
							end
							--Initial dash spawns effects
							if p.hmsdash == 1
								s.hmsspinfreeze = true
								s.hmsspinpass = 0
								s.hmsroflstomped = false
								S_StartSound(s, sfx_smach)
								s.hudboost = 1
								p.hmsdash = 2
								
								if not s.airboostroll
									if s.hmsrotateright
										s.hmsrotateright = false
									else
										s.hmsrotateright = true
									end
									s.airboostroll = 12
									s.rollangle = 0
								end
								if not (p.cmd.buttons & BT_CUSTOM1) //You're using the double-tap method.
									p.sms_autoboosthold = 2
								else						
									s.hmsdashDOWN = 8
								end
								
								s.SMSLASTANGLE = s.angle
								local BOOSTSPEED = (s.HMS_airboostspeed and s.HMS_airboostspeed > p.speed) and s.HMS_airboostspeed or (190*s.scale)+60<<16
								P_InstaThrust(s, EXTRATURN, BOOSTSPEED)
								if (s.HMS_airboostspeed and (s.HMS_airboostspeed > BOOSTSPEED))
									s.HMS_airboostspeed = $+12*s.scale
								else
									s.HMS_airboostspeed = BOOSTSPEED+12*s.scale
								end
								s.HMS_airboostspeedtimer = 24
								A_SMSquake(s, 66<<16, 11, 2022)
								if (s.HMS_airboostspeed and (s.HMS_airboostspeed > (220*s.scale+60<<16)))
									local rvolume = max(3, min(255, FixedInt(s.HMS_airboostspeed/3)))
									S_StartSoundAtVolume(s, sfx_bkpoof, rvolume)
									if (s.HMS_airboostspeed > (640*s.scale+60<<16))
									
										local rvolume2 = max(3, min(255, FixedInt(s.HMS_airboostspeed/7)))
										local SfX = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
										SfX.flags2 = MF2_DONTDRAW SfX.tics = 77 SfX.tics = 77
										S_StartSoundAtVolume(SfX, sfx_bkpoof, rvolume2)
										S_StartSoundAtVolume(SfX, sfx_smscrt, rvolume2/4)
										
										if not S_SoundPlaying(s,sfx_machwb) 
											S_StartSoundAtVolume(s, sfx_machwb, rvolume2)
										end
										
										A_SMSquake(s, 106<<16, 10, 2022)
										
										local ghs = HMS_GigaJetBolt(s, (FRACUNIT-500)+(FixedInt(s.HMS_airboostspeed)*16), 12)
										ghs.tracer = s
										ghs.ditchtracer = 1
										ghs.frame = ($|FF_PAPERSPRITE)+FF_TRANS20
										ghs.color = SKINCOLOR_SUPERSKY5
										ghs.colorized = true
										ghs.GSoffsetX = 69*s.scale
										ghs.GSoffsetY = 69*s.scale
										ghs.GSoffsetZ = 0
										ghs.sttfade = 14
										ghs.destscale = 999<<16										
									end
								end
								
								--FAST airboost!
								local ghs = P_SpawnMobjFromMobj(s, 0,0,0, MT_RADIALBOOST)
								ghs.target = s
								local HMSTRAILTABLE = {SKINCOLOR_SMS3R, SKINCOLOR_ORANGE, SKINCOLOR_RED, SKINCOLOR_RUBY, SKINCOLOR_BLUEBELL, SKINCOLOR_SKY, SKINCOLOR_SMS2R, SKINCOLOR_SMS3R, SKINCOLOR_ORANGE, SKINCOLOR_RED,SKINCOLOR_RUBY}
								local FIRSTCOLOR = 0
								
								for i = 0,4,2
									if i == 0
										ghs = HMS_RollWaves(s, nil, 17, HMSTRAILTABLE[SMS_TimeFrame(7, 1)], FRACUNIT-11000, nil, s)
										ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS30
										ghs.scalespeed = $+(FRACUNIT/9)
									else
										ghs = HMS_RollWaves(s, nil, 17, HMSTRAILTABLE[SMS_TimeFrame(7, 1)+FIRSTCOLOR], FRACUNIT-11000) //,FRACUNIT-7000-(6900*i))
										ghs.momx = s.momx
										ghs.momy = s.momy
										ghs.momz = s.momz
										ghs.frame = $+(FRACUNIT*i)
										ghs.sttroll = $*i
									end
									FIRSTCOLOR = $+1
								end
								if s.SMS_DLtrail == nil
									s.SMS_DLtrail = {timer = 7, colorized = true,
									COLORT_trail = HMSTRAILTABLE,
									COLORT_trailmax = 7}
								end
								
							else --Continued hyperdash (Fast)
							
								if (leveltime % 7 == 0) and not s.SMS_DLtrail
									local ghs = HMS_GigaJetBolt(s, FRACUNIT-31000, 8)
									ghs.tracer = s
									ghs.frame = $+FF_TRANS20
									ghs.sttfade = nil
									ghs.dispoffset = -11
								end
								if not (p.lddiscount == 3 or p.lddiscount == 1)
									s.smspickupCD = 3
									local BOOSTSPEED = (s.HMS_airboostspeed and s.HMS_airboostspeed > (180*s.scale)+50<<16) and s.HMS_airboostspeed or (190*s.scale)+60<<16
									P_InstaThrust(s, EXTRATURN, BOOSTSPEED)
									local HMSTRAILTABLE = {SKINCOLOR_SMS3R, SKINCOLOR_ORANGE, SKINCOLOR_RED, SKINCOLOR_RUBY, SKINCOLOR_BLUEBELL, SKINCOLOR_SKY, SKINCOLOR_SMS2R, SKINCOLOR_SMS3R, SKINCOLOR_SMS5R, SKINCOLOR_PURPLE,SKINCOLOR_LAVENDER}
									local RNGANG = SMSLocalRNG(0,360,s)
									for i = -1,1,2
										local PICKCOLOR = HMSTRAILTABLE[SMSLocalRNG(1,10+i,s)]
										local ghs = HMS_BigBangVortex(s, 10, FRACUNIT, ANGLE_45, Z+5, PICKCOLOR)	
										ghs.rollangle = (RNGANG*ANG1)+(ANGLE_90*i)
										ghs.sttrollangle = ghs.rollangle
										ghs.sttfade = (p.lddiscount == 2) and 8 or 6
										ghs.frame = ($ & ~FF_TRANSMASK)|FF_PAPERSPRITE|FF_TRANS70
										ghs.scalespeed = $+(RNGANG*43)
										ghs.spritexscale = $+(RNGANG*399)
										ghs.spriteyscale = ghs.spritexscale
										ghs.momx = s.momx/2
										ghs.momy = s.momy/2
										ghs.tracer = s
										ghs.spriteyoffset = $+13<<16
										ghs.GSoffsetX = (p.lddiscount == 2) and -2*s.scale or -16*s.scale
										ghs.GSoffsetY = (p.lddiscount == 2) and -2*s.scale or -16*s.scale
										ghs.GSoffsetZ = -(s.height*4/3)-(ghs.spritexscale*7)									
										ghs.ditchtracer = (p.lddiscount == 2) and 5 or 3
									end										
								end								
							end	
							s.hmsmwh = 1
						end
						
						s.smspickupCD = 3
						p.pflags = $ & ~PF_SPINNING
						if (p.pflags & PF_DIRECTIONCHAR)
							s.forcesmsangletimer = 6
							s.forcesmsangle = s.angle
						end
						if (p.speed > 23*s.scale) //When you reach speeds above 250, stick to it.
							local ghs = SMSRSpawnGhost(s)
							if s.hmsspinpass and ghs and ghs.valid and s.hmsspinang != nil
								ghs.angle = s.hmsspinang
							end
						end
				  end
				elseif p.hmsdash
					p.hmsdash = 0
					s.HMS_airboostspeed = nil
				end		

		//Rise skywards in the blink of an eye! Kind of wish I had a better 
		//button for this than "toss flag", a button you'd never use otherwise.
		//I'll make a jump tap alternative for the simpletons, maybe.

			if s.hms_readyriseboost
				s.hms_readyriseboost = $-1
			end
			if s.hms_jumprisen and not p.starthmscombo
				if (abs(s.momz) > 2*s.scale) --Rising fast!				
					if not s.bhlcamtimer or s.bhlcamtimer == 1
						p.camerascale =  FRACUNIT*5/4
						s.bhlcamtimer = 2
					end	
					if SMS_Graphix(s) != 2
						if (leveltime % 4 == 0) 
							A_SMSSTOMPSMOKE(s, SMSLocalRNG(5, 20,s), MT_NIGHTSPARKLE, SMSLocalRNG(1, 75,s)<<16, nil, s.scale*2, SKINCOLOR_SUPERGOLD5)
						end
						SMS_TwirlGFX(s)	
					end			
					
					if s.jumprsmoke and s.jumprsmoke.valid and s.jumprsmoke.health
						s.jumprsmoke.fed = 2
					else
						s.jumprsmoke = P_SpawnMobjFromMobj(s,0,0,0, MT_HMSRISEAURA)
						s.jumprsmoke.initscale = s.scale*3/2
						s.jumprsmoke.target = s
						s.jumprsmoke.fed = 2
					end
					
					if s.hmsspinang != nil and s.hmsspinpass
						local ghs = P_SpawnGhostMobj(s) --Spinning ghosts.
						ghs.colorized = true
						ghs.color = SKINCOLOR_SUPERGOLD3
						ghs.blendmode = AST_ADD
						ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS70
						ghs.rollangle = s.rollangle
						ghs.fuse = 15 ghs.tics = 16
						ghs.scalespeed = FRACUNIT/20
						ghs.destscale = ghs.scalespeed+1					
						ghs.angle = s.hmsspinang
						ghs.spriteyoffset = s.spriteyoffset-26<<16
						ghs.dispoffset = -5
						local ANGLE = (s.momx or s.momy) and R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy) or s.angle
						P_TryMove(ghs, s.x+s.momx+FixedMul(s.scale*3, cos(ANGLE)), s.y+s.momy+FixedMul(s.scale*3, sin(ANGLE)), true)
					end
				end
				if s.hms_jumprisen == 3 --Start of the Hyper Rise Dash up.
				
					if (s.momz*P_MobjFlip(s) > 0)
						A_SMSquake(s,
						max( 10<<16, min(180<<16, s.momz/2) ),
						max( min( 12 , s.momz/(FRACUNIT/12) ), 2)
						)			
						if SMS_Graphix(s) == 0
							if not s.haltthespam
								local ghs = P_SpawnMobjFromMobj(s, 0,0,s.momz/2, MT_HMSNOVAWAVE) 
								ghs.scale = ($*10)/SMSLocalRNG(9,15,s)
								A_SMSSTOMPSMOKE(s, 20, MT_ENERGYBALL, 200)
							end								
							local ghs = SMS_ElectricBody(s, 5, SKINCOLOR_SUPERSKY5)
							ghs.spriteyscale = FRACUNIT+42000
							ghs.spritexscale = FRACUNIT+45000

							ghs = SMS_LightFlash(s, SKINCOLOR_MYSTICAL3, FRACUNIT-27000, 7, Z+3|FF_TRANS30)
							ghs.tracer = s
							ghs.fuse = 6
						end
						SMS_TwirlGFX(s, SKINCOLOR_RED, 11)
						if not (s.SMS_squashtable and s.SMS_squashtable.timer > 2)
							s.spritexscale = FRACUNIT-16000
							s.spriteyscale = FRACUNIT+27100
							s.spriteyoffset = -9<<16
							s.SMS_squashtable = {timer = 3, Xspeed = 6450, Yspeed = 11200, air = true}		
						end
					end

					p.pflags = $|PF_JUMPED & ~(PF_STARTJUMP|PF_SPINNING|PF_THOKKED)
					S_StartSound(s, sfx_kc5b)		
					s.hms_jumprisen = 2
					s.haltthespam = 2		
					
					//Spam the button to rise even faster.
					P_SetObjectMomZ(s, (p.cmd.buttons & BT_TOSSFLAG) and 8<<16 or 11<<16, true)
					
				elseif s.hms_jumprisen
					s.hms_jumprisen = $-1
				end
			end
			--What does the jump button do?
			if (p.cmd.buttons & BT_JUMP)
				if P_IsObjectOnGround(s)
					s.hms_jumphold = 10
					s.hms_readyriseboost = 0
					s.hms_jumprisen = 0
				else
					s.hms_jumphold = s.hms_jumphold and $+1 or 1
					--If HMS runs off a cliff, let him fly again at will. Apply PF_JUMPED!
					if not (p.pflags & (PF_STARTJUMP|PF_JUMPED)) 
					and (p.powers[pw_carry] != CR_ZOOMTUBE)
						p.pflags = $|PF_JUMPED & ~(PF_SPINNING|PF_STARTDASH|PF_SLIDING|PF_STARTJUMP|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SHIELDABILITY|PF_GLIDING|PF_BOUNCING|PF_JUMPDOWN|PF_USEDOWN)
						p.smsdivetimer = 0
					end	
				end
			elseif s.hms_jumphold
				if P_IsObjectOnGround(s)
					s.hms_jumphold = 10
					s.hms_readyriseboost = 0 
					s.hms_jumprisen = 0
				else
					s.hms_jumphold = 0
				end
			end		
			
			if ((p.cmd.buttons & BT_JUMP) or (p.cmd.buttons & BT_TOSSFLAG))
			and not P_IsObjectOnGround(s)
			and not SMS_Locked(s, p)
			and not (p.pflags & (PF_STARTDASH|PF_STASIS))
			
				//Hyper Rise input! Toss flag is more responsive, while jump is simpler for some control layouts.
				if (p.pflags & PF_JUMPED)
				and ((p.cmd.buttons & BT_TOSSFLAG) or not (s.hms_jumphold > 3))
				and not (p.cmd.buttons & BT_CUSTOM2) //No stomping and rising at the same time!
				and not (p.pflags & PF_SLIDING)
				and not p.hmsthrownnorise
				
					if not s.hms_readyriseboost and not (p.cmd.buttons & BT_TOSSFLAG)
						s.hms_readyriseboost = 8
						s.hms_jumphold = 10
						
					elseif s.hms_readyriseboost or (p.cmd.buttons & BT_TOSSFLAG)
					
						s.hms_readyriseboost = (not (p.cmd.buttons & BT_TOSSFLAG)) and 2 or 0
						s.hms_jumphold = (p.cmd.buttons & BT_TOSSFLAG) and 10 or 0
						s.hms_jumprisen = (s.hms_jumprisen) and 2 or 3
						if s.momz and not s.hmsspinfreeze
							s.hmsspinpass = 16
						end
						s.hmgodticket = true
						s.hmsstompsfx = false
						
						if (p.cmd.buttons & BT_TOSSFLAG)
							if not (s.momz*P_MobjFlip(s) >= 42*s.scale) //Don't need to set this if you're already going over 40.
								P_SetObjectMomZ(s, 42<<16)
							end
						elseif not (s.momz*P_MobjFlip(s) >= 48*s.scale)
							P_SetObjectMomZ(s, 48<<16)
						end
					end
				end			
				if (p.cmd.buttons & BT_JUMP) and p.sms_jumphold <= 2
				and not ((p.pflags & PF_STARTJUMP) and (s.momz*P_MobjFlip(s)) > s.scale)
				and not s.hms_jumprisen
				and not (s.momz*P_MobjFlip(s) > 12*s.scale)
					if (s.state == S_PLAY_SPRING) //Recreating the old superfly.
						s.state = S_PLAY_RUN
					end
					p.sms_jumphold = 0
					s.hmsstompsfx = false
					if (p.cmd.buttons & BT_FIRENORMAL)
					and (s.z > s.ceilingz-120*s.scale)
					and (s.floorz < s.ceilingz-300*s.scale) //Not in extremely tight spaces...
						s.momz = 0
					else
						P_SetObjectMomZ(s, 7<<16, false)
					end
					p.pflags = $ & ~PF_STARTJUMP
				end			
			end
		
		--p.hypermysticsonic is still on-going!
			
		//Alongside HMS' instant transmi---I mean instant movement, he can also do a short teleport/
		//a short warp. It checks whether the missile blew up or not and then dashes you there!

			if (s.state != S_HMS_ATOMLAND)
				if p.hmswarpcooldown
					if not s.forceHMSyellanim --Stay in animation...
						if not HMS_Warp(s, p) --Dash-teleport in front of yourself!
							if (s.state == S_HMS_INSTANTMOVE1)
							and (p.cmd.buttons & BT_WEAPONNEXT)
							and not p.hms_instamove
								if s.tics < 3
									s.tics = 4
								end
								if s.anim_duration < 3
									s.anim_duration = 4
								end
								p.hmswarpcooldown = max($,7)
							end
							HMS_InstantMovement(s, p) //Instantly flash to any other player! Works even in match, but with a delay!
						end
					end
				elseif (p.cmd.buttons & BT_WEAPONNEXT)
					if (netgame or splitscreen) --You don't need this anywhere else.
					and not p.objectplacer
						if not (p.pflags & (PF_SPINNING|PF_STARTDASH))
						and (s.state != S_HMS_INSTANTMOVE2) --The warping state.
						and not SMS_Locked(s, p)
							for i = 1,32
								if HMS_InstantMoveCheck(s, p)
									break --
								else 
									p.warpedtoguy = p.warpedtoguy and $+1 or 1 
								end
							end	
							if P_IsObjectOnGround(s)
								s.z = $+(20*s.scale*P_MobjFlip(s))
								P_SetObjectMomZ(s, 6<<16)
							end
							s.state = S_HMS_INSTANTMOVE1
							p.hmswarpcooldown = 7
						end
					end	
				elseif (p.cmd.buttons & BT_WEAPONPREV) and not (p.weaponprevhold > 1)
					HMS_WarpInput(s, p)					
				else
					if s.hmsgcheck
						if P_IsObjectOnGround(s) and (p.pflags & PF_JUMPED)
							p.pflags = $ & ~(PF_JUMPED|PF_JUMPDOWN)
						end
						s.hmsgcheck = nil
					end
				end
			end
			  
			  --godmatch-ticket, floating orbs and sparks.
			  
			if s.hmgodmticket and SMS_Graphix(s) != 2
			 	--Glowing Match Aura effects. Rising particles that are very scary in darkness!
			 	if SMS_Graphix(s) == 0
				local ghs
					--Rising sparkles.
			  		if SMSLocalRNG(0,1,s) == 1
						ghs = P_SpawnMobjFromMobj(s, 
						SMSLocalRNG(-2500, 2500,s)*s.scale,
						SMSLocalRNG(2500, -2501,s)*s.scale,
						SMSLocalRNG( 350, -200, s)*s.scale,
						MT_THOK)
					else				
						ghs = P_SpawnMobjFromMobj(s, 
						SMSLocalRNG(-750, 750,s)*s.scale,
						SMSLocalRNG(750, -751,s)*s.scale,
						SMSLocalRNG(40, -200, s)*s.scale,
						MT_SMSTSPARK)
					end
					if ghs and ghs.valid --Might not be valid because of Death Pits!
						ghs.target = s
						ghs.flags = $|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOBLOCKMAP
						P_SetObjectMomZ(ghs, SMSLocalRNG(2, 6,s)<<16)	
						if (ghs.type == MT_THOK)
							ghs.flags2 = $|MF2_SHADOW	
							ghs.color = SKINCOLOR_WHITE
							ghs.scale = s.scale/2
							ghs.scalespeed = $/12
							ghs.destscale = s.scale*2
							ghs.tics = 80
						else //if (ghs.type == MT_SMSTSPARK)	
							ghs.state = S_SMSTSPARK2
							ghs.color = SMSLocalRNG(SKINCOLOR_WHITE, SKINCOLOR_SUPERGOLD5,s)				
							ghs.scale = s.scale*2
							ghs.destscale = s.scale*(SMSLocalRNG(4, 8, s))
							ghs.tics = 40
						end
					end
				end
				--Pulsing Illusions!
			  	if not ((p.hypermysticsonic % 2) and not SMSLocalRNG(0,3,s)) // and not (p.pflags & PF_STARTDASH)
				and not ((p.cmd.buttons & BT_TOSSFLAG) and (p.speed < 5*s.scale) and P_IsObjectOnGround(s))
				and not s.hmsspinpass
				and not (s.hmsgalaxystorm > 125)
					local ghs = P_SpawnGhostMobj(s)
					ghs.tics = 3
					ghs.scale = s.scale+(SMSLocalRNG(1000, 950,s))
					ghs.flags = $|MF_NOCLIPHEIGHT|MF_NOCLIP
					ghs.momx = s.momx
					ghs.momy = s.momy
					if not (s.hms_jumprisen and (s.z > s.ceilingz-100*s.scale))
						ghs.momz = s.momz
					end
					ghs.scalespeed = $/2+(SMSLocalRNG(0, 3000,s))
					ghs.destscale = s.scale*3
				end	
				s.NoSMSGlow = true
				s.hmgodmticket = false
			end
		end
		if p.spectator
			HMS_UntransformedStats(s, p) --
			p.hypermysticsonic = 0
		end
	elseif p.wasHMS --if not p.hypermysticsonic. Skin check doesn't apply.
		HMS_UntransformedStats(s, p) 
	end	
end, MT_PLAYER)

addHook("MapChange", function()
	for z in players.iterate
		z.hmshascome = nil
	end
end)

//Death handles for SMS and the Mystic Supers
addHook("MobjDeath", function(s, i, so) if not s.player return end local p = s.player
	if s.ibethrownbysmshelp and p.smsgriefw == nil and not p.smsdontgrabme
		p.smsgriefw = 180 --Inform players they can turn off the ability to get grabbed.
	end
	if p.smspickup and (p.smspickup == i or so == p.smspickup) and p.smspickup.valid 
		return true --Can't get killed by what you're holding.(Crushing, usually)	
	end
	if s.skin == "sms"
		if p.hypermysticsonic
			if not (p.pflags & PF_GODMODE) or (p.rings <= 0) or (s.health <= 0)
				HMS_Rewrite(s,p,i,so)
			end return true --
		end
		if s.sdlfhkgsdfjlhkflsjhglkdfjshglsdkjfhgldfjh
			s.sdlfhkgsdfjlhkflsjhglkdfjshglsdkjfhgldfjh = nil return true --
		end
		P_FlashPal(p, PAL_MIXUP, 3)
		S_StartSound(s, sfx_s3k66)
		for d = 0,15
			P_SpawnParaloop(s.x, s.y, s.z+s.momz+s.height*2, 10<<16, 16, MT_NIGHTSPARKLE, d*ANGLE_22h, S_SMSTSPARK1, false)
		end return --
	elseif p.mysticsuper --Lose Mystic Super on death, ofc.
		A_ENDMYSTICSUPER(s) return --
	end
end, MT_PLAYER)

local function RealT(s) if not (s.valid and s.facc) return end --
	local facc,PHASE = s.facc,(s.facc.phase) or 1
	if s.state == S_FACCIOLO2_INTO 
		if not s.DidEnding
			ResetW(s, facc)
		end return --
	elseif PHASE != 1
		facc.health = max($,2)
		if (s.sprite == SPR_MNRV) and ((s.frame & FF_FRAMEMASK) >= 54)
			s.lol = s.lol and $+1 or 1
			if s.lol == 150
				local NoChars = true
				for z in players.iterate
					if z and z.mo and z.mo.health and (z.mo.skin == "aether" or z.mo.skin == "inazuma") and not (z.bot)
						NoChars = false break --
					end
				end
				if NoChars == true
					local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_EXPLODE)
					ghs.tics = 12 ghs.scale = $*5 ghs.dispoffset = 150 S_StartSound(ghs, sfx_pop) 
					S_StartSound(nil, sfx_pop) s.state = S_NULL
					for z in players.iterate P_DoPlayerExit(z) end
				end return --
			end
		else
			if s.target and s.target.skin == "sms" and s.target.player and s.target.player.hypermysticsonic
				if S_MusicName() == "PHASE2" S_ChangeMusic("MAPX7M", true) end
				if (s.target.player.cmd.buttons & BT_CUSTOM3) and (s.target.player.cmd.buttons & BT_TOSSFLAG)
					Silverhorn.Phase2Destruction(m)
				end			
			end
			if s.MovingOn
				s.MovingOn = max($-1,0)
				if not s.MovingOn
					ResetW(s, facc)
					s.fusrodah,s.rollangle,facc.active = nil,0,2 
					if s.cmphtracker 
						if s.cmphtracker.valid
							s.cmphtracker.state = S_NULL
						end s.cmphtracker = nil
					end
					for z in players.iterate if (gamemap==746) break end
						if z.mo and z.mo.valid and (z.mo.y >= -16160<<16 or z.mo.x <= 16736<<16)
							P_SetOrigin(z.mo, 20608<<16, -22016<<16, 5880<<16)
						end
					end
				end return --
			end
		end		
	else
		facc.health = max($,1)
		if (s.z < 5400<<16) or (s.z > 8300<<16)
			s.z = min(8300<<16, max(5400<<16, $))
		end
	end
	
	if s.DidEnding return end --
	
	if ((facc.health<PHASE) or (s.health <= PHASE) or s.fusrodah or s.MovingOn) and facc.active
	and not ( PHASE>=2 and s.sprite == SPR_MNRV and (s.frame & FF_FRAMEMASK)>53 )
		if s.fusrodah
			s.frame = (s.sprite!=SPR_MNRV) and L|FF_FULLBRIGHT or FF_FULLBRIGHT
			P_Thrust(s, R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy), 16<<16)
		end
		for i = 0,4
			local ghs = P_SpawnMobj(0,0,0,MT_THOK) ghs.flags2 = MF2_DONTDRAW
			s.health,facc.health = i+1,i
			if (i!=0) ResetW(s, facc) end
			s.MovingOn = (s.MovingOn == nil) and 50 or s.MovingOn
			P_DamageMobj(s,ghs,ghs,1)
			if (facc.phase >= 2) End(s) end
		end
end	end
local function RealDMG(s,i,so,dmg,dmgtype) if not (s.valid and s.facc) return end --or s.DidEnding 
	local SMS = so and so.skin == "sms" and so.player or i and i.skin == "sms" and i.player
	if SMS
		if SMS.hypermysticsonic
			local ghs = P_SpawnMobjFromMobj(s,0,0,0,MT_BLUECRAWLA)
			if ghs and ghs.valid P_KillMobj(ghs, SMS.mo, SMS.mo) end
			ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_EXPLODE)
			ghs.tics = 9 ghs.scale = $*5 ghs.dispoffset = 150 S_StartSound(ghs, sfx_pop) 
			S_StartSound(nil, sfx_pop) s.state = S_NULL
			for z in players.iterate P_DoPlayerExit(z) end return true --	
		else
			if s.facc.phase == 2
				s.facc.health = max($-(dmg*4), 2)
			else
				s.facc.health = max($-dmg, 1)
			end
		end
	end
end
local function RealD(s,i,so) if not (s.valid and s.facc) return end  --or s.DidEnding 
	if so and so.skin == "sms" or i and i.skin == "sms"
		ResetW(s, s.facc)	
		s.fusrodah = nil
		if s.cmphtracker 
			if s.cmphtracker.valid
				s.cmphtracker.state = S_NULL
			end s.cmphtracker = nil
		end
		if s.facc.phase == 2
			s.facc.health = 2
		else
			s.facc.health = 1
		end
		P_DamageMobj(s, i, so, 1, DMG_ELECTRIC) return true --
	end
end	addHook("MobjDeath",RealD,MT_FACCIOLO_BOSS) addHook("MobjDamage",RealDMG,MT_FACCIOLO_BOSS) addHook("MobjThinker",RealT,MT_FACCIOLO_BOSS)

local function GaxAsteroid(s, planet, star, noroll)
	local t = s.gaxas
	if t and t.valid
		s.gaxas = P_SpawnMobj(s.x+(P_RandomRange(-100, 100)*s.scale), s.y+(P_RandomRange(-100, 100)*s.scale), s.z+(P_RandomRange(-50, 100)*s.scale), MT_HMSGAXA)
		local cframe,hb = P_RandomRange(1,4),t.hitboxspawn
		t.hitboxspawn = P_SpawnMobj(t.x, t.y, t.z, MT_HMSGAXHB)
		hb.gaxhbtarget = t
		hb.oggax = s
		if s.target
			hb.hmstarget = s.target
		end
			
		//What does the universe bring us today?
		
		if star //Star
			hb.radius,hb.height = 120<<16,120<<16
			t.frame = 5|FF_FULLBRIGHT|FF_TRANS30
			t.color = P_RandomRange(SKINCOLOR_SUPERSILVER4, SKINCOLOR_SUPERGOLD5)
			t.scale = s.scale
		
		elseif planet //Planet
			if noroll
				t.noroll = true
			end
			hb.radius,hb.height = 430<<16,430<<16
			if not (s.target.player and s.target.player.smsgraphix == 2)
				local ghs = P_SpawnMobj(s.x, s.y, s.z+P_RandomRange(1, 300)<<16, MT_HMSNOVAWAVE)
				ghs.scale = s.scale/3
				ghs.scalespeed = $*3
				ghs.rollangle = s.rollangle
				ghs.ghs = P_SpawnGhostMobj(ghs)
				ghs.ghs.tics = 4
				ghs.ghs.rollangle = s.rollangle+ANGLE_90
			end
			t.frame = 6|FF_FULLBRIGHT|FF_TRANS10
			S_StartSound(s, sfx_s3k4e)
			t.scale = s.scale*3/P_RandomRange(14,9)
			t.scalespeed = $*3
			t.destscale = $*2
		
			local planetc = P_RandomRange(1,7)
			if planetc < 3
				t.color =  (planetc == 1) and SKINCOLOR_TEAL or SKINCOLOR_LAVENDER
			elseif (planetc < 6)
				t.color = (planetc == 3) and SKINCOLOR_GREY or (planetc == 4) and SKINCOLOR_PERIDOT or SKINCOLOR_PINK
			else
				t.color = (planetc == 6) and SKINCOLOR_AZURE or SKINCOLOR_BLUEBELL
			end
			
		elseif cframe
		
			t.scale = s.scale/10
			t.scalespeed = $*3
			t.destscale = s.scalespeed+1
			hb.radius = 160<<16
			hb.height = 160<<16
			t.frame = cframe|FF_FULLBRIGHT|FF_TRANS10
		end
		
		t.momx = (FixedMul(FixedDiv(s.x-t.x, 450<<16), FixedDiv(132<<16, 3<<16/2)) )/-6
		t.momy = (FixedMul(FixedDiv(s.y-t.y, 450<<16), FixedDiv(132<<16, 3<<16/2)) )/-6
		t.momz = (FixedMul(FixedDiv(s.z-t.z, 450<<16), FixedDiv(132<<16, 3<<16/2)) )/-8
		if s.target
			t.hmstarget = s.target
		end
	end
end

//HMSGALAXYSTORM Mobjs. Tracker, hitbox, asteroids, galaxy
local function GaxKillMobj(s, t)
	t.hmsgaxed = false
	if not t.player
		P_KillMobj(t, s, s.hmstarget)
	elseif t
		if s.hmstarget and s.hmstarget.player
			local p = s.hmstarget.player
			local PNAME = "\x80"+p.name
			if p.ctfteam and G_GametypeHasTeams()
				PNAME = ((p.ctfteam==1) and "\x85" or "\x84")+p.name+"\x80"
			end
			
			local tp = t.player
			local TPNAME = "\x80"+tp.name
			if tp.ctfteam and G_GametypeHasTeams()
				TPNAME = ((tp.ctfteam==1) and "\x85" or "\x84")+tp.name+"\x80"
			end	
			
			if not t.player.rings and not (t.player.powers[pw_shield]
			or t.player.powers[pw_flashing] or t.player.powers[pw_super] or t.player.powers[pw_invulnerability])
				print(PNAME+" spaghettified "+TPNAME+" with the Galaxy Storm!")
			else
				print(PNAME+" engulfed "+TPNAME+" with the Galaxy Storm!")
			end
		end
		P_DamageMobj(t, s, s.hmstarget)
	end
	if s.valid s.state = S_NULL return end//Die, tracker
end

addHook("MobjThinker", function(s)
	if not s.valid return end --
 	if s.gaxedboi and s.gaxedboi.valid
		local t = s.gaxedboi		
			P_SpawnGhostMobj(t)
			if s.oggax and s.oggax.valid
				s.tics = s.oggax.tics
				P_Thrust(t, R_PointToAngle2(t.x, t.y, s.oggax.x, s.oggax.y), 16<<16) 
				P_Thrust(t, R_PointToAngle2(t.x, t.y, s.oggax.x, s.oggax.y)-ANGLE_90+ANG2, 65000)
				if t.player
					t.state = S_PLAY_PAIN
				end
				t.momz = (t.z < (s.oggax.z+550<<16)) and $+2<<16 or $-2<<16
				
				if s.gaxangle == nil
					s.maxlimit = 80
					s.gaxangle = 0
					P_HomingAttack(t, s)
					
					local ghs = P_SpawnMobj(
					t.x+(P_RandomRange(-50,50)*t.scale),
					t.y+(P_RandomRange(-50,50)*t.scale),
					t.z+(P_RandomRange(-10,30)*t.scale),
					MT_BOSSEXPLODE)
					ghs.scale = t.scale*3
					S_StartSound(t, sfx_cybdth)
				else
					s.maxlimit = $-1
					s.gaxangle = $+FixedAngle(30<<16)
					t.angle = s.gaxangle
				end
				
				if ((s.oggax.tics <= 3) or (s.maxlimit < 2)) and t and t.valid 
					GaxKillMobj(s, t) return --
				end
			elseif t and t.valid
				GaxKillMobj(s, t) return --
			end
			if (s.tics <= 3) and t and t.valid
				GaxKillMobj(s, t) return --
			end
	else
		s.state = S_NULL return --
	end
end, MT_HMSGAXT)

addHook("MobjThinker", function(s)
 	if not s.valid return end --
	local t = s.gaxhbtarget
 	if t and t.valid
		s.tics = $+1
		s.momx = t.momx s.momy = t.momy s.momz = t.momz
		P_MoveOrigin(s, t.x, t.y, s.gaxmainhb and t.z-600<<16 or t.z-20<<16)		
	else
		s.state = S_NULL return --
	end
end, MT_HMSGAXHB)

addHook("MobjThinker", function(s)
	if not s.valid return end --
 	if s.gaxroll == nil
		s.gaxroll = P_RandomRange(-14, 14)
		s.gaxab = true
		s.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
	end
	if not s.noroll
  		s.rollangle = $+FixedAngle(s.gaxroll<<16)
	end
	if s.gaxab
		if (s.z < s.floorz-50<<16) or (s.z+50<<16 > s.ceilingz) --Recoil off ceilings/floors.
		s.momz = -$
		s.gaxab = false
			S_StartSound(s, sfx_bexpld)
		end
	end
	if s.tics == 16
		s.frame = ($ & ~FF_TRANSMASK)|FF_TRANS50
	elseif s.tics == 8
		s.frame = ($ & ~FF_TRANSMASK)|FF_TRANS70
	end
end, MT_HMSGAXA)

addHook("MobjThinker", function(s)
	if not s.valid return end
	
	--Initial frame.
	if s.gaxphase1 == nil
		s.gaxphase1 = 30
		if s.target and s.target.valid
			s.burstangle = s.target.angle
			s.burstspeed = 45<<16
			s.gaxstartscale = s.target.scale
			s.scale = s.target.scale*6
			s.scalespeed = $*2
			s.destscale = s.scalespeed+1
		else
			s.state = S_NULL return --
		end
	end
	
	P_InstaThrust(s, s.burstangle, 42<<16)

	--Setup the thrown ball	
	if s.gaxphase1
		local trn = FF_TRANS10*max( 1,min(6,6-(s.gaxphase1-9)/2) ) //Mathematics! 
		s.frame = A|(trn)|FF_FULLBRIGHT		
		s.gaxphase1 = $-1
		s.rollangle = $+FixedAngle(30<<16)
		s.color = (s.gaxphase1%2==0) and P_RandomRange(SKINCOLOR_BLACK, SKINCOLOR_JET) or P_RandomRange(SKINCOLOR_SUPERPURPLE2, SKINCOLOR_SUPERPURPLE5)
		
		if (s.gaxphase1 < 15)
			if not (s.target.player and s.target.player.smsgraphix)
			P_SpawnMobj(s.x+P_RandomRange(-140, 140)<<16, s.y+P_RandomRange(-140, 140)<<16, s.z+P_RandomRange(-100, 200)<<16, MT_SPARK)
				local ghs = P_SpawnGhostMobj(s)
				ghs.rollangle = s.rollangle
				ghs.tics = 4
				if (s.gaxphase1 % 3 == 0)
					local ghs = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_HMSNOVAWAVE)
					ghs.scale = $*3
					ghs.rollerwave = P_RandomRange(-14, 14)<<16
				end
			end
			if s.gaxphase1 == 1 --Magic frame.
			
				--Spawn your hitbox.
				if not s.gaxhitbox and s.target
					local ghs = P_SpawnMobj(s.x, s.y, s.z-610<<16, MT_HMSGAXHB)
					s.gaxhitbox = ghs
					ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
					ghs.gaxmainhb = true	
					ghs.gaxhbtarget = s
					ghs.novatarget = s
					ghs.hmstarget = s.target
					ghs.eflags = s.eflags
					ghs.gaxhbphase2 = true
					if SMS_NerfedMode(p) //As usual, slight range nerf for match.
						ghs.radius = 999<<16
						ghs.height = 999<<16
					else
						ghs.radius = 1220<<16
						ghs.height = 1220<<16
					end
				end

				s.gaxphase2 = 180
				s.gaxphase1 = 0
				s.scalespeed = $/2
				s.frame = H|FF_TRANS50|FF_FULLBRIGHT
				s.scale = s.gaxstartscale*8
				s.destscale = s.scale*2

				if not (s.target.player and s.target.player.smsgraphix)			
					local ghs = P_SpawnMobj(s.x, s.y, s.z+s.height+100<<16, MT_THOK)
					ghs.sprite = SPR_AURA
					ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
					ghs.frame = S|FF_TRANS60
					ghs.color = SKINCOLOR_WHITE
					ghs.scale = s.scale
					ghs.scalespeed = $*2
					ghs.momz = s.momz/2  
					ghs.destscale = $*50	
					ghs.tics = 17
				end

				for nz in players.iterate
					if nz.mo and ( (FixedHypot(nz.mo.x-s.x, nz.mo.y-s.y)) <= 5000<<16)
						A_SMSquake(nz.mo, 40<<16, 57, 800)
						P_FlashPal(nz, PAL_MIXUP, 5)
					end
				end
				
				if not s.aaaa
					local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
					ghs.flags2 = MF2_DONTDRAW ghs.tics = 150
					S_StartSound(ghs, sfx_hmsnob)
					s.aaaa = true
				end	
			end
		elseif (s.gaxphase1 % 5 == 0)
			local ghs = P_SpawnGhostMobj(s)
			ghs.rollangle = s.rollangle
			ghs.tics = 10
		end
		
	//Okay, actual galaxy phase!		

	elseif s.gaxphase2
	
		if not (s.target.player and s.target.player.smsgraphix == 2)
			if (s.gaxphase2 % 5 == 0)
				GaxAsteroid(s, false, true)
				local ghs = P_SpawnGhostMobj(s)
				ghs.rollangle = s.rollangle
				ghs.tics = 42
			end
			if (s.gaxphase2 % 3 == 0)
				GaxAsteroid(s)
			end
			if (s.gaxphase2 % 20 == 0)
				GaxAsteroid(s, true)
				S_StartSound(s, sfx_bkpoof)
			end
		elseif(s.gaxphase2 % 17 == 0)
			GaxAsteroid(s, true, false, true)
			S_StartSound(s, sfx_bkpoof)
		end
		if (s.gaxphase2 == 129)
			local ghs = P_SpawnMobjFromMobj(s, 0,0, s.height+100<<16, MT_THOK)
			ghs.sprite = SPR_AURA
			ghs.frame = S|FF_TRANS70|FF_FULLBRIGHT
			ghs.color = SKINCOLOR_SUPERGOLD4
			ghs.scalespeed = $*2
			ghs.momz = s.momz/2  
			ghs.destscale = $*50	
			ghs.tics = 17
			for z in players.iterate --Shake screen for all nearby players.
				if z.mo and ( (FixedHypot(z.mo.x-s.x, z.mo.y-s.y)) <= 5000<<16)
					A_SMSquake(z.mo, 30<<16, 70, 800)
				end
			end
		end
		if (s.z < s.floorz)
			s.momz = $+29000
		elseif (s.z > s.ceilingz)
			s.momz = $-29000
		end
		s.rollangle = $+FixedAngle(s.gaxphase2*5000)
		s.gaxphase2 = $-1
	end	
end, MT_HMSGAX)