//Let's ditch the A_DualAction crap and use Lua instead.

addHook("MobjThinker", function(s)
	if s and s.target
		if s.aftertrail and s.target
		local t = s.target
			if not (s.sprite == SPR_SMBO and s.tics >= 6)
				if t.thokaurapass >= 7
				s.color = SKINCOLOR_FLAME
				s.frame = B|FF_FULLBRIGHT|TR_TRANS40
				elseif t.thokaurapass >= 5
				s.color = SKINCOLOR_ORANGE
				s.frame = B|FF_FULLBRIGHT|TR_TRANS50				
				elseif t.thokaurapass == 4
					if SMSisyellow(t)
					s.color = SKINCOLOR_GOLD
					else
					s.color = t.color
					end
				s.frame = B|FF_FULLBRIGHT|TR_TRANS70
				elseif t.thokaurapass >= 2
				s.color = t.color
				s.frame = B|FF_FULLBRIGHT|TR_TRANS80
				end
				
				if s.tics == 2
				s.frame = B|TR_TRANS80
				elseif s.tics == 1
				s.frame = B|TR_TRANS90
				end
			end
				
				s.rollangle = $+FixedAngle(s.aftertrail*FRACUNIT)
				s.target.lasttrailra = s.rollangle
		elseif not s.aftertrail
			s.target.thokaurapass = 8
			s.tics = 1
			s.fuse = 1
		end
	end
end, MT_SMSAURATRAIL)

//For drifting, wind, underwater and other sounds, this lets me cut off sounds at any point reliably.

addHook("MobjThinker", function(s)
	if s and s.health and s.master and s.master.valid and (s.master.skin == "sms")
		P_TeleportMove(s, s.master.x, s.master.y, s.master.z)
		if s.smsrbt 
			if not s.fuse
			s.fuse = 110
			end
			if s.master.player.hometrickanim
			s.imfree = true	
			elseif (s.master.player.sms_ringburstfly != s.smsrbt)
				if s.imfree
				elseif s and s.valid
				P_KillMobj(s)
				return
				end
			end
		elseif s.smsmachwb
			s.smsmachwb = $+1
			if not P_IsObjectOnGround(s.master)
				if not s.smsmachwbbonus
					if (s.master.player.speed < 130*FRACUNIT)
					s.smsmachwb = $+40
					s.smsmachwbbonus = true
					end
				end
				if not s.machwbtol2
				s.machwbtol2 = 1
				else
				s.machwbtol2 = $+1
				end
			end
			if not (s.master.player and (s.master.player.speed > 20*FRACUNIT))	
				if not s.machwbtol
				s.machwbtol = 1
				else
				s.machwbtol = $+1
				end
			else
				s.machwbtol = 0
			end
			if (s.machwbtol and (s.machwbtol > 4))
			or (s.smsmachwb > 77)
				if s and s.valid 
				P_KillMobj(s)
				return
				end
			end
		elseif s.smsdrtim != nil
			if not s.smsdrtim
			S_StartSound(s, sfx_smsdr)
			s.smsdrtim = 65 
			else
			s.smsdrtim = $-1
			end
			if not P_IsObjectOnGround(s.master)
			or not s.master.driftsens
			or not ((s.master.state >= S_SMS_BOOST01) and (s.master.state <= S_SMS_BOOST04)) 			
				if s and s.valid 
				P_KillMobj(s)
				return
				end
			end
		elseif s.smsmwtim != nil
			if not s.smsmwtim
			S_StartSoundAtVolume(s, sfx_machw, 10)
			s.smsmwtim = 74
			else
			s.smsmwtim = $-1
			end
			if (s.master.player.speed < 52*FRACUNIT) or (s.master.state == S_PLAY_RUN and (s.master.player.normalspeed < 62*FRACUNIT))
				if s and s.valid 
				P_KillMobj(s)
				return
				end
			end
		elseif s.smsmwhtim != nil
			P_TeleportMove(s, s.master.x-(s.master.momx), s.master.y-(s.master.momy), s.master.z)
			if not s.smsmwhtim
			S_StartSound(s, sfx_machwh)
			s.smsmwhtim = 51
			else
			s.smsmwhtim = $-1
			end
			if not (s.master.player.hmsdash and s.master.player.hmsdash == 2)
				if not (s.master.player.speed >= 137*FRACUNIT)
					if not s.smsmwhtol
					s.smsmwhtol = 1
					else
					s.smsmwhtol = $+1
					end
				end
			else
				s.smsmwhtol = 0	
			end
			if not (s.master.player.hypermysticsonic)
			or (s.smsmwhtol and s.smsmwhtol > 4)
				if s and s.valid 
				P_KillMobj(s)
				return
				end
			end
		elseif s.smsquaketim != nil
			P_TeleportMove(s, s.master.x-(s.master.momx*2), s.master.y-(s.master.momy*2), s.master.z)
			if not s.smsquaketim
				if s.smsquakerefresh
					if P_RandomRange(0,1) //Leveltime is a bad idea here.
					S_StartSound(s, sfx_rocks4)
					end
				S_StartSound(s, sfx_cdfm42) //I dunno why this works, I made a mistake, but it works.
				s.smsquaketim = P_RandomRange(1, 3)
				s.smsquakerefresh = false
				else
					if s and s.valid 
					P_KillMobj(s)
					return
					end
				end
			else
				if (s.smsquaketim > 2) and s.smsquakerefresh
				s.smsquakerefresh = false
				end
			s.smsquaketim = $-1
			end
		end
	elseif s
	P_KillMobj(s)
	return
	end
end, MT_SMSSOUNDOBJ)

addHook("TouchSpecial", function(s, v)
	if (G_PlatformGametype() and not (s.target and s.target.battlemodsms))
	return false //Just despawn flames you walk through.
	end

	//Hurt players when they touch it, the source being HMS.	
	if v and v.player and v.health
	and not (v.player.powers[pw_flashing] or v.player.powers[pw_super] or v.player.powers[pw_shield] == SH_ELEMENTAL)
	and s.target and s.target.player
	and not (v == s.target) //Don't hurt yourself or teammates
	and not (v.player.ctfteam and v.player.ctfteam == s.target.player.ctfteam) 
		if (s.target and s.target.battlemodsms)
		P_DamageMobj(v, s.target, s.target) //Battlemod is an ass
		return true
		else
		P_DamageMobj(v, s, s.target)
		return true
		end
	else
		return true
	end
end, MT_HMSFLAMEREST)

//Is fire a thing underwater? No, it's not.
//Also, let's pass over the target properties to our flamerest.
//That way we can make sure the score system works as it should.

