if pcall(do return _G["MT_FLYBOOSTER"] end)
    print("\131NOTICE:\128 Fly Booster objects already loaded.")
    return
end


freeslot(
"MT_FLYBOOSTER",
"S_FLYBOOSTER",
"S_FLYBOOSTERCD",
"MT_FLYBOOSTERGLOW",
"S_FLYBOOSTERGLOW",
"S_FLYBOOSTERGLOW2",
"S_FLYBOOSTERGLOW3",
"S_FLYBOOSTERGLOW4",
"S_FLYBOOSTERGLOW5",
"S_FLYBOOSTERFRONT",
"S_FLYBOOSTERARROWS",
"SPR_FLYB",
"SPR_FLYC"
)


function A_FlyBoostFrame(actor, var1, var2)
	if (var1) then
		actor.frame = $|actor.tracer.damage
	else
		actor.frame = actor.damage
	end
end

mobjinfo[MT_FLYBOOSTER] = {
//$Name Flight Booster
//$Category Springs and Fans
//$Sprite FLYBI1
//$Flags1Text Strong Booster
//$Flags4Text Weak Booster
//$Flags8Text Retain Momentum
//$ParameterText Pitch (0-15)
//$AngleText Yaw
spawnstate = S_FLYBOOSTER,
seestate = S_FLYBOOSTERCD,
activesound = sfx_cdfm62,
doomednum = 570,
reactiontime = 16,
speed = 10*FRACUNIT,
radius = 64*FRACUNIT,
height = 128*FRACUNIT,
damage = 3,
spawnhealth = 0,
dispoffset = 0,
flags = MF_NOGRAVITY|MF_SPECIAL
}


states[S_FLYBOOSTER] = {
sprite = SPR_FLYB,
frame = A,
action = A_FlyBoostFrame,
var1 = 0,
tics = -1,
nextstate = S_FLYBOOSTER
}
states[S_FLYBOOSTERCD] = {
sprite = SPR_FLYB,
frame = A,
action = A_FlyBoostFrame,
var1 = 0,
tics = 20,
nextstate = S_FLYBOOSTER
}


mobjinfo[MT_FLYBOOSTERGLOW] = {
spawnstate = S_FLYBOOSTERGLOW,
reactiontime = 16,
speed = 10*FRACUNIT,
radius = 128*FRACUNIT,
height = 128*FRACUNIT,
damage = 3,
spawnhealth = 0,
dispoffset = 0,
flags = MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT
}


states[S_FLYBOOSTERGLOW] = {
sprite = SPR_NULL,
frame = A|FF_FULLBRIGHT|TR_TRANS80,
action = A_FlyBoostFrame,
var1 = 1,
tics = -1,
nextstate = S_FLYBOOSTERGLOW
}
states[S_FLYBOOSTERGLOW2] = {
sprite = SPR_FLYC,
frame = A|FF_FULLBRIGHT,
action = A_FlyBoostFrame,
var1 = 1,
tics = 5,
nextstate = S_FLYBOOSTERGLOW3
}
states[S_FLYBOOSTERGLOW3] = {
sprite = SPR_FLYC,
frame = A|FF_FULLBRIGHT|TR_TRANS20,
action = A_FlyBoostFrame,
var1 = 1,
tics = 5,
nextstate = S_FLYBOOSTERGLOW4
}
states[S_FLYBOOSTERGLOW4] = {
sprite = SPR_FLYC,
frame = A|FF_FULLBRIGHT|TR_TRANS40,
action = A_FlyBoostFrame,
var1 = 1,
tics = 5,
nextstate = S_FLYBOOSTERGLOW5
}
states[S_FLYBOOSTERGLOW5] = {
sprite = SPR_FLYC,
frame = A|FF_FULLBRIGHT|TR_TRANS60,
action = A_FlyBoostFrame,
var1 = 1,
tics = 5,
nextstate = S_FLYBOOSTERGLOW
}


