local firecancel = false
local firesolnic = false --used to track if you used the sol emeralds to become fire sonic

local function DoFireDust(player) //Function based on spindash dust from source. For later.
	local mo = player.mo
	local prandom = {}
	for i = 0, (leveltime%7) >> 1 // 1, 2, 3 or 4 particles
		local particle = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_SPINDUST)
		if (player.realmo.eflags & MFE_UNDERWATER or player.realmo.eflags & MFE_TOUCHWATER)
			particle.state = S_SPINDUST_BUBBLE1
		else
			particle.state = S_SPINDUST_FIRE1
		end
		//particle.fuse = 40
		particle.frame = $|FF_FULLBRIGHT
		particle.target = mo
		//particle.destscale = (mo.destscale << 1)/3
		//P_SetScale(particle, particle.destscale)
		if mo.eflags & MFE_VERTICALFLIP // readjust z position if needed
			particle.z = mo.z + mo.height - particle.height
		end
		prandom[0] = P_RandomFixed()<<2 // P_RandomByte()<<10
		prandom[1] = P_RandomRange(-30, 30) // P_RandomRange(-ANG30/FRACUNIT, ANG30/FRACUNIT)*FRACUNIT
		prandom[2] = P_RandomFixed()<<3 // P_RandomByte()<<11
		P_SetObjectMomZ(particle, player.normalspeed/50 + prandom[0], false)
		P_InstaThrust(particle,
				player.drawangle + prandom[1]*ANG1,
				-FixedMul(player.normalspeed/12 + FRACUNIT + prandom[2], mo.scale))
		P_TryMove(particle, particle.x + particle.momx, particle.y + particle.momy, true)
	end
end

//real
if not solchars
    rawset(_G, "solchars", {})
end
solchars["supersonic"] = {SKINCOLOR_FIRESTORMSUPER, 3}

//Fire Sonic, put together by SuperPhanto
//Shield Abilities re-created by CloneFighter
freeslot("MT_FIRESONIC_AURA1","MT_FIRESONIC_AURA2")

addHook("PlayerSpawn", function(player)
	player.stomping = false
	player.mo.ssmorbing = false
	firesolnic = false
end)

addHook("AbilitySpecial", function(player)
	if player.mrce return end
	if player.pflags & PF_THOKKED return end
	if player.mo.skin != "supersonic" return end
	if player.isTC return end -- i was asked to add this for some reason
	if (player.powers[pw_shield] & SH_FIREFLOWER)
	and not player.hyper.transformed
		P_Thrust(player.mo, player.mo.angle, 60*player.mo.scale)
		player.mo.state = S_PLAY_ROLL
		S_StartSound(player.mo, sfx_s3k43)
		player.pflags = $|PF_THOKKED
		player.flameauratimer = 35
		player.pflags = $ & ~PF_SPINNING
		return true
	end
end)

