--╔════════════════════════════╗══════════════════════════════════════════════════════════════════════════════════════════════#
--║        Super Sonic         ║ Functions and passive thinkers! Chaos Snap works together with the regular Snap Dive.
--╚════════════════════════════╝══════════════════════════════════════════════════════════════════════════════════════════════#
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

--Attempt an airdash?
XSon.TryAirZipDash = function(p,s,xs, FORCE)
	if xs.zipdash return end --duh
	local RB = xs.FreeFlight
	
	if RB and (not xs.snapdivetrick or RB.canforcezip and (RB.canforcezip < 12))
	or (p.pflags & (PF_JUMPED|PF_NOJUMPDAMAGE))
	or xs.snapdive 
	or xs.snapdivetrick and (xs.snapdivetrick > 10) and not (RB and RB.forcesnap and RB.LockOn and RB.refreshC1)
	or p.panim == PA_FALL or p.panim == PA_SPRING
	or p.panim == PA_WALK or p.panim == PA_RUN or p.panim == PA_IDLE
	or FORCE==true
		if not (p.pflags & (PF_SLIDING|PF_STASIS|PF_FULLSTASIS))
		and not ((p.pflags & PF_SPINNING) and not (p.pflags & PF_JUMPED))
		and not (xs.rollcd and not RB and FORCE!=true)
		and not p.xsringburst 
		and not xs.snapdivekick 
		and not (p.xswallrun and not (RB and RB.WallTransfer))
		and not (xs.ChaosLambent and xs.ChaosLambent.firing)
		and not (xs.ChaosSnap and ((xs.ChaosSnap.init or 0)<7) )
		and not p.powers[pw_carry]
		and not (RB and 
		(RB.haymaker and (RB.haymaker.timer < 17) or RB.painstun and (RB.painstun>4)
		or RB.RingBurstChase and (RB.RBmissed==nil)
		or RB.explosion and (RB.explosion > 10)
		)
		)
			p.pflags = $ & ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_THOKKED|PF_SPINNING)
			xs.custom3 = 0
			XSSnapDiveReset(p, s, xs, true)
			XSon.PrepZipDash(p, s, xs, 3) 
			if xs.zipdash 
				if RB and RB.explosion
					RB.explosion = 0
				end
				if not s.XSstretch
					s.spritexscale,s.spriteyscale = FRACUNIT-8000,FRACUNIT+11500
					s.XSstretch = {timer = 4, Xspeed = 2200, Yspeed = 2800}
				end
				if (RB and RB.WallTransfer) or xs.ChaosLambent
					if(p.cmd.buttons & BT_CUSTOM1) and (xs.direct > 2) --and not xs.walljump
					
						xs.zipdash = 4 xs.zipcontinue = true --Instantly dash again.
						if RB
							RB.WallTransfer  = nil
						end
						S_StopSoundByID(s, sfx_xssfp5) S_StopSoundByID(s, sfx_xssfp4)
					end
				end
				if xs.ChaosLambent
					XSon.RemoveLambentHitBoxes(p)
					xs.ChaosLambent = nil
				end
			end
			return true --
		end
	end	
end

--Super Sonic's passive properties.
XSon.SuperSonicPassive = function(p,s,xs)
	if (p.powers[pw_spacetime] > 0) and (p.powers[pw_spacetime] < 750)
		p.powers[pw_spacetime] = 800 --Infinite spacetime for Super Sonic at Blur's request.
	end
	if not xs.zipdashslide
		if (p.normalspeed < (52<<16)+221)
			p.normalspeed = (s.eflags & MFE_UNDERWATER) and (104<<16)+221 or (52<<16)+221
		end
	end
	if (p.runspeed > (44<<16)+221)
		p.runspeed = (44<<16)+221
	end
	if (p.jumpfactor < FRACUNIT+36000)
		p.jumpfactor = FRACUNIT+36000
	end
	p.charflags = $|SF_NOSKID
	xs.supersonic = true
	
	if (p.powers[pw_super] < 3) and (s.state == S_PLAY_SUPER_TRANS1) --Wrong state! Switch to correct animation.
		XSon.StartTransformation(p,s,xs,1) return --
	elseif (p.powers[pw_super] > 1) or (s.state >= S_PLAY_SUPER_TRANS3)
	
		if not p.scolor or (p.scolor=="default") --Compatibility with supercolors
			if ((XSon.Hyper(p))!=true) 
				s.color = SKINCOLOR_SUPASONIKKU --Use this color, not SUPERGOLD1/2/3/4/5
			end
		end	
		
		--Super Sonic's corona splat effect
		local CCOLOR = (xs.ChaosSnap) and SKINCOLOR_SKY or (s.color==SKINCOLOR_SUPASONIKKU) and SKINCOLOR_YELLOW or s.color
		XSon.ShinySplat(s, CCOLOR, 3, (xs.ChaosSnap) and 97 or 95, false)
		
		if (s.state != S_PLAY_S_XTRANSFORM)
			if s.XSboomshot --Give the Super Sonic Boom projectile properties!
				XSon.BoomShotHitBox(s,800*s.scale,30,21,13,6,2)
			end
			if s.XSSuperRadius --Activate a destruction hitbox.
				P_RadiusAttack(s, s, s.XSSuperRadius, DMG_NUKE, true)
				s.XSSuperRadius = nil
			end
			if s.XSsuperroll --Aerial Zipdash roll.
				if P_IsObjectOnGround(s) or p.powers[pw_carry] or xs.snapdive or p.xsringburst or (XS_CRAPPYPRIORITIES==1)
					s.XSsuperroll = 0
					s.rollangle = 0
				else
					s.XSsuperroll = (s.XSsuperroll<0) and min($+1,0) or max($-1,0)
					s.rollangle = s.XSsuperroll*ANGLE_45
				end
			end
			--Will not allow infinite Super Stun!
			if s.state == S_PLAY_STUN or s.state == S_PLAY_PAIN 
				if (s.tics > 70) or s.tics == -1
					s.tics = 70
					if (s.state == S_PLAY_STUN) and xs.stupidbugoverride != 2 and not (p.pflags & PF_SLIDING)
						xs.stupidbugoverride = 2
						XSon.Quake(so, 80<<16, 5, 1250<<16)
						XSon.ElecticBody(s, 14, s.color)
						XSon.FlickerLight(s)
						XSon.DeTransformGFX(p,s,xs)
						local ghs = XSon.SuperSonicWind(s, SKINCOLOR_FLAME, nil, nil, FRACUNIT-18000)
						ghs.dispoffset = 122			
					end
				end	
			end
			--Play Super Sonic's aura SFX on loop.
			if not s.XSauraSFX or ((not netgame) and not S_SoundPlaying(s, sfx_xssfxy))
				local SPEED = (xs.snapdive or p.xsringburst) and 60 or ((p.speed+abs(s.momz*2))/s.scale) or 0
				local RVolume = (SPEED>30) and max(33, min(60, 104-SPEED)) or 60 --Get less noticable the faster you move.
				s.XSauraSFX = 76
				S_StopSoundByID(s, sfx_xssfxy)
				XSon.Sound(s, sfx_xssfxy, RVolume)
			elseif netgame and not S_SoundPlaying(s, sfx_xssfxy)
				XSon.Sound(s, sfx_xssfxy, 50)
			end
			s.XSauraSFX = max($-1,0)
			
			if xs.FreeFlight and ((XSon.FreeFlight(p,s,xs)) == true) --Freeflight system!
				if xs.snapdivetrick and (xs.snapdivetrick > 10)
					XSon.SnapDiveTrickProperties(p,s,xs)
				elseif s.XSkickextend
					s.XSkickextend = $-1
				end
				if (p.cmd.buttons & BT_CUSTOM1) and ((xs.FreeFlight.custom1 <= 1) or xs.FreeFlight.WallTransfer)
					xs.custom1 = 1
					if XSon.TryAirZipDash(p,s,xs)	 --Super Sonic can zipdash in midair with custom1!
						if xs.FreeFlight
							xs.FreeFlight.forceanim = nil
						end
					end
				end
			elseif xs.custom1 == 1 and not P_IsObjectOnGround(s) and XSon.TryAirZipDash(p,s,xs)	
				--	
			elseif (s.state == S_PLAY_FLOAT) and not (p.cmd.buttons & BT_CUSTOM3)
				s.state = (s.momz*P_MobjFlip(s) > s.scale*10) and S_PLAY_SPRING or S_PLAY_FALL
				p.pflags = $|PF_JUMPED
				
			elseif (xs.custom3 > 10) and (p.cmd.buttons & BT_CUSTOM3) --Funny float?
			and not (p.cmd.buttons & (BT_SPIN|BT_CUSTOM2|BT_CUSTOM1|BT_TOSSFLAG)) and not P_IsObjectOnGround(s)
			
				if ( (s.state == S_PLAY_WALK or p.panim == PA_IDLE or p.panim == PA_RUN or (s.state == S_PLAY_FLOAT))
				or (p.pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) and ((p.panim == PA_JUMP or p.panim == PA_ROLL or p.panim == PA_SPRING or p.panim == PA_FALL) or xs.snapdivetrick and xs.snapdivetrick > 16))
					if not (p.pflags & (PF_THOKKED|PF_GLIDING|PF_SLIDING|PF_SPINNING|PF_FULLSTASIS|PF_STASIS)) 
					and not xs.zipdash and not xs.wallrun and not xs.snapdivetrick and not xs.snapdive and not xs.ringburst
						if (s.state != S_PLAY_FLOAT)
							s.state = S_PLAY_FLOAT
							xs.skydive = 0
							if (xs.custom3 < 99<<16)
								xs.custom3 = 99<<16
								XSon.CrossArmEffect(p,s,xs)
								s.spriteyoffset = -5<<16
							end				
						end
						p.pflags = $ & ~(PF_JUMPED|PF_NOJUMPDAMAGE|PF_STARTJUMP)
						if (p.speed > 28*s.scale) or not xs.direct and p.speed
							s.momx = ((p.speed > 60*s.scale) or not xs.direct) and FixedDiv(FixedMul($, 10), 11) or FixedDiv(FixedMul($, 25), 26)
							s.momy = ((p.speed > 60*s.scale) or not xs.direct) and FixedDiv(FixedMul($, 10), 11) or FixedDiv(FixedMul($, 25), 26)
						end
						if (s.tics <= -1) or (s.tics > 6) or (s.anim_duration <= -1) or (s.anim_duration > 6)
							s.anim_duration, s.tics = 6,6
						end
						if (abs(s.momz) > 4<<16)
							s.momz = (s.momz*P_MobjFlip(s)>FRACUNIT) and FixedDiv(FixedMul($, 25), 26) or FixedDiv(FixedMul($, 3), 4)
						else
							local GRAVITY = P_GetMobjGravity(s) or 8500
							s.momz = ((abs(GRAVITY)/4)-8500)*P_MobjFlip(s)
						end
					end
				end
			else
				if s.state == S_PLAY_EDGE
					if (s.tics > 6)
						s.tics = 6
					end
				elseif (s.state >= S_PLAY_XZIPBRAKESUPER) and (s.state <= S_PLAY_XZIPSLIDE2)
					xs.stupidbugoverride = xs.stupidbugoverride and $+1 or 1
					if (xs.stupidbugoverride > 41)
						XSZipDashCancel(p, s, xs)
						xs.waszipping = false
						RestoreZipDashCam(p, s, xs)
						XSAirGroundState(p, s, xs)
						xs.zipcd = 0
						xs.stupidbugoverride = 0
					end
				elseif (s.sprite2 == SPR2_GLID|FF_SPR2SUPER) --Auto animate!
					s.frame = ($ & ~FF_FRAMEMASK)| ((leveltime%2) and B or A)	
				else
					if s.state == S_PLAY_RUN
						if (leveltime%2) and (p.speed > 40*s.scale)
							P_RadiusAttack(s, s, min(176*s.scale, p.speed+10*s.scale), DMG_NUKE, true)
						end	
					elseif s.state == S_PLAY_STND
						if s.tics == 1
							s.tics = 350
						end
					elseif s.state == S_PLAY_WAIT --Huh? Don't use this animation.
						s.state = S_PLAY_STND
					end
					xs.stupidbugoverride = 0
					if ((xs.custom3 <= 4) and p.cmd.buttons & BT_CUSTOM3) and not xs.FreeFlight
					and not P_IsObjectOnGround(s) and not xs.flightCD and not p.xsringburst
						if (p.pflags & (PF_JUMPED|PF_NOJUMPDAMAGE)) 
						or (p.panim >= PA_WALK and p.panim <= PA_DASH)
						or (p.panim >= PA_ROLL and p.panim <= PA_FALL)
							if XSon.TryFlight(p,s,xs, nil, 111, (s.momz*P_MobjFlip(s)<0) and 222 or 111)
								XSon.Sound(s, sfx_xssfpi)
								XS_RingBurstSparkles(s)	
								XSon.RadiantLight(s)
								XSon.Quake(s, 30<<16, 8, 500<<16)
								for i = -2,2
									local ghs = XSon.TransformGFX2(s, i*188<<16) 
									if ghs and ghs.valid
										ghs.tracer = s
										ghs.momx,ghs.momy,ghs.momz = $+s.momx,$+s.momy,$+s.momz --Rising orbs
									end
								end				
							end
						end
					end
				end 		
			end
		elseif (leveltime % 35 == 0) and (p.powers[pw_super] > 1)
			p.rings = max($+1,2) --Don't lose rings in your transforming animation!
			xs.LastRings = nil
		end
	end

	local SPEEDAJ = p.speed/(4<<16) --Acceleration adjustment. X sonic's is ridiculously high across the board.
	p.acceleration = max(min(63-SPEEDAJ, 52), 36) //Last 2 values. 52 & 36 are max & min.	
	if s.skin != "xsonic"
		XSon.DeTransform(p,s,xs)
	end
