--#==============================================================================#
--Aura effects!
--#==============================================================================#
local XSon = XSon
local function P_MobjFlip(s) if s and s.valid and ((s.eflags&MFE_VERTICALFLIP) or (s.flags2&MF2_OBJECTFLIP)) return -1 end return 1 end

--Delete any of these?
XSon.DeleteAura = function(p, s, xs, RINGBURST, SUPER, BLUR)
	if p.xsringburst return end
	if RINGBURST --Delete the Ring Burst Aura?
		if xs.XSuperAura
			if xs.XSuperAura.valid P_RemoveMobj(xs.XSuperAura) end
			xs.XSuperAura = nil
		end
	end
	if SUPER and p.XSauratable --Delete the Super Sonic aura?
		for _,ghs in pairs(p.XSauratable)
			if ghs if ghs.valid P_RemoveMobj(ghs) end
				ghs = nil
			end
		end
	end
	if BLUR and p.XSblurtable --Delete the Super Sonic Blur overlay?
		for _,ghs in pairs(p.XSblurtable)
			if ghs if ghs.valid P_RemoveMobj(ghs) end
				ghs = nil
			end
		end
	end
end


--The smokey aura used for the Ring Burst and Super Saiyan forms.
XSon.SmokeAura = function(p, s, xs, COLOR)
	if p.xsringburst return end --
	
	local ghs = xs.XSuperAura
	if not (ghs and ghs.valid) --X Aura, the animated aura.
		ghs = P_SpawnMobjFromMobj(s, 0,0,0, MT_XSUNDERGLOW)
		xs.XSuperAura = ghs
		ghs.fuse = 2
		ghs.tracer = s
		ghs.sprite = SPR_XSAA
		ghs.frame = A|FF_TRANS60
		ghs.blendmode = AST_ADD
		ghs.renderflags = $|RF_FULLBRIGHT|RF_NOCOLORMAPS
		ghs.XAura = "ringburst"
	end
	if ghs and ghs.valid
		local STATE,PANIM = s.state,p.panim
		ghs.fuse,ghs.tics,ghs.anim_duration = 2,2,2 --Keep it alive!
		ghs.scale = (s.scale*2)/5
		
		if (PANIM == PA_ROLL) or (PANIM == PA_JUMP) or (s.state == S_PLAY_SKID) or p.xsringburst	
		or (STATE >= S_PLAY_XZIPSLIDE) and (STATE <= S_PLAY_XRINGBURST)
			ghs.sprite = SPR_XSAB --Crouching aura		
		else
			ghs.spritexscale = (s.spritexscale*9)/8
			if (PANIM == PA_RUN) or (STATE == S_PLAY_XZIPLEAP) or (STATE == S_PLAY_XWALLRUN)
				ghs.sprite = SPR_XSAC --Forward leaning state
			elseif (ghs.sprite != SPR_XSAA) 
				ghs.sprite = SPR_XSAA --Default
			end
		end
		if ((ghs.frame & FF_FRAMEMASK) > 30) --Failsafe. Don't exceed the max aura number!
			ghs.sprite = SPR_XSAA
			ghs.frame = $ & ~FF_FRAMEMASK
		end	
		if COLOR
			if COLOR == SKINCOLOR_SKY and (xs and xs.ringburstcharge and not xs.supersonic and not xs.darkphase)
				ghs.colorized = true
			end
			ghs.color = (tonumber(COLOR)) or s.color
		end return ghs --
	end
end

