/*
[[ Super Tails' Flickies v1.1
Author: birbhorse (aka EeveeEuphoria)
Sprites: Sonic Team Jr. (with modifications by author, to allow for coloration)
Shoutouts: gregory_house for making the original Super Flickies mod. I was already a ways in developing this when I discovered this already existed! The code used here is from how the flickies are arranged, and the general flow of the code is derrived from them.
And to MotorRoach for their Flicky character mod, I didn't use their sprites, but I did learn how to give the flicky sprites the abillity to be colored.

TO-DO LIST:
	- Have birds swoop in when player is spawned, and only let them go after enemies when the player is done doing the transformation animation.
		- Make it so that the "BirdsSummoned" value is only set when the player is not in their TRANS state.
		- Have birds target their home.
	- Fix Fang's boss fight from letting the birds attack him when he's in the box.
	- Use P_HomingAttack instead of A_HomingChase
	- Optimize code, condense the "slow" and "aggressive" down as much as possible. Maybe use local mobj = STUFF.

]]
*/
rawset(_G, "STFModLoaded", true) -- detection of this mod, if needed for any reason

local STFDebug

if STFINTHEPK3 -- detects if file is in the PK3, in which a rawset _G value was placed in a "pk3.lua" file
	STFDebug = false
	else
	STFDebug = false
end

local function DebugPrint(text) -- debug printer
	if STFDebug
		print(text)
	end
end

freeslot(
"MT_TLBRD",
"MT_TLHME",
"S_TAILSBIRD1",
"S_TAILSBIRD2",
"S_TAILSBIRD3",
"S_TAILSBIRD4",
"S_TAILSBIRD5",
"S_TAILSBIRD6",
"S_TAILSBIRDHOUSE",
"SPR_FLTS"
)

states[S_TAILSBIRD1] = {
	sprite = SPR_FLTS,
	frame = A,
	tics = 2,
	nextstate = S_TAILSBIRD2
}

states[S_TAILSBIRD2] = {
	sprite = SPR_FLTS,
	frame = B,
	tics = 2,
	nextstate = S_TAILSBIRD3
}

states[S_TAILSBIRD3] = {
	sprite = SPR_FLTS,
	frame = C,
	tics = 2,
	nextstate = S_TAILSBIRD4
}

states[S_TAILSBIRD4] = {
	sprite = SPR_FLTS,
	frame = A,
	tics = 2,
	nextstate = S_TAILSBIRD5
}

states[S_TAILSBIRD5] = {
	sprite = SPR_FLTS,
	frame = B,
	tics = 2,
	nextstate = S_TAILSBIRD6
}

states[S_TAILSBIRD6] = {
	sprite = SPR_FLTS,
	frame = C,
	tics = 2,
	nextstate = S_TAILSBIRD1
}

states[S_TAILSBIRDHOUSE] = {
	sprite = SPR_NULL,
	frame = D,
	tics = -1,
	nextstate = S_TAILSBIRDHOUSE
}

mobjinfo[MT_TLBRD] = {
	doomednum = -1,
	spawnstate = S_TAILSBIRD1,
	speed = 10*FRACUNIT,
	height = 50,
	flags = MF_RUNSPAWNFUNC|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY
}

mobjinfo[MT_TLHME] = {
	doomednum = -1,
	spawnstate = S_TAILSBIRDHOUSE,
	speed = 10*FRACUNIT,
	height = 50,
	flags = MF_RUNSPAWNFUNC|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY
}

local STFCheckSpeed = 6
local STFAttackNum = 4
local STFSuperTails = "on"
local STFSearchType = "aggressive"

-- [[[ Commands ]]] --
-- A lot of this stuff is just code carried over from MMT, because...uh, laziness, and comfort.

--[[TODO: Add:	
	-- STFCheckSpeed: Adjusts the cooldown tic rate that scans are performed on where enemies are. (default: 6, min = 1, max = TICRATE)
	-- STFAttackNum: The amount of flickies that can attack (default & max : 4, min: 1)
	-- STFSuperTails: Toggles if tails can go super or not. Make compatible with MMT by having this disabled, and display a warning if MMT is enabled when using this command!
--]]
local commandDescription = {
["STFCheckSpeed"] = "*\x85 STFCheckSpeed \x81<num>\x80: Adjusts the speed in which checks are performed on the map for enemies, for STFSearchType aggressive. Set to a higher number for slower computers.",
["STFAttackNum"] = "*\x85 STFAttackNum \x81<1, 2, 3, 4>\x80: Changes the number of flickies that are allowed to attack enemies simultaneously.",
["STFSuperTails"] = "*\x85 STFSuperTails \x81<on/off>\x80: Allows Tails to go super.",
["STFSearchType"] = "*\x85 STFSearchType \x81<slow/aggressive>\x80: Changes search type, slow is less accurate but less CPU-demanding."
}