addHook("MobjThinker", function(s)
	if s.target
	and (s.target.skin == "sms" and s.target.player.hypermysticsonic)
		s.creator = s.target
	elseif s.target
	and s.target.target
	and (s.target.target.skin == "sms")
	and (s.target.skin == "sms" and s.target.player.hypermysticsonic)
		s.creator = s.target.target
		s.target = s.target.target
	end
	if (s.state == S_HMSNAPALMFLAME_DIE)
	and s.creator
	s.sf2 = P_SpawnMobj(s.x, s.y, s.z, MT_HMSFLAMEREST)
		if s.creator.valid and s.creator.player and s.creator.playerhypermysticsonic
		s.sf2.scale = s.creator.scale*P_RandomRange(0,3)
		else
		s.sf2.scale = s.creator.scale
		end
	s.sf2.target = s.creator
	s.sf2.eflags = s.creator.eflags
	end
		if (s.eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
		or P_CheckDeathPitCollide(s)
		s.state = S_NULL //Just disappear into nothingness.
		end
end, MT_HMS_NAPALM_FLAMES)

addHook("MobjThinker", function(s)
	if s.valid and not s.svrng
		s.scale = 2*FRACUNIT
		s.color = SKINCOLOR_SILVER
		s.svrng = true
	end
end, MT_SMSSILVERRING)

addHook("MobjThinker", function(s)
	if P_CheckDeathPitCollide(s)
	or (s.eflags & (MFE_TOUCHWATER|MFE_UNDERWATER))
		s.state = S_NULL
	end
end, MT_HMSFLAMEREST)

addHook("MobjThinker", function(s)
	if s and s.twoshot and s.health
		if s.smfltimer == nil
		s.smfltimer = 10
		s.fuse = 500
		end
		if s.smfltimer or (s.smfltimer == 0)
			if not s.twoshot2 //Modify the WaveBeam script to get an X-blast
					if (s.smfltimer > 8)
						P_Thrust(s, s.angle+ANGLE_90, 25355)
					else
						P_Thrust(s, s.angle-ANGLE_90, 25355)
					end
			else
					if (s.smfltimer > 8)
						P_Thrust(s, s.angle-ANGLE_90, 25355)
					else
						P_Thrust(s, s.angle+ANGLE_90, 25355)
					end
			end 
			if not s.smfltimer
			s.smfltimer = 16
				if not s.hsz
				s.hsz = true
				s.destscale = s.scale*3/2
				end
			else
			s.smfltimer = $-1
			end
		end
		if ((s.z+s.momz <= s.floorz) or (s.z+s.momz >= s.ceilingz))
		s.momz = 0
			if not s.turhitsfx
			P_SpawnGhostMobj(s)
			S_StartSound(s, sfx_turhit)
			s.turhitsfx = true
			end
		end
	end
	
	if s and s.mysticflame and s.valid
		if not s.sparkletimer
		s.sparkletimer = 20
		end
		if s.sparkletimer
		s.sparkletimer = $-1
		end
		if (s.sparkletimer >= 10)
		s.magicalsparkleyay = P_SpawnMobj(s.x, s.y, s.z, MT_IVSP)
			if s.magicalsparkleyay and s.magicalsparkleyay.valid
			s.magicalsparkleyay.scale = s.scale
			end
		end

		if not s.alreadygrown
		A_SetScale(s, s.scale+150001, 1)
		s.fuse = 300
		s.alreadygrown = true
		s.scalespeed = $/(5/4)
		end
		if (G_PlatformGametype())
		and (s.state == s.info.deathstate)
			if s.target
			P_RadiusAttack(s, s.target, 180*FRACUNIT)
			else
			P_RadiusAttack(s, s, 180*FRACUNIT)
			end
		end
		if (s.scale > 94000)
			if not s.alreadyspedup1
			and (s.health)
				if s.smspointer and s.smspointer.valid and s.smspointer.health
				s.angle = R_PointToAngle2(s.x, s.y, s.smspointer.x, s.smspointer.y)
				P_InstaThrust(s, s.angle, 70*FRACUNIT)
				S_StartSound(s, sfx_s3k4b)
				S_StartSound(s, sfx_s3k82)
				S_StartSound(s, sfx_fire)
				end
			s.momx = s.momx*5/4
			s.momy = s.momy*5/4 //gradually speed up as you go!
			s.momz = s.momz*5/4
			s.alreadyspedup1 = true
			end
			if s.target and (leveltime % 2 == 0) and (s.scale > 99999) and not (s.state >= S_SMSFIRE3)
			A_SMSSpinFire(s, MT_SMSSPINFIRE, 65357, 0, s.target)
			end
		end

		if (s.scale > 120000)
		and not (s.scale > 150000)
			if (s.state == s.info.deathstate)
			and not s.alreadyblown
				P_NukeEnemies(s, s.target, 120*FRACUNIT)
				s.alreadyblown = true
			end
		end
		if (s.scale > 150000)
			if not s.alreadyspedup3
			and (s.health)
			s.flags2 = $|MF2_EXPLOSION
			s.momx = s.momx*4/3
			s.momy = s.momy*4/3
			s.momz = s.momz*5/3
			s.alreadyspedup3 = true
			end
			P_SpawnGhostMobj(s)
			for p in players.iterate
				if p.mo and p.mo.health and (FixedHypot(FixedHypot(s.x - p.mo.x, s.y - p.mo.y), s.z - p.mo.z) < 106*FRACUNIT)
				P_DamageMobj(p.mo, s, s.target)
				end
			end

			P_SpawnGhostMobj(s)
			if (s.state == s.info.deathstate)
			and not s.alreadyblown
				P_NukeEnemies(s, s.target, 340*FRACUNIT)
				s.alreadyblown = true
				s.state = S_RINGEXPLODE
				A_SMSSTOMPSMOKE(s, 5, MT_SMOKE)
			end
		end
	end
	if s and s.readyforonemoreplant
	s.readyforonemoreplant = $-1
	end
end, MT_SMSFIREBLAST)

//Specifically use Lua to make sure the "target" feature passes over.

addHook("MobjThinker", function(s)
	if s
	and s.target
	//	if (s.target.color <= SKINCOLOR_SUPERGOLD5)
	//	s.color = s.target.color+10
	//	end
		if s.health and not (s.state == S_HMSFIRE3)
			if s.monoroll == nil
			s.monoroll = 1
			s.scale = $*2
			s.destscale = $/2
		//	s.color = SKINCOLOR_SUPERSKY5
			//	if P_RandomRange(0,1)
			//	s.color = P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5)
			//	end
			else
				s.monoroll = $+1
				if (s.monoroll < 11)
				s.rollangle = $+FixedAngle(36*FRACUNIT)
				elseif s.rollangle != 0
				s.rollangle = 0
				end
			end
			if P_RandomRange(0,1)
				if (s.color > SKINCOLOR_SUPERSKY1)
				s.color = $-1
				else
				s.color = SKINCOLOR_SUPERSKY5
				end
			end
			s.rollangle = $+FixedAngle(18*FRACUNIT)
  			if not s.ogtarget and (s.target and (s.target.skin == "sms"))
			s.ogtarget = s.target
			elseif s.ogtarget and (s.target and (s.target.skin != "sms"))
			s.foundyoufaker = s.target
			s.target = s.ogtarget
				if s.foundyoufaker and s.target
				P_DamageMobj(s.foundyoufaker, s, s.target)
				end
				if s and s.valid and s.health
				P_KillMobj(s)
				return
				end
			end
		elseif s.rollangle
		s.rollangle = 0
		end
	 	if s.readyforonemoreplant
		s.readyforonemoreplant = $-1
		end
		if (s.state == S_HMSFIRE3)
		and not s.napalm
			if s.target and ( (FixedHypot(FixedHypot(s.target.x-s.x, s.target.y-s.y), s.target.z-s.z)) < (900*FRACUNIT) )
			A_SMSquake(s.target, 22*FRACUNIT, 3, 200, true)
			end
			s.rollangle = 0
			if not (s.target and s.target.player and s.target.player.smsgraphix and s.target.player.smsgraphix == 2) 
			s.napalmdrop = P_SpawnMobj(s.x, s.y, s.z, MT_HMS_NAPALM_FLAMES)
			s.napalmdrop.target = s.target
			s.napalmdrop.scale = $*P_RandomRange(1, 3)
			end
			s.napalm = true
		end
	end
end, MT_HMSFIREBLAST)

//Let's give the Novablast a few MORE destructive side effects.

addHook("MobjThinker", function(s)
 if s and s.valid
	if not s.novahitbox and s.target
	s.novahitbox = P_SpawnMobj(s.x, s.y, s.z-80*FRACUNIT, MT_HMSNOVABLASTHB)
	s.novahitbox.radius = 340*FRACUNIT
	s.novahitbox.height = 340*FRACUNIT
	s.novahitbox.novatarget = s
	s.novahitbox.hmstarget = s.target
	s.novahitbox.eflags = s.eflags
	elseif s.novahitbox and s.novahitbox.valid
	P_TeleportMove(s.novahitbox, s.x, s.y, s.z-80*FRACUNIT)
	s.novahitbox.tics = 2
	end
	s.gottoexist = s.gottoexist and $+1 or 1

	if (s.gottoexist > 10) and (s.gottoexist % 4 == 0) and not s.nopenopenope
	  if not (s.target.player and s.target.player.smsgraphix)
		s.nbar = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_THOK)
		s.nbar.sprite = SPR_AURA
		if (s.state == S_NOVABLAST)
		s.nbar.frame = S|TR_TRANS60|FF_FULLBRIGHT
		else
		s.nbar.frame = S|TR_TRANS80|FF_FULLBRIGHT
		end
		s.nbar.color = s.color // P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5)
		s.nbar.scale = s.scale*2
		if s.target.sqaang != nil
		s.nbar.rollangle = s.target.sqaang*ANG1
		end
		s.nbar.momx = s.momx*P_RandomRange(-1, 2)/2
		s.nbar.momy = s.momy*P_RandomRange(-1, 2)/2
		s.nbar.momz = s.momz*P_RandomRange(-1, 2)/2
		s.nbar.scalespeed = $*4-P_RandomRange(1, 65534)				  
		s.nbar.destscale = $*50
	  end
	end
 	if s.readyforonemoreplant
	s.readyforonemoreplant = $-1
	end
	if not s.rollangle
	s.rollangle = $+FixedAngle((P_RandomRange(1, 170))*FRACUNIT)
	end
	if (s.state == S_NOVABLAST)
	 	if (s.gottoexist % 3 == 0) and (s.gottoexist > 8) or (s.gottoexist == 2)
			if not (s.target.player and s.target.player.smsgraphix and s.target.player.smsgraphix == 2)
			s.ghs = P_SpawnGhostMobj(s)
			s.ghs.rollangle = s.rollangle+ANGLE_180
			end
		end
	s.rollangle = $-FixedAngle(10*FRACUNIT)
		if s.target and (s.gottoexist < 6)
		s.color = s.target.color
		else
		s.color = P_RandomRange(SKINCOLOR_SUPERSILVER2, SKINCOLOR_SUPERTAN3)
		end
		
		if not s.ogtarget and (s.target and (s.target.skin == "sms"))
		s.ogtarget = s.target
		elseif s.ogtarget and (s.target and (s.target.skin != "sms"))
		s.foundyoufaker = s.target
		s.target = s.ogtarget
			if s.foundyoufaker and s.target
			P_DamageMobj(s.foundyoufaker, s, s.target)
			end
			if s and s.valid and s.health
			P_KillMobj(s)
			return
			end
		end
	else
			if not s.aaaa
			s.aaa = P_SpawnMobj(s.x, s.y, s.z, MT_THOK)
			s.aaa.flags2 = $|MF2_DONTDRAW
			s.aaa.tics = 150
			S_StartSound(s.aaa, sfx_hmsnob)
			s.aaaa = true
			end	
	s.rollangle = $-FixedAngle(3*FRACUNIT)
	s.color = P_RandomRange(SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERSKY5)
		if (s.state == S_NOVAEXPLODE1)
			if s.novahitbox and s.novahitbox.valid
			s.novahitbox.radius = 1201*FRACUNIT
			s.novahitbox.height = 1100*FRACUNIT
			end
			P_StartQuake(11*FRACUNIT, 3)
			if s.target
			P_NukeEnemies(s, s.target, 1100*FRACUNIT)
			end
			if (s.gottoexist < 10)
			s.gottoexist = 0
			s.nopenopenope = true
				if s.target and s.target.player	and s.target.player.sms_flamedelay != nil
				s.target.player.sms_flamedelay = $+1
					if (s.gottoexist < 5)
					s.target.player.sms_flamedelay = $+1
						if (s.gottoexist < 3)
						s.target.player.sms_flamedelay = $+3
						end
					end
				end
			end
		elseif (s.state == S_NOVAEXPLODE3)
		and not s.napalm1
			if s.target and s.target.napalmswitch
				if not (s.target.player and s.target.player.smsgraphix and s.target.player.smsgraphix == 2)
				A_NapalmScatter(s, MT_HMS_NAPALM_FLAMES, 256)
				end
			s.target.napalmswitch = false
			else
			s.target.napalmswitch = true //Maybe when SRB2 uses more than 1 core...
		//	A_SMSSTOMPSMOKE(s, 18, MT_NIGHTSPARKLE, 0, 50*FRACUNIT, 4*FRACUNIT, P_RandomRange(7, 103))
		//	A_SMSSTOMPSMOKE(s, 28, MT_NIGHTSPARKLE, 0, 20*FRACUNIT, 4*FRACUNIT, P_RandomRange(7, 103))
			end
			s.napalm1 = true
			if not s.nopenopenope
			and not (s.target.player and s.target.player.smsgraphix and s.target.player.smsgraphix == 2)
				s.novawaveex = true 
				s.novawave = P_SpawnMobj(s.x, s.y, s.z+s.height/2, MT_HMSNOVAWAVE)
				s.novawave.scale = $*P_RandomRange(2,4)
				s.novawave.novaog = true
				if (leveltime % 3 == 0) and s.novawave and s.novawave.valid
				s.rollangle = ANGLE_90
				s.novawave.color = P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERGOLD5)
				end
				if (leveltime % 2 == 0) and s.novawave and s.novawave.valid
				s.novawave.rollerwave = P_RandomRange(-14, 14)*FRACUNIT
				s.novawave.color = P_RandomRange(SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERGOLD5)
				end
			end
		elseif (s.state == S_NOVAEXPLODE4)
		and not s.napalm2
		A_NapalmScatter(s, MT_HMSFLAMEREST, 512)
		s.napalm2 = true
		end
	end
 end