end

--Another one for the GFX. Can be used during Chaos Lambent too.
local function ChaosSnapInitGFX(p,s,xs,yu,FF)

	local SPEED = 0
	local TIMER = 1
	if (yu)
		SPEED = yu.speed
		TIMER = yu.timer
	end
	
	XS_RingBurstDust(p, s, xs, 350*s.scale)
	XSon.FlickerLight(s, nil, nil, (not (SPEED)) and ANGLE_90 or nil)
	XS_RingBurstSparkles(s, nil, SKINCOLOR_SUPERSKY5)
	
	local ghs = P_SpawnGhostMobj(s)
	ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
	ghs.blendmode = AST_ADD
	ghs.momx,ghs.momy,ghs.momz = $/-5,$/-5,$/-5
	ghs.colorized = true
	ghs.color = (xs.darkphase) and SKINCOLOR_PURPLE or SKINCOLOR_SUPERSKY2
	ghs.fuse,ghs.tics = 14,99
	ghs.scalespeed = FRACUNIT/(ghs.fuse+1)
	ghs.destscale = 1
	if FF and FF.MeteorSmash and not xs.ChaosLambent
		ghs.sprite2 = SPR2_TAL3|FF_SPR2SUPER
		ghs.frame = C|FF_TRANS50|FF_VERTICALFLIP
		ghs.angle = p.drawangle
		ghs.fuse = 10
	end
	
	if p != displayplayer --and FixedHypot( FixedHypot(z.mo.x-s.x, z.mo.y-s.y), z.mo.z-s.z) < 580*s.scale
		ghs.spritexscale,ghs.spriteyscale = $*3,$*3
	end
	
	--Our colored overlays! Because p.mo.colorized has a risk of being permanent if literally anything happens
	if xs.ChaosLambent and not xs.ChaosSnap
		yu = xs.ChaosLambent
	end
	yu.OverLay = {}
	for i = 1,2
		yu.OverLay[i] = P_SpawnMobjFromMobj(s,0,0,0,MT_XSOVERGLOW)
		local ghs = yu.OverLay[i]
		ghs.dispoffset = 16+(i*8)
		ghs.tracer = s
		ghs.XAura = "scaled"
		ghs.copyframe = true
		XSon.OverGlowThinker(ghs) --Use the thinker, then continue!
		if ghs and ghs.valid
			ghs.fuse = max(1, (TIMER-4)+(i*2))
			ghs.tics = 99
			ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
			ghs.XAura = "scaled"
			ghs.colorized = true
			if xs.darkphase
				ghs.color = (i==2) and SKINCOLOR_FLAME or SKINCOLOR_CRIMSON
				ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS30
			else
				ghs.blendmode = AST_ADD //(i==2) and AST_ADD or AST_TRANSLUCENT
				ghs.color = SKINCOLOR_SUPERSKY5
				if FF and FF.MeteorSmash
					ghs.sprite2 = SPR2_TAL3|FF_SPR2SUPER
					ghs.frame = ($ & ~(FF_TRANSMASK|FF_FRAMEMASK))|C|FF_TRANS50|FF_VERTICALFLIP
					ghs.angle = p.drawangle
					ghs.ditchtracer = 3
					ghs.XAura = "MSmash"
					ghs.GSoffsetX,ghs.GSoffsetY,ghs.GSoffsetZ = -8<<16,-8<<16,-3<<16
					ghs.GSoffsetang = p.drawangle				
					P_Thrust(ghs, ghs.angle, -24*s.scale)
					for i = 1,3
						local ths = XS_CircleWave(s, 1, SKINCOLOR_SKY)
						ths.blendmode = AST_ADD
						ths.tracer,ths.ditchtracer = s,3
						ths.sprite = SPR_XSG2
						ths.fuse,ths.tics = ($+2)/2,($+2)/2
						ths.frame = (28+i)|(FF_TRANS50+(i<<16))
						ths.scalespeed = ($*3)/i
						P_Thrust(ths, ghs.angle, -28*i*s.scale)	
					end
				else
					ghs.frame = ($ & ~FF_TRANSMASK)|((i==2) and FF_TRANS20 or FF_TRANS50)
				end		
			end
			if i == 1
				ghs.ditchtracer = 3
				ghs.sttfade = 16
				ghs.fuse = 6
			else
				ghs.fuse = max(1, TIMER-2)
				ghs.scale = $*3/2
				ghs.destscale = s.scale*2
				ghs.sttfade = true
			end
		end
	end
	local ghs = XS_CircleWave(s, (SPEED) and 1 or 2, s.color, 10, (SPEED) and FRACUNIT+5111 or 2<<16)
	ghs.frame = E|FF_TRANS60
	ghs.spriteyoffset = $-20<<16
	
	XSon.sparkles(p,s,xs, 38, 5, 5, 2<<16, (xs.darkphase) and SKINCOLOR_BLACK or SKINCOLOR_SUPERGOLD2, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT)
end

