freeslot(
"MT_FROCKET",
"SFX_FTDRJ1",
"SFX_FTDRJ2",
"S_PLAY_FROCKET",
"S_FTDBALL1",
"SFX_FTDRJ3",
"MT_FTDFLAME",
"MT_FTDBALL",
"MT_FTDDOWNBALL",
"SFX_FTDFB1",
"S_FROCKET_EXPL2"
)
sfxinfo[sfx_ftdrj1].caption = "Rocket burst"
sfxinfo[sfx_ftdrj2].caption = "Rocket spark"
sfxinfo[sfx_ftdrj3].caption = "Burst hit"
sfxinfo[sfx_ftdfb1].caption = "Fireball impact"

// Recharge Exists
local function initTables(mobj)
	if mobj.flamewep == nil
		mobj.flamewep = {
		  recharge = 0,
		  super = 0,
		  shine = 0

}
	end
end
// Recharge Restore
addHook("MobjThinker", function(mobj)
   if mobj.player 
   and mobj.skin == "flame" 
	if mobj.health > 0
		initTables(mobj)
		if (mobj.flamewep.recharge ~= 3)
		and P_IsObjectOnGround(mobj) or mobj.player.powers[pw_carry]
			mobj.flamewep.recharge = 3
		end	
		if (mobj.flamewep.super ~= 4)
		and P_IsObjectOnGround(mobj) or mobj.player.powers[pw_carry]
			mobj.flamewep.super = 4
		end	
		if (mobj.flamewep.shine > 0)
			mobj.flamewep.shine = $ - 1
		end	
			   
	end
   end	
end, MT_PLAYER)

addHook("ShieldSpecial", function(p)
  if p.mo and p.mo.valid
   if p.mo.skin == "flame"
     if p.mo.flamewep.super > 0
       return true
	 end  
	 if p.mo.flamewep.super == 0 
	   return false
	 end  
   end	 
  end
end)




// Ground Frocket
addHook("SpinSpecial", function(player, mobj)
    if(player.mo.skin == "flame")
	and player.playerstate == PST_LIVE
		    if not (player.exiting)
		    and not (gametype == GT_TRON)
			and not player.powers[pw_carry]
			and not (player.pflags&PF_SPINDOWN)
			and not player.ftd.crashing == true
			and not P_PlayerInPain(player)
			and player.mo.flamewep.shine == 0
			and not player.isjettysyn
            and P_IsObjectOnGround(player.mo)
			and not srb2p
			and player.ftd.cstage < 2
			  if not (player.cmd.buttons & BT_JUMP) 
			  or player.ftd.pressjump > 2
				   local groundfrocket = P_SpawnPlayerMissile(player.mo,MT_FROCKET,MF2_AMBUSH)
				   if (player.powers[pw_super] or (player.solchar and player.solchar.istransformed))			   
				      P_SPMAngle(player.mo,MT_FTDBALL,player.mo.angle,0)
					  if (player.hyper or mrce_hyperunlocked)
					  and not (player.solchar and player.solchar.istransformed)
					     P_NukeEnemies(player.mo, player.mo, 600*FRACUNIT)
					  end
				   end
				   local waterfactor = FRACUNIT
		           if player.mo.eflags&MFE_UNDERWATER
			          waterfactor = $*3/5
			       end
				   if player.powers[pw_super] and (player.hyper or mrce_hyperunlocked)

			       elseif (player.solchar and player.solchar.istransformed)		
					     P_SetObjectMomZ(player.mo, 13*waterfactor)				
			       else
					     P_SetObjectMomZ(player.mo, 10*waterfactor)
			       end	
				   if groundfrocket and groundfrocket.valid then		
                      groundfrocket.momx = player.mo.momx / 2
                      groundfrocket.momy = player.mo.momy / 2
				      groundfrocket.state = S_FROCKET_EXPL1
					  groundfrocket.target = player.mo
				   end	
				   S_StartSound(player.mo,sfx_ftdrj1)	
				   player.pflags = $& ~PF_THOKKED
				   player.mo.flamewep.recharge = $ - 1
				   player.spcanflip = false
				   if (CBW_Battle and CBW_Battle.BattleGametype())
				       player.mo.flamewep.shine = $ + 20
				   end	  
		      end		   
		    end

    end
end)