end, MT_HMSNOVABLAST)

//The wave that comes after a hyper novablast-explosion.

addHook("MobjThinker", function(s)
 if s and s.valid
	if not s.momgio
		if s.rollerwave
		s.rollangle = $+(P_RandomRange(0, 359)*ANG1)
		end
		if not s.color
		s.color = SKINCOLOR_FLAME
		end
		if s.novaog
		s.scalespeed = $*20/P_RandomRange(2,10)
		else
		s.scalespeed = $*2		
		end
		s.destscale = $*25
	s.momgio = true
	end
	if s.followme and s.followme.valid
	P_TeleportMove(s, s.followme.x, s.followme.y, s.followme.z)
	elseif s.followmenoz and s.followmenoz.valid
	P_TeleportMove(s, s.followmenoz.x, s.followmenoz.y, s.z)
	end
	if s.rollerwave != nil
	s.rollangle = $+FixedAngle(s.rollerwave)
	end
 end
end, MT_HMSNOVAWAVE)

//Make it look like the black hole's stationary and growing.

addHook("MobjThinker", function(bkhl)
if not bkhl.target
	A_FindTarget (bkhl, MT_PLAYER, 0)
end
if bkhl.hmsblackholesuction == nil
	bkhl.hmsblackholesuction = true
	bkhl.hmsblackholesuction2 = true
end
   if bkhl.valid
   	bkhl.rollangle = $-FixedAngle(10*FRACUNIT)
	if bkhl.target.player and not (bkhl.target.player.hypermysticsonic or bkhl.target.player.hmsenoughdeath)
	bkhl.state = S_NULL
	return
	end
	if bkhl.target and bkhl.target.valid
	A_CapeChase(bkhl, 0, 0) //Stay on HMS' heels or this'll look awkward.
	end
	if bkhl.valid and bkhl.scale == FRACUNIT
	bkhl.scale = 5*FRACUNIT
	end
	if (G_GametypeHasSpectators())
		for z in players.iterate
			if z.hmsblackhole == nil
			z.hmsblackhole = 0
			end
			if not (z.hypermysticsonic) //Let's not have it affect HMS.
			and (z.mo and z.mo.health) //If they're dead, you can stop killing them.
			and not (z.mo == bkhl.target)
			and not (z.ctfteam and z.ctfteam == bkhl.target.player.ctfteam) 
				if (FixedHypot(FixedHypot(bkhl.x - z.mo.x, bkhl.y - z.mo.y), bkhl.z - z.mo.z) < 1500*FRACUNIT)

				local homiedist2 = FixedHypot(FixedHypot(bkhl.x - z.mo.x, bkhl.y - z.mo.y), bkhl.z - z.mo.z)
				local speedmuller2 = FixedMul(18*FRACUNIT, z.mo.scale)
				z.mo.momx = FixedMul(FixedDiv(bkhl.x - z.mo.x, homiedist2), speedmuller2)
				z.mo.momy = FixedMul(FixedDiv(bkhl.y - z.mo.y, homiedist2), speedmuller2)
				z.mo.momz = FixedMul(FixedDiv(bkhl.z - z.mo.z, homiedist2), speedmuller2)
					if (FixedHypot(FixedHypot(bkhl.x - z.mo.x, bkhl.y - z.mo.y), bkhl.z - z.mo.z) < 140*FRACUNIT)
					and not (z.ctfteam and bkhl.target.player.ctfteam == z.ctfteam) 
					P_PlayerFlagBurst(z)
					P_KillMobj(z.mo, bkhl, bkhl)
					P_AddPlayerScore(bkhl.target.player, 100)
                        		print(bkhl.target.player.name+" sucked "+z.name+" into the black void! There were no survivors.")
					end
				end
			end
		end
	end
	if bkhl.valid and (bkhl.hmsblackholesuction or ((bkhl.hmsblackholesuction2) and (bkhl.state == S_BLACKHOLE5)))
	bkhl.hmsblackholesuction = false
	    for m in mobjs.iterate(mobjs) //Only check twice, let the tracker do the rest.
		if (m.flags & (MF_ENEMY|MF_BOSS))
		and not m.bkhltracked
			if (FixedHypot(FixedHypot(bkhl.x - m.x, bkhl.y - m.y), bkhl.z - m.z) < 4300*FRACUNIT)
			bkhl.bkhltracker = P_SpawnMobj(m.x, m.y, m.z, MT_CMPHTRACKER)
			bkhl.bkhltracker.bkhl = true
			bkhl.bkhltracker.target = m
			bkhl.bkhltracker.tracer = bkhl.target
				if not bkhl.hmsblackholesuction
				bkhl.hmsblackholesuction2 = false
				end
			end
		end
	    end
	end
   end
end, MT_HMSBLACKHOLE)

addHook("MobjThinker", function(s)
	if s.valid
	P_SetObjectMomZ(s, 95777)
		if (s.tics > 20)
		s.tics = 18
		end
		if (s.tics < 6)
		s.flags2 = $|MF2_SHADOW
		s.scalespeed = FRACUNIT/200
		A_SetScale(s, 3*FRACUNIT, 1)
		end
	end
end, MT_SMSSTEAM)

//Also, the sign fucks up.
//Let's replace it's state with this one.

/* addHook("MobjThinker", function(s)
	if (s.tics == -1)
	and (s.target and s.target.skin == "sms")
	and ((s.target.player and (s.target.player.skincolor == SKINCOLOR_YELLOW)) or (s.target.color == 0) or (s.target.color > 77 and s.target.color < 83) )
		s.moveitman = P_SpawnMobj(s.tracer.x, s.tracer.y, s.tracer.z,  MT_HMSWAVEAURA)
		s.moveitman.state = S_SMSYELLOWSIGN
	//	S_StartSound(s.moveitman, sfx_s3k66)
		for d = 0,15
			P_SpawnParaloop(s.x, s.y, s.z+FixedMul(20*FRACUNIT, s.scale), 10*FRACUNIT, 16, MT_NIGHTSPARKLE, d*ANGLE_22h, S_SMSTSPARK1, false)
		end
		if s.tracer and s.tracer.valid
		s.tracer.flags2 = $|MF2_DONTDRAW
		end
		if s and s.valid
		s.flags2 = $|MF2_DONTDRAW
		return
		end
	end
end, MT_SIGN) */

//Minor effect for spindash smear.

/* addHook("MobjThinker", function(s)
	if s and s.valid and not s.monogr and s.sector and s.sector.subsector
		for fof in s.sector.subsector.ffloors() //Gotta do this because SRB2 is trash at rendering scaling objects over FOFs.
			if ((fof.flags & FF_EXISTS)
			and (s.z >= fof.topheight))
			s.nopefofhere = true
			end
		end
		if not s.nopefofhere
			P_SetObjectMomZ(s, 72246, true) //Exact number we need to negate the "sinking" effect of a half-speed destscale.
			s.scale = $*8/7
			s.scalespeed = $/2
			s.destscale = $/4
		end
		s.monogr = true
	end
end, MT_SMSBLINDDASH) */