--Called at the very start of the Chaos Snap
local function ChaosSnapInit(p,s,xs, yu)
	S_StopSoundByID(s, sfx_xssfxz) S_StopSoundByID(s, sfx_xssfp8)
	yu.SFX = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
	yu.SFX.flags2 = MF2_DONTDRAW yu.SFX.tics = 99 yu.SFX.fuse = 99
	S_StartSoundAtVolume(yu.SFX, sfx_xssfxz, 240)
	
	yu.init,s.rollangle = 0,0
	p.xsringburst,p.xswallrun,p.xstauntstance = nil
	yu.hitspring = 0
	s.eflags = $ & ~(MFE_JUSTHITFLOOR|MFE_SPRUNG|MFE_APPLYPMOMZ)
	
	local FF = xs.FreeFlight
	if not xs.snapdivetrick
		if FF
			if FF.RingBurstChase
				s.momx,s.momy,s.momz = $/2,$/2,$/2
			end
			if FF.explosion
				FF.explosion = 0
			end
			FF.shock = nil
			
			local SFX = (xs.FourKidsRB) and sfx_xssfpz or sfx_xssfxx
			S_StopSoundByID(s, SFX)
			FF.pressedC2 = max(FF.pressedC2 or 0, 5)
			FF.refreshC1,FF.MeteorSmashed,FF.painstack,FF.CantHitLambence = nil
		--	if not FF.holdcam
		--		FF.holdcam = (xs.direct > 20) and 1 or 2
		--	end	
			if (xs.custom2 > 9) and (p.cmd.buttons & BT_CUSTOM2)
				xs.custom2 = 2
			end
			if (FF.custom2 > 9)
				FF.custom2 = 2
			end
		end
		
		xs.jump = (p.cmd.buttons & BT_JUMP) and 99<<16 or 0
		xs.spin = (p.cmd.buttons & BT_SPIN) and 99<<16 or 0
		s.XSkickextend,s.XSstretch,xs.zipstretch,xs.zipstretch2,xs.spinstretch,xs.jumpstretch,xs.edgestretch = nil
		s.spriteyoffset = 0 --Disable all the other stretchy crap!
		
		if yu.speed and yu.angle != nil --Shoot forwards?
			P_InstaThrust(s, yu.angle, yu.speed)
			s.spritexscale = 2<<16 s.spriteyscale = FRACUNIT
		else
			s.spritexscale = FRACUNIT s.spriteyscale = 2<<16
			p.drawangle = s.angle
		end
		
		if yu.momz --Set momz? Auto-accounts for MobjFlip.
			if (p.cmd.buttons & BT_SPIN) or yu.didrise
				local YMOMZ,SMOMZ = yu.momz*P_MobjFlip(s),s.momz*P_MobjFlip(s)
				if not ((YMOMZ > 0) and (SMOMZ >= YMOMZ))
				and not ((YMOMZ < 0) and (SMOMZ <= YMOMZ))
					s.momz = (p.cmd.buttons & BT_SPIN) and abs(YMOMZ)*-1*P_MobjFlip(s) or abs(YMOMZ)*P_MobjFlip(s)
				end
				yu.didrise = true
			end
		elseif yu.Zmomdiv --Divide current momz?
			s.momz = $/yu.Zmomdiv				
		end
		if yu.XYmomdiv --Divide speed by...?
			s.momx = $/yu.XYmomdiv
			s.momy = $/yu.XYmomdiv
		end
	end
	if ((XSon.Hyper(p))==true)
		XSon.Quake(s, 99<<16, 3, 750*s.scale)
		P_NukeEnemies(s, s, 1150<<16)
		S_StartSound(yu.SFX, sfx_zoom)
		if (xs.direct>18) and (p.speed < (185+xs.direct)*s.scale) 
			P_Thrust(s, R_PointToAngle2(s.x, s.y, s.x+s.momx, s.y+s.momy), (xs.direct/2)*s.scale)
		end
	end	
	ChaosSnapInitGFX(p,s,xs,yu,FF) --Now ANOTHER set of effects.
end