addHook("ThinkFrame", do
	for player in players.iterate
		if player.mo and player.mo.valid
		and player.mo.skin == "supersonic"
			if player.mo.ssmorbing
				if player.hyper.capable == true
					player.hyper.capable = false -- (:
				end
			end
			if (player.charflags & (SF_CANBUSTWALLS|SF_NOSPINDASHDUST)) //fuckthisfuckthisfuckthisFUCKTHIS -Icezer
				if (player.charflags & SF_CANBUSTWALLS)
				and not ((player.hyper.transformed) or (player.powers[pw_shield] & SH_FIREFLOWER))
					player.charflags = $ & ~SF_CANBUSTWALLS
				end
				if (player.charflags & SF_NOSPINDASHDUST)
				and not (player.powers[pw_shield] & SH_FIREFLOWER)
					player.charflags = $ & ~SF_NOSPINDASHDUST
				end
			end
			//Running effect
			/*if P_IsObjectOnGround(player.mo)
			and ((player.powers[pw_shield] & SH_FIREFLOWER) and player.mo.state == S_PLAY_RUN)
				nothing lol
			end*/
			if (player.solchar and player.mo and solchars[player.mo.skin]) then
				if (player.cmd.buttons & BT_CUSTOM2)
				and not (player.exiting)
				and not (player.solchar.istransformed == 1)
				and not (player.powers[pw_shield] & SH_FIREFLOWER)
				and not (player.hyper.transformed)
				and player.rings >= 75
				and not ultimatemode
					P_PlayJingleMusic(player, "METAM", nil, true, JT_OTHER)
					player.solchar.istransformed = 1
					player.mo.state = S_PLAY_SUPER_TRANS1
					player.hyper.capable = false
					S_StartSound(player.mo, sfx_secir)
					player.powers[pw_extralife] = 0
					player.solchar.emeraldcircle = 1
					player.mo.ssmorbing = true -- it's morbin' time
					if firecancel == true
						firecancel = false
					end
				end
				//Transformation
				if player.SolTransforming
					if player.CancelSolTransform then
						player.mo.ssmorbing = false
						firecancel = true --don't transform when you're fucking not supposed tO SONIC -Icy
						S_StopMusic(player)
						return
					end
					if player.SolTransforming == 1
					and not firecancel -- DON'T. DO IT.
						player.powers[pw_shield] = $|SH_FIREFLOWER
						S_StartSound(nil, sfx_mario3)
						player.rings = $ - 50
						player.solchar.istransformed = 0
						player.mo.ssmorbing = false
						firesolnic = true
					end
				end
			end
			if (player.powers[pw_shield] & SH_FIREFLOWER)
				if P_RandomRange(3, 0) == 0
					local fire = P_SpawnMobjFromMobj(player.mo, P_RandomRange(-18, 18) * FRACUNIT, P_RandomRange(-18, 18) * FRACUNIT, P_RandomRange(0, 32) * FRACUNIT, MT_FLAMEPARTICLE)
					P_SetObjectMomZ(fire, P_RandomRange(1,3)*player.mo.scale, false)
					fire.scale = player.mo.scale
				end
				if not ((player.scolor and player.scolor ~= "default"))
					player.mo.color = SKINCOLOR_FIRESTORMSUPER
				end
				player.realmo.eflags = $|MFE_FORCESUPER
				player.charflags = $|(SF_CANBUSTWALLS|SF_NOSPINDASHDUST)
				if P_IsObjectOnGround(player.mo)
				and (player.pflags & PF_SPINNING)
					if (player.pflags & PF_STARTDASH)
						DoFireDust(player)
					else
						if (player.realmo.eflags & MFE_UNDERWATER or player.realmo.eflags & MFE_TOUCHWATER) continue end
						P_ElementalFire(player)
					end
				end
				if player.flameauratimer == nil
					player.flameauratimer = 0			
				end
				if player.flameauratimer < 0
					player.flameauratimer = $ - 1
				end
				if (player.powers[pw_shield] & SH_FIREFLOWER)
				and (player.cmd.buttons & BT_CUSTOM1)
				and not player.hyper.transformed
				and not P_IsObjectOnGround(player.mo)
				and player.pflags & PF_JUMPED
					player.stomping = true
					player.mo.momz = -30*FRACUNIT*P_MobjFlip(player.mo)
					player.pflags = $|PF_THOKKED
					S_StartSound(player.mo, sfx_s3k43)
					player.pflags = $ & ~PF_SPINNING
				end
				if player.stomping == false
				and player.mo.state == S_PLAY_ROLL
				and player.flameauratimer > 0
					if (leveltime % 2 == 0)
						local aura = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_FIRESONIC_AURA1)
						aura.angle = R_PointToAngle2(0,0,player.mo.momx,player.mo.momy)
						aura.color = player.mo.color
					end
				end
				
				if player.stomping == true
					local sectorthing = P_PlayerTouchingSectorSpecial(player, 0, 0)
					if sectorthing.valid then
						for fof in sectorthing.ffloors()
							if fof.valid and (fof.flags & FF_BUSTUP) and (fof.flags & FF_EXISTS)
							and (abs(fof.topheight - player.mo.z) <= 40*player.mo.scale) then
								EV_CrumbleChain(player.sectorthing, fof)
							end
						end
					end
					if (leveltime % 2 == 0)
						local aura = P_SpawnMobjFromMobj(player.mo,0,0,0,MT_FIRESONIC_AURA2)
						aura.angle = R_PointToAngle2(0,0,player.mo.momx,player.mo.momy)
						aura.color = player.mo.color
					end
					if not (player.mo.eflags & MFE_SPRUNG)
						P_InstaThrust(player.mo, 0, 0)
						player.mo.state = S_PLAY_ROLL
					end
					if P_IsObjectOnGround(player.mo) or player.mo.eflags & MFE_JUSTHITFLOOR
					or player.powers[pw_carry]
					or (P_IsObjectInGoop(player.mo))
					or player.mo.eflags & MFE_SPRUNG
					or ((player.mo.momz*P_MobjFlip(player.mo)) > 2*FRACUNIT)
						player.stomping = false
						if not ((player.mo.eflags & MFE_SPRUNG) or (P_IsObjectInGoop(player.mo) or ((player.mo.momz*P_MobjFlip(player.mo)) > 2*FRACUNIT)))
							player.mo.state = S_PLAY_FALL
							player.pflags = $|PF_NOJUMPDAMAGE|PF_THOKKED
							if (player.realmo.eflags & MFE_UNDERWATER or player.realmo.eflags & MFE_TOUCHWATER)
							and not (player.realmo.eflags & MFE_TOUCHLAVA)
								S_StartSound(player.mo, sfx_s3k4c)
								P_SetObjectMomZ(player.mo, 2*FRACUNIT)
							else
								P_ElementalFire(player, true)
								S_StartSound(player.mo, sfx_s3k47)
								P_SetObjectMomZ(player.mo, 4*FRACUNIT)
							end
						end
					end
				elseif player.mo.eflags & MFE_SPRUNG or player.mo.eflags & MFE_GOOWATER or ((player.mo.momz*P_MobjFlip(player.mo)) > 2*FRACUNIT) then
					player.stomping = false
				end
			elseif (player.realmo.eflags & MFE_FORCESUPER)
				player.realmo.eflags = $ & ~MFE_FORCESUPER
			end
		end
	end
end)