//SMS' blinddash charge aura has some changes to the regular thok/spin auras. It grows over time.
//It also slowly creeps downwards to give the illusion it's truely stationary as it grows. Spooky.

addHook("MobjThinker", function(s)
		if s.valid
		and s.target
			if s.target.player.hypermysticsonic
			s.destscale = FixedMul(15*FRACUNIT/3, s.target.scale) 
			s.scalespeed = FixedMul(7500, s.target.scale)
			P_SetObjectMomZ(s, FixedMul(-54036, s.target.scale))
			else
			s.destscale = FixedMul(5*FRACUNIT/3, s.target.scale) 
			s.scalespeed = FixedMul(2500, s.target.scale)
			P_SetObjectMomZ(s, FixedMul(-18012, s.target.scale))
			end
		end
end, MT_SMSBLINDDASHCHARGE)

//Same with the air and groundboost shockwaves.

addHook("MobjThinker", function(s)
	if s.valid
		if s.color == 0
		s.color = SKINCOLOR_BONE
		end
		if s.tracer
			if s.color == SKINCOLOR_BONE
				if (s.tracer.color == 0)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERGOLD4)
				else
				A_ChangeColorAbsolute(s, 0, s.tracer.color)
				end
			end
			if (s.state == S_SMSAIRBOOST1) and not (s.scale == s.tracer.scale)
			s.scale = s.tracer.scale
			end
		end
	end
end, MT_SMSAIRBOOST)

addHook("MobjThinker", function(s)
	if s.valid
		if s.color == 0
		s.color = SKINCOLOR_SUPERSILVER5
		end
		if s.tracer and s.tracer.valid
			if not s.prism and (s.color == SKINCOLOR_SUPERSILVER5)
				if (s.tracer.color == 0)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERGOLD3)
				else
				A_ChangeColorAbsolute(s, 0, s.tracer.color)
				end
			elseif s.prism
				s.prismno = P_RandomRange(2, 9)
				if (s.prismno < 4)
				s.color = SKINCOLOR_BONE
				elseif (s.prismno == 4)
				s.color = SKINCOLOR_EMERALD
				elseif (s.prismno == 5)
				s.color = SKINCOLOR_BLUE
				elseif (s.prismno == 6)
				s.color = SKINCOLOR_CYAN
				elseif (s.prismno == 7)
				s.color = SKINCOLOR_PURPLE
				elseif (s.prismno == 8)
				s.color = SKINCOLOR_RED
				else
				s.color = SKINCOLOR_ORANGE
				end
			end
			if (s.state == S_SMSGROUNDBOOST) and not s.done and (s.smsgbs or not (s.scale == s.tracer.scale))
				if s.smsgbs
				 	if (s.smsgbs < 3)
					s.scale = s.tracer.scale*2/3
				 	elseif (s.smsgbs < 6)					
					s.scale = s.tracer.scale				
					elseif (s.smsgbs < 10)
					s.scale = s.tracer.scale*4/5
					s.done = true
					elseif (s.smsgbs < 12)
					s.scale = s.tracer.scale*2/3
					s.frame = A|TR_TRANS50
					elseif (s.smsgbs > 11)
					s.scale = s.tracer.scale/P_RandomRange(2,3)
					s.frame = A|TR_TRANS70
					s.done = true
					end
					s.destscale = 10
					s.momz = $+(32354)*(P_MobjFlip(s.tracer))
				else
				s.scale = s.tracer.scale
				s.done = true
				end
			end
			if not s.gogofade
			s.gogofade = P_RandomRange(1, 4)
			s.scale = ($/3)*s.gogofade
				if (s.gogofade <= 2) and s.tracer
				P_TeleportMove(s, s.x, s.y, s.z+(40*FRACUNIT*(P_MobjFlip(s.tracer))))
				end
			end

		end
	end
end, MT_SMSGROUNDBOOST)

//The electricity spawner is unique in the way it never spawns the same patterns.
//We'll also make it do some interesting things depending on what happens.

addHook("MobjThinker", function(s)
if not (s.target and s.target.player and s.target.skin == "sms")
A_FindTarget(s, MT_PLAYER, 0)
end
	if s.valid and s.target and s.target.player
local t = s.target
local tp = s.target.player
		if s.dustwave
			if s.dustwavet 
				if (s.dustwave % 7 == 0)
				s.frame = $+1
				end
			elseif (s.dustwave % 3 == 0)
			s.frame = $+1
			end
			s.frame = $|TR_TRANS20
			s.tics = $+1
			s.dustwave = $+1
			return
		elseif s.dustwave2
			if (s.dustwave2 % 2 == 0)
			s.frame = $+1
			end
			if (s.fuse > 20)
			s.frame = $|TR_TRANS20|FF_PAPERSPRITE
			elseif (s.fuse < 18)
			s.frame = $|TR_TRANS40|FF_PAPERSPRITE
			elseif (s.fuse < 12)
			s.frame = $|TR_TRANS60|FF_PAPERSPRITE
			elseif (s.fuse < 8)
			s.frame = $|TR_TRANS80|FF_PAPERSPRITE
			elseif (s.fuse < 4)
			s.frame = $|TR_TRANS90|FF_PAPERSPRITE
			end
			s.tics = $+1
			s.dustwave2 = $+1
			return
		elseif (s.state == S_HMSWAVEAURAG) //Ground sparkle. Is somewhat special compared to the rest.
			P_InstaThrust(s, R_PointToAngle2(t.x, t.y, s.x, s.y), 20*FRACUNIT)
		//	s.gmj = P_SpawnGhostMobj(s) -- Too intensive for no reason.
		//	s.gmj.momx = s.momx/2*-1
		//	s.gmj.momy = s.momy/2*-1
		//	s.gmj.tics = 4 
		//	s.gmj.scale = $*10/P_RandomRange(5, 20)
			if not (s.frame == P|FF_FULLBRIGHT|TR_TRANS40)
			s.frame = $+1
			end
			return
		end
		if (tp.elauracolors)
			if (tp.elauracolors > 0 and tp.elauracolors < 20)
			s.color = SKINCOLOR_SUPERSILVER3 //Pure white
			end
			if (tp.elauracolors >= 20 and tp.elauracolors < 40)
			s.color = SKINCOLOR_BONE
			end
			if (tp.elauracolors >= 40 and tp.elauracolors < 60)
			s.color = SKINCOLOR_WAVE 
			end
			if (tp.elauracolors >= 60 and tp.elauracolors < 80)
			s.color = SKINCOLOR_TEAL
			end
			if (tp.elauracolors >= 80 and tp.elauracolors < 100)
			s.color = SKINCOLOR_CYAN
			end
			if (tp.elauracolors >= 100 and tp.elauracolors < 120)
			s.color = SKINCOLOR_GREEN //To green
			end
			if (tp.elauracolors >= 120 and tp.elauracolors < 140)
			s.color = SKINCOLOR_PERIDOT
			end
			if (tp.elauracolors >= 140 and tp.elauracolors < 160)
			s.color = SKINCOLOR_EMERALD
			end
			if (tp.elauracolors >= 160 and tp.elauracolors < 180)
			s.color = SKINCOLOR_LIME 
			end
			if (tp.elauracolors >= 180 and tp.elauracolors < 200)
			s.color = SKINCOLOR_GOLD
			end
			if (tp.elauracolors >= 200 and tp.elauracolors < 220)
			s.color = SKINCOLOR_YELLOW
			end
			if (tp.elauracolors >= 220 and tp.elauracolors < 240)
			s.color = SKINCOLOR_SANDY 
			end
			if (tp.elauracolors >= 240 and tp.elauracolors < 260)
			s.color = SKINCOLOR_RED
			end
			if (tp.elauracolors >= 260 and tp.elauracolors < 281)
			s.color = SKINCOLOR_PEACHY
			end
		end
		if (s.state == S_HMSELAURA1) //Tiny upwards spark
		or (s.state == S_HMSELAURA1A)
			s.destscale = FixedMul(2*FRACUNIT, t.scale) 
			s.scalespeed = FixedMul(1500, t.scale)
			if (tp.pflags & PF_STARTDASH)
			P_TeleportMove(s, s.x, s.y, s.z-10)
			end
		end
		if (s.state == S_HMSELAURA2) //Tiny middle spark
		or (s.state == S_HMSELAURA2A)
			s.destscale = FixedMul(2*FRACUNIT, t.scale) 
			s.scalespeed = FixedMul(2300, t.scale)
			P_SetObjectMomZ(s, FixedMul(-9001, t.scale))
			if (tp.pflags & PF_STARTDASH)
			P_TeleportMove(s, s.x, s.y, s.z-10)
			end
		end
		if (s.state == S_HMSELAURA3) //Tiny westward spark
		or (s.state == S_HMSELAURA3A)
			s.destscale = FixedMul(2*FRACUNIT, t.scale) 
			s.scalespeed = FixedMul(2100, t.scale)
			P_SetObjectMomZ(s, FixedMul(-13279, t.scale))
			s.momx = (s.x-t.x)/16
			s.momy = (s.y-t.y)/16
			if (tp.pflags & PF_STARTDASH)
			P_TeleportMove(s, s.x, s.y, s.z-10)
			end
		end
		if (s.state == S_HMSELAURA4) //Tiny eastward spark
		or (s.state == S_HMSELAURA4A)
			s.destscale = FixedMul(2*FRACUNIT, t.scale) 
			s.scalespeed = FixedMul(1800, t.scale)
			P_SetObjectMomZ(s, FixedMul(-38551, t.scale))
			s.momx = (s.x-t.x)/16
			s.momy = (s.y-t.y)/16
		end
		if ((s.state == S_HMSELAURA5)
		or (s.state == S_HMSELAURA5A)
		or (s.state == S_HMSELAURA5B))
		P_SetObjectMomZ(s, FixedMul(45000, t.scale))
			if not (s.state5)
			A_OverlayThink (s, 0, FixedMul(-32*FRACUNIT, t.scale))
			s.state5 = 1
			else
			P_InstaThrust(s, s.angle, 0)
			end
			if (tp.pflags & PF_STARTDASH)
			P_TeleportMove(s, s.x, s.y, s.z-10)
			end
		end
		if (s.state == S_HMSELAURA5)
			s.destscale = FixedMul(115535, t.scale) 
			s.scalespeed = FixedMul(2900, t.scale)
			if (tp.speed > 9*FRACUNIT)
			s.state = S_HMSELAURA5B
			end
		end
		if (s.state == S_HMSELAURA5A)
			s.destscale = FixedMul(40000, t.scale) 
			s.scalespeed = FixedMul(10000, t.scale)
		end
		if (s.state == S_HMSELAURA5B)
			s.destscale = FixedMul(FRACUNIT*2, t.scale) 
			s.scalespeed = FixedMul(4000, t.scale)
		end

		if (s.state == S_HMSELAURA6)
			s.destscale = FixedMul(FRACUNIT*2, t.scale) 
			s.scalespeed = FixedMul(500, t.scale)
			if not (s.state6)
				A_OverlayThink (s, 0, 0)
				s.state6 = 1
			else
			P_InstaThrust(s, s.angle, 0)
			s.momz = 0
			end
		end
		if (s.state == S_HMSELAURA6B)
			s.destscale = FixedMul(FRACUNIT*2, t.scale) 
			s.scalespeed = FixedMul(2600, t.scale)
		end
	end
end, MT_HMSWAVEAURA)