--Chaos...SNAP!! Hey, don't blame me for Shadow naming it first. It's just Sonic's Snap Dive with Chaos Control. ChaosSnap"
XSon.ChaosSnap = function(p,s,xs,yu)
	local RB = xs.FreeFlight
	--================================Ending Conditions=====================================	
	if not yu.timer --Instant cancel.
	or p.powers[pw_carry] or p.xsringburst or p.xswallrun 
	or ((s.eflags & MFE_SPRUNG) and yu.init) or not xs.supersonic
	
		XSon.RemoveCSOverlay(xs)
		
		if not xs.snapdivetrick
			s.spritexscale,s.spriteyscale = FRACUNIT,FRACUNIT
			p.pflags = $ & ~PF_THOKKED
			xs.snapdive,xs.snapdivetrick = 0,0
			xs.ringburstcd = 0
			XSSnapDiveReset(p, s, xs)
			if RB and not (p.cmd.buttons & (BT_JUMP|BT_SPIN))
				RB.spin = 0 RB.truespin = 0 RB.jump = 0
			end
		end
		if xs.FreeFlight and (p.cmd.buttons & BT_CUSTOM1)
			xs.FreeFlight.custom1 = 0
		end
		xs.ChaosSnap = nil return --We're done.
		
	elseif xs.snapdivetrick or xs.snapdivekick --Transition into an attack!
	or (s.state >= S_PLAY_XKICK1) and (s.state <= S_PLAY_XKICK4)
	
		if not yu.FINISH
			yu.FINISH = true
			S_StopSoundByID(s, sfx_thok)
			if not S_SoundPlaying(s, sfx_xssfxz)
				XSon.Sound(s, sfx_xssfxz)
			end
			--Snap effects!
			XSon.FlickerLight(s)
			if not xs.snapdivekick
				XSon.ElecticBody(s, 5, SKINCOLOR_SUPERGOLD4)
				XSon.LightningStrike(s, SKINCOLOR_SILVER)
				
				local ghs = XS_CircleWave(s, 2, SKINCOLOR_FLAME, 8, FRACUNIT)
				ghs.sprite = SPR_XSG4
				ghs.renderflags = RF_FLOORSPRITE|RF_FULLBRIGHT|RF_NOCOLORMAPS
				ghs.frame = O|FF_TRANS50
				ghs.sttfade = true
				if not P_IsObjectOnGround(s)
					ghs.z = s.z-(16*s.scale*P_MobjFlip(s))
				end
				XS_QuickDust(s, (xs.darkphase) and SKINCOLOR_RUBY or SKINCOLOR_SUPERSKY5, AST_ADD, nil, nil, N|FF_TRANS20)
				local RNG1 = XSon.RNG(4,11,s)
				XSon.sparkles(p,s,xs, RNG1*3, RNG1, (XSon.RNG(-14,14,s)) or 8, 
				(s.momz*2/3)+7<<16, (xs.darkphase) and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERSKY4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT, FF_TRANS20, 32-RNG1)
			end
			XS_MediumDust(s, (xs.darkphase) and SKINCOLOR_RUBY or SKINCOLOR_SUPERGOLD4, AST_ADD, Q|FF_TRANS40)		
			
			if (yu.timer > 5) yu.timer = 5 end
			if yu.init == nil yu.init = 0 end 
			if xs.snapdivetrick 
				XSon.RemoveCSOverlay(xs, 6, 99<<16)
			end
		end
	elseif P_IsObjectOnGround(s) and (s.momz*P_MobjFlip(s)<=0) --Half-cancel if you hit the ground.
		if yu.FINISH != 2
			if (p == displayplayer) and yu.SFX and yu.SFX.valid
				S_StopSound(yu.SFX)
			end
			if yu.FINISH != true
				if not S_SoundPlaying(s, sfx_xssfxz)
					XSon.Sound(s, sfx_xssfxz, 210)
				end
				local RNG1 = XSon.RNG(4,11,s)
				
				XSon.sparkles(p,s,xs, RNG1*3, RNG1, (XSon.RNG(-14,14,s)) or 8, (s.momz*2/3)+7<<16, 
				xs.darkphase and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERSKY4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT, FF_TRANS20, 32-RNG1)
				
				XS_QuickDust(s, (xs.darkphase) and SKINCOLOR_RUBY or SKINCOLOR_SUPERSKY5, AST_ADD, nil, nil, N|FF_TRANS20)	
				XS_MediumDust(s, (xs.darkphase) and SKINCOLOR_RUBY or SKINCOLOR_SUPERGOLD4, AST_ADD, Q|FF_TRANS50)
				XS_RingBurstDust(p, s, xs, 100*s.scale)
				XSon.FlickerLight(s)
				XSon.sparkles(p,s,xs, 32, 6, 6, 5<<16, (xs.darkphase) and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERGOLD4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT)
			
				local ghs = P_SpawnGhostMobj(s)
				ghs.fuse = 14 ghs.tics = 99
				ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
				ghs.blendmode = AST_ADD
				ghs.colorized = true
				ghs.momx,ghs.momy = s.momx/2,s.momy/2
				ghs.scalespeed = FRACUNIT/10
				ghs.destscale = 99<<16
				ghs.color = (xs.darkphase) and SKINCOLOR_RED or SKINCOLOR_SUPERSKY5
				ghs.frame = ($ & ~FF_TRANSMASK)|FF_TRANS60
				if (yu.timer > 4) 
					yu.timer = 4
					if (p.speed > 40*s.scale)
						s.momx,s.momy = $/2,$/2
					end
					if yu.init == nil yu.init = 0 end --Don't run init at this stage!
				end
				XSon.RemoveCSOverlay(xs,4,99<<16)
			end			
			yu.FINISH = 2
		end
	end

	--===========================Beginning=====================================================	
	if yu.init == nil --The very start!
		ChaosSnapInit(p,s,xs,yu) --Gonna local function this for organization.
	else 
		if yu.init == 2	
			local ghs,ths = XS_RingBurstStripes(s, s.color, AST_ADD, -16<<16, nil, p.drawangle)
			if (p.speed < 46*s.scale) and ghs and ghs.valid and ths and ths.valid
				if yu.momz and ( (p.cmd.buttons & (BT_JUMP|BT_SPIN)) or yu.didrise)
				and not (XS_CRAPPYPRIORITIES==1)
					ghs.rollangle = $+((s.momz<0) and ANGLE_270 or ANGLE_90)
					ths.rollangle = $+((s.momz<0) and ANGLE_270 or ANGLE_90)
				end
			end
		elseif yu.init == 3
			if yu.momz and yu.didrise != true --and (p.cmd.buttons & (BT_JUMP|BT_SPIN)) 
				local YMOMZ,SMOMZ = yu.momz*P_MobjFlip(s),s.momz*P_MobjFlip(s)
				if not ((YMOMZ > 0) and (SMOMZ >= YMOMZ))
				and not ((YMOMZ < 0) and (SMOMZ <= YMOMZ))
					s.momz = (p.cmd.buttons & BT_SPIN) and abs(YMOMZ)*-1*P_MobjFlip(s) or abs(YMOMZ)*P_MobjFlip(s)
				end
				yu.didrise = true
			end
		elseif yu.init == 4
			XS_RingBurstDust(p, s, xs, 250*s.scale)
			if not xs.snapdivetrick
				local ghs = XS_CircleWave(s, 1, SKINCOLOR_XSSUPERBLUR, 9, FRACUNIT+7777)
				ghs.frame = Q|FF_TRANS70
				if (s.momz*P_MobjFlip(s) > 3*s.scale)
					ghs.frame = $|FF_VERTICALFLIP
				end
			end
		end
	end
	
	--==========================Continuous======================================================	
	
	yu.init = $+1 --Perpetual changes
	yu.timer = max($-1,0)
	xs.ringburstcharge,xs.falltransition = 0,0
	xs.rollcd = 2
	p.pflags = $ & ~(PF_SPINNING|PF_CANCARRY)
	
	if (yu.timer > 5)
	
		if yu.init != 1
			if yu.speed and yu.angle != nil
				s.spritexscale = max($-20500, 1)
				s.spriteyscale = min(FRACUNIT/2, max($-6500, 1))
			else
				s.spritexscale = min(FRACUNIT/2, max(1, $-6500))
				s.spriteyscale = max($-20500, 1)
			end
			if yu.timer == 6 and not xs.snapdivetrick
			and not (P_IsObjectOnGround(s) and (yu.init > 2))
				if not (p.cmd.buttons & BT_JUMP)
					if (s.momz*P_MobjFlip(s) > 4*s.scale)
						s.momz = $/2
					else
						P_SetObjectMomZ(s, -2<<16, true)
					end
				end
			end
		end
		if (p.cmd.buttons & BT_SPIN) and (p.speed < 70*s.scale)
			local FLOORZ = (s.eflags & MFE_VERTICALFLIP) and abs((s.z+s.height)-s.ceilingz) or abs(s.z-s.floorz)
			if (FLOORZ < 24*s.scale) and not xs.snapdivetrick and not xs.snapdivekick
				p.cmd.buttons = $|BT_JUMP & ~BT_SPIN
				xs.spin = 0
				if RB
					RB.spin = 0
				end
			end
		end
	else
		if not yu.timer and (yu.init < 5)
			if not xs.snapdivetrick
				s.spritexscale,s.spriteyscale = FRACUNIT,FRACUNIT
			end
			XSon.FlickerLight(s)
			XSon.sparkles(p,s,xs, 32, 6, 6, 5<<16, (xs.darkphase) and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERGOLD4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT)
		else
			if yu.timer == 5
				XSon.FlickerLight(s, nil, nil, ANGLE_45)
			elseif yu.timer == 1
				local RNG1 = XSon.RNG(3,11,s)
				XSon.sparkles(p,s,xs, RNG1*3, RNG1, XSon.RNG(-14,14,s) or 8, (s.momz*2/3)+7<<16, 
				xs.darkphase and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERSKY4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT, max(FF_TRANS30, ((RNG1-2)/FRACUNIT)), 32-RNG1)
			end
			if not xs.snapdivetrick				
				if (yu.timer <= 1) and (s.momz*P_MobjFlip(s)>10*s.scale) and not P_IsObjectOnGround(s)		
					s.state = RB and S_PLAY_RUN or (p.speed>40*s.scale) and S_PLAY_XZIPLEAP or S_PLAY_SPRING
					s.tics = min($,20)
					if not s.XSstretch
						s.spritexscale,s.spriteyscale = FRACUNIT-5000,FRACUNIT+14000
						s.spriteyoffset = -2<<16
						s.XSstretch = {timer = 3, Xspeed = 1600, Yspeed = 4500, air = true}	
					end				
				else --Return to your normal shape!
					if yu.timer == 3
						XS_RingBurstStripes(s, (xs.darkphase) and SKINCOLOR_CRIMSON or SKINCOLOR_SILVER, AST_ADD, -11<<16)	
					end
					s.spritexscale = (yu.speed) and min(FRACUNIT, $+14500) or min(FRACUNIT, $+23000)
					s.spriteyscale = (not yu.speed) and min(FRACUNIT, $+14500) or min(FRACUNIT, $+23000)				
				end
				if yu.timer == 2
					if not S_SoundPlaying(s, sfx_xssfxz)
						XSon.Sound(s, sfx_xssfxz, 182)
					end					
				end
			end
		end
	end
	if RB and ((p.cmd.buttons & BT_SPIN) or ((xs.direct > 30) and not (p.cmd.buttons & BT_JUMP)))
	and (s.momz*P_MobjFlip(s) < 5*s.scale)
	and not (xs.snapdivetrick or xs.snapdivekick or (s.state >= S_PLAY_XKICK1) and (s.state <= S_PLAY_XKICK4))
		if P_IsObjectOnGround(s)
			s.z = $+(8*s.scale*P_MobjFlip(s))
			P_SetObjectMomZ(s, 14<<16)				
			RB.noZcontrol = max(RB.noZcontrol or 0, 7)
		else
			local FLOORZ = (s.eflags & MFE_VERTICALFLIP) and s.ceilingz or s.floorz
			if (abs((s.z+s.momz)-FLOORZ) < 61*s.scale)
				P_SetObjectMomZ(s, 6<<16)
			end
		end
	elseif P_IsObjectOnGround(s) 
	or (xs.snapdivetrick or xs.snapdivekick or (s.state >= S_PLAY_XKICK1) and (s.state <= S_PLAY_XKICK4))
		return --Don't continue further if we're grounded, or in a trick/kick animation
	end 
	
	if (p.cmd.buttons & BT_SPIN) --Descend!
		if (s.momz*P_MobjFlip(s) >= 6*s.scale)
			s.momz = $/2
		elseif not (s.momz*P_MobjFlip(s) < -60*s.scale)
			local MOMZ = (abs(s.momz)<33*s.scale) and -(2<<16+42500) or -97500
			if RB and not (RB.LockOn and RB.LockOn.valid) MOMZ = $*5/2 end --Freeflight doesn't have gravity, so boost this.
			P_SetObjectMomZ(s, MOMZ, true)
		end
	end
	if (p.cmd.buttons & BT_JUMP) or (RB and RB.custom2 == 1) --Ascend!
		if not (p.cmd.buttons & BT_SPIN) and not (RB and RB.LockOn and RB.LockOn.valid)
			local GRAVITY = P_GetMobjGravity(s) or 1
			s.momz = $+( (abs(GRAVITY)/4)*P_MobjFlip(s) )
		end
		if (xs.jump <= 3) or (RB and RB.custom2 == 1)
			if (yu.init > 3)  --Cancel the teleport to immediately do it again?
			and not (RB and RB.LockOn and RB.LockOn.valid and (RB.SnapOverHeat>32))
				local INIT = yu.init
				XSSnapDiveReset(p, s, xs, true)
				if (abs(s.z-s.floorz) < 9*s.scale)
					s.z = $+(2*s.scale*P_MobjFlip(s))
				end
				p.pflags = $|PF_JUMPED & ~(PF_SPINNING|PF_NOJUMPDAMAGE|PF_THOKKED|PF_JUMPDOWN|PF_USEDOWN)
				XSon.RemoveCSOverlay(xs,3)
				XSStartSnapDive(p, s, xs, true) return --
			end
		end
--	elseif RB and (xs.direct > 22) and (s.momz*P_MobjFlip(s) > -7*s.scale)
--		P_SetObjectMomZ(s, -FRACUNIT/3, true) --Always go a little down when flying.
	end
	if (p.cmd.buttons & BT_CUSTOM1) and (yu.init > 8) and (xs.custom1 <= 8)
		xs.custom3,xs.rollcd = 0,0
		if XSon.TryAirZipDash(p,s,xs)
			yu.timer,s.rollangle = 0,0
			XSon.RemoveCSOverlay(xs, 3)
			XSSnapDiveReset(p, s, xs)
			p.pflags = $ & ~(PF_THOKKED|PF_JUMPED|PF_NOJUMPDAMAGE)
			xs.spin = 850 return --
		end
	end
end

--Remove Chaos Snap Overlay, either by timer or instant deletion.
XSon.RemoveCSOverlay = function(xs, TIMER, GROW) 
	if not (xs.ChaosSnap and xs.ChaosSnap.Overlay) return end --
	local yu = xs.ChaosSnap
	for i = 1,2	
		if yu.Overlay[i]
			local ghs = yu.OverLay[i]
			if not TIMER
				if ghs.valid
					ghs.state = S_NULL
				end yu.Overlay[i] = nil
			elseif ghs.valid
				if (TIMER > ghs.fuse)
					ghs.fuse = TIMER
					if ((ghs.frame & FF_TRANSMASK) < FF_TRANS80) and (ghs.blendmode == AST_TRANSLUCENT)
						ghs.frame = $+FF_TRANS10
					end
					if GROW
						ghs.scalespeed = FRACUNIT/7
						ghs.destscale = GROW
					end
				end
				ghs.sttfade = true
			end
		end
	end