addHook("MapThingSpawn", function(actor, spawnpoint)
	actor.reactiontime = (spawnpoint.extrainfo*-1125)/100
	if (actor.reactiontime == 90) then
		actor.reactiontime = 1
	elseif (actor.reactiontime == 180) then
		actor.reactiontime = 181
	elseif (actor.reactiontime == -90) then
		actor.reactiontime = -91
	elseif (actor.reactiontime == -180) then
		actor.reactiontime = -181
	end
	
		local targetColor = SKINCOLOR_YELLOW
	actor.mass = 0
	if (spawnpoint.options & (MTF_AMBUSH)) then
		targetColor = SKINCOLOR_GREEN
		actor.mass = 1
	end
	
	actor.speed = 20
	
	//There are way more effecient ways to do this, but it only runs once for each object on mapload, so who cares?
	//Discord got me self conscious about my if chains ;<
	if (spawnpoint.options & (MTF_EXTRA)) then
		if (spawnpoint.options & MTF_AMBUSH) then
			targetColor = SKINCOLOR_TEAL
		else
			targetColor = SKINCOLOR_BLUE
		end
		actor.speed = 10
	end
	if (spawnpoint.options & (MTF_OBJECTSPECIAL)) then
		if (spawnpoint.options & MTF_AMBUSH) then
			targetColor = SKINCOLOR_GOLD
		else
			targetColor = SKINCOLOR_RED
		end
		actor.speed = 30
	end	
	if ((spawnpoint.options & MTF_EXTRA) and (spawnpoint.options & MTF_OBJECTSPECIAL)) then
		if (spawnpoint.options & MTF_AMBUSH) then
			targetColor = SKINCOLOR_JET
		else
			targetColor = SKINCOLOR_WHITE
		end
		actor.speed = 40
	end
	
	actor.damage = spawnpoint.extrainfo
	actor.frame = spawnpoint.extrainfo
	actor.color = targetColor
	
	local glow = P_SpawnMobj(actor.x,actor.y,actor.z, MT_FLYBOOSTERGLOW)
	glow.angle = (spawnpoint.angle%360)*ANG1
	glow.blendmode = AST_ADD

	actor.tracer = glow
	glow.tracer = actor
	glow.color = targetColor
	
	
end, MT_FLYBOOSTER)

addHook("MobjThinker", function(actor)
	if (actor.speed == 40 and leveltime % 4 == 0) then
		if (actor.mass > 0) then
			actor.color = (($+1)%9)+1
			actor.tracer.color = (($+1)%9)+1
			actor.front.color = (($+1)%9)+1
		
		else
			actor.color = ($+1)%69
			actor.tracer.color = ($+1)%69
			actor.front.color = ($+1)%69
		end
	end

end, MT_FLYBOOSTER)


addHook("TouchSpecial", function(actor, toucher)
    if (actor.state == S_FLYBOOSTER) then
        local player = toucher.player
        actor.state = S_FLYBOOSTERCD
            if (player) then
            if (toucher.state == S_PLAY_FLY or toucher.state == S_PLAY_FLY_TIRED) then //tails has special interactions with the booster
                player.powers[pw_tailsfly] = tailsflytics
                toucher.state = S_PLAY_FLY
            elseif (player.aether) //allowing aether to have special interactions with the booster
                Silverhorn.Aether.StartFlight(player)    
			elseif (toucher.skin == "shadow")  then //shadow also gets to be special!
				player.shadow.snaps = 2
                player.pflags = $1&~PF_THOKKED
			elseif (toucher.skin == "flame")  then //as does flame
				toucher.flamewep.recharge = 3
                player.pflags = $1&~PF_THOKKED
            else
                toucher.state = S_PLAY_JUMP
                player.pflags = $1&~PF_THOKKED
                player.pflags = $1&~PF_GLIDING
                player.pflags = $1|PF_JUMPED
            end
        end
        
        P_TeleportMove(toucher, actor.x, actor.y, actor.z)
		if (actor.mass > 0) then
		
			local boostForce = max(actor.speed, player.speed/FRACUNIT);
			local horizMom = cos((actor.reactiontime+90)*ANG1)*boostForce
			local vertiMom = sin((actor.reactiontime+90)*ANG1)*boostForce
			P_InstaThrust(toucher, actor.angle, horizMom)
			P_SetObjectMomZ(toucher, vertiMom, false)
			toucher.angle = actor.angle
		
		else
			local boostForce = actor.speed 
			local horizMom = cos((actor.reactiontime+90)*ANG1)*boostForce
			local vertiMom = sin((actor.reactiontime+90)*ANG1)*boostForce
			P_InstaThrust(toucher, actor.angle, horizMom)
			P_SetObjectMomZ(toucher, vertiMom, false)
			toucher.angle = actor.angle
		end
		
        if (actor.tracer) then
            actor.tracer.state = S_FLYBOOSTERGLOW2
        end
        A_PlayActiveSound(actor, 0, 0)
        
    end
    return true
end, MT_FLYBOOSTER)