local function cmdDesc(tbl, key)
    for k, v in pairs(tbl) do
        if k == key then 
			return v
		end
    end
    return nil
end

local function stfcheckspeed(player, arg1)
local cmdname = "STFCheckSpeed"
	if STFSearchType == "slow"
		CONS_Printf(player, "\x85\ERROR:\x80 Can not use while STFSearchType is set to slow!")
		return
	end
	if tonumber(arg1)
		arg1 = tonumber(arg1)
	end
	if tonumber(arg1) and arg1 > 0 and arg1 < TICRATE+1
		STFCheckSpeed = tonumber(arg1)
		CONS_Printf(player, "*\x8A ".. cmdname .."\x80 is set to \x87" .. arg1)
	else
		CONS_Printf(player, cmdDesc(commandDescription, cmdname))
		CONS_Printf(player, "*\x8A " .. cmdname .. "\x80 is set to \x87" +STFCheckSpeed)
		CONS_Printf(player, "*\x8E Options:\x80 Values go between 0 and " .. TICRATE .. ", default is 6.")
	end
end

local function stfattacknum(player, arg1)
local cmdname = "STFAttackNum"
	if tonumber(arg1)
		arg1 = tonumber(arg1)
	end
	if tonumber(arg1) and arg1 > 0 and arg1 < 4
		STFAttackNum = tonumber(arg1)
		CONS_Printf(player, "*\x8A ".. cmdname .."\x80 is set to \x87" .. arg1)
	else
		CONS_Printf(player, cmdDesc(commandDescription, cmdname))
		CONS_Printf(player, "*\x8A " .. cmdname .. "\x80 is set to \x87" +STFAttackNum)
		CONS_Printf(player, "*\x8E Options:\x80 Values go between 1 and 4, default is 4.")
	end
end

local function stfsupertails(player, arg1)
local cmdname = "STFSuperTails"
	if mmtVersion
		CONS_Printf(player, "\x85\ERROR:\x80 Can not use while MMT is loaded! Use \"everysuper disable\" instead!")
		return
	end
	if arg1 == "on" or arg1 == "off"
		STFSuperTails = arg1
		CONS_Printf(player, "*\x8A ".. cmdname .."\x80 is set to \x87" .. arg1)
	else
		CONS_Printf(player, cmdDesc(commandDescription, cmdname))
		CONS_Printf(player, "*\x8A " .. cmdname .. "\x80 is set to \x87" +STFSuperTails) 
		CONS_Printf(player, "*\x8E Options:\x80 \"on\", \"off\".")
	end
end

local function stfsearchtype(player, arg1)
local cmdname = "STFSearchType"
	if arg1 == "aggressive" or arg1 == "slow"
		STFSearchType = arg1
		CONS_Printf(player, "*\x8A ".. cmdname .."\x80 is set to \x87" .. arg1)
	else
		CONS_Printf(player, cmdDesc(commandDescription, cmdname))
		CONS_Printf(player, "*\x8A " .. cmdname .. "\x80 is set to \x87" +STFSearchType) 
		CONS_Printf(player, "*\x8E Options:\x80 \"slow\", \"aggressive\".")
	end
end

COM_AddCommand("STFCheckSpeed", stfcheckspeed, 1)
COM_AddCommand("STFAttackNum", stfattacknum, 1)
COM_AddCommand("STFSuperTails", stfsupertails, 1)
COM_AddCommand("STFSearchType", stfsearchtype, 1)


-- [[[ Player Thinker ]]] --