end

--Make your projectile actually ACT like a projectile?
XSon.BoomShotHitBox = function(s, RAD, FUSE1,FUSE2,FUSE3,FUSE4,FUSE5)
	if not s.XSboomshot.valid s.XSboomshot = nil return end --
	local t = s.XSboomshot if not t.fuse return end --
	FUSE5 = (FUSE5) or 2 --Keep activating your Sonic Boom shot!
	if t.fuse == FUSE1 or t.fuse == FUSE2  or t.fuse == FUSE3 or t.fuse == FUSE4 or t.fuse == FUSE5
		if t.fuse == FUSE2
			S_StartSound(t, sfx_beelec)			
		elseif t.fuse == FUSE1
			S_StartSound(t, sfx_xssfxc)
			S_StartSound(t, sfx_xssfxy)
		end
		RAD = (RAD) or 500*s.scale
		local ghs = P_SpawnMobjFromMobj(t, t.momx, t.momy, t.momz-(RAD/3), MT_XSLAMBENTHB)
		if ghs and ghs.valid
			ghs.radius,ghs.height = RAD,RAD*3/4
			ghs.momx,ghs.momy = t.momx*2,t.momy*2
			ghs.momz = t.momz
			P_Thrust(ghs, t.angle, 3)	
			ghs.KillType = "SonicBoom"
			ghs.tics,ghs.fuse = 3,3
			ghs.target = s ghs.tracer = s
		end
end	end

