rawset(_G, "US_SpawnSkidDust", function(s)
	for i = -4,4 do
		local ZFLIP = (P_MobjFlip(s)== -1 and s.height or 0)
		local SPEED = abs(s.momx)+abs(s.momy)
		
		local dust = P_SpawnMobjFromMobj(s, 0,0, 0+ZFLIP, MT_SPINDUST)
		dust.angle = R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy)+(i*ANG2)
		P_InstaThrust(dust, dust.angle, SPEED-10*s.scale)
		dust.scale = s.scale
		dust.destscale = 99*FU
		dust.tics = 2
		dust.flags2 = $|MF2_SHADOW
		dust.blendmode = AST_TRANSLUCENT
	end
end)

rawset(_G, "US_SpawnLandDust", function(s)
	for i = 0,8 do
		local ZFLIP = (P_MobjFlip(s)== -1 and s.height or 0)
		
		local dust = P_SpawnMobjFromMobj(s, 0,0, 0+ZFLIP, MT_SPINDUST)
		dust.angle = i*ANGLE_45
		P_InstaThrust(dust, dust.angle, 8*FU)
		dust.scale = s.scale
		dust.destscale = 99*FU
		dust.tics = 2
		dust.flags2 = $|MF2_SHADOW
		dust.blendmode = AST_TRANSLUCENT
	end
end)

rawset(_G, "US_SpawnHeavyLandDust", function(s)
	for d = 1,3 do
		for i = 0,8 do
			local ZFLIP = (P_MobjFlip(s)== -1 and s.height or 0)
		
			local dust = P_SpawnMobjFromMobj(s, 0,0, 0+ZFLIP, MT_SPINDUST)
			dust.angle = i*ANGLE_45
			P_InstaThrust(dust, dust.angle, (20*d)*FU)
			if d==2
				P_SetObjectMomZ(dust, 5*(d-1)*FU, false)
			end
			dust.scale = s.scale*3/2
			dust.destscale = 99*FU
			dust.tics = 2
			dust.flags2 = $|MF2_SHADOW
			dust.blendmode = AST_TRANSLUCENT
		end
	end
end)

rawset(_G, "US_ChaosEmeraldWarp", function(s, COLOR, TICK)
	COLOR = (COLOR) or nil
	
	for i = 0,6 do
		local X = FixedMul(s.radius*3, cos(ANG60*i+TICK*ANG2))
		local Y = FixedMul(s.radius*3, sin(ANG60*i+TICK*ANG2))
		local gfx = P_SpawnMobjFromMobj(s, X, Y, s.height/4, MT_THOK)
	--	gfx.scale = s.scale
		gfx.renderflags = RF_FULLBRIGHT
		gfx.destscale = 99*FU
		gfx.scalespeed = s.scale/8
		gfx.blendmode = AST_ADD
		gfx.color = COLOR[i+1]
		gfx.dispoffset = 3
		gfx.fuse = 20
		gfx.tics = 20
	end
end)

rawset(_G, "SpawnHitSpark", function(s, COLOR, SCALE)
	SCALE = (SCALE) or s.scale/2
	
	local gfx = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
	gfx.sprite = SPR_BARX
	gfx.scale = SCALE
	gfx.frame = ($ & ~(FF_FRAMEMASK|FF_TRANSMASK))
	gfx.dispoffset = 1
	gfx.blendmode = AST_ADD
	gfx.tics,gfx.fuse = 11,50
	gfx.US_GraphicEffect = 3
	gfx.US_InitialFrame = 1
	if COLOR
		gfx.colorized = true
		gfx.color = COLOR
	end
end)

rawset(_G, "US_SpawnShadowStep", function(s, FOLLOW, TRANS, SCALE)
	TRANS = (TRANS) or FF_TRANS50
	SCALE = (SCALE) or s.scale
	
	local gfx = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
	gfx.tracer = (FOLLOW) and s or nil
	gfx.scale = (SCALE)
	gfx.sprite = SPR_USDP
	gfx.frame = $ & ~(FF_FRAMEMASK)
	gfx.frame = ($ & ~FF_TRANSMASK)|TRANS
	gfx.fuse,gfx.tics = 16,50
	gfx.dispoffset = 3
	gfx.US_GraphicEffect = 4
	gfx.US_InitialFrame = 1
	gfx.renderflags = RF_SEMIBRIGHT
--	gfx.blendmode = AST_ADD
end)