//CEZ3 Eggman tends to get stuck in painframes forever if you look at him funny. Hotfix here.

addHook("MobjThinker", function(s)
	if s and s.valid and s.health
		if (s.flags2 & MF2_FRET)
			if s.fretfailsafe == nil
			s.fretfailsafe = 1
			else
			s.fretfailsafe = $+1
				if (s.fretfailsafe > 180)
				s.fretfailsafe = 0
				s.flags2 = $ & ~MF2_FRET
				end
			end
		elseif s.fretfailsafe
			s.fretfailsafe = 0
		end
	end
end, MT_EGGMOBILE4)

//HMS' Rising Aura

addHook("MobjThinker", function(s)
	if s and s.valid
		if s.fed
		s.fed = $-1
			if s.initscale
			s.scale = s.initscale*10/P_RandomRange(5, 9)
			end
			if s.target
			s.momy = s.target.momy
			s.momx = s.target.momx
			if (s.target.momz > -2*FRACUNIT and s.target.momz < 2*FRACUNIT)
				if s and s.valid and s.health
				P_KillMobj(s)
				return
				end
			else
			s.ghostaura = P_SpawnGhostMobj(s)
			s.ghostaura.rollangle = s.rollangle
			s.ghostaura.destscale = 9
			s.ghostaura.scalespeed = $/3
			s.ghostaura.momx = s.momx/2
			s.ghostaura.momy = s.momy/2
			s.ghostaura.tics = 5
			s.ghostaura.momz = $-10*FRACUNIT*P_MobjFlip(s)
			end
			if (s.scale >= s.initscale*10/7) 
			P_TeleportMove(s, s.target.x-s.target.momx, s.target.y-s.target.momy, s.target.z-(50*FRACUNIT)*P_MobjFlip(s.target))
			else
			P_TeleportMove(s, s.target.x-s.target.momx, s.target.y-s.target.momy, s.target.z)
			end
				if (s.target.eflags & MFE_VERTICALFLIP)
				s.z = $-FixedMul(29*FRACUNIT, s.target.scale)
				end
			s.color = s.target.color
			end
		elseif s.fed != nil and s.fed <= 0
			if s and s.valid and s.health
			P_KillMobj(s)
			return
			end
		end
	end
end, MT_HMSRISEAURA)

//Huh. This is a good example of how to take the difficult route.
//Well, SMSreborn is my first project using Lua...

addHook("TouchSpecial", function(pwsh, s)
		if s and s.player 
		and not ((s.skin == "sms") or (s.skin == "samus"))
	local p = s.player
			if (p.pflags & PF_JUMPED) and p.readyforpowershare //Only work when jumping
			and (p.cmd.buttons & BT_CUSTOM3)
		//	and (p.speed < 7*FRACUNIT) //Slow down!
				if (p.rings > 49)
				and not p.powers[pw_super] and not p.mysticsuper //Not when you're ALREADY super!
					A_STARTMYSTICSUPER(s)
					return true
				end
			end
			if not p.powers[pw_super] and not p.mysticsuper
				if not s.sms_auradelay
				s.sms_auradelay = 16
				P_SpawnMobj(s.x, s.y, s.z, MT_SMSPOWERAURA)
				end
				s.ssxaticket = true
				p.readyforpowershare = 18
				return true
			end
		else
			return true
		end
end, MT_POWERSHARE)

//If the poweraura is the default color, become white.

addHook("MobjThinker", function(s)
A_OverlayThink(s, 0, 0) //Don't lag behind!
		if s.valid //Make sure it's valid, incase someone dies.
			if s.color == 0
			A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER3)
			end
			if s.target and s.target.player
				if s.target.player.hypermysticsonic
				A_ChangeColorAbsolute(s, 0, s.target.color)
				elseif SMSisyellow(s)
				A_ChangeColorAbsolute(s, 0, SKINCOLOR_SUPERSILVER3)
				end
			end
		end
end, MT_SMSPOWERAURA)

addHook("MobjThinker", function(s)
		if s.valid
			if (s.tics < 4)
				if (s.tics == 3)
				s.frame = $ & ~TR_TRANS10 & ~TR_TRANS30 //Someone will read this and yell at me, I just know it. ;~;
				s.frame = $|TR_TRANS50
				elseif (s.tics == 2)
				s.frame = $ & ~TR_TRANS10 & ~TR_TRANS30 & ~TR_TRANS50
				s.frame = $|TR_TRANS70
				elseif (s.tics == 1)
				s.frame = $ & ~TR_TRANS10 & ~TR_TRANS30 & ~TR_TRANS50 & ~TR_TRANS70
				s.frame = $|TR_TRANS80
				end
			elseif s.mcd 
				if s.mcd == 1
				s.frame = $ & ~TR_TRANS10 & ~TR_TRANS30 & ~TR_TRANS40
				s.mcd = 0
				end
			s.mcd = $-1
			end
		end
end, MT_SSXA)

//We need to do an extra check to see if we're in a "projectile-only" wall, 
//or hit an impassable linedef which projectiles apparently just pass through normally.

addHook("MobjThinker", function(s)
		if s and s.valid and (s.state == S_SMSWALLJUMP4)
				if s.target and s.target.player and s.target.health
					if not (P_CheckPosition(s.target, s.x, s.y)) //Player blocked?
						P_KillMobj(s) //Then walljump.
						return
					end
				end
		local sectorz = R_PointInSubsector(s.x, s.y).sector 
			for fof in sectorz.ffloors()
				if (fof.flags & FF_EXISTS) and (fof.flags & FF_BLOCKPLAYER) //If it blocks the player, it blocks you too!
				and not (s.z > fof.topheight)
				and not (s.z+s.height < fof.bottomheight)
				P_KillMobj(s)
				return
				end
			end
		end
end, MT_SMSWALLJUMP)

//The leading cause of military death in the USA is caused by reflected
//weapon fire from HMS, cleverly dubbed Revenge Missiles.
//The more you know~

addHook("MobjThinker", function(rvg)
	if rvg.target and rvg.target.valid
		if rvg.target.disappeartimer
			rvg.target.disappeartimer = rvg.target.disappeartimer-1
		elseif rvg.target.valid
			rvg.target.state = S_NULL
	  		rvg.state = S_NULL
	  		return
		end
		if not (rvg.target.state == rvg.target.info.deathstate)
		and not (rvg.target.state == rvg.target.info.xdeathstate)
			if rvg.target and not rvg.target.health
	  		rvg.target.state = S_BOSSEXPLODE
	  		rvg.target.scale = $+200000
			S_StartSound(rvg.target, sfx_brakrx)
	  		rvg.state = S_NULL
	  		return
			end
			if rvg.target.health and rvg.target.valid
				if rvg.target.boomerangtarget
				and rvg.target.boomerangtarget.valid
				and rvg.target.boomerangtarget.health
				rvg.target.angle = R_PointToAngle2(rvg.target.x, rvg.target.y, rvg.target.boomerangtarget.x, rvg.target.boomerangtarget.y)
				rvg.target.thokspawner = P_SpawnMobj(rvg.target.x, rvg.target.y, rvg.target.z, MT_THOK)
				rvg.target.thokspawner.color = 1
				rvg.target.thokspawner.flags2 = $|MF2_SHADOW
				local homiedist = FixedHypot(FixedHypot(rvg.target.boomerangtarget.x - rvg.target.x, rvg.target.boomerangtarget.y - rvg.target.y), rvg.target.boomerangtarget.z - rvg.target.z)
				local speedmuller = FixedMul(90*FRACUNIT, rvg.target.scale)

				if (homiedist < 1)
				homiedist = 1 //What are you TAAAALKING about I reused code? I have no ideaaa what you mean.
				end
				rvg.target.momx = FixedMul(FixedDiv(rvg.target.boomerangtarget.x - rvg.target.x, homiedist), speedmuller)
				rvg.target.momy = FixedMul(FixedDiv(rvg.target.boomerangtarget.y - rvg.target.y, homiedist), speedmuller)
				rvg.target.momz = FixedMul(FixedDiv(rvg.target.boomerangtarget.z - rvg.target.z, homiedist), speedmuller)
				end
			end 
		else
	  		rvg.target.state = S_BOSSEXPLODE
	  		rvg.target.scale = $+200000
			S_StartSound(rvg.target, sfx_brakrx)
	  		rvg.state = S_NULL
			return
		end
	end
end, MT_RVGMISSILE)

