freeslot(
	"S_PLAY_FCRASH"
)

--thanks for this circle function alfredo, you're a lifesaver
local function ftdcircle(mobj, mobjtype, ns, vertical, vertangle)
	local i = 0	while i < 40
		local fa = (i*(ANGLE_180/20))
		local mo = P_SpawnMobjFromMobj(mobj, 0, 0, -50*FRACUNIT*P_MobjFlip(mobj)*mobj.scale, mobjtype)
		if mo and mo.valid
			if mobjtype == MT_FLAMEJETFLAME
				mo.source = mobj
				mo.target = mobj
				if (mobj.player.solchar and mobj.player.solchar.istransformed)
				    mo.scale = 1*FRACUNIT
				else
				    mo.scale = 1*FRACUNIT/2
				end
				mo.blendmode = AST_ADD
				if mobj.player.powers[pw_super]
				or (mobj.player.solchar and mobj.player.solchar.istransformed) 
				or G_GametypeHasTeams()
					mo.color = mobj.color
					mo.colorized = true
				end
			end
			if vertical
				mo.momz = FixedMul(sin(fa),ns)/2
				P_InstaThrust(mo, vertangle+ANGLE_90,
				FixedMul(cos(fa),ns)/2)
			else
				mo.momx = FixedMul(sin(fa),ns)/2
				mo.momy = FixedMul(cos(fa),ns)/2
			end
		end
		i = $+1
	end
end
local function ftdcirclesmall(mobj, mobjtype, ns, vertical, vertangle)
	local i = 0	while i < 20
		local fa = (i*(ANGLE_180/10))
		local mo = P_SpawnMobjFromMobj(mobj, 0, 0, -5*FRACUNIT*P_MobjFlip(mobj)*mobj.scale, mobjtype)
		if mo and mo.valid
			if mobjtype == MT_FLAMEJETFLAME
				mo.source = mobj
				mo.target = mobj
				if (mobj.player.solchar and mobj.player.solchar.istransformed)
				    mo.scale = 1*FRACUNIT
				else
				    mo.scale = 1*FRACUNIT/2
				end
				mo.blendmode = AST_ADD
				if mobj.player.powers[pw_super]
				or (mobj.player.solchar and mobj.player.solchar.istransformed) 
				or G_GametypeHasTeams()
					mo.color = mobj.color
					mo.colorized = true
				end
			end
			if vertical
				mo.momz = FixedMul(sin(fa),ns)/2
				P_InstaThrust(mo, vertangle+ANGLE_90,
				FixedMul(cos(fa),ns)/2)
			else
				mo.momx = FixedMul(sin(fa),ns)/2
				mo.momy = FixedMul(cos(fa),ns)/2
			end
		end
		i = $+1
	end