--The smokey aura used for the Ring Burst and Super Saiyan forms.
--Style 0/nil is superform, 1 is Ring Burst.
XSon.SuperAura = function(p, s, xs, COLOR)
	if p.xsringburst or (s.XS_DidSuperAura) return end --
	
	local DPHASE = (xs.darkphase) or 0
	
	COLOR = (COLOR) or xs.darkphase and SKINCOLOR_XSDARKNESS or SKINCOLOR_XSSUPERAURA
	if s.XS_modScolor and (COLOR == SKINCOLOR_XSSUPERBLUR or COLOR == SKINCOLOR_XSSUPERAURA)
		COLOR = s.XS_modScolor 
	end
	local BLEND = (DPHASE) and AST_TRANSLUCENT or AST_ADD
	local TRANS = FF_TRANS90 
	local RFLAGS = RF_FULLBRIGHT|RF_NOCOLORMAPS
	
	local HFLIP,VFLIP = (s.frame & FF_HORIZONTALFLIP),(s.frame & FF_VERTICALFLIP)
	local RENDERER = 2
	if (p==displayplayer)
		RENDERER = CV_FindVar("renderer").value
	end
	local SPRITE2 = (s.sprite2 & ~FF_SPR2SUPER)
	local ANIM = SPR_XSAA --Exact animation to use.
	local STATE,PANIM = s.state,p.panim
	local SCALE = s.scale*2/5
	local PLUSX = 0
	
	--If we're in NiGHTS, pay attention and change the virtual states/panims.
	if (p.powers[pw_carry]==CR_NIGHTSMODE) and (STATE>=S_PLAY_NIGHTS_TRANS1)
		if (STATE<=S_PLAY_NIGHTS_FLOAT) or (STATE==S_PLAY_NIGHTS_STUN)
			STATE = S_PLAY_WALK
			PANIM = PA_WALK 
		elseif (STATE<= S_PLAY_NIGHTS_ATTACK) 
			local SIDE = abs(p.cmd.sidemove)/3
			if (abs(s.momz) > (2+SIDE)*s.scale )
				STATE = S_PLAY_WALK --Make it vertical again.
				PANIM = PA_WALK 
				SCALE = s.scale/3
			else
				PANIM = PA_ROLL --Smallest aura
				SCALE = s.scale*10/23
				PLUSX = 9001
			end
		end
	end	
	
	
	if PANIM == PA_ROLL or PANIM == PA_JUMP
	or (STATE >= S_PLAY_XZIPSLIDE) and (STATE <= S_PLAY_XRINGBURST)
	or SPRITE2 == SPR2_SKID or SPRITE2 == SPR2_GLID or SPRITE2 == SPR2_GRND	
		ANIM = SPR_XSAB --Smallest one.
	elseif PANIM == PA_RUN or SPRITE2 == SPR2_DIVE
		ANIM = SPR_XSAC --Forward leaning.
	end
	
	if (abs(s.rollangle) > ANG1) --I can't mimmick the rollangle, that causes memory leaks. Let's do the next best thing.
		PLUSX = AngleFixed(abs(s.rollangle))/180 --Adjust width of aura instead of changing it's rollangle
	end
	if p.XSauratable == nil p.XSauratable = {} end
	s.XS_DidSuperAura = true
	
	local ghs	
	for d = -30,10,20
		if DPHASE and (d != -10) 
			if (d == -30) or DPHASE == 1
				continue --
			end
		end
		ghs = p.XSauratable[d] 
		if not (ghs and ghs.valid) --Super Sonic's animated aura!
			p.XSauratable[d] = P_SpawnMobjFromMobj(s,0,0,0, MT_XSUNDERGLOW)
			ghs = p.XSauratable[d]
		end
		if not (ghs and ghs.valid)
			continue --
		end
		
		--Activate the rest regardless of what phase we're on.
		
		ghs.fuse,ghs.tics,ghs.anim_duration = 2,2,2 --Keep it alive!
		ghs.eflags = $|MFE_FORCENOSUPER
		if (s.eflags & MFE_VERTICALFLIP)
			ghs.eflags = $|MFE_VERTICALFLIP
		else
			ghs.eflags = $ & ~MFE_VERTICALFLIP
		end
		ghs.dispoffset = (s.dispoffset)+d
		ghs.blendmode = (d==10) and AST_ADD or BLEND
		ghs.renderflags = RFLAGS
		ghs.scale = SCALE --Match scale to player 24/7
		ghs.spritexoffset = s.spritexoffset	
		ghs.sprite = ANIM
		ghs.frame = ($ & ~FF_TRANSMASK)| ((d==-30) and FF_TRANS70 or TRANS)
		ghs.mirrored = s.mirrored
		ghs.XAura = "super"
		ghs.tracer = s
		if (s.flags2 & MF2_DONTDRAW)
			ghs.flags2 = $|MF2_DONTDRAW
		else
			ghs.flags2 = $ & ~MF2_DONTDRAW
		end	
		
		if d == -30 --The inner whiter part of the aura. Don't be colorized for the best effect.
			ghs.spritexscale = ((s.spritexscale*10)/13) + PLUSX
			ghs.spriteyscale = (s.spriteyscale*10)/13
			ghs.spriteyoffset = s.spriteyoffset + 34<<16
			if DPHASE == 3
				ghs.blendmode = AST_REVERSESUBTRACT
				ghs.frame = ($&~FF_TRANSMASK)|FF_TRANS90
			end
		else
			ghs.spritexscale = ((s.spritexscale*10)/9) + PLUSX --Outter auras get a bit wider.
			ghs.spriteyscale = s.spriteyscale
			ghs.spriteyoffset = s.spriteyoffset	
			ghs.color,ghs.colorized = COLOR, true
		end
		
		--Use THESE sprites, scales, and offsets for each animation!
		if ANIM == SPR_XSAB --Crouching aura. The flattest one.
		
			ghs.spriteyoffset = $-2<<16
			if PANIM == PA_ROLL or PANIM == PA_JUMP
				ghs.spriteyoffset = $-24<<16
			end
			if d == -30
				ghs.spriteyscale = $*5/6
			end
			
		elseif ANIM == SPR_XSAC --Forward leaning states. Widest aura.
		
			if SPRITE2 == SPR2_DIVE --Diving state adjustment.
				ghs.spriteyoffset = $+14<<16
			elseif xs.FreeFlight 
				ghs.spriteyoffset = $+17<<16			
			else
				ghs.spritexscale = $*7/6 --xscale
			end
			
		else --Default aura.
		
			if PANIM == PA_WALK
				ghs.spritexscale = $*8/7
			end
			if P_IsObjectOnGround(s) or (p.powers[pw_carry]==CR_NIGHTSMODE) --Adjust upwards so you don't clip into the floor!
				ghs.spriteyoffset = $+30<<16
				ghs.spriteyscale = $*5/6
				if PANIM == PA_IDLE
					ghs.spritexscale = $*7/8
				end
			else
				if PANIM == PA_SPRING or PANIM == PA_FALL
					ghs.spriteyoffset = $-4<<16
				else
					if PANIM == PA_IDLE or SPRITE2 == SPR2_FLT or SPRITE2 == SPR_FRUN
						ghs.spritexscale = $*7/8
					end
					ghs.spriteyoffset = (PANIM == PA_WALK) and $+24<<16 or $+20<<16
				end
			end	
		end
		if (leveltime%2) --Do X Aura thinking?
			local FRAME = (ghs.frame & FF_FRAMEMASK) --Remember the original frame.
			ghs.frame = ($ & ~FF_FRAMEMASK)
			if not (FRAME >= Z+6) --Do we advance the frame?
				ghs.frame = $|(min(Z+6, FRAME+1) )
			end			
		end
	--	ghs.frame = (VFLIP) and $|FF_VERTICALFLIP or $ & ~FF_VERTICALFLIP
		ghs.frame = (HFLIP) and $|FF_HORIZONTALFLIP or $ & ~FF_HORIZONTALFLIP		
		if (d != -10) and (RENDERER!=2)  --Hide all but 1 aura from software.
			ghs.flags2 = $|MF2_DONTDRAW
		end
		
		A_CapeChase(ghs,1,0) --Save dangerous capechase for last.
	end