//Shoot off sparks that explode into rising lightning upon contact with walls!

addHook("MobjThinker", function(s)
	if s and s.valid
	  if s.color == 0
	  s.color = SKINCOLOR_SKY
	  end
	  if s.started
	 	s.lifetime = $+1
			if (s.lifetime > 3)
			s.flags = $ & ~MF_NOCLIPHEIGHT
			end
		s.frame = (P_RandomRange(0, 3))|FF_FULLBRIGHT|TR_TRANS20
	 	s.scale = s.started*10/P_RandomRange(4,11)
		if P_IsObjectOnGround(s) //Hop over the ground a little.
		P_SetObjectMomZ(s, 2*FRACUNIT, true)
		end
	/*	if s.immunityfromboom
		s.immunityfromboom = $-1
			if s.immunityfromboom == 1
			s.flags = $ & ~MF_NOGRAVITY & ~MF_NOCLIPHEIGHT
			end
		end */
		if (s.momx < 0)
		s.lmomx = s.momx*-1
		else
		s.lmomx = s.momx
		end
		if (s.momy < 0)
		s.lmomy = s.momy*-1
		else
		s.lmomy = s.momy
		end
		if (leveltime % 2 == 0)
		s.eg = P_SpawnGhostMobj(s)
		s.eg.momx = s.momx*-P_RandomRange(1,4)
		s.eg.momy = s.momy*-P_RandomRange(1,4)
		s.eg.scale = s.scale*10/P_RandomRange(2, 15)
		s.eg.tics = P_RandomRange(3, 6)
		end
		s.momtotal = s.lmomy+s.lmomx
		if (s.momtotal < FRACUNIT) or (s.fuse <= 2) //Too slow, now DIE
			if ((s.lifetime and (s.lifetime < 4)) and s.immunityfromboom == nil) and not (s.fuse and (s.fuse <= 2))
			/*	s.immunityfromboom = 15
				s.flags = $|MF_NOGRAVITY|MF_NOCLIPHEIGHT
				s.momz = 0
				if s.target
				P_InstaThrust(s, R_PointToAngle2(s.target.x, s.target.y, s.x, s.y), 23*FRACUNIT)
				end */
			elseif not s.immunityfromboom
				S_StartSound(s, sfx_s3ka6) //Fizzle out sound	
				if not (s.target and s.target.player and s.target.player.smsgraphix)
					s.newl = P_SpawnMobj(s.x, s.y, s.z, MT_HMSLIGHTNING2)
						if (s.lifetime > 9)
						s.newl.expsfx = true
						end
					s.newl.target = s.target
					s.newl.eflags = s.eflags
					s.newl.color = s.color
				end
				
				if s and s.valid
				P_KillMobj(s)
				return
				end
			end
		end
	  else
	  s.lifetime = 1
	  s.fuse = 39
	  s.started = s.scale
	  end
	end
end, MT_HMSLIGHTNING1)

//Second lighting effect. Slowly vanish into thin air.

addHook("MobjThinker", function(s)
	if s and s.valid
	//	if s.target and s.target.valid and s.target.color
	//	s.color = s.target.color
	//	end
		if not s.ltimer
		s.ltimer = 1
			if P_RandomRange(0,1) and not s.silentl and not s.color == SKINCOLOR_JET
			S_StartSound(s, sfx_kc4d) //Burst out sound
			end
			if s.expsfx and not s.silentl
				if P_RandomRange(0,1)
				S_StartSound(s, sfx_cdfm55) //Possibly obnoxious bzzzt
				else
				S_StartSound(s, sfx_s3k78) //Possibly even more obnoxious PPSZZZZT bzzzt
				end
			S_StartSound(s, sfx_s3k45) //Shield jump sound, possibly too obvious.
			s.expsfx = false
			end
		s.scale = $*2
			if s.growx2
			s.color = SKINCOLOR_RED
			s.destscale = $*15
			s.scalespeed = $*2
			else
				if s.color == 0
				s.color = SKINCOLOR_SKY
				s.scalespeed = $/2
				end
			s.destscale = $*5
			end
		P_SetObjectMomZ(s, 9999, true)
		else
		s.ltimer = $+1
			if s.followsms and s.followsms.valid
			P_TeleportMove(s, s.followsms.x, s.followsms.y, s.followsms.z+(s.followsms.height*3/4))
			end
			if s.color == SKINCOLOR_JET //The train for the Elseif Ruins will be departing soon.
				if not s.movh
				s.movh = P_RandomRange(1,2)
				else
					if s.movh == 1
					s.rollangle = ANGLE_90
					s.momz = 0
					end
				end
			elseif SMSisyellow(s)
			s.color = P_RandomRange(SKINCOLOR_SUPERGOLD1, SKINCOLOR_SUPERGOLD5)
			elseif s.color == SKINCOLOR_RED
			s.color = SKINCOLOR_FLAME
			elseif s.color == SKINCOLOR_FLAME
			s.color = SKINCOLOR_RED
			elseif s.color == SKINCOLOR_SKY
			s.color = SKINCOLOR_CYAN
			elseif s.color == SKINCOLOR_CYAN
			s.color = SKINCOLOR_SKY
			end
			if (s.ltimer < 6)
			s.frame = (P_RandomRange(4, 6))|FF_FULLBRIGHT|TR_TRANS10
			elseif (s.ltimer < 25)
			s.frame = (P_RandomRange(4, 6))|FF_FULLBRIGHT|TR_TRANS30
			elseif (s.ltimer < 46)
				if s.ltimershort and s and s.valid
				P_KillMobj(s)
				return
				end
			s.frame = (P_RandomRange(4, 6))|FF_FULLBRIGHT|TR_TRANS50
			else
			s.frame = (P_RandomRange(4, 6))|FF_FULLBRIGHT|TR_TRANS70			
			end
			if (((s.ltimer > 60) and not s.growx2) or ((s.ltimer > 90) and s.growx2)) 
			and s and s.valid
			P_KillMobj(s)
			return
			end
		end
	end
end, MT_HMSLIGHTNING2)

//Robot gore! Avert your eyes, children!

addHook("MobjThinker", function(s)
	if s
		if not s.smsrgtimer
			if s.srgorelvl and (s.srgorelvl > 20)
			s.smsrgtimer = P_RandomRange(200, 280)-(s.srgorelvl*2)
				if (s.smsrgtimer < 10)
				s.smsrgtimer = 10
				end
			else
			s.smsrgtimer = P_RandomRange(200, 280)
			end
		else
		s.smsrgtimer = $-1 //Pirating Lua from my own mods 'cuz of course I would
		end
		if not s.rolldecide
			if P_RandomRange(0,1)
			s.rolldecide = 1
			else
			s.rolldecide = -1
			end
			if s and s.valid 
				if not ( P_TryMove(s, s.x+s.momx, s.y+s.momy, true) )
				or not (P_CheckPosition(s, s.x, s.y))
				s.flags = $ & ~MF_GRENADEBOUNCE & ~MF_BOUNCE
				end
			end
		end
		if (s.momx < 0) s.rgmomx = s.momx*-1 else s.rgmomx = s.momx end
		if (s.momy < 0) s.rgmomy = s.momy*-1 else s.rgmomy = s.momy end
		s.trgmom = s.rgmomy+s.rgmomx
		
		if ( ((s.momx < -23555) or (s.momx > 23555)) or ((s.momy > 23555) or (s.momy < -23555)) ) and s.rolldecide and s.trgmom
		and not (s.floorz == s.ceilingz)
		s.rollangle = $+((FixedAngle(s.trgmom)*s.rolldecide)) //Roll faster the faster you go.
	//	s.angle = $+((FixedAngle(s.trgmom)*s.rolldecide)) //Doesn't actually apply, since gore sprites aren't 3D.
		elseif (s.flags & MF_GRENADEBOUNCE)
		s.flags = $ & ~MF_GRENADEBOUNCE
		end
		if not s.gentrgsfx and P_IsObjectOnGround(s)
		s.gentrgsfx = true
		S_StartSound(s, sfx_gentrg)
		end
		if s.hmsexplosioncurse
		s.hmsexplosioncurse = $-1
			if ((P_RandomRange(0,9)) == 9)
				s.hmsec = P_SpawnMobj(s.x, s.y, s.z, MT_BOSSEXPLODE)
				s.hmsec.scale = $*P_RandomRange(1,3)
			//	S_StartSound(s.rgs, sfx_cybdth)
			end
		end
		if ((P_CheckDeathPitCollide(s)) or (s.smsrgtimer == 1)) and s and s.valid
		s.state = S_NULL
		return
		end
	end
end, MT_SMSRGORE)