rawset(_G, "US_SpawnSonicStorm", function(s, ANGLE, SPEED)
	local gfx = P_SpawnMobjFromMobj(s, FixedMul(s.radius, cos(ANGLE)), FixedMul(s.radius, sin(ANGLE)), 0, MT_THOK)
	Sonic_GibSound(gfx, sfx_vssonm, 60)
	S_StartSound(gfx, sfx_vssonn)
	gfx.target = s
	gfx.sprite = SPR_BFBR
	gfx.scale = s.scale*4 --Pretty big huh?
	gfx.radius = 250*s.scale
	gfx.height = 400*s.scale
	gfx.US_SonicStorm = true
	gfx.angle = ANGLE
	gfx.blendmode = AST_ADD
	gfx.colorized = true
	gfx.color = SKINCOLOR_SKY
	gfx.fuse,gfx.tics = 70,70
	gfx.frame = ($ & ~(FF_FRAMEMASK|FF_TRANSMASK))
	gfx.flags = $|MF_SPECIAL & ~(MF_NOCLIP|MF_NOCLIPTHING)
--	gfx.flags = $|MF_PAIN & ~(MF_NOCLIPTHING)
	
	P_InstaThrust(gfx, gfx.angle, SPEED)
end)
local function US_SonicStormTouch(m, s)
	if not (m and m.valid and m.US_SonicStorm) return end
	if m.health
		if (s and s.valid and s.health) 
		and (s.player or (s.flags & (MF_ENEMY|MF_BOSS|MF_SHOOTABLE)))
		and m.target != s
			P_DamageMobj(s, m, m.target)
		end
		
		P_RadiusAttack(m, m.target, 500*FU)
		local gfx = P_SpawnMobjFromMobj(m, 0,0,0, MT_THOK)
		gfx.scale = m.scale
		gfx.destscale = 99*FU
		gfx.scalespeed = m.scale/2
		gfx.color = m.color
		gfx.blendmode = AST_ADD
		gfx.fuse = 20
		gfx.tics = 20
		Sonic_GibSound(m, sfx_vssonl, 35)
		P_RemoveMobj(m)
	end
end
addHook("TouchSpecial", US_SonicStormTouch, MT_THOK)

rawset(_G, "US_SpawnFlashDash", function(s, COLOR, BLENDMODE, ROLLANGLE)
	COLOR = (COLOR) or s.color
	BLENDMODE = (BLENDMODE) or AST_ADD
	local MIRROR = P_RandomRange(1, 2)==2 and true or false
	if ROLLANGLE == nil
		local ROLLRNG = P_RandomRange(1, 4)
		local TYPE = {"Vertical", "Diagonal", "Deeper-Diagonal", "Horizontal"}
		if s.US_LastFlashDash and s.US_LastFlashDash==TYPE[ROLLRNG]
			ROLLRNG = $+1
			if ROLLRNG > 4
				ROLLRNG = 1
			end
		end
		ROLLRNG = TYPE[$]
		s.US_LastFlashDash = ROLLRNG
		
		ROLLANGLE = (ROLLRNG=="Vertical" and "Zero" 
		or ROLLRNG=="Diagonal" and ANGLE_45
		or ROLLRNG=="Deeper-Diagonal" and ANG60
		or ROLLRNG=="Horizontal" and ANGLE_90)
		
		if ROLLANGLE == "Zero"
			ROLLANGLE = 0
		end
	end
	
	local gfx = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
	gfx.sprite = SPR_USFD
	gfx.blendmode = BLENDMODE
	gfx.frame = ($ & ~(FF_FRAMEMASK|FF_TRANSMASK))|A
	gfx.scale = $*8
	gfx.mirrored = MIRROR
	gfx.rollangle = ROLLANGLE
	gfx.renderflags = RF_FULLBRIGHT
	gfx.dispoffset = 2
	gfx.tics,gfx.fuse = 10,50
	gfx.US_GraphicEffect = 1
	gfx.color = COLOR
	gfx.US_InitialFrame = 1
	
	return gfx --
end)


rawset(_G, "US_HeavyFloorImpact", function(m, COLOR, BLENDMODE)
	COLOR = (COLOR) or m.color
	BLENDMODE = (BLENDMODE) or AST_ADD
	local ZFLIP = (P_MobjFlip(m)== -1 and m.height or 0)
	
	local gfx = P_SpawnMobjFromMobj(m, 0,0,8*P_MobjFlip(m)+ZFLIP, MT_THOK)
	gfx.sprite = SPR_USSM
	gfx.blendmode = BLENDMODE
	gfx.frame = ($ & ~(FF_FRAMEMASK|FF_TRANSMASK))|A
	gfx.spritexscale = m.scale*3
	gfx.spriteyscale = m.scale*3
	gfx.renderflags = RF_FULLBRIGHT
	gfx.flags2 = $|MF2_SPLAT
	gfx.dispoffset = 1
	gfx.tics,gfx.fuse = 11,50
	gfx.US_GraphicEffect = 2
	gfx.color = COLOR
	gfx.US_InitialFrame = 1
	
	return gfx --
end)

rawset(_G, "US_RenderSuperAura", function(s, COLOR, SCALE)
	SCALE = (SCALE) or s.scale
	local Time = leveltime
	local FRAME = (Time % 8)>=6 and D or (Time % 8)>=4 and C or (Time % 8)>=2 and B or A
	
	local gfx = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
	gfx.sprite = SPR_USSA
	gfx.blendmode = AST_ADD
	gfx.frame = ($ & ~(FF_FRAMEMASK|FF_TRANSMASK))|FRAME|FF_TRANS30
	gfx.renderflags = RF_FULLBRIGHT
	gfx.dispoffset = 2
	gfx.tics = 2
	gfx.fuse = 50
	gfx.scale = SCALE
	gfx.tracer = s
	gfx.US_GraphicEffect = 5
	if COLOR
		gfx.colorized = true
		gfx.color = COLOR
	end
	
	return gfx --
end)