end

--Overlay an additive Blur effect? Requires an extra skin to work, which sucks, but hey.
XSon.SuperBlur = function(p, s, xs, COLOR)
	if (s.sprite != SPR_PLAY)
	or not (s.sprite2&FF_SPR2SUPER) --Must be Super Saiyan!
	or p.xsringburst or not (xs.supersonic)
	or (s.XS_DidBlur)
		return  --Don't render!
	end
	if p.XSblurtable == nil p.XSblurtable = {} end --Make sure we have a valid table first.
	
	local ghs
	local BLEND = AST_ADD
	if xs.darkphase
		BLEND = AST_REVERSESUBTRACT
		COLOR = SKINCOLOR_XSSUPERBLUR
	elseif s.XS_modScolor and COLOR == SKINCOLOR_XSSUPERBLUR
		COLOR = s.XS_modScolor --Overwrite!
	end
	local RENDERER,HIDE = 2,false
	if (p==displayplayer) and not (splitscreen and p==players[1])
		if not (p.awayviewtics) and CV_FindVar("chasecam").value
			HIDE = true
		end
		if not (p.bot)
			RENDERER = CV_FindVar("renderer").value
		end
	end
	s.XS_DidBlur = true
	
	for d = -4,8,12 -- In order: -4,8
		ghs = p.XSblurtable[d] 
		if not (ghs and ghs.valid) --Super Sonic's blur effect
			p.XSblurtable[d] = P_SpawnMobjFromMobj(s, 0,0,0, MT_XSOVERGLOW) --Overglow has a different MobjThinker.
			ghs = p.XSblurtable[d]
			ghs.tracer = s
			ghs.dispoffset = d
			ghs.colorized = true
			ghs.flags2 = $|MF2_DONTDRAW --Be invisible on the first frame!
			ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
			ghs.XAura = "blur"
		end
		--Activate this regardless of what phase we're on.
		if ghs and ghs.valid
			ghs = p.XSblurtable[d] --Seems valid, so select it!		
			ghs.fuse,ghs.tics,ghs.anim_duration = 2,2,3 --Keep it alive!	
			ghs.spritexoffset,ghs.spriteyoffset = s.spritexoffset,s.spriteyoffset
			ghs.color = (COLOR) or SKINCOLOR_XSSUPERBLUR
			ghs.scale = s.scale --Match scale to player 24/7
			ghs.blendmode = BLEND
			if (s.flags2 & MF2_DONTDRAW) or (HIDE==true)
				ghs.flags2 = $|MF2_DONTDRAW
			else
				ghs.flags2 = $ & ~MF2_DONTDRAW
			end	
			if (d == -4) --Inner white blur effect, hiding behind the sprite itself.
				ghs.spritexscale = (s.spritexscale*15)/14
				ghs.spriteyscale = (s.spriteyscale*15)/14
				ghs.spriteyoffset = $-(5<<16+35123)
				if (ghs.color == SKINCOLOR_XSSUPERBLUR)
					ghs.color = SKINCOLOR_SILVER
				end
				if (RENDERER != 2) --Hide all but 2 blur layers from software.
					ghs.flags2 = $|MF2_DONTDRAW
				end
			else
				ghs.spritexscale = s.spritexscale
				ghs.spriteyscale = s.spriteyscale
			end	
			if (s.sprite2 & ~FF_SPR2SUPER)==SPR2_WALK
				ghs.sprite2 = SPR2_TAL6
			end
		end
	end