addHook("MobjThinker", function(gayer) local player = gayer.player

-- [[ Give player super, if MMT isn't loaded! ]] --
if not player.STFCheckedForSuper and (player.charability == CA_FLY) and STFSuperTails == "on"
	if not mmtVersion 
		player.charflags = $1 | SF_SUPER
		DebugPrint("Granted player the ability to go super!")
	else
		DebugPrint("MMT is detected, not changing player's super state.")
	end
	player.STFCheckedForSuper = true
end

if player.birdangle == nil
	player.birdangle = 0 
	player.birdheightangle = 0 
	player.birdheight = 0 
end

-- [[ Spawn The Birb ]] --
	if (player.charability == CA_FLY) and player.powers[pw_super] and (player.mo.skin == "tailsre") and not player.BirdsSummoned --when player is super, but birds are not out
		player.birdMissionTime = 0
		player.CoolDownBirdTimer = 0
		player.bird1target = "none"
		player.bird2target = "none"
		player.bird3target = "none"
		player.bird4target = "none"		
		player.bird1MissionTime = false
		player.bird2MissionTime = false
		player.bird3MissionTime = false
		player.bird4MissionTime = false
		player.target1distance = 0
		player.target2distance = 0
		player.target3distance = 0
		player.target4distance = 0
		player.bird1 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_TLBRD)
		player.bird2 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_TLBRD)
		player.bird3 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_TLBRD)
		player.bird4 = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_TLBRD)
		player.bird1.number = 1
		player.bird2.number = 2
		player.bird3.number = 3
		player.bird4.number = 4
		player.bird1.idle = true
		player.bird2.idle = true
		player.bird3.idle = true
		player.bird4.idle = true
		player.bird1.tailsdude = player.mo
		player.bird2.tailsdude = player.mo
		player.bird3.tailsdude = player.mo
		player.bird4.tailsdude = player.mo
		player.birdhome = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_TLHME)
		player.birdhome.tailsdude = player.mo
		player.BirdsSummoned = true
	end