--The finisher beam against SA2's Final Hazard! "XSon.ChaosLambent" ChaosBeam"
XSon.ChaosLambent = function(p,s,xs,yu)
	if yu==nil or ((yu.init or 0) > 51)
		if xs.ChaosLambent.SFX and xs.ChaosLambent.SFX.valid xs.ChaosLambent.SFX.state = S_NULL end	
		XSon.RemoveLambentHitBoxes(p)
		xs.ChaosLambent = nil
		if P_IsObjectOnGround(s)
			s.eflags = $|MFE_JUSTHITFLOOR
		end
		s.spritexoffset = 0 s.spriteyoffset = 0
		S_StopSoundByID(s, sfx_xssfp1) return false --
	end
	local yu = xs.ChaosLambent local RB = yu
	if yu.init == nil --Start up
		yu.init = 0
		yu.frame = A
		yu.Zangle = 0
		if yu.ruin and yu.ruin.valid
			yu.ruin.state = S_NULL
		end
		S_StopSoundByID(s, sfx_xssfp3) S_StopSoundByID(s, sfx_xssfp4) S_StopSoundByID(s, sfx_xssfp5)
		XSon.Sound(s, sfx_xssfpr)
		XSon.Sound(s, sfx_xssfp1)
		
		yu.SFX = P_SpawnMobjFromMobj(s, 0,0,0, MT_THOK)
		yu.SFX.fuse = 28 yu.SFX.tics = 28 yu.SFX.flags2 = MF2_DONTDRAW
		XSon.Sound(yu.SFX, sfx_xssfp6)
		
		p.viewrollangle,s.rollangle = 0,0
		s.momx,s.momy,s.momz = 0,0,$/2
		s.XSkickextend = nil
		
		s.spritexscale,s.spriteyscale = FRACUNIT-13000,FRACUNIT+18000
		s.spriteyoffset = 4<<16
		s.XSstretch = {timer = 8, Xspeed = 1600, Yspeed = 1800}	
		
		XSon.ElecticBody(s, 12, SKINCOLOR_SUPERGOLD4)
		local ghs = XSon.ElecticBody(s, 6, SKINCOLOR_CRIMSON)
		ghs.frame = $|FF_HORIZONTALFLIP
		
		ghs = XSon.FlickerLight(s, nil, 9, nil, FF_HORIZONTALFLIP, 2<<16+25000)
		ghs.spriteyoffset = $+6<<16
		ghs.dispoffset = 99
		
		XSon.DeTransformGFX(p,s,xs, "ghosts")
		XSon.ExpandingGlow(s, SKINCOLOR_SUPASONIKKU, 18, 97, true, AST_ADD)
		p.xssuperflash = {trans = FF_TRANS80, timer = 2, speed = 1, reversephase = true, COLOR = SKINCOLOR_SUPERORANGE4}
		
		yu.jump,yu.spin = 0,0
		local FF = xs.FreeFlight
		if FF
			if FF.explosion
				FF.explosion = 0
			end
			if not FF.counters and not FF.countered
			or FF.painstun and (FF.painstun > 2)
				FF.dontextendagain = nil
			end
			xs.stopbutton,xs.stopstick = 0,0
			FF.refreshC1,FF.MeteorSmash,FF.MeteorSmashed,FF.painstack,FF.CantHitLambence = nil
			FF.cantsnap = 0
		end
	end
	--Main thinker.
	yu.init = $+1
	if P_IsObjectOnGround(s)
		s.z = $+(9*s.scale*P_MobjFlip(s))
		P_SetObjectMomZ(s, 4<<16, true)
	end	
	local FF = xs.FreeFlight
	if FF
		FF.forceanim = nil
		FF.recordtap = 0 
		FF.rocketspin = 0 
		FF.rocketjump = 0
		FF.rocket = 0
		FF.lambentCD = 7
		if yu.noHB
			yu.noHB = $-1
		end
	end
	if yu.struggle
		XSon.LambentStruggle(p,s,xs,FF,yu) 
	elseif yu.checksight 
		yu.checksight = $-1
	end
	if yu.ghstable --Iterate through a table every few tics, spawning hitboxes.
		if yu.struggledone==true
		or not yu.noHB and not yu.struggle
		and ((yu.init%2) or (yu.init<19) or yu.init==32)
			local shine,IX = yu.ghstable,1
			local ADD = abs(yu.Zangle or 0) if ADD==0 ADD=1 end
			local RAD = 600*s.scale //(553-min(99,yu.init*2)) *s.scale
			local HEIGHT = 800*s.scale //(1000- min(200,yu.init*3)) *s.scale
			for _,ghs in pairs(shine)		
				if ghs and ghs.valid and not (ghs.NoKillType)
					local hb = ghs.clHB
					local MIN = (HEIGHT/2)+(HEIGHT/7) //min(1600<<16, max(250<<16, 575*ghs.scale)) + max(0, min(150*s.scale, ADD*2))
					local MOMX,MOMY,MOMZ = ghs.momx*8,ghs.momy*8,ghs.momz
					if (abs(yu.Zangle or 0) > 9*s.scale)
						MOMX,MOMY = ghs.momx*4,ghs.momy*4 --Hitbox stuttering for better accuracy without needing more.
					end
					if (IX%2==0) --Hitbox stutter.
						if (IX%8==0)
							MOMX,MOMY,MOMZ = $/9,$/9,$/9
						elseif (IX%6==0)
							MOMX,MOMY,MOMZ = $/2,$/2,$/2 
						else
							MOMX,MOMY,MOMZ = $/3,$/3,$/-3 
						end
					end
					if not (hb and hb.valid)
						local MPLUS = max(0, min(150*s.scale, ADD*2))
						hb = P_SpawnMobjFromMobj(ghs, MOMX, MOMY, MOMZ-(MIN+MPLUS), MT_XSLAMBENTHB)
						if hb and hb.valid
							ghs.clHB = hb
							if yu.ChaosControl==true
								hb.XChaosControlHB = true --Deals a bit more damage.
							end
							hb.KillType = "SonicBoom"
							hb.GFX = ghs
							hb.radius = RAD --max(250<<16, 575*ghs.scale) + min(250*s.scale, ADD) + (24<<16)
							hb.height = HEIGHT --(MIN+MPLUS)*2
							hb.target,hb.tracer,hb.ChaosBeam = s,s,s					
						end
					else
						if (IX%8==0)
							P_MoveOrigin(hb, ghs.x+MOMX, ghs.y+MOMY, ghs.z+MOMZ-(MIN/3))
						elseif (IX%2==0) and not (IX%4==0)
							P_MoveOrigin(hb, ghs.x, ghs.y, ghs.z-MIN)
						else
							P_MoveOrigin(hb, ghs.x+MOMX, ghs.y+MOMY, (ghs.z+MOMZ)-MIN)
						end
					end
					if hb and hb.valid
						hb.checksight = (yu.checksight) and true or false
						hb.fuse,ghs.tics = 8,8
						hb.momx,hb.momy = MOMX*4/3, MOMY*4/3
						hb.momz = MOMZ or 1
						if not hb.momx hb.momx = 1 end
						IX = $+1
					end
				end
			end
		end	
	end
	yu.firing = ((yu.init > 13) and (yu.init < 47)) and true or false	
	
	local FANGLE = (xs.forceangle and xs.forceangle.angle) or p.drawangle --Angle to use.
	if (yu.init > 16)
		yu.frame = (yu.init%2) and C or B
	end
	
	if (yu.init < 36)
		local INIT = yu.init
		if (INIT < 16) --Charging up, shifting back, ready to fire.
		
			local STEP = (yu.ChaosControl==true) and -48*s.scale or -16*s.scale
			P_TryMove(s, s.x+FixedMul(STEP, cos(FANGLE)), s.y+FixedMul(STEP, sin(FANGLE)), true)
			
			if FF and FF.LockOn and FF.LockOn.valid and FF.LockOn.player and FF.LockOn.player.xsonictable
				local t = FF.LockOn local tp = t.player local xss = tp.xsonictable local RBB = xss.FreeFlight
				if RBB and not (yu.struggledone==true) and not (yu.struggle)
				
					if yu.ChaosControl==true --Now we're in Chaos Control!
						if RBB.delaycam == 1
							xss.hudboost = 3
							xss.zoomlines = 12 --NNnnnnnnooooooOOOOOOOOOOOOOOAAAAAAAAAAAAHHH!!!!!!
							xs.zoomlines = 7 --HAAAAAAAAAAAAAAAAAAAAAAAA!!!!
						end
						if (INIT < 11) or (INIT%2==0)
							XS_RingBurstSparkles(s, 26, SKINCOLOR_SUPERSKY5)
							
							local RNG1 = XSon.RNG(4,11,s)
							XSon.sparkles(p,s,xs, RNG1*3, RNG1, XSon.RNG(-14,14,s) or 8, 
							7<<16, SKINCOLOR_SUPERSKY4, AST_ADD, FF_TRANS20, 32-RNG1)
							
							if (INIT%2==0)
								local ghs = P_SpawnGhostMobj(s) --Giant avatar ghosts.
								ghs.sprite2 = SPR2_MLEL|FF_SPR2SUPER
								ghs.frame = B|FF_TRANS10|FF_FULLBRIGHT
								ghs.scale = (s.scale*4)/3
								ghs.scalespeed = (INIT%4==0) and FRACUNIT/5 or FRACUNIT/4
								ghs.destscale = 99<<16
								ghs.momx,ghs.momy,ghs.momz = s.momx,s.momy,s.momz/2
								ghs.fuse,ghs.tics = 6,99
								ghs.blendmode = AST_ADD
								ghs.color,ghs.colorized = SKINCOLOR_SUPERSKY2+min(4,INIT/2), true
								ghs.dispoffset = 110+(INIT*2)
								ghs.spritexscale = $*3/2
								ghs.spriteyoffset = $-8<<16
								if p==displayplayer
									P_Thrust(ghs, FANGLE+(XSon.RNG(-15,15,ghs)*ANG1), -8*s.scale)
								elseif not (splitscreen)
									P_Thrust(ghs, FANGLE+(XSon.RNG(-15,15,ghs)*ANG1), 8*s.scale)
								end	
								if (INIT%4==0)
									ghs.spritexscale,ghs.spriteyscale = $*4,$/2
								elseif INIT==10 and yu.ChaosDelay
									yu.ChaosDelay = max($-2,0)
									yu.init = 8
								end							
								local ghs = FF.flicker
								if not (FF.flicker and FF.flicker.valid)
									FF.flicker = XSon.Overglow(s, 2, SKINCOLOR_SKY)
									ghs = RB.flicker
								end
								if ghs and ghs.valid
									ghs.sprite2 = SPR2_MLEL|FF_SPR2SUPER
									ghs.renderflags = RF_FULLBRIGHT|RF_NOCOLORMAPS
									ghs.frame = B|FF_TRANS10	
									ghs.color,ghs.colorized = SKINCOLOR_CORNFLOWER, true
									ghs.fuse,ghs.tics,ghs.sttfade = 3,3,1	
									ghs.dispoffset = 149
									P_MoveOrigin(ghs, s.x, s.y, s.z)
									if not (INIT%6==0)
										ghs.flags2 = $ & ~MF2_DONTDRAW
										XSon.OverGlowThinker(ghs)
									else
										ghs.flags2 = $|MF2_DONTDRAW
									end
								end
							end
							P_Thrust(t, FANGLE, (xss.zipdash or tp.speed<80*s.scale) and 4*s.scale or (tp.speed < 180*s.scale) and 3*s.scale or s.scale)
						end	
						xs.stopstick,xs.stopbutton,FF.snapCD,FF.magicC3 = 2,2,2,3
						FF.cantsnap,FF.SnapCD,FF.CantHitLambence = 3,3,3
						RBB.blackbars = 4
						RBB.blackbarsshow = max(RBB.blackbarsshow or 0, 5) 
						
					elseif (FF.PvPENERGY > 9800) and FF.magicC3==1 --Wanna use Chaos Control?
					
						local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
						ghs.flags2 = MF2_DONTDRAW ghs.tics,ghs.fuse = 99,99 S_StartSound(ghs, sfx_xssfxz) 
						
						yu.ChaosControl = true --The REAL name of the move!
						t.momz = $*3/4 --Slow target's vertical momentum a bit.
						
						local RNG1 = XSon.RNG(4,11,s)
						XSon.sparkles(p,s,xs, RNG1*3, RNG1, XSon.RNG(-14,14,s) or 8, 
						7<<16, SKINCOLOR_SUPERSKY4, AST_ADD, FF_TRANS20, 32-RNG1)
						
						local Zoff = -((183*8)<<16)
						for i = -3,2
							local ghs = XSon.TransformGFX2(s, Zoff) --Rising orbs
							if ghs and ghs.valid
								ghs.tracer = nil
								ghs.color,ghs.colorized = SKINCOLOR_CORNFLOWER, true
								ghs.spritexscale = ($*(5-min(4,abs(i)))) *4/5
							end Zoff = $+(188<<16)
						end	
						ghs = XSon.RadiantLight(s, SKINCOLOR_SKY, 28, nil, S|FF_TRANS20, 5<<16)
						if ghs and ghs.valid
							ghs.tracer = nil
							ghs.sttfade = 21
							ghs.spriteyscale = $*4
							ghs.spritexscale = $*2/3
						end
						
						P_MoveOrigin(s, t.x, t.y, t.z)
						XSon.Quake(t, 160<<16, 7, 2100<<16)
						
						local TA = t.angle+ANGLE_180
						if xss.zipdash or xss.zipdashslide
							tp.cmd.buttons = $ & ~BT_CUSTOM1
							xss.stopbutton,xss.stopstick = 2,2
							if (xss.zipdash > 5) and xss.zipdashangle!=nil
								if not xss.zipdashslide
									xs.zipdashslide = 1
									xs.custom1,xs.spin = 0,0
									XSon.ZipDashSlideTimer(tp,t,xss, 120)
								end
								TA = xss.zipdashangle+ANGLE_180
								xss.forceangle = {angle = xss.zipdashangle, timer = 8, nosangle = true}
							end
						end
						P_MoveOrigin(s, t.x, t.y, t.z)
						
						for i = 1,8
							P_TryMove(s, t.x-t.momx+FixedMul(128*t.scale, cos(TA)), t.y-t.momy+FixedMul(128*t.scale, sin(TA)), true) 
						end
						FF.PvPENERGY = max(0, min(10000, $-6050)) --Subtract a ton of energy up front!
						p.drawangle,s.angle = TA,TA
						p.cmd.angleturn = TA>>16
						yu.init = nil
						ChaosSnapInitGFX(p,s,xs,nil,FF)
						
						local Zoff = -((183*8)<<16)
						for i = -5,3
							local ghs = XSon.TransformGFX2(s, Zoff) --Rising orbs
							if ghs and ghs.valid
								ghs.color,ghs.colorized = SKINCOLOR_CORNFLOWER, true
								ghs.spritexscale = ($*(5-min(4,abs(i)))) *4/5
							end Zoff = $+(188<<16)
						end	
						ghs = XSon.ElectricBody(s, 16, SKINCOLOR_NOBLE)
						ghs.destscale = 99<<16
						ghs.frame = ($ & ~FF_TRANSMASK)|FF_HORIZONTALFLIP
						ghs.blendmode = AST_TRANSLUCENT
						ghs.tracer = s
						ghs.spriteyoffset = $-8<<16
										
						XSon.EarthQuake(s, 7, 300*s.scale, 1, 70000, FRACUNIT/5, ANG30, 32|FF_TRANS40, 28, SKINCOLOR_SKY, AST_ADD)
						
						XSon.SwapStretch(p, s, xs)
						s.spritexscale,s.spriteyscale = 5000,FRACUNIT+55000
						s.spriteyoffset = 9<<16
						s.XSstretch = {timer = 6, Xspeed = 9999, Yspeed = 9999}	
						
						p.xssuperflash = {trans = FF_TRANS50, timer = 10, speed = 1, reversal = 5, COLOR = SKINCOLOR_CORNFLOWER}
						tp.xssuperflash = p.xssuperflash
						ghs = XSon.RadiantLight(s, SKINCOLOR_CORNFLOWER, 18, nil, S|FF_TRANS10, 4<<16)
						if ghs and ghs.valid
							ghs.tracer = s
							ghs.sttfade = 17
							ghs.spriteyscale = $*2
							ghs.spritexscale = $/2
						end
						XSVoice(p, s, xs, sfx_xsvopq, "ForceEcho")
						S_StopSoundByID(s, sfx_xssfp8)
						
						local ghs = P_SpawnMobjFromMobj(s,0,0,0, MT_THOK)
						ghs.flags2 = MF2_DONTDRAW ghs.tics,ghs.fuse = 99,99
						S_StartSound(ghs, sfx_xssfxz)  S_StartSound(ghs, sfx_xssfe2)
						S_StartSoundAtVolume(nil, sfx_xssfxz, 255, tp) S_StartSoundAtVolume(nil, sfx_xssfxz, 210, p)
					
						xss.ZoomLines = 0
						RBB.delaycam = 13 --The camera won't immediately reveal where you are!
						yu.ChaosDelay = 10 --Give extra time to react, naturally.
						yu.firing = false
						if (tp.speed < 42*s.scale) and (p.panim >= PA_IDLE) and (tp.panim <= PA_RUN)
						and not (RBB.haymaker or RBB.painstun or RBB.RingBurstChase or xss.zipdash or xss.ChaosSnap)
							P_InstaThrust(t, FANGLE, 42*s.scale)	
						end
						local Zoff = -((183*8)<<16)
						for i = -4,5 
							local ghs = XSon.TransformGFX2(s, Zoff) --Rising orbs
							if ghs and ghs.valid
								ghs.color,ghs.colorized = SKINCOLOR_KETCHUP, true
								ghs.spritexscale = ($*(5-min(4,abs(i)))) *4/5
							end Zoff = $+(188<<16)
						end
						XSon.ChaosLambent(p,s,xs,yu) return --
					end
					if (INIT < 12)
						if RBB.painstun and (RBB.painstun > 15) and not (RBB.painstun >= FRACUNIT)
							RBB.painstun = 15
						end					
						RBB.forcesnap = 10
					end
				end
			else
				p.XSscalecam = 20
				p.camerascale = (p.pflags & PF_ANALOGMODE) and FRACUNIT-9000 or FRACUNIT-3800				
			end		
			if (INIT%6==0)
				local ghs = XS_RingBurstShine(p, s, xs, true)
				if yu.ChaosControl==true and ghs and ghs.valid
					ghs.color,ghs.colorized = SKINCOLOR_SUPERSKY5, true
				end
			elseif (INIT==14)
				xs.ZoomLines = 8
			elseif (INIT==9) and FF
				FF.CantHitLambence = 10  --You can do this, go for that Beam Clash!
			end
		else
			
			--The massive initial blast!
			if INIT == 16
				xs.forceangle = {angle = FANGLE, timer = 29, nosangle = true} 
				S_StopSoundByID(s, sfx_xssfpr) S_StopSoundByID(s, sfx_xssfp1)
				XSVoice(p, s, xs, sfx_xssfp6, "ForceEcho")
				if yu.struggle or yu.ChaosControl==true
					if yu.ChaosControl==true and not (yu.struggle)
						FF.PvPENERGY = max(0, min(10000, $-1500)) --This is a two stage process.
					end
					if (abs(p.aiming) > ANG1)
						yu.Zangle = AngleFixed(p.aiming)/2
					end
				else
					if p.aiming
						p.aiming = $/2
					end
					if (p.cmd.buttons & BT_JUMP) and not (p.cmd.buttons & BT_SPIN)  --Aim up and down!
						yu.Zangle = 25*s.scale
					elseif (p.cmd.buttons & BT_SPIN) and not (p.cmd.buttons & BT_JUMP)
						yu.Zangle = -25*s.scale
					end
					if FF
						FF.windlines = 6
						FF.noZcontrol = 25
						FF.noXYcontrol = 25
						P_TryMove(s, s.x+FixedMul(-40*s.scale, cos(FANGLE)), s.y+FixedMul(-40*s.scale, sin(FANGLE)), true)
					end					
				end
				P_SetObjectMomZ(s, FRACUNIT, true)
				xs.hudboost = 1
				
				s.spritexscale,s.spriteyscale = FRACUNIT+20000,FRACUNIT-15000
				s.spriteyoffset = 4<<16					
				s.XSstretch = {timer = 8, Xspeed = 1600, Yspeed = 1800}	
				p.xssuperflash = {trans = FF_TRANS10, timer = 15, speed = 2, reversephase = true, COLOR = SKINCOLOR_SUPERSILVER1}
			
				yu.frame = B
				s.sprite2 = SPR2_MLEL|FF_SPR2SUPER
				s.frame = (s.frame & ~FF_FRAMEMASK)|B	
				XSon.Quake(s, 90<<16, 18, 1600<<16)
				XS_RingBurstWave(s, 14, s.color, 2<<16)
				XS_QuickDust(s, SKINCOLOR_SUPERSKY5, AST_TRANSLUCENT, nil, nil, N|FF_TRANS10)	
				XS_RingBurstDust(p, s, xs, 100*s.scale)
				XSon.FlickerLight(s)
				XSon.sparkles(p,s,xs, 32, 6, 6, 5<<16, (xs.darkphase) and SKINCOLOR_LAVENDER or SKINCOLOR_SUPERGOLD4, (not xs.darkphase) and AST_ADD or AST_TRANSLUCENT)
		
				XSon.DeTransformGFX(p,s,xs)
				XSon.ExpandingGlow(s, SKINCOLOR_YELLOW, 17, 95, true, AST_ADD)
				XSon.ExpandingGlow(s, SKINCOLOR_RUBY, 21, 100, true, AST_ADD)
				XSon.SuperSonicBoomShot(s, 70*s.scale, 0, nil, 31, FF_TRANS10,  "noboom", xs)
			
				P_RadiusAttack(s, s, 500*s.scale, DMG_NUKE, true)
			end
			--Autoaim at target if not manually firing.
			if yu.Zangle==nil 
			or yu.ChaosControl==true
			or yu.struggle
			or (yu.struggledone==true)
			or INIT==16 and not (yu.Zangle)
			or INIT==16
			and not ((p.cmd.buttons & BT_JUMP) and not (p.cmd.buttons & BT_SPIN))
			and not ((p.cmd.buttons & BT_SPIN) and not (p.cmd.buttons & BT_JUMP))
				local t = FF and FF.LockOn
				if t and t.valid
					local DIST = FixedHypot(s.x-(t.x+t.momx), s.y-(t.y+t.momy))
					local ZDIST = (s.z+s.momz)-(t.z+t.momz)
					local ZAIM = (abs(ZDIST)>10<<16) and FixedInt(ZDIST) or 0 
					if ZAIM
						local CDIST = (DIST>100<<16) and FixedInt(DIST) or 100
						ZAIM = $*17*(ANG1/CDIST)
						if ZAIM
							local NANGLE = FixedInt(AngleFixed(ZAIM)) --Gonna try and make this shit actually readable...
							if (t.z >= s.z)	
								if (NANGLE <= 290)
									ZAIM = 0 -- -ANG60
								else
									ZAIM = min($,0)
								end
							else
								if (NANGLE >= 70)
									ZAIM = 0 -- ANG60 
								else
									ZAIM = max($,0)
								end
							end
							local NEWANG = ZAIM/ANG1
							if (abs(NEWANG) >= 1)
								yu.Zangle = (-NEWANG)*((s.scale*11)/3) --Autoaim
							end
						end
					end	
					if yu.ChaosControl==true and ((INIT<=16) or (INIT > 18) and (INIT < 29))
					or yu.struggle or yu.struggledone
						FANGLE = R_PointToAngle2(s.x, s.y, t.x+t.momx, t.y+t.momy)
						if xs.forceangle
							xs.forceangle = {angle = FANGLE, timer = 4, nosangle = true}
						end
						p.drawangle,s.angle = FANGLE,FANGLE
					else
						P_Thrust(t, FANGLE, (t.player and (t.player.speed < 84*t.scale)) and 24*t.scale or t.scale) --Push foe
					end
				end
				if yu.struggle --In a beam struggle?
					yu.struggle = $+1
					yu.jump = (p.cmd.buttons & BT_JUMP) and $+1 or 0
					yu.spin = (p.cmd.buttons & BT_SPIN) and $+1 or 0
				end	
			end			
			if (INIT < 49) --Shot recoil and sprite shaking!
				if FF and FF.LockOn and not yu.checksight
				and not yu.struggle and not yu.struggledone 
					if P_CheckSight(s, FF.LockOn)
						yu.checksight = 3
					end
				end
				s.spritexscale,s.spriteyscale = FRACUNIT-2,FRACUNIT+2 --Violently shake at this part.
				s.spritexoffset = XSLocalRNG(-4<<16-35000,4<<16+35001,s)
				s.spriteyoffset = XSLocalRNG(4<<16+35000,-4<<16-35000,s)	
				s.XSstretch = {timer = 2, Xspeed = 1, Yspeed = 1}

				XSon.FlightWindLines(s, 400*s.scale, nil, FF_TRANS10|FF_FULLBRIGHT, FRACUNIT+25000, 12, SKINCOLOR_FLAME)
				XSon.FlightWindLines(s, 700*s.scale, {
				XY = XSLocalRNG(50, 230,s)*s.scale,
				EZ = XSLocalRNG(-210,200,s)*s.scale },
				FF_TRANS10|FF_FULLBRIGHT, FRACUNIT+44000, 22, SKINCOLOR_RUBY)	
				
				if not yu.struggle --Allow very minor horizontal aim after firing.
					local RECOILANG,RECOIL = FANGLE,s.scale
					if (INIT%2) and (abs(p.cmd.sidemove) > 33) and xs.forceangle and xs.forceangle.angle != nil
					and not ((s.flags2 & MF2_TWOD) or twodlevel)
						xs.forceangle.angle = (p.cmd.sidemove > 0) and $-(ANG1*3) or $+(ANG1*3)
						RECOILANG = (p.cmd.sidemove > 0) and $-ANGLE_45 or $+ANGLE_45
						RECOIL = (INIT%3==0) and $*18 or $*24 --Shift violently to the side.
					end
					P_TryMove(s, s.x+FixedMul(-RECOIL, cos(RECOILANG)), s.y+FixedMul(-RECOIL, sin(RECOILANG)), true)
				end
			end
		end
		--Repeatable effects, both visual and in hitbox!
		if INIT == 16 or INIT == 25 or INIT == 33 or INIT == 21 or INIT == 35
		or (INIT > 16) and (INIT%2==0)
			if (INIT < 23) and (p.rings > 2) 
			and not (yu.struggle) and not (yu.struggledone==true) --This drains rings!
				if FF and FF.LockOn and FF.LockOn.valid
					if FF.PvPHEALTH and (FF.PvPHEALTH > 1)
					and ((FF.PvPtime or 0) > 16) and not yu.ChaosControl==true
						FF.PvPHEALTH = max($-49,1)
					end
				elseif p.rings
					p.rings = max($-1,0)
				end
			end
			s.momx,s.momy,s.momz = $/2,$/2,$/2
			local ghs,ths
			local RNG = XSon.RNG(2,26,s)		
			for i = 1,2
				if i == 1 
					if (INIT%4==0)
						ghs,ths = XS_MediumDust(s, SKINCOLOR_WHITE, AST_TRANSLUCENT, Q|((yu.struggle) and FF_TRANS50 or FF_TRANS30), (36+(RNG*2))*s.scale, FANGLE)
					elseif yu.struggle and (INIT%2==0)
						ghs = XSon.SmokeMist(s, 0, 99*s.scale)						
					end
				elseif (INIT%4==0)
					ghs,ths = XS_RingBurstStripes(s, (INIT%4==0) and SKINCOLOR_WHITE or s.color, (INIT%4==0) and AST_ADD or AST_TRANSLUCENT, 9<<16)
				end
				if ghs and ghs.valid
					P_Thrust(ghs, FANGLE, (27-RNG)*-s.scale)
					if yu.struggle
						local NEWZ = -(XSLocalRNG(-128,96,s)<<16)/2
						ghs.z = $+(NEWZ/i)
					end
				end
				if ths and ths.valid	
					P_Thrust(ths, FANGLE, (27-RNG)*-s.scale)
					if yu.struggle
						local NEWZ = -(XSLocalRNG(-128,96,s)<<16)/2
						ths.z = $+(NEWZ/i)
					end				
				end
			end

			local DIFFPLAYER = false
			if displayplayer and (displayplayer != p) or splitscreen
				DIFFPLAYER = true
			end			
			local HIDE = 0 
			if (consoleplayer)
				if (CV_FindVar("renderer").value) != 2
					HIDE = 2 --TRY not to crash shitty-ass software, pls.
				elseif (netgame==true) and DIFFPLAYER==true
					HIDE = 1
				end
			end
			--Do some complicated hitbox shit to save performance. Not for the sake of FPS, but so the effect can get even more intense!
			local CCcolor = (yu.ChaosControl) and SKINCOLOR_SKY or SKINCOLOR_FLAME
			local CCcolor2 = (yu.ChaosControl) and SKINCOLOR_SUPERSKY4 or SKINCOLOR_XSSUPERAURA
			for i = 1,3
				if i == 1 and INIT != 16 and INIT != 28 
					continue --
				end
				local ghs = XSon.RadiantLight(s, (i==1) and CCcolor or (i==2) and CCcolor2 or s.color, 
				(yu.ChaosControl==true and not (yu.struggle)) and 40 or 31, nil, S|FF_TRANS10, (i==1) and FRACUNIT-25000 or FRACUNIT)
				if ghs and ghs.valid
					ghs.dispoffset = -70*i
					ghs.spriteyoffset = $+8<<16
					ghs.target = s
					if i != 1
						P_Thrust(ghs, FANGLE, (i==3) and 100*s.scale or 59*s.scale)
						ghs.frame = $|((i==2) and FF_HORIZONTALFLIP or 0)
						ghs.tracer = nil
						ghs.spriteyoffset = $+(6<<16)						
						if yu.Zangle
							ghs.momz = $+yu.Zangle
						end
						if INIT == 25 or INIT == 33 or INIT == 21
							P_Thrust(ghs, FANGLE, INIT*s.scale)
							P_MoveOrigin(ghs, ghs.x+ghs.momx+FixedMul((INIT*23)*s.scale, cos(FANGLE)), ghs.y+ghs.momy+FixedMul((INIT*23)*s.scale, sin(FANGLE)), ghs.z)
							if ghs.momz
								ghs.momz = $*2
							end
							ghs.scalespeed = FRACUNIT/5	 continue --
						end
						if i == 3
							ghs.scale = $/2 //(INIT < 24) and $/4 or $/2
							ghs.scalespeed = FRACUNIT/7
							ghs.sttYspeed = (INIT%4==0) and 6<<16 or 15<<16
							if s.XSfirstshot and s.XSfirstshot.valid --Spawn particle effects around a chosen projectile
								if INIT != 16
									local SHOT = s.XSfirstshot 
									
									local bpp = XSon.SuperSonicWind(SHOT, (INIT%4==0) and SKINCOLOR_XSSUPERAURA or SKINCOLOR_SILVER, 
									59, (INIT%4==0) and FF_TRANS10|FF_HORIZONTALFLIP or FF_TRANS10, FRACUNIT+XSLocalRNG(9999,48500,s))
									bpp.spriteyoffset = $+(XSLocalRNG(-102,0,s)<<16)
									bpp.sttYspeed = -5500-(XSLocalRNG(-65500,9500,bpp))
									
									local FLOORZ = XSon.GetFloorZ(SHOT)
									if FLOORZ != nil 
									and (abs(s.z-FLOORZ) <  ((yu.Zangle and (yu.Zangle > 0)) and 444*s.scale or 777*s.scale))
									and not (FLOORZ > s.z+225*s.scale)
										local bpp = XS_RingBurstDust(p, SHOT, xs, "manual", FLOORZ)
										bpp.renderflags = ($ & ~RF_SEMIBRIGHT)|RF_FULLBRIGHT
										bpp.spritexscale = (INIT<20) and $*3 or $*4
										bpp.spriteyscale = (INIT&3==0) and $*5/2 or $*2
										if DIFFPLAYER==true
											bpp.spritexscale = (INIT<20) and $*4 or $*5/3
										end
										bpp.destscale = 99<<16
										bpp.scalespeed = FRACUNIT/max(4, 57-(INIT*4/3))
										bpp.sttspeed = 4 bpp.sttfade = 18
										P_Thrust(bpp, s.angle, -(INIT+36)*s.scale)
										bpp.fuse = 37 bpp.tics = 55
										bpp.frame = ($ & ~FF_TRANSMASK)|FF_TRANS10|((INIT%4==0) and FF_HORIZONTALFLIP or 0)
										if (INIT > 20)
											for i = 1,3
												local ROCK = XS_CraterSpew(SHOT, XSLocalRNG(0,356+(i*6),SHOT), 14-i)
												if ROCK and ROCK.valid
													ROCK.z = FLOORZ+(24*s.scale)
													ROCK.spritexscale,ROCK.spriteyscale = $*i,$*i
													ROCK.momz = $+((22-i*3)*s.scale*P_MobjFlip(s))
													ROCK.momx = ($*i*2)-(SHOT.momx/3)
													ROCK.momy = ($*i*2)-(SHOT.momy/3)
													ROCK.fuse = 66
													ROCK.ROCK = nil
												end
											end
										else
											bpp.color = SKINCOLOR_XSSUPERAURA bpp.colorized = true
										end
									end
								end				
							else
								s.XSfirstshot = ghs
							end
						else
							ghs.sttYspeed = (INIT%4==0) and -1 or -FRACUNIT
						end			
					else
						ghs.GSoffsetX = 70*s.scale ghs.GSoffsetY = 70*s.scale ghs.GSoffsetZ = s.height/2
						ghs.spriteyscale = $*2/3 ghs.spritexscale = $*2/3
						ghs.ditchtracer = 5
					end
					if yu.struggle and not (yu.struggledone==true)
						if yu.struggleDIV and yu.struggleDIV != 100 --Adjust beam for a struggle.
							ghs.tics = FixedDiv(FixedMul($,100),yu.struggleDIV)
							ghs.fuse = FixedDiv(FixedMul($,100),yu.struggleDIV)
							if yu.struggleBEAM != 100 --Beam gets larger when pressured by the other beam
								ghs.spritexscale = FixedDiv(FixedMul($,100),yu.struggleBEAM)
								ghs.spriteyscale = FixedDiv(FixedMul($,100),yu.struggleBEAM)
								if (yu.struggleBEAM < 75) --You're going to lose!
									ghs.color = SKINCOLOR_RUBY
								end
							end
						end
					end
					if (i==3)
						if (INIT > 14) and ghs
							if yu.struggledone==true
							or yu.struggle and (INIT%6==0)
							or not yu.struggle and (INIT%2==0)
							or (INIT < 18)
							or INIT==27
								if yu.ghstable==nil yu.ghstable = {} end
								table.insert(yu.ghstable, ghs)
							end
						end
					elseif (HIDE==2) and (i==2) and (INIT%4==0)
					or (HIDE) and (i==1) and (INIT%6==0)
						ghs.flags2 = $|MF2_DONTDRAW
					end
					if displayplayer and (displayplayer != p) or splitscreen==true
						ghs.spritexscale,ghs.spriteyscale = $+((2<<16)+22500),$*5/4 --Only do this for other players, don't blind the player shooting!
					end
				end
			end	
		end
	elseif (yu.init > 45) and xs.FreeFlight --Buffer into other actions?
		if xs.FreeFlight.custom2 xs.FreeFlight.custom2 = 0 end
		if xs.FreeFlight.custom1 or xs.FreeFlight.spin xs.FreeFlight.spin = 0 xs.FreeFlight.custom1 = 0 end
	end
	s.sprite2 = SPR2_MLEL|FF_SPR2SUPER
	s.frame = (s.frame & ~FF_FRAMEMASK)|yu.frame
	
/*	local TRUEINIT = (INIT-15)
	local HBSIZE,HBDIST = 601*s.scale, INIT*100*s.scale
	if (INIT < 25)
		HBDIST = 250*s.scale*TRUEINIT
		HBSIZE = 500*s.scale
	elseif ZADD != 1
		HBDIST = 300*s.scale*(TRUEINIT-5)
		HBSIZE = $+(30*s.scale)
	end */
	
	if s.xsoverglow and s.xsoverglow.valid
		XSon.OverGlowThinker(s.xsoverglow)
	end
	return true --
end