end

--Spawn an overglow on top of the player? This assumes it IS a player, be careful of that.
--The overglow is a blurry additive effect put on Super Sonic to make him look more like in the show.
--The smoke aura would be the "underlay" instead.
XSon.Overglow = function(s, STYLE, COLOR)
	local ghs
	if not (s.xsoverglow and s.xsoverglow.valid)
		s.xsoverglow = P_SpawnMobjFromMobj(s,0,0,0,MT_XSOVERGLOW)
		ghs = s.xsoverglow
	end
	ghs = s.xsoverglow --Upkeep.
	ghs.style = STYLE
	ghs.target,ghs.tracer = s,s
	ghs.blendmode = AST_ADD
	if STYLE == 2 --Exact copy of object's sprite.
		ghs.skin = s.skin
		ghs.copyframe,ghs.copyskin = true,true
		ghs.sprite,ghs.sprite2 = s.sprite,s.sprite2
		ghs.frame = (s.frame & FF_FRAMEMASK)|FF_TRANS50
	else --Super Sonic!
		ghs.skin = "xsonicoverlay"
		ghs.copyframe,ghs.copyskin = false,false
	end	
	ghs.fuse,ghs.tics,ghs.anim_duration = 2,2,2
	if COLOR
		ghs.colorized = true
		ghs.color = COLOR
	end	return ghs --
end