rawset(_G, "US_SuperTransFormGFX", function(s)
	local RADIUS = 10000 --Only meant to be like 100 radius, but sparkles everywhere lowkey hit!
	local X = P_RandomRange(-RADIUS, RADIUS)
	local Y = P_RandomRange(-RADIUS, RADIUS)
	local Z = P_RandomRange(0, 2000)
	local SCALEDIV = P_RandomRange(1, 3)
	local FLOAT = P_RandomRange(10, 20)
					
	local gfx = P_SpawnMobjFromMobj(s, X*FU, Y*FU, 0, MT_BOXSPARKLE)
	gfx.z = s.floorz+FU*3+Z*FU
	gfx.blendmode = AST_ADD
	gfx.color = skins[s.skin].supercolor
	gfx.colorized = true
	gfx.renderflags = RF_FULLBRIGHT
	gfx.scale = $*25/SCALEDIV
	gfx.tics = P_RandomRange(6, 14)
	P_SetObjectMomZ(gfx, FLOAT*FU, false)
	
--	RADIUS = 300
--	X = P_RandomRange(-RADIUS, RADIUS)
--	Y = P_RandomRange(-RADIUS, RADIUS)
--	Z = P_RandomRange(0, 2000)
--	SCALEDIV = P_RandomRange(1, 3)
--	FLOAT = P_RandomRange(9, 20)
--	local gfx2 = P_SpawnMobjFromMobj(s, X*FU, Y*FU, 0, MT_THOK)
--	gfx2.US_GraphicEffect = 6
--	gfx2.sprite = SPR_SSPK
--	gfx2.z = s.floorz+FU*3+Z*FU
--	gfx2.blendmode = AST_ADD
--	gfx2.color = skins[s.skin].supercolor
--	gfx2.colorized = true
--	gfx2.tics = 20
--	gfx2.fuse = 50
--	gfx2.renderflags = RF_FULLBRIGHT
--	gfx2.scale = ($*3/2)/SCALEDIV
--	P_SetObjectMomZ(gfx2, FLOAT*FU, false)
end)

local function US_GFXThinker(m)
	if not (m and m.valid and m.US_GraphicEffect) return end
	--1 for Flash Dash, 2 for Heavy Floor Impact
	if m.US_GraphicEffect == 1
		if m.US_InitialFrame
			m.US_InitialFrame = nil
			return
		end
		local FRAME = (m.frame & FF_FRAMEMASK)
		
		if FRAME>=I
			P_RemoveMobj(m)
			return 
		end
		
		FRAME = $+1
		m.frame = ($ & ~FF_FRAMEMASK)|FRAME
	elseif m.US_GraphicEffect == 2
		if m.US_InitialFrame
			m.US_InitialFrame = nil
			return
		end
		local FRAME = (m.frame & FF_FRAMEMASK)
		
		if FRAME>=J
			P_RemoveMobj(m)
			return 
		end
		
		FRAME = $+1
		m.frame = ($ & ~FF_FRAMEMASK)|FRAME
		m.spritexscale = $+m.scale*5/2
		m.spriteyscale = $+m.scale*5/2
	elseif m.US_GraphicEffect == 3
		if (leveltime % 2) and m.US_InitialFrame
			m.US_InitialFrame = nil
			return --
		end
		m.US_InitialFrame = nil
		
		if (leveltime % 2)
			local FRAME = (m.frame & FF_FRAMEMASK)
			
			if FRAME>=D
				P_RemoveMobj(m)
				return 
			end
			
			FRAME = $+1
			m.frame = ($ & ~FF_FRAMEMASK)|FRAME
		end
	elseif m.US_GraphicEffect == 4
		if (leveltime % 3)==0 and m.US_InitialFrame
			m.US_InitialFrame = nil
			return --
		end
		m.US_InitialFrame = nil
		if (leveltime % 3)==0
			local FRAME = (m.frame & FF_FRAMEMASK)
			
			if FRAME>=D
				P_RemoveMobj(m)
				return 
			end
			
			FRAME = $+1
			m.frame = ($ & ~FF_FRAMEMASK)|FRAME
		end
		if m.tracer and m.tracer.valid
			A_CapeChase(m, 1, 0)
		end
	elseif m.US_GraphicEffect == 5
		if m.tracer and m.tracer.valid
			local s = m.tracer
			P_SetOrigin(m, s.x+s.momx, s.y+s.momy, s.z+s.momz)
		end
	elseif m.US_GraphicEffect == 6
		local trail = P_SpawnMobjFromMobj(m, 0, 0, 0, MT_BOXSPARKLE)
		trail.blendmode = AST_ADD
		trail.color = SKINCOLOR_GOLDENROD
		trail.colorized = true
		trail.renderflags = RF_FULLBRIGHT
		trail.scale = m.scale
	end
end
addHook("MobjThinker", US_GFXThinker, MT_THOK)
	