//Complicated Robot Gore Function. Avoids having to write it all down 500 times, and makes it easier to repeat.
local function RobotGoreSpawn(s, object, eneradius, eneheight, momentum, zmomentum, color, scale, extramom, extramomang, hmsspecial)
	if s and object and eneradius and eneheight and momentum and zmomentum and color and scale
		s.rgs = P_SpawnMobj(s.x+((P_RandomRange(-eneradius, eneradius))*FRACUNIT), s.y+((P_RandomRange(-eneradius, eneradius))*FRACUNIT), s.z+((P_RandomRange(0, s.height/FRACUNIT))*FRACUNIT), object)
		s.rgs.color = color
		s.rgs.sprite = SPR_RGOR
			if hmsspecial
			s.rgs.hmsexplosioncurse = 20
			s.rgs.frame = A
			else
			s.rgs.frame = P_RandomRange(0,4)
			end
		s.rgs.momx = (P_RandomRange(-momentum, momentum))*FRACUNIT
		s.rgs.momy = (P_RandomRange(-momentum, momentum))*FRACUNIT
			if extramom and (extramom > 200) //Cap max height.
			s.rgs.momz = (P_RandomRange(1, 100))*FRACUNIT	
			elseif extramom and (extramom > 50)
			s.rgs.momz = (P_RandomRange(1, extramom/2))*FRACUNIT	
			else
			s.rgs.momz = (P_RandomRange(1, zmomentum))*FRACUNIT	
			end
			if extramom and extramomang
			P_Thrust(s.rgs, extramomang+ANGLE_180, extramom*FRACUNIT)
			end
			if scale
			s.rgs.scale = scale
			else
			s.rgs.scale = s.scale
			end
			if s.srgorelvl
			s.rgs.srgorelvl = s.srgorelvl
			end
	end
end

//This thing spawns the gore. There are a LOT of actions at once here.

addHook("MobjThinker", function(s)
	if s and s.valid
		if not s.actiontime
		
			//Setup, incase no enemy data came in.
			if s.eneheight else s.eneheight = 28*FRACUNIT end 
			if s.eneradius else s.eneradius = 32*FRACUNIT end
			if s.enex else s.enex = s.x end if s.eney else s.eney = s.y end if s.enez else s.enez = s.z end
			if s.enemom else s.enemom = 10*FRACUNIT end
			if s.enecolor else s.enecolor = SKINCOLOR_SILVER end
			if s.enescale else s.enescale = FRACUNIT end
			if s.enethrust else s.enethrust = 9*FRACUNIT end
			if s.eneanglethrust != nil elseif s.target and s.target.valid R_PointToAngle2(s.x, s.y, s.target.x, s.target.y) else s.enethrust = nil s.eneanglethrust = nil end
	
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(10, 25), s.enecolor, s.enescale, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 22), s.enecolor, s.enescale, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 24), s.enecolor, s.enescale, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 22), s.enecolor, s.enescale, s.enethrust/FRACUNIT, s.eneanglethrust)
			if s.target and s.target.valid
			P_TeleportMove(s, s.target.x, s.target.y, s.target.z+s.target.height/2)
			end
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*3, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*2, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*2, s.enethrust/FRACUNIT, s.eneanglethrust)
			RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*3, s.enethrust/FRACUNIT, s.eneanglethrust)
			if s and s.valid and not s.hmskiller
			P_KillMobj(s) return
			end
			s.actiontime = 1
		elseif s.actiontime
			s.actiontime = $+1
			if s.hmskiller and s.hmskiller.valid and s.hmskiller.player and s.target
			local t = s.target
				if s.actiontime == 2 or s.actiontime == 6 or s.actiontime == 12
				RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*1, s.enethrust/FRACUNIT, s.eneanglethrust, true)
				RobotGoreSpawn(s, MT_SMSRGORE, s.eneradius/FRACUNIT, s.eneheight/FRACUNIT, s.enemom/FRACUNIT, P_RandomRange(8, 25), s.enecolor, s.enescale*3, s.enethrust/FRACUNIT, s.eneanglethrust, true)
					if s.target and s.target.hmsgodaurad
						if s.actiontime == 2
						s.hmskiller.suddenquickspeed = 7
						s.hmskiller.flags2 = $|MF2_DONTDRAW
						end
					S_StartSound(s.hmskiller, sfx_nerf)
					A_SMSquake(s.hmskiller, 60*FRACUNIT, 3, 1222)
					P_SpawnMobj(s.enex+((P_RandomRange(-s.eneradius/FRACUNIT*10, s.eneradius/FRACUNIT*6))*FRACUNIT), s.eney+((P_RandomRange(-s.eneradius/FRACUNIT*6, s.eneradius/FRACUNIT*6))*FRACUNIT), s.enez+((P_RandomRange(0, (s.height/FRACUNIT)*9))*FRACUNIT), MT_BURSTWAVE)
					s.enebl = P_SpawnMobj(s.enex+((P_RandomRange(-s.eneradius/FRACUNIT*10, s.eneradius/FRACUNIT*6))*FRACUNIT), s.eney+((P_RandomRange(-s.eneradius/FRACUNIT*6, s.eneradius/FRACUNIT*6))*FRACUNIT), s.enez+((P_RandomRange(0, (s.height/FRACUNIT)*9))*FRACUNIT), MT_BURSTLIGHT)
					s.enebl.color = SKINCOLOR_SUPERGOLD4
					s.enebl.target = s.hmskiller
					end
				end
				if (s.actiontime > 12)
					if s.rgs and s.rgs.valid
					//Extra room for code?
					elseif s and s.valid
					P_KillMobj(s)
					return
					end
				end
			elseif s and s.valid
			P_KillMobj(s)
			return
			end
		end
		if P_CheckDeathPitCollide(s)
		s.state = S_NULL
		return 	
		end
	end
end, MT_SMSRGORESPAWN)

//Oh shit, it's about time we abandon this man.

/*addHook("MobjThinker", function(s)
	if s and s.valid 
		if s.target and s.target.godbreakervictim and s.health
		P_KillMobj(s)
		return
		end
	end
end, MT_CYBRAKDEMON_ELECTRIC_BARRIER)*/

//Warppoint! Colliding with 1-way linedefs? Adjust your property.

addHook("MobjThinker", function(s)
	if s and s.valid
		if (s.ceilingz < s.ogz) or (s.floorz > s.ogz)
		s.nowgoslowly = true //Slow down when you clip through something! Wouldn't want to overshoot things.
		end
		if s.tptime
				if not P_TryMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), true)
				P_TeleportMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), s.z)
				s.nowgoslowly = true
				end
				if not P_TryMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), true)
				P_TeleportMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), s.z)
				s.nowgoslowly = true
				end
				if not P_TryMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), true)
				P_TeleportMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), s.z)
				s.nowgoslowly = true
				end
				if not P_TryMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), true)
				P_TeleportMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), s.z)
				s.nowgoslowly = true
				end
				if not P_TryMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), true)
				P_TeleportMove(s, s.x+FixedMul(35*FRACUNIT, cos(s.angle)), s.y+FixedMul(35*FRACUNIT, sin(s.angle)), s.z)
				s.nowgoslowly = true
				end
			s.tptime = false
		else
			if s.nowgoslowly
			P_InstaThrust(s, s.angle, 30*FRACUNIT)
			else
			P_InstaThrust(s, s.angle, 150*FRACUNIT)
			end
		end
	end
end, MT_HMSWARPPOINT)
addHook("MobjLineCollide", function(s, l)
	if s and s.valid and l and l.valid
		if (l.flags == ML_IMPASSIBLE) or not (l.backside and l.frontside)
		s.dontwarptome = true
		return false
		else
		s.ihavetped = true
		s.tptime = true
		return false
		end
	end
	return false
end, MT_HMSWARPPOINT)

addHook("MobjThinker", function(s)
		if s.valid
		and s.target and s.target.valid and s.target.player
			if s.target.player.powers[pw_sneakers]
			and s.target.health
			and not s.target.player.exiting
				A_Capechase(s, 0, 0)
			//	P_TeleportMove(s, s.target.x+s.target.momx, s.target.y+s.target.momy, s.target.z+s.target.momz)
			elseif s.valid
			and (s.target and not s.target.player.speedspeedspeedspeedspeed or not s.target)
				P_KillMobj(s)
			end
		elseif s and s.valid
			P_KillMobj(s)
		end
end, MT_SMSSPARKLESPAWN)

addHook("MobjThinker", function(s)
		if s.valid
			if (s.target and s.target.skin == "sms")
			and s.target.player.speedspeedspeedspeedspeed
			and s.target.health
			and not (s.eflags & MFE_UNDERWATER)
			and not s.target.player.exiting
			and not s.target.player.hypermysticsonic
				if not (s.flags2 & MF2_SHADOW)
					P_SpawnGhostMobj(s)
				end
			   if not s.woopwoopwoop
				if (s.target.player.lddiscount == 1)
					s.flags2 = $|MF2_SHADOW
				elseif (s.target.player.lddiscount == 2)
					s.state = S_SMSTSPARK1
					s.color = P_RandomRange(SKINCOLOR_WHITE, SKINCOLOR_ROSY)
				end
				P_SetObjectMomZ(s, FRACUNIT*4)
				s.momx = (s.x-s.target.x)/15
				s.momy = (s.y-s.target.y)/15
				s.woopwoopwoop = true
			   end
			elseif s.valid
				P_KillMobj(s)
			end
		end
end, MT_SMSSPEEDSPARKLE)