-- [[ The Good Birb Stuff, contains logic for the movement when idle, and the detection of enemies ]] --
	if player.powers[pw_super] and player.BirdsSummoned
		-- [ Bird Home ] --
		P_TeleportMove(player.birdhome, player.mo.x, player.mo.y, (player.mo.z+(player.mo.height/2)))
		
		-- [ Bobbing ] -- Todo: Duplicate the GayBirdH thing 3 times to make different ones for each individual birb.
		if player.gaybirdtimer == nil
		player.gaybirdtimer = 0
		player.GayBirdH = 40*FRACUNIT
		else
		player.gaybirdtimer = $+1
		end
		if player.gaybirdtimer < 40
			player.GayBirdH = $+(3/FRACUNIT)
		elseif player.gaybirdtimer < 80
			player.GayBirdH = $ - (3/FRACUNIT)
		else
			player.gaybirdtimer = 0
		end

		-- [ Player Flip ] --
		if (player.mo.eflags & MFE_VERTICALFLIP) or (player.mo.flags2 & MF2_OBJECTFLIP)
			player.GayBirdHFlip = (-player.GayBirdH)
		else
			player.GayBirdHFlip = 0
		end

		-- [ Floating Stuffs ] --
		player.birdangle = $+5*FRACUNIT
		player.birdheightangle = $+7*FRACUNIT
		player.birdheight = player.mo.z+player.GayBirdH+player.GayBirdHFlip -- add timer to make this bob up and down
		player.birddistance = 45
		
		-- [ Search Cooldown Timer ] --
		if player.CoolDownBirdTimer > 0
			player.CoolDownBirdTimer = $ - 1
		end
	end
	
	if player.BirdsSummoned
		-- [ Distance between player and target enemy ] --
		if player.bird1MissionTime and player.bird1target.valid
			player.target1distance = R_PointToDist2(player.bird1target.x, player.bird1target.y, player.mo.x, player.mo.y)/FRACUNIT
		end
		if player.bird2MissionTime and player.bird2target.valid
			player.target2distance = R_PointToDist2(player.bird2target.x, player.bird2target.y, player.mo.x, player.mo.y)/FRACUNIT
		end
		if player.bird3MissionTime and player.bird3target.valid
			player.target3distance = R_PointToDist2(player.bird3target.x, player.bird3target.y, player.mo.x, player.mo.y)/FRACUNIT
		end
		if player.bird4MissionTime and player.bird4target.valid
			player.target4distance = R_PointToDist2(player.bird4target.x, player.bird4target.y, player.mo.x, player.mo.y)/FRACUNIT
		end
		
		-- [ Keep Up With Da Player ] --
		player.bird1 = { x =  player.mo.x+cos(FixedAngle(player.birdangle))*player.birddistance, y = player.mo.y+sin(FixedAngle(player.birdangle))*player.birddistance, z = player.birdheight+sin(FixedAngle(2*player.birdheightangle))*5 }
		player.bird2 = { x =  player.mo.x+cos(FixedAngle(player.birdangle+90*FRACUNIT))*player.birddistance, y = player.mo.y+sin(FixedAngle(player.birdangle+90*FRACUNIT))*player.birddistance, z = player.birdheight+sin(FixedAngle(2*player.birdheightangle))*5 }
		player.bird3 = { x =  player.mo.x+cos(FixedAngle(player.birdangle+180*FRACUNIT))*player.birddistance, y = player.mo.y+sin(FixedAngle(player.birdangle+180*FRACUNIT))*player.birddistance, z = player.birdheight+sin(FixedAngle(2*player.birdheightangle))*5 }
		player.bird4 = { x =  player.mo.x+cos(FixedAngle(player.birdangle+270*FRACUNIT))*player.birddistance, y = player.mo.y+sin(FixedAngle(player.birdangle+270*FRACUNIT))*player.birddistance, z = player.birdheight+sin(FixedAngle(2*player.birdheightangle))*5 }
	
	
	
		
		-- [ Break The Targets v.2 ] --
		if STFSearchType == "slow"
			player.SearchTime = P_LookForEnemies(player, false, false)
			if player.SearchTime
				if (((player.SearchTime.flags & MF_ENEMY) or (player.SearchTime.flags & MF_BOSS)))
				and not (player.SearchTime.flags2 & MF2_FRET)
				and not (player.SearchTime.type == MT_TURRET)
				and not ((player.SearchTime.type == MT_EGGMOBILE4) and (player.SearchTime.health >= 4) and (player.SearchTime.state == S_EGGMOBILE4_STND)) -- CEZ 3 Boss
				and ((player.SearchTime.flags & MF_SPECIAL) or player.SearchTime.type == MT_DETON or player.SearchTime.type == MT_EGGGUARD) -- detects if enemy can actually be hit, or if it's a deton
				and P_CheckSight(player.mo, player.SearchTime) -- checks to see if not obscured by wall
				and player.SearchTime.health > 0
					-- [ Send the Birbs ] -- 
					if player.bird1target == "none" and not (player.bird2target == player.SearchTime or player.bird3target == player.SearchTime or player.bird4target == player.SearchTime)
					and STFAttackNum >= 1
						player.bird1target = player.SearchTime
					elseif player.bird2target == "none" and not (player.bird1target == player.SearchTime or player.bird3target == player.SearchTime or player.bird4target == player.SearchTime)
					and STFAttackNum >= 2
						player.bird2target = player.SearchTime
					elseif player.bird3target == "none" and not (player.bird1target == player.SearchTime or player.bird2target == player.SearchTime or player.bird4target == player.SearchTime)
					and STFAttackNum >= 3
						player.bird3target = player.SearchTime
					elseif player.bird4target == "none" and not (player.bird2target == player.SearchTime or player.bird3target == player.SearchTime or player.bird1target == player.SearchTime)
					and STFAttackNum >= 4
						player.bird4target = player.SearchTime
					end
					DebugPrint("ENEMY SPOTTED, IT'S: " +player.SearchTime.type .. " WITH A STATE OF: " .. player.SearchTime.state .. " AND HEALTH OF: " .. player.SearchTime.health .. " AND FLAG VALUES: " .. player.SearchTime.flags .. " " .. player.SearchTime.flags2 .. " " .. player.SearchTime.eflags)
				end
			end
		end
		if STFSearchType == "aggressive" and player.CoolDownBirdTimer == 0
			player.CoolDownBirdTimer = STFCheckSpeed
			for mobj in mobjs.iterate("mobj")
			if (R_PointToDist2(mobj.x, mobj.y, player.mo.x, player.mo.y) < 512*FRACUNIT) and (abs(mobj.z - player.mo.z) < 512*FRACUNIT) 
			and (((mobj.flags & MF_ENEMY) or (mobj.flags & MF_BOSS)))
			and not (mobj.flags2 & MF2_FRET)
			and not (mobj.type == MT_TURRET)
			and not ((mobj.type == MT_EGGMOBILE4) and (mobj.health >= 4) and (mobj.state == S_EGGMOBILE4_STND)) -- CEZ 3 Boss
			and ((mobj.flags & MF_SPECIAL) or mobj.type == MT_DETON or mobj.type == MT_EGGGUARD) -- detects if enemy can actually be hit, or if it's a deton
			and P_CheckSight(player.mo, mobj) -- checks to see if not obscured by wall
			and mobj.health > 0
			-- [ Send the Birbs ] -- 
				if player.bird1target == "none" and not (player.bird2target == mobj or player.bird3target == mobj or player.bird4target == mobj)
				and STFAttackNum >= 1
				player.bird1target = mobj
				elseif player.bird2target == "none" and not (player.bird1target == mobj or player.bird3target == mobj or player.bird4target == mobj)
				and STFAttackNum >= 2
				player.bird2target = mobj
				elseif player.bird3target == "none" and not (player.bird1target == mobj or player.bird2target == mobj or player.bird4target == mobj)
				and STFAttackNum >= 3
				player.bird3target = mobj
				elseif player.bird4target == "none" and not (player.bird2target == mobj or player.bird3target == mobj or player.bird1target == mobj)
				and STFAttackNum >= 4
				player.bird4target = mobj
				end
				DebugPrint("AGGRESSIVE SEARCH, ENEMY SPOTTED, IT'S: " +mobj.type .. " WITH A STATE OF: " .. mobj.state .. " AND HEALTH OF: " .. mobj.health .. " AND FLAG VALUES: " .. mobj.flags .. " " .. mobj.flags2 .. " " .. mobj.eflags)
			end
		end
	end
			-- [ Assign Birb on a mission] -- 
			if player.bird1target != "none" and not player.bird1MissionTime and player.bird1target.valid
				player.bird1MissionTime = true
				DebugPrint("SENDING OUT: FIRST BIRB")
			end
			if player.bird2target != "none" and not player.bird2MissionTime and player.bird2target.valid
				player.bird2MissionTime = true
				DebugPrint("SENDING OUT: SECOND BIRB")
			end
			if player.bird3target != "none" and not player.bird3MissionTime and player.bird3target.valid
				player.bird3MissionTime = true
				DebugPrint("SENDING OUT: THIRD BIRD")
			end
			if player.bird4target != "none" and not player.bird4MissionTime and player.bird4target.valid
				player.bird4MissionTime = true
				DebugPrint("SENDING OUT: FINAL BIRD")
			end
	end 
	
	if not player.powers[pw_super] and player.BirdsSummoned --when player is no longer super, but birds are still out
		player.BirdsSummoned = false
	end