//Pulling this from Supercolor Revamp. why's it in the fire lua? Order of operations.
//2.2.10 will let this hook set the ghost's colors properly, too.
//Thanks to Mari0shi06 for tweaking this to work better.
addHook("MobjThinker", function(ghost)
    if ghost and ghost.valid and ghost.skin == "supersonic"
		if not ((ghost.target) and (ghost.target.valid)) return end
		if not ((ghost.target.player) and (ghost.target.player.valid)) return end
		if ((ghost.target.player.hyper and ghost.target.player.hyper.transformed) and ((ghost.source) and (ghost.source.valid))) return end
		if ghost.target.player.powers[pw_super] >= 2
			ghost.color = ghost.target.color
		end
		if (ghost.target.player.powers[pw_shield] & SH_FIREFLOWER)
		and not (ghost.target.player.scolor and ghost.target.player.scolor ~= "default")
			ghost.color = SKINCOLOR_FIRESTORMSUPER --this is hacky but i don't care
		end
	end
end, MT_GHOST)

//let fireballs give rings lmao
addHook("MobjDamage", function(target, inflictor, source, damage, damagetype)
	if inflictor and inflictor.valid and ((inflictor.type == MT_SPINFIRE) or (inflictor.type == MT_FIREBALL)) and source.type == MT_PLAYER
		//print("e")
		local issuper = false
		for player in players.iterate
			if player.mo and player.mo.valid
			and player.mo.skin == "supersonic"
				issuper = true
			end
		end
		if issuper
			if target.flags & MF_BOSS
			and source.skin == "supersonic" --Double checking since the 'issuper' check isn't enough, apparently.
				P_GivePlayerRings(source.player, 5)
				S_StartSoundAtVolume(target.mo, sfx_kc5e, 105)
			end
			if target.flags & MF_ENEMY
			and source.skin == "supersonic" --Double checking since the 'issuper' check isn't enough, apparently.
				if source.player.hyper.transformed
					P_GivePlayerRings(source.player, 5)
				else
					P_GivePlayerRings(source.player, 3)
				end
				S_StartSoundAtVolume(source, sfx_kc5d, 105)
			end
		end
	end
end)

local yourmom
addHook("PreThinkFrame", function(r)
	yourmom = S_GetMusicPosition()
end)

addHook("MusicChange", function(om, nm)
	if (gamestate != GS_LEVEL) return end
	if (consoleplayer and consoleplayer.mo and consoleplayer.mo.valid
	and consoleplayer.mo.health and consoleplayer.solchar
	and consoleplayer.mo.skin == "supersonic" and consoleplayer.powers[pw_shield] & SH_FIREFLOWER and firesolnic)
	and (nm == "_shoes" or nm == "_inv" or nm == "_minv" or nm == mapmusname)
		if om == "metam"
			return true
		else
			return "metam", 0, true, yourmom
		end
	end
end)