//The radial spinboost effect. It changes to your colors of course!

addHook("MobjThinker", function(s)
	if s.valid
		if s.target
			if (s.target.eflags & MFE_VERTICALFLIP)
			and not (s.flags2 & MF2_OBJECTFLIP)
			s.flags2 = $|MF2_OBJECTFLIP
			s.z = s.target.z-64*FRACUNIT
			end
			if SMSisyellow(s)
				s.color = SKINCOLOR_BONE
			else
				A_ChangeColorAbsolute(s, 0, s.target.color)
			end
			if (s.state == S_SMSSPINBOOST3)
			or (s.state == S_SMSSPINBOOST4)
			s.scalespeed = 25000
			P_SetObjectMomZ(s, -8*FRACUNIT, relative)
			end
		end
	end
end, MT_RADIALBOOST)

addHook("MobjThinker", function(s)
	if s 
		if (s.state == S_BURSTLIGHT1)
		and s.color == 0
		s.color = SKINCOLOR_BEIGE //Default color is beige.
		end
		if (s.state == S_BURSTLIGHT3)
		and not s.shrunkdowntosizealready
		A_SetScale(s, s.scale*3/2, 1)
		s.shrunkdowntosizealready = true
		end
		if (s.state == S_BURSTLIGHT5)
		and not s.l_gr
		A_SetScale(s, s.scale+5*FRACUNIT, 1)
		s.l_gr = true
		end
	end 
end, MT_BURSTLIGHT)

addHook("MobjThinker", function(s)
	if s.valid
		P_SetObjectMomZ(s, -FRACUNIT)
		if (s.state == S_BURSTWAVE1)
		s.scalespeed = s.scalespeed*4
		A_SetScale(s, s.scale+25*FRACUNIT, 1)
			if (s.color == 0)
			s.color = SKINCOLOR_BONE //Default color is silver.
			end
		end
		if (s.state == S_BURSTWAVE2) or (s.state == S_BURSTWAVE3) or (s.state == S_BURSTWAVE4)
		P_SpawnGhostMobj(s)
		end
		if (s.state == S_BURSTWAVE5)
		and (s.color == SKINCOLOR_RED)
		s.color = SKINCOLOR_YELLOW
		end
		if (s.state == S_BURSTWAVE6)
		and (s.color == SKINCOLOR_YELLOW)
		s.color = SKINCOLOR_EMERALD
		end
	end
end, MT_BURSTWAVE)

//SMS' overly colorfull stomp aura. Did I go a little overboard here?

addHook("MobjThinker", function(s)
 if s and s.valid
    if s.target and s.target.health

	if (s.target and s.target.eflags & MFE_VERTICALFLIP)
		s.eflags = $|MFE_VERTICALFLIP
	else
		s.eflags = $ & ~MFE_VERTICALFLIP
	end
	if s.target and (s.target.player.hypermysticsonic or s.target.player.sms_sontransform)
	P_SetObjectMomZ(s, 9*FRACUNIT)
	end
	if (s.target and P_IsObjectOnGround(s.target))
	and not (s.target.player.hypermysticsonic)
	s.momx = (s.x-s.target.x)/16
	s.momy = (s.y-s.target.y)/16
	end

		if (s.state == S_SMSLINE2)
		s.color = SKINCOLOR_ORANGE
		elseif (s.state == S_SMSLINE3)
		s.color = SKINCOLOR_YELLOW
		elseif (s.state == S_SMSLINE4)
		s.color = SKINCOLOR_PERIDOT
		elseif (s.state == S_SMSLINE5)
		s.color = SKINCOLOR_EMERALD
		else
		s.color = SKINCOLOR_RED
		end
    elseif s
    P_KillMobj(s)
    end
 end
end, MT_SMSSTOMPLINE)

addHook("MobjThinker", function(s)
	if s
	and s.target
	and not s.blown
		A_NapalmScatter(s, MT_HMS_NAPALM_FLAMES, 256)
		s.blown = true
	end
end, MT_HMSSTOMPEXPLODE)

addHook("MobjThinker", function(s)
	if s and s.valid and (s.state != S_STARPOST_IDLE)
		if not s.trymsspawn
			for z in players.iterate
				if z.smsnomsspawn
				s.trymsspawn = true
				return
				end
			end
			if not (s.msstarp and s.msstarp.valid)
			and multiplayer or (players[(0)] and players[(0)].mo and (players[(0)].mo.skin == "sms" or A_SMScompatibleskin((players[(0)].mo))))
			
			s.msstarp = P_SpawnMobj(s.x+P_RandomRange(-1,1), s.y+P_RandomRange(-1,1), s.z+16*FRACUNIT, MT_THEMYSTICEMERALD)
				if s.msstarp and s.msstarp.valid
				s.msstarp.msexisting = 15
				end
			S_StartSound(s, sfx_s1c9)
			A_SMSSTOMPSMOKE(s, 2, MT_IVSP, 21*FRACUNIT)
			A_SMSSTOMPSMOKE(s, 10, MT_IVSP, 5*FRACUNIT)
			A_SMSSTOMPSMOKE(s, 6, MT_IVSP, 71*FRACUNIT)
			end
		end
		s.trymsspawn = true
	end
end, MT_STARPOST)

addHook("MobjThinker", function(s)
	if s and s.valid and s.target and s.target.valid
		if ((s.state == S_SMSSPRINTLINE3) or (s.state == S_SMSSPRINTLINE3M)) or (((s.state == S_SMSSPRINTLINE4) or (s.state == S_SMSSPRINTLINE4M))  and (s.tics > 1))
				if s.target and s.target.valid and s.target.player and s.target.player.hypermysticsonic
				s.color = SKINCOLOR_SUPERSILVER3
				else
				s.color = SKINCOLOR_SUPERGOLD3
				end
		end
		if (((s.state == S_SMSSPRINTLINE4) or (s.state == S_SMSSPRINTLINE4M)) and s.tics == 1)
			if s.target and s.target.valid and s.target.player and s.target.player.hypermysticsonic
			s.color = SKINCOLOR_COBALT
			else
			s.color = SKINCOLOR_EMERALD
			end
		end
	end
end, MT_SMSSPRINTLINE)

addHook("MobjThinker", function(s)
	if s 
		if s.target and s.target.valid
		P_TeleportMove(s, s.target.x, s.target.y, s.target.z)
			if (s.target.player and (s.target.player.sms_ringburstfly))
				if (s.target.player.sms_ringburstfly == 3)			
					if s and s.valid
					s.state = S_NULL
					return
					end
				end
			elseif (s.tics > 18)
			s.tics = 18
			end
		end
		s.rollangle = $+FixedAngle(40*FRACUNIT)
		if (s.tics < 22)
			local trn = TR_TRANS10*max( 1,min(6,6-(s.tics-9)/2) ) //Mathematics! 
			s.frame = U|(trn)|FF_FULLBRIGHT
		end
	end
end, MT_GOLDENSHINE)

local OverLayMan = nil //Sigh. They didn't update MT_OVERLAY to work with directionchar....
addHook("MobjThinker", function(s)
	if s and s.target and s.target.player and s.target.player.mysticsuper and s.target.skin == "sonic"
		OverLayMan = s
			if (s.target.player.pflags & PF_DIRECTIONCHAR) 
			OverLayMan.directchar = true
			end
			if CBW_Battle //Battlemoooooodddd....
			s.goddamnitwhybattlemod	= true
			end
	end
end, MT_OVERLAY)

addHook("PostThinkFrame", do
	if OverLayMan and OverLayMan.valid and OverLayMan.target and OverLayMan.target.valid and OverLayMan.target.player
		if mariomode
		OverLayMan.color = OverLayMan.target.color
		end
		if OverLayMan.directchar
		OverLayMan.angle = OverLayMan.target.player.drawangle
		OverLayMan.directchar = nil
		end
		if OverLayMan.goddamnitwhybattlemod
		OverLayMan.goddamnitwhybattlemod = nil
		OverLayMan.flags2 = $ & ~MF2_DONTDRAW
		end
	end
end)

//"B-but HMS-sama, I've got no hitbox for you to hit me with!"
//Oh SRB2-chan....you sweet, naïve fool~ ♥ /EndCreepyFetishDialogue

local function DummyHBadd(s)
	if s and s.valid and not s.dummyhb and s.health
	s.dummyhb = P_SpawnMobj(s.x, s.y, s.z, MT_SMSDUMMYTRACKER)
	s.dummyhb.target = s
	s.dummyhb.tics = -1
	s.dummyhb.dummyhbx = true
	end
end

addHook("MobjThinker", DummyHBadd, MT_EGGGUARD)
addHook("MobjThinker", DummyHBadd, MT_TURRET)
addHook("MobjThinker", DummyHBadd, MT_MINUS)
addHook("MobjThinker", DummyHBadd, MT_CYBRAKDEMON)
addHook("MobjThinker", DummyHBadd, MT_METALSONIC_BATTLE)
addHook("MobjThinker", DummyHBadd, MT_BLACKEGGMAN)
addHook("MobjThinker", DummyHBadd, MT_SUSPICIOUSFACESTABBERSTATUE)
addHook("MobjThinker", DummyHBadd, MT_KOOPA)
addHook("MobjThinker", DummyHBadd, MT_EGGROBO1)