end, MT_PLAYER)


-- [[ Bird Thinker ]] --
addHook("MobjThinker", function(gaybird) -- figure out how to sync their pulses with the character's pulses
local player = gaybird.tailsdude.player
-- [ Colors and States ] -- 
	if gaybird.timer == nil
	gaybird.timer = 0 + (gaybird.number*2) --offset the color
	else
	gaybird.timer = $+1
	end
	if player.mo.color ~= player.skincolor
		gaybird.color = player.mo.color
	else
		gaybird.color = SKINCOLOR_CORNFLOWER
	end
	if gaybird.number == 1
		gaybird.state = S_TAILSBIRD1
	elseif gaybird.number == 2
		gaybird.state = S_TAILSBIRD2
	elseif gaybird.number == 3
		gaybird.state = S_TAILSBIRD3
	elseif gaybird.number == 4
		gaybird.state = S_TAILSBIRD4
	end

-- [ player flip, bird flip ] --

if (player.mo.eflags & MFE_VERTICALFLIP)
	gaybird.flags2 = $1 | MF2_OBJECTFLIP
	else
	gaybird.flags2 = $ & ~MF2_OBJECTFLIP
end


-- [[ It begins ]] --

-- [ Hover near player ] --
	if gaybird.idle --and player.bird1target == "none"
		if gaybird.number == 1 and not player.bird1MissionTime
			gaybird.angle = R_PointToAngle2(gaybird.x, gaybird.y, player.bird2.x, player.bird2.y)+45*FRACUNIT
			gaybird.momx = (player.bird2.x - gaybird.x)/2
			gaybird.momy = (player.bird2.y - gaybird.y)/2
			gaybird.momz = (player.bird2.z - gaybird.z)/2
		elseif gaybird.number == 2 and not player.bird2MissionTime
			gaybird.angle = R_PointToAngle2(gaybird.x, gaybird.y, player.bird3.x, player.bird3.y)+45*FRACUNIT
			gaybird.momx = (player.bird3.x - gaybird.x)/3
			gaybird.momy = (player.bird3.y - gaybird.y)/3
			gaybird.momz = (player.bird3.z - gaybird.z)/3
		elseif gaybird.number == 3 and not player.bird3MissionTime
			gaybird.angle = R_PointToAngle2(gaybird.x, gaybird.y, player.bird4.x, player.bird4.y)+45*FRACUNIT
			gaybird.momx = (player.bird4.x - gaybird.x)/4
			gaybird.momy = (player.bird4.y - gaybird.y)/4
			gaybird.momz = (player.bird4.z - gaybird.z)/4
		elseif gaybird.number == 4 and not player.bird4MissionTime
			gaybird.angle = R_PointToAngle2(gaybird.x, gaybird.y, player.bird1.x, player.bird1.y)+45*FRACUNIT
			gaybird.momx = (player.bird1.x - gaybird.x)/5
			gaybird.momy = (player.bird1.y - gaybird.y)/5
			gaybird.momz = (player.bird1.z - gaybird.z)/5
		end
	end
	
	-- [ Target Enemy ] --
	if gaybird.number == 1 and not gaybird.returninghome
		if player.bird1MissionTime and player.target1distance and player.bird1target.valid 
			--DebugPrint("I've been summoned, I am: " .. gaybird.number)
			gaybird.idle = false
			if player.bird1target != "none" gaybird.target = player.bird1target end
			if gaybird.target and gaybird.target.valid and gaybird.target.health > 0 and not (gaybird.target.flags2 & MF2_FRET)
			and player.target1distance < 768
				A_HomingChase(gaybird, 35*FRACUNIT, 0)
				if (R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y))/FRACUNIT < 30
					if gaybird.target.health > 1
					P_DamageMobj(gaybird.target, gaybird, player.mo, 1)
					else
					P_KillMobj(gaybird.target, gaybird, player.mo, DMG_INSTAKILL)
					end
				end
			else
				player.bird1target = "none"
				gaybird.target = nil
				player.target1distance = nil
				player.bird1MissionTime = false
				gaybird.returninghome = true
				DebugPrint("Enemy is gone, or mission has failed! Number: 1")
			end
		end	
	elseif gaybird.number == 2 and not gaybird.returninghome 
		if player.bird2MissionTime and player.target2distance and player.bird2target.valid
			--DebugPrint("I've been summoned, I am: " .. gaybird.number)
			gaybird.idle = false
			if player.bird2target != "none" gaybird.target = player.bird2target end
			if gaybird.target and gaybird.target.valid and gaybird.target.health > 0 and not (gaybird.target.flags2 & MF2_FRET)
			and player.target2distance < 768
				A_HomingChase(gaybird, 35*FRACUNIT, 0)
				if (R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y))/FRACUNIT < 30
					if gaybird.target.health > 1
					P_DamageMobj(gaybird.target, gaybird, player.mo, 1)
					else
					P_KillMobj(gaybird.target, gaybird, player.mo, DMG_INSTAKILL)
					end
				end
			else
				player.bird2target = "none"
				gaybird.target = nil
				player.target2distance = nil
				player.bird2MissionTime = false
				gaybird.returninghome = true
				DebugPrint("Enemy is gone, or mission has failed! Number: 2")
			end
		end	
		elseif gaybird.number == 3 and not gaybird.returninghome
		if player.bird3MissionTime and player.target3distance and player.bird3target.valid
			--DebugPrint("I've been summoned, I am: " .. gaybird.number)
			gaybird.idle = false
			if player.bird3target != "none" gaybird.target = player.bird3target end
			if gaybird.target and gaybird.target.valid and gaybird.target.health > 0 and not (gaybird.target.flags2 & MF2_FRET)
			and player.target3distance < 768
				A_HomingChase(gaybird, 35*FRACUNIT, 0)
				if (R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y))/FRACUNIT < 30
					if gaybird.target.health > 1
					P_DamageMobj(gaybird.target, gaybird, player.mo, 1)
					else
					P_KillMobj(gaybird.target, gaybird, player.mo, DMG_INSTAKILL)
					end
				end
			else
				player.bird3target = "none"
				gaybird.target = nil
				player.target3distance = nil
				player.bird3MissionTime = false
				gaybird.returninghome = true
				DebugPrint("Enemy is gone, or mission has failed! Number: 3")
			end
		end
		elseif gaybird.number == 4 and not gaybird.returninghome
		if player.bird4MissionTime and player.target4distance and player.bird4target.valid
			--DebugPrint("I've been summoned, I am: " .. gaybird.number)
			gaybird.idle = false
			if player.bird4target != "none" gaybird.target = player.bird4target end
			if gaybird.target and gaybird.target.valid and gaybird.target.health > 0 and not (gaybird.target.flags2 & MF2_FRET)
			and player.target4distance < 768
				A_HomingChase(gaybird, 35*FRACUNIT, 0)
				if (R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y))/FRACUNIT < 30
					if gaybird.target.health > 1 and not (gaybird.target.type == MT_EGGGUARD)
					P_DamageMobj(gaybird.target, gaybird, player.mo, 1)
					else
					P_KillMobj(gaybird.target, gaybird, player.mo, DMG_INSTAKILL)
					end
				end
			else
				player.bird4target = "none"
				gaybird.target = nil
				player.target4distance = nil
				player.bird4MissionTime = false
				gaybird.returninghome = true
				DebugPrint("Enemy is gone, or mission has failed! Number: 4")
			end
		end	
	end
	
	-- [ Return back to player ] --
	if gaybird.returninghome
		gaybird.idle = false
		gaybird.target = player.birdhome
		gaybird.DistanceFromPlayer = R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y)/FRACUNIT
		gaybird.SpeedPlus = gaybird.DistanceFromPlayer / 70
		if gaybird.SpeedPlus < 10
		gaybird.SpeedPlus = 10
		end
		if gaybird.imlost
			A_HomingChase(gaybird, 10*gaybird.SpeedPlus*FRACUNIT, 0)
		else 
			A_HomingChase(gaybird, 3*gaybird.SpeedPlus*FRACUNIT, 0)
		end
		if gaybird.target and (R_PointToDist2(gaybird.target.x, gaybird.target.y, gaybird.x, gaybird.y))/FRACUNIT < 45
			gaybird.target = nil
			gaybird.returninghome = false
			gaybird.imlost = false
			if gaybird.number == 1
				player.bird1target = "none"
				player.bird1MissionTime = false
				player.target1distance = nil
			elseif gaybird.number == 2
				player.bird2target = "none"
				player.bird2MissionTime = false
				player.target2distance = nil
			elseif gaybird.number == 3
				player.bird3target = "none"
				player.bird3MissionTime = false
				player.target3distance = nil
			elseif gaybird.number == 4 
				player.bird4target = "none"
				player.bird4MissionTime = false
				player.target4distance = nil
			end
			gaybird.idle = true
			DebugPrint("back home, number: " +gaybird.number)
		end
	end