end
addHook("PlayerThink",  function(p)
	if not(p.mo and p.mo.valid) return end //CBW
	if p.ftd == nil
		local ftd = {
		crashing = false,
		crashjump = false,
		jumpdown = false,
		spindown = false,
		flipkiller = false,
		canflip = false,
		dontspamfire = false,
		doesthefunny = false,
		statelast = string,
		crashstart = 0,
		cstage = 1,
		cstagelast = 1,
		cstagetimer = 0,
		cpowervert = 0,
		cpowerhor = 0,
		cleappower = 0,
		cdashpower = 0,
		cleaptimer = 0,
		storedspeed = 0,
		storedspeed2 = 0,
		thoktrail = 0,
		divethoked = 0,
		pressjump = nil
		}
		if p.mo.skin == "flame"
			p.ftd = ftd
		else
			p.ftd = nil
		end
	end
	local B = CBW_Battle
	----------------------
	--actual flame stuff--
	----------------------
	if p.mo.health and p.mo.skin == "flame" //CBW
		--Are you doing the flame crash?
		if p.ftd.crashing == true
		and not p.powers[pw_carry]
			p.pflags = $ | PF_JUMPED
			--Flame crash thrusting
			--momz check so you can badnikbounce
			if p.mo.momz*P_MobjFlip(p.mo) <= 0
				P_InstaThrust(p.mo, p.mo.angle, p.ftd.cpowerhor)
				P_SetObjectMomZ(p.mo, p.ftd.cpowervert, false)
				if p.mo.state == S_PLAY_FCRASH
					p.drawangle = p.mo.angle
				end
				if p.mo.state != S_PLAY_FCRASH
					p.mo.state = S_PLAY_FCRASH
				end
				if (leveltime%3)
					local flameafterimage = P_SpawnGhostMobj(p.mo)
					flameafterimage.colorized = true
					flameafterimage.color = p.mo.color
					flameafterimage.blendmode = AST_ADD
				end
			end
			if p.mo.momz*P_MobjFlip(p.mo) > 0 
				
				if p.mo.state == S_PLAY_FCRASH
					p.mo.state = S_PLAY_JUMP
				end
				p.ftd.canflip = true
				p.ftd.crashing = false
			end
		end	
		
		--brute forcing this because heck this game
		if p.mo.state == S_PLAY_FCRASH and p.mo.momz*P_MobjFlip(p.mo) > 0
			p.mo.state = S_PLAY_JUMP
		end
		if (p.mo.eflags & MFE_SPRUNG) and p.ftd.statelast == S_PLAY_FCRASH
			p.mo.momz = $*5/4
			p.mo.momx = $*5/4
			p.mo.momy = $*5/4
			S_StartSound(p.mo, sfx_sprong)
		end
		--timer for power of the crash
		if p.ftd.crashing
			if p.ftd.cstage < 3
				if not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
					p.ftd.cstagetimer = $ + 1
				else
					p.ftd.cstagetimer = $ + 2
				end
			end
			if not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
				if p.ftd.cstage < 3 and p.ftd.cstagetimer == 18
					p.ftd.cstage = $ + 1
					p.ftd.cstagetimer = 0
				end
			else
				if p.ftd.cstage < 3 and p.ftd.cstagetimer == 22
					p.ftd.cstage = $ + 1
					p.ftd.cstagetimer = 0
				end
			end
			if p.ftd.cstage > 3
				p.ftd.cstage = 3
			end
		end
		--crash-leap
		--if you're on the ground, stop thrusting downwards idiot
		if P_IsObjectOnGround(p.mo)
			if p.ftd.crashing == true
				p.ftd.crashing = false
				p.ftd.crashjump = true
			end
			if p.ftd.crashjump == false
				p.ftd.cstage = 1
				p.ftd.cstagetimer = 0
			end
		else
			p.ftd.crashjump = false
		end
		--set the power of the crash dependant on the stage of the crash
		if p.ftd.cstage == 1 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
			p.ftd.cpowerhor = 20*FRACUNIT
			p.ftd.cpowervert = -20*FRACUNIT
			p.ftd.cleappower = 0*FRACUNIT
		end
		if p.ftd.cstage == 2 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
			p.ftd.cpowerhor = 30*FRACUNIT
			p.ftd.cpowervert = -30*FRACUNIT
			p.ftd.cleappower = 18*FRACUNIT
			p.ftd.cdashpower = 50*FRACUNIT
		end
		if p.ftd.cstage == 3 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
			p.ftd.cpowerhor = 45*FRACUNIT
			p.ftd.cpowervert = -45*FRACUNIT
			p.ftd.cleappower = 33*FRACUNIT
			p.ftd.cdashpower = 88*FRACUNIT
		end
		if (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
			/*p.ftd.cpowerhor = 60*FRACUNIT
			p.ftd.cpowervert = -60*FRACUNIT
			p.ftd.cleappower = 40*FRACUNIT
			p.ftd.cdashpower = 90*FRACUNIT*/
			if p.ftd.cstage == 1
				p.ftd.cpowerhor = 35*FRACUNIT
				p.ftd.cpowervert = -35*FRACUNIT
				p.ftd.cleappower = 0*FRACUNIT
			end
			if p.ftd.cstage == 2
				p.ftd.cpowerhor = 50*FRACUNIT
				p.ftd.cpowervert = -50*FRACUNIT
				p.ftd.cleappower = 33*FRACUNIT
				p.ftd.cdashpower = 60*FRACUNIT
			end
			if p.ftd.cstage == 3
				p.ftd.cpowerhor = 70*FRACUNIT
				p.ftd.cpowervert = -70*FRACUNIT
				p.ftd.cleappower = 55*FRACUNIT
				p.ftd.cdashpower = 100*FRACUNIT
			end
		end
		--if p.cmd.buttons & BT_CUSTOM1
		--print(p.ftd.cstagetimer)
		--end
		--if on the ground and not crashjumping kill stat stuff idk im tired and i cant explAINNNNN
		if P_IsObjectOnGround(p.mo) and p.ftd.cstage == 1
			p.ftd.cstage = 1
			p.ftd.cstagetimer = 0 
		end
		--crash-leap
		if P_IsObjectOnGround(p.mo) 
		and p.ftd.crashjump == true 
		and p.ftd.cstage > 1
		and p.mo.state == S_PLAY_ROLL
		  p.ftd.thoktrail = 1
		end
		if P_IsObjectOnGround(p.mo) 
		and p.ftd.crashjump == false
		  p.ftd.thoktrail = 0
		end
		if P_IsObjectOnGround(p.mo) 
		and not p.mo.state == S_PLAY_ROLL
		  p.ftd.thoktrail = 0
		end
		if p.powers[pw_carry]
		or P_PlayerInPain(p)
		  p.ftd.thoktrail = 0
        end		
		if P_IsObjectOnGround(p.mo) 
		or p.powers[pw_carry]
           p.ftd.divethoked = 0
		end
		// THIS IS THE THING YOU ARE LOOKING FOR LOGAN!!!!!
	//	if p.ftd.thoktrail == 1
	    //   if (leveltime%3)
			//		local flameafterimage = P_SpawnGhostMobj(p.mo)
			//		flameafterimage.colorized = true
			//		flameafterimage.color = p.mo.color
			//		flameafterimage.blendmode = AST_ADD
		//   end
		//end
		//Detect jump inputs
        if p.ftd.pressjump == nil
        or not (p.cmd.buttons & BT_JUMP)
            p.ftd.pressjump = 0
        else
            p.ftd.pressjump = $ + 1
        end
		if p.mo.eflags & MFE_JUSTHITFLOOR and p.ftd.crashjump == true and p.dontspamfire == false
			if p.ftd.cstage == 1 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
                if not (CBW_Battle and CBW_Battle.BattleGametype())	
				  ftdcirclesmall(p.mo, MT_FLAMEJETFLAME, 8 << FRACBITS, false, 0)
				end
                if (CBW_Battle and CBW_Battle.BattleGametype())
				and CBW_Chaos
				  ftdcirclesmall(p.mo, MT_FLAMEJETFLAME, 8 << FRACBITS, false, 0)
				end
				--p.ftd.cstage = 0
			end
			if p.ftd.cstage == 1 and (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
			   if not (CBW_Battle and CBW_Battle.BattleGametype())
				 ftdcircle(p.mo, MT_FLAMEJETFLAME, 22 << FRACBITS, false, 0)
			   end
			   if (CBW_Battle and CBW_Battle.BattleGametype())
			   and CBW_Chaos
				 ftdcircle(p.mo, MT_FLAMEJETFLAME, 22 << FRACBITS, false, 0)
			   end
				--p.ftd.cstage = 0
			end
		end
		if p.mo.eflags & MFE_JUSTHITFLOOR
			p.dontspamfire = true
		else
			p.dontspamfire = false
		end
		if P_IsObjectOnGround(p.mo) 
		and p.ftd.crashjump == true 
		and p.ftd.cstage > 1 --or P_IsObjectOnGround(p.mo) and p.ftd.crashjump == true and p.powers[pw_super]
			//Compensate for underwater physics
			local waterfactor = FRACUNIT
			if p.mo.eflags&MFE_UNDERWATER
				waterfactor = $*3/5
			end
			p.mo.momx = 0 
			p.mo.momy = 0
			p.jumpfactor = 0
			if p.mo.state != S_PLAY_ROLL
				p.mo.state = S_PLAY_ROLL
				if p.ftd.cstage == 1 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
				   if not (CBW_Battle and CBW_Battle.BattleGametype()) 
					ftdcircle(p.mo, MT_FLAMEJETFLAME, 5 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end
				   end	
				   if (CBW_Battle and CBW_Battle.BattleGametype()) 
				   and CBW_Chaos
					ftdcircle(p.mo, MT_FLAMEJETFLAME, 5 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end
				   end	
				end
				if p.ftd.cstage == 2 and not (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
				    if not (CBW_Battle and CBW_Battle.BattleGametype())
					  ftdcircle(p.mo, MT_FLAMEJETFLAME, 14 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end
					end
				    if (CBW_Battle and CBW_Battle.BattleGametype())
					and CBW_Chaos
					  ftdcircle(p.mo, MT_FLAMEJETFLAME, 14 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end
					end
					if (p == displayplayer)
						P_StartQuake(25*FRACUNIT, 2)
					end
					if not S_SoundPlaying(p.mo, sfx_pstop)
						S_StartSound(p.mo, sfx_pstop)
					end
				end
				if p.ftd.cstage == 3 or (p.powers[pw_super] or (p.solchar and p.solchar.istransformed))
				    if not (CBW_Battle and CBW_Battle.BattleGametype())
					  ftdcircle(p.mo, MT_FLAMEJETFLAME, 22 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end  
					end  
				    if (CBW_Battle and CBW_Battle.BattleGametype())
					and CBW_Chaos
					  ftdcircle(p.mo, MT_FLAMEJETFLAME, 22 << FRACBITS, false, 0)
					  if p.powers[pw_super] and (p.hyper or mrce_hyperunlocked)
					     P_NukeEnemies(p.mo, p.mo, 600*FRACUNIT)
					  end  
					end  					
					if (p == displayplayer)
						P_StartQuake(50*FRACUNIT, 4)
					end
					if not S_SoundPlaying(p.mo, sfx_beeyow)
						S_StartSound(p.mo, sfx_beeyow)
					end
				end
			end
			//Jumping
			if p.cmd.buttons & BT_JUMP and p.ftd.jumpdown == false
				if p.cmd.sidemove > 0 or p.cmd.sidemove < 0 or p.cmd.forwardmove > 0 or p.cmd.forwardmove < 0 
					p.ftd.canflip = true
					P_SetObjectMomZ(p.mo, FixedMul(p.ftd.cleappower,waterfactor), false)
					if not S_SoundPlaying(p.mo, sfx_beflap)
						S_StartSound(p.mo, sfx_beflap)
					end
					if p.ftd.storedspeed > p.ftd.storedspeed2
						P_InstaThrust(p.mo, p.mo.angle, FixedMul(p.ftd.storedspeed,waterfactor))
					else
						P_InstaThrust(p.mo, p.mo.angle, FixedMul(p.ftd.storedspeed2,waterfactor))
					end
					p.mo.state = S_PLAY_JUMP
					/*p.pflags = $ |(PF_JUMPED)*/
					p.ftd.doesthefunny = true
					p.ftd.jumpdown = true
					p.ftd.cstage = 1
					p.ftd.crashjump = false
					p.ftd.cstagetimer = 0
				else
					p.ftd.canflip = true
					P_SetObjectMomZ(p.mo, FixedMul(p.ftd.cleappower,waterfactor), false)
					if not S_SoundPlaying(p.mo, sfx_beflap)
						S_StartSound(p.mo, sfx_beflap)
					end
					p.mo.state = S_PLAY_JUMP
					p.ftd.doesthefunny = true
					p.ftd.jumpdown = true
					p.ftd.cstage = 1
					p.ftd.crashjump = false
					p.ftd.cstagetimer = 0
				end
			end
			//Lunging forward
			if p.cmd.buttons & BT_USE and p.ftd.spindown == false
				if p.cmd.sidemove > 0 or p.cmd.sidemove < 0 or p.cmd.forwardmove > 0 or p.cmd.forwardmove < 0 
					p.ftd.canflip = false
					P_SetObjectMomZ(p.mo, FixedMul(10*FRACUNIT,waterfactor), false)
					P_InstaThrust(p.mo, p.mo.angle, p.ftd.cdashpower)
					if not S_SoundPlaying(p.mo, sfx_cdfm62)
						S_StartSound(p.mo, sfx_cdfm62)
					end
					p.mo.state = S_PLAY_ROLL
					/*p.pflags = $ |(PF_JUMPED)*/
					p.ftd.cstage = 1
					p.ftd.crashjump = false
					p.pflags = $& ~PF_THOKKED
					p.pflags = $|PF_JUMPED
					p.ftd.cstagetimer = 0
					p.ftd.thoktrail = 1
				end
			end
			if p.cmd.sidemove == 0 and p.cmd.forwardmove == 0 and (p.cmd.buttons & BT_USE and p.ftd.spindown == false)
				p.ftd.canflip = true
				P_SetObjectMomZ(p.mo, FixedMul(10*FRACUNIT,waterfactor), false)
				p.mo.state = S_PLAY_JUMP
				p.ftd.cstage = 1
				p.ftd.crashjump = false
				p.ftd.cstagetimer = 0
			end
			--if p.cmd.sidemove > 0 or p.cmd.sidemove < 0 or p.cmd.forwardmove > 0 or p.cmd.forwardmove < 0 
			else
			p.jumpfactor = skins[p.mo.skin].jumpfactor
		end
		--Play a sound effect when you advance a crash stage.
		if p.ftd.cstage > p.ftd.cstagelast --and not p.powers[pw_super]
			S_StartSound(p.mo, sfx_zoom)
		end
		--What was your previous speed? This is used to give you back your speed during the leap.
		if not P_IsObjectOnGround(p.mo) and not p.ftd.crashing
			p.ftd.storedspeed = p.speed
		end
		if not P_IsObjectOnGround(p.mo)-- and not p.ftd.crashing
			p.ftd.storedspeed2 = p.speed
		end
		if p.ftd.doesthefunny == true
			--ftdcircle(p.mo, MT_FLAMEJETFLAME, 5 << FRACBITS, false, 0)
			//if p.cmd.buttons & BT_JUMP and not p.ftd.jumpdown
				//if p.speed >= 15*FRACUNIT
					//P_InstaThrust(p.mo, p.mo.angle, p.speed + p.speed/5)
				//else
					//P_InstaThrust(p.mo, p.mo.angle, 15*FRACUNIT)
				//end
				//P_SetObjectMomZ(p.mo, 10*FRACUNIT + p.speed/10, false)
				//ftdcircle(p.mo, MT_FLAMEJETFLAME, p.speed/FRACUNIT*3/2 << FRACBITS, false, 0)
				//p.mo.state = S_PLAY_ROLL
				//S_StartSound(p.mo, sfx_zoom)
				//p.ftd.doesthefunny = false
				//p.ftd.canflip = false
			//end
		end
		--what was your crash stage the previous frame?
		p.ftd.cstagelast = p.ftd.cstage
		--Was you pressing jump the previous frame?
		if (p.cmd.buttons & BT_JUMP)
			p.ftd.jumpdown = true
		else
			p.ftd.jumpdown = false
		end
		--Was you pressing spin the previous frame?
		if (p.cmd.buttons & BT_USE)
			p.ftd.spindown = true
		else
			p.ftd.spindown = false
		end
		--flip things idk brain dead rn 
		if P_IsObjectOnGround(p.mo) and p.ftd.crashjump == false 
			p.ftd.canflip = false
		end
		--kill the crash if in goop
		if P_IsObjectInGoop(p.mo)
			p.ftd.crashing = false
		end
		// Kill the crash if stunned
		if p.powers[pw_nocontrol]
			p.ftd.cstage = 1
		end
		--you can figure out what this does
		if p.mo.state == S_PLAY_SPRING
			--p.mo.state = S_PLAY_JUMP
			p.ftd.canflip = true
			--p.pflags = $ & PF_JUMPED
		end

		--kill the crash if being carried
		if p.powers[pw_carry]

			p.ftd.crashing = false
			p.ftd.cstage = 1
			--p.ftd.cpowervert = 0
			--p.ftd.cpowerhor = 0 
			--p.ftd.cstage = 1
			--p.ftd.cstagetimer = 0 
			--p.ftd.cstagelast = 1
		end
		--print(p.ftd.doesthefunny)
		if p.mo.eflags & MFE_JUSTHITFLOOR
			p.ftd.doesthefunny = false
		end
		p.ftd.statelast = p.mo.state
	end
end)

addHook("AbilitySpecial", function(p)
	if p.mo and p.mo.health and p.mo.valid and p.mo.skin == "flame"
	  if p.ftd.divethoked == 0
		if p.ftd.crashing == false and not (p.pflags & PF_JUMPDOWN) and not P_IsObjectInGoop(p.mo) and p.gotflag == 0 and not p.gotcrystal and not p.isjettysyn
			p.ftd.crashing = true
			p.mo.momz = 0 
			p.ftd.thoktrail = 0
			S_StartSound(p.mo, sfx_zoom)
			if CBW_Battle and CBW_Battle.BattleGametype()
			and not CBW_Chaos
			  p.ftd.divethoked = 1
			end
		end
	  end	
	end
end)

addHook("PlayerCanDamage", function(p, badnik)
	if p.mo and p.mo.health and p.mo.valid and p.mo.skin == "flame"
		if p.ftd.crashing == true or p.mo.state == S_PLAY_ROLL or p.mo.state == S_PLAY_FCRASH
			return true
		end
	end
end)

addHook("PlayerSpawn", function(p)
	if p.mo and p.mo.health and p.mo.valid and p.mo.skin == "flame" and p.ftd
		p.ftd.cstage = 1
		p.ftd.cstagetimer = 0 
		p.ftd.cstagelast = 1
		p.ftd.crashjump = false
	end
end)
addHook("JumpSpecial", function(p)
	if p.mo and p.mo.health and p.mo.valid and p.mo.skin == "flame" and p.ftd
		if P_IsObjectOnGround(p.mo) and p.ftd.crashjump == true and p.ftd.cstage > 1 --or P_IsObjectOnGround(p.mo) and p.ftd.crashjump == true and p.powers[pw_super]
			return true
		end
	end
end)
addHook("MobjMoveCollide", function(tmthing, thing)
	if tmthing.source == thing
		return false
	end
end, MT_FLAMEJETFLAME)