//Mid-air Frocket
addHook("SpinSpecial", function(player, mobj)
    if(player.mo.skin == "flame")
	and player.playerstate == PST_LIVE
		    if not (player.exiting)
		    and not (gametype == GT_TRON)
			and not player.powers[pw_carry]
			and not (player.pflags&PF_SPINDOWN)
			and not player.ftd.crashing == true
			and not P_IsObjectOnGround(player.mo)
			and player.gotflag == 0
			and not player.gotcrystal
			and not P_PlayerInPain(player)
			and not player.isjettysyn
			and player.mo.flamewep.recharge > 0
			and not srb2p
			 if player.powers[pw_super]
                local rocket = P_SpawnPlayerMissile(player.mo,MT_FROCKET)
                if rocket and rocket.valid then
                  rocket.flags2 = $&~MF2_OBJECTFLIP|(player.mo.flags2&MF2_OBJECTFLIP)
                  rocket.eflags = $&~MFE_VERTICALFLIP|(player.mo.eflags&MFE_VERTICALFLIP)
				  rocket.target = player.mo
                end
                P_SetObjectMomZ(player.mo, 4<<FRACBITS)
			    player.mo.state = S_PLAY_FROCKET
				player.ftd.thoktrail = 0
				player.pflags = $& ~PF_THOKKED
				player.spcanflip = false
				player.pflags = $ |PF_NOJUMPDAMAGE
			 elseif (player.solchar and player.solchar.istransformed)
			    local groundfrocket = P_SpawnPlayerMissile(player.mo,MT_FROCKET)		   
				P_SPMAngle(player.mo,MT_FTDBALL,player.mo.angle,0)
				if groundfrocket and groundfrocket.valid then		
                      groundfrocket.momx = player.mo.momx / 2
                      groundfrocket.momy = player.mo.momy / 2
				      groundfrocket.state = S_FROCKET_EXPL1
					  groundfrocket.target = player.mo
				end
				S_StartSound(player.mo,sfx_ftdrj1)	
				player.pflags = $& ~PF_THOKKED
				player.mo.flamewep.recharge = $ - 1
				player.spcanflip = false
				player.ftd.thoktrail = 0
				player.spcanflip = false
			 else			
                local airrocket = P_SpawnPlayerMissile(player.mo,MT_FROCKET)
                if airrocket and airrocket.valid then
                  airrocket.flags2 = $&~MF2_OBJECTFLIP|(player.mo.flags2&MF2_OBJECTFLIP)
                  airrocket.eflags = $&~MFE_VERTICALFLIP|(player.mo.eflags&MFE_VERTICALFLIP)
				  airrocket.target = player.mo
                end
                P_SetObjectMomZ(player.mo, 4<<FRACBITS)
			    player.mo.state = S_PLAY_FROCKET
				player.ftd.thoktrail = 0
				player.spcanflip = false
				player.mo.flamewep.recharge = $ - 1
             end						 			 
            end
			if not P_IsObjectOnGround(player.mo)
			and not (player.pflags&PF_SPINDOWN)
			and not player.powers[pw_carry]
			and not P_PlayerInPain(player)
			      player.mo.flamewep.super = $ - 1
		    end
    end
end)

local Uncurl = function(pmo,mo,source)
	local B = CBW_Battle
	local vulnerable = B.PlayerCanBeDamaged(pmo.player)
	B.PlayerCreditPusher(pmo.player,source)
	B.ResetPlayerProperties(pmo.player,false,false)
	local thrust
		//Commented out code is ground-skidding stun behavior
-- 		if P_IsObjectOnGround(pmo) then
-- 			thrust = 7
-- 			P_InstaThrust(pmo,mo.angle,mo.scale*thrust)
-- 			pmo.state = S_PLAY_SKID
-- 		else
			//Air-juggle stun
		pmo.momz = $/2
		P_SetObjectMomZ(pmo,FRACUNIT*5/B.WaterFactor(pmo),1)
		thrust = 6
		P_InstaThrust(pmo,mo.angle,mo.scale*thrust)
		pmo.state = S_PLAY_FALL
-- 		end
	S_StartSound(mo,sfx_ftdrj3)
	//Do uncurling, skidding
	local time = thrust
	local angle = R_PointToAngle2(0,0,pmo.momx,pmo.momy)
	local recoilthrust = FixedHypot(pmo.momx,pmo.momy)
	B.DoPlayerFlinch(pmo.player, thrust, angle, recoilthrust)
	//P_RemoveMobj(mo)
	return false



end

//Frocket no friendly fire
addHook('MobjThinker',function(mo)
	if mo and mo.valid	
       if mo.state == S_FROCKET_EXPL2
	      if (mo.target and mo.target.valid)
             local waterfactor = FRACUNIT
		     if mo.target.eflags&MFE_UNDERWATER
			    waterfactor = $*3/5
			 end		 
			 if not P_PlayerInPain(mo.target.player)
			    //Launch owner
			    if mo.target.player.powers[pw_super] and (mo.target.player.hyper or mrce_hyperunlocked)
					  P_SetObjectMomZ(mo.target, 20*waterfactor)
			    elseif (mo.target.player.solchar and mo.target.player.solchar.istransformed)	
					  if not P_IsObjectOnGround(mo.target.player.mo)
					  and not(mo.flags2 & MF2_AMBUSH)
                         P_SetObjectMomZ(mo.target, 16*waterfactor)
					  else
					     //P_SetObjectMomZ(mo.target, 13*waterfactor)
					  end					
			    else
					  if not P_IsObjectOnGround(mo.target.player.mo)
					  and not(mo.flags2 & MF2_AMBUSH)
                         P_SetObjectMomZ(mo.target, 14*waterfactor)
					  else
					     //P_SetObjectMomZ(mo.target, 10*waterfactor)
					  end
			    end	
				if CBW_Battle and CBW_Battle.BattleGametype()
				and not CBW_Chaos
				and mo.target.skin == "flame" 
					//Disallow multiple walljumps in battle gametypes
					mo.target.flamewep.recharge = 0
                end
				mo.target.state = S_PLAY_ROLL
				mo.target.player.pflags = $& ~PF_THOKKED
				mo.target.player.pflags = $|PF_JUMPED
			 end
			 
			 local dist = 120*FRACUNIT
             for player in players.iterate
                local pmo = player.mo
                if (pmo and pmo.valid)				
				   if R_PointToDist2(0, mo.z, R_PointToDist2(mo.x, mo.y, pmo.x, pmo.y), pmo.z) < dist
				      if pmo.health 
					  and not P_PlayerInPain(player)
					  and pmo ~= mo.target
					       if not(CBW_Battle) 
					         //Launch ally
                             P_SetObjectMomZ(pmo, 17*waterfactor)
					         pmo.state = S_PLAY_ROLL
				             pmo.player.pflags = $& ~PF_THOKKED
					         pmo.player.pflags = $|PF_JUMPED	
				           elseif CBW_Battle.MyTeam(mo.target, pmo)
						     //bruh
                           else 
					          Uncurl(pmo, mo, mo.target)
				           end
                      end
                   end
				end				
             end		  
          end	   
       end
	end
end, MT_FROCKET)

addHook("MobjSpawn", function(mo)
	mo.cantreflect = true
end, MT_FROCKET)


//Frocket no friendly fire
addHook("ShouldDamage", function(target, inflictor, source, damage)
    if inflictor and inflictor.valid
        if inflictor.type == MT_FROCKET
				if not(source and source.valid and target.player) return end //Must be dealing with real players to continue
                if (CBW_Battle) 
				   return false
				end
        end
    end
end, MT_PLAYER)


addHook("PlayerCanDamage", function(player, mobj)
	if player.mo and player.mo.valid and player.mo.skin == "flame"
		local mo = player.mo
		if mo.state == S_PLAY_FROCKET
			return false
		end
		if mo.state == S_PLAY_FALL
			return false
		end
	end
end)



addHook("ShouldDamage", function(target, inflictor, source, damage)
	if inflictor and inflictor.valid
		if inflictor.type == MT_FTDDOWNBALL
		or inflictor.type == MT_FTDBALL
		    if target.player.actionstate == 1 or target.player.actionstate == 3
				  if (target.player.mo.skin == "knuckles")
                     return false
				  end	 
			end		   
			if (gametype == GT_COOP) 
			or (gametype == GT_CHAOS)
			or (gametype == GT_DEBUGCHAOS)
				return false
			elseif source != nil and source.valid
				if not G_GametypeHasTeams()
					if target == source
						return false
					end
				elseif target.player.ctfteam == source.player.ctfteam
					return false
				end
			end
		end
	end
end, MT_PLAYER)





//Burst Color 
local function BurstColor (mo)
     if mo.target and mo.target.valid and mo.target.player then
       if G_GametypeHasTeams()
	   or mo.target.player.powers[pw_super]
         mo.color = mo.target.color
         mo.colorized = true
       end
	 end  
end
addHook("MobjThinker",function(mo) BurstColor(mo) end,MT_FROCKET)
addHook("MobjThinker",function(mo) BurstColor(mo) end,MT_FLAMEJETFLAME)
addHook("MobjThinker",function(mo) BurstColor(mo) end,MT_FTDFLAME)
addHook("MobjThinker",function(mo) BurstColor(mo) end,MT_FTDBALL)
addHook("MobjThinker",function(mo) BurstColor(mo) end,MT_FTDDOWNBALL)

//Fireball trail, this is just pasted from ivory
local function LavaBombThinker(mo)
	local angle = mo.angle
	local newx
	local newy
	local i
	if leveltime%3==0
	and mo.state == S_FTDBALL1
		for i = 0,1 do
			newx = mo.x + P_ReturnThrustX(mo, angle + ((i == 0) and -1 or 1)*ANGLE_90, FixedMul(mo.radius, mo.scale))			
			newy = mo.y + P_ReturnThrustY(mo, angle + ((i == 0) and -1 or 1)*ANGLE_90, FixedMul(mo.radius, mo.scale))
			local ivbombflames = P_SpawnMobj(newx, newy, mo.z+P_MobjFlip(mo)+P_RandomRange(0,mo.height/FRACUNIT)*FRACUNIT, MT_SPINFIRE)
			if ivbombflames and ivbombflames.valid then
				ivbombflames.scale = mo.scale
				ivbombflames.colorized = true
				ivbombflames.target = mo.target
				ivbombflames.color = mo.color
				ivbombflames.fuse = 35
				ivbombflames.flags = $&~MF_NOGRAVITY
			end
		end	
	end
end
addHook("MobjThinker",function(mo) LavaBombThinker(mo) end,MT_FTDBALL)