-- [ bird is travelling dimensions when they're supposed to be idle ] --
-- this shouldn't be a problem anymore, but this is just for in case it comes up in some Wild situation
	gaybird.idleplayerdistance = R_PointToDist2(player.mo.x, player.mo.y, gaybird.x, gaybird.y)/FRACUNIT
	if gaybird.idleplayerdistance > 1600 and gaybird.idle
		if gaybird.number == 1
			player.bird1target = "none"
			player.target1distance = nil
			player.bird1MissionTime = false
		elseif gaybird.number == 2
			player.bird2target = "none"
			player.target2distance = nil
			player.bird2MissionTime = false
		elseif gaybird.number == 3
			player.bird3target = "none"
			player.target3distance = nil
			player.bird3MissionTime = false
		elseif gaybird.number == 4
			player.bird4target = "none"
			player.target4distance = nil
			player.bird4MissionTime = false
		end
		gaybird.returninghome = true
		gaybird.imlost = true
		DebugPrint("Too far away, forcing self to return! Number is: " .. gaybird.number)
	end

-- [ Player is no longer super, disperse. ] --
	if not player.powers[pw_super]
		DebugPrint(gaybird.number)
		P_RemoveMobj(gaybird) -- replace with function that first makes them fly up and away, and after a certain distance, it removes them; offset by the bird number
	end
end, MT_TLBRD)

addHook("MobjThinker", function(CoryInTheHouse)
local player = CoryInTheHouse.tailsdude.player
	if not player.powers[pw_super]
		P_RemoveMobj(CoryInTheHouse)
	end
end, MT_TLHME)