freeslot("SPR_LKST", 
"SPR_LKSA", 
"SPR_LKSB",
"SPR_LKSC",

"SPR_LKL2",
"SPR_LKL3",
"SPR_LKL4",
"SPR_LKL5",
"SPR_LKNL",
"SPR_LKFL",

"S_LKSTR1", 
"S_LKSTR2",
"S_LKSTR3",
"S_LKSTR4",
"S_LKSTR5",
"S_LKSTR6",
"S_LKSTR7",
"S_LKSTR8",

"S_LKSTA1", 
"S_LKSTA2",
"S_LKSTA3",
"S_LKSTA4",
"S_LKSTA5",
"S_LKSTA6",
"S_LKSTA7",
"S_LKSTA8",

"S_LKSTB1", 
"S_LKSTB2",
"S_LKSTB3",
"S_LKSTB4",
"S_LKSTB5",
"S_LKSTB6",
"S_LKSTB7",
"S_LKSTB8",

"S_LKSTC1", 
"S_LKSTC2",
"S_LKSTC3",
"S_LKSTC4",

"S_LKLAP1", 
"S_LKLAP2",
"S_LKLAP3",
"S_LKLAP4",
"S_LKLAP5",

"S_LKL201",
"S_LKL202",
"S_LKL203",
"S_LKL204",
"S_LKL205",
"S_LKL206",
"S_LKL207",
"S_LKL208",
"S_LKL209",
"S_LKL210",
"S_LKL211",

"S_LKL301",
"S_LKL302",
"S_LKL303",
"S_LKL304",
"S_LKL305",
"S_LKL306",
"S_LKL307",
"S_LKL308",
"S_LKL309",
"S_LKL310",
"S_LKL311",
"S_LKL312",

"S_LKL401",
"S_LKL402",
"S_LKL403",
"S_LKL404",
"S_LKL405",
"S_LKL406",
"S_LKL407",
"S_LKL408",
"S_LKL409",
"S_LKL410",
"S_LKL411",
"S_LKL412",

"S_LKL501",
"S_LKL502",
"S_LKL503",
"S_LKL504",
"S_LKL505",
"S_LKL506",
"S_LKL507",
"S_LKL508",
"S_LKL509",
"S_LKL510",
"S_LKL511",
"S_LKL512",

"S_LKNL01",
"S_LKNL02",
"S_LKNL03",
"S_LKNL04",
"S_LKNL05",
"S_LKNL06",
"S_LKNL07",
"S_LKNL08",
"S_LKNL09",
"S_LKNL10",
"S_LKNL11",
"S_LKNL12",

"S_LKFL01",
"S_LKFL02",
"S_LKFL03",
"S_LKFL04",
"S_LKFL05",
"S_LKFL06",
"S_LKFL07",
"S_LKFL08",
"S_LKFL09",
"S_LKFL10",
"S_LKFL11",
"S_LKFL12",
"S_LKFL13",
"S_LKFL14",
"S_LKFL15",
"S_LKFL16",

"MT_K64LAKITU")

-- mobj and state setup
mobjinfo[MT_K64LAKITU] = {
	doomednum = -1,
	spawnstate = S_LKSTR1,
	spawnhealth = 1000,
	radius = 20*FRACUNIT,
	height = 56*FRACUNIT,
	flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_DONTENCOREMAP|MF2_DONTDRAW
}

-- condensing this for my sanity

-- race start
states[S_LKSTR1] = {SPR_LKST, 0, -1, nil, 0, 0, nil}
states[S_LKSTR2] = {SPR_LKST, 1, 2, nil, 0, 0, S_LKSTR3}
states[S_LKSTR3] = {SPR_LKST, 2, 2, nil, 0, 0, S_LKSTR4}
states[S_LKSTR4] = {SPR_LKST, 3, 2, nil, 0, 0, S_LKSTR5}
states[S_LKSTR5] = {SPR_LKST, 4, 2, nil, 0, 0, S_LKSTR6}
states[S_LKSTR6] = {SPR_LKST, 5, 2, nil, 0, 0, S_LKSTR7}
states[S_LKSTR7] = {SPR_LKST, 6, 2, nil, 0, 0, S_LKSTR8}
states[S_LKSTR8] = {SPR_LKST, 7, -1, nil, 0, 0, nil}

states[S_LKSTA1] = {SPR_LKSA, 0, 4, nil, 0, 0, S_LKSTA2}
states[S_LKSTA2] = {SPR_LKSA, 1, 4, nil, 0, 0, S_LKSTA3}
states[S_LKSTA3] = {SPR_LKSA, 2, 4, nil, 0, 0, S_LKSTA4}
states[S_LKSTA4] = {SPR_LKSA, 3, 4, nil, 0, 0, S_LKSTA5}
states[S_LKSTA5] = {SPR_LKSA, 4, 4, nil, 0, 0, S_LKSTA6}
states[S_LKSTA6] = {SPR_LKSA, 5, 4, nil, 0, 0, S_LKSTA7}
states[S_LKSTA7] = {SPR_LKSA, 6, 4, nil, 0, 0, S_LKSTA8}
states[S_LKSTA8] = {SPR_LKSA, 7, -1, nil, 0, 0, nil}

states[S_LKSTB1] = {SPR_LKSB, 0, 4, nil, 0, 0, S_LKSTB2}
states[S_LKSTB2] = {SPR_LKSB, 1, 4, nil, 0, 0, S_LKSTB3}
states[S_LKSTB3] = {SPR_LKSB, 2, 4, nil, 0, 0, S_LKSTB4}
states[S_LKSTB4] = {SPR_LKSB, 3, 4, nil, 0, 0, S_LKSTB5}
states[S_LKSTB5] = {SPR_LKSB, 4, 4, nil, 0, 0, S_LKSTB6}
states[S_LKSTB6] = {SPR_LKSB, 5, 4, nil, 0, 0, S_LKSTB7}
states[S_LKSTB7] = {SPR_LKSB, 6, 4, nil, 0, 0, S_LKSTB8}
states[S_LKSTB8] = {SPR_LKSB, 7, -1, nil, 0, 0, nil}

states[S_LKSTC1] = {SPR_LKSC, 0, 2, nil, 0, 0, S_LKSTC2}
states[S_LKSTC2] = {SPR_LKSC, 1, 2, nil, 0, 0, S_LKSTC3}
states[S_LKSTC3] = {SPR_LKSC, 2, 2, nil, 0, 0, S_LKSTC4}
states[S_LKSTC4] = {SPR_LKSC, 3, -1, nil, 0, 0, nil}

--lap count

states[S_LKLAP1] = {SPR_LKL2, 0, 16, nil, 0, 0, S_LKLAP2}
states[S_LKLAP2] = {SPR_LKL2, 1, 1, nil, 0, 0, S_LKLAP3}
states[S_LKLAP3] = {SPR_LKL2, 2, 1, nil, 0, 0, S_LKLAP4}
states[S_LKLAP4] = {SPR_LKL2, 3, 1, nil, 0, 0, S_LKLAP5}
states[S_LKLAP5] = {SPR_LKL2, 4, -1, nil, 0, 0, nil}

states[S_LKL201] = {SPR_LKL2, 5, 1, nil, 0, 0, S_LKL202}
states[S_LKL202] = {SPR_LKL2, 6, 1, nil, 0, 0, S_LKL203}
states[S_LKL203] = {SPR_LKL2, 7, 1, nil, 0, 0, S_LKL204}
states[S_LKL204] = {SPR_LKL2, 8, 1, nil, 0, 0, S_LKL205}
states[S_LKL205] = {SPR_LKL2, 9, 1, nil, 0, 0, S_LKL206}
states[S_LKL206] = {SPR_LKL2, 10, 1, nil, 0, 0, S_LKL207}
states[S_LKL207] = {SPR_LKL2, 11, 1, nil, 0, 0, S_LKL208}
states[S_LKL208] = {SPR_LKL2, 12, 1, nil, 0, 0, S_LKL209}
states[S_LKL209] = {SPR_LKL2, 13, 1, nil, 0, 0, S_LKL210}
states[S_LKL210] = {SPR_LKL2, 14, 1, nil, 0, 0, S_LKL211}
states[S_LKL211] = {SPR_LKL2, 15, -1, nil, 0, 0, nil}

states[S_LKL301] = {SPR_LKL3, 0, 1, nil, 0, 0, S_LKL302}
states[S_LKL302] = {SPR_LKL3, 1, 1, nil, 0, 0, S_LKL303}
states[S_LKL303] = {SPR_LKL3, 2, 1, nil, 0, 0, S_LKL304}
states[S_LKL304] = {SPR_LKL3, 3, 1, nil, 0, 0, S_LKL305}
states[S_LKL305] = {SPR_LKL3, 4, 1, nil, 0, 0, S_LKL306}
states[S_LKL306] = {SPR_LKL3, 5, 1, nil, 0, 0, S_LKL307}
states[S_LKL307] = {SPR_LKL3, 6, 1, nil, 0, 0, S_LKL308}
states[S_LKL308] = {SPR_LKL3, 7, 1, nil, 0, 0, S_LKL309}
states[S_LKL309] = {SPR_LKL3, 8, 1, nil, 0, 0, S_LKL310}
states[S_LKL310] = {SPR_LKL3, 9, 1, nil, 0, 0, S_LKL311}
states[S_LKL311] = {SPR_LKL3, 10, 1, nil, 0, 0, S_LKL312}
states[S_LKL312] = {SPR_LKL3, 11, -1, nil, 0, 0, nil}

states[S_LKL401] = {SPR_LKL4, 0, 1, nil, 0, 0, S_LKL402}
states[S_LKL402] = {SPR_LKL4, 1, 1, nil, 0, 0, S_LKL403}
states[S_LKL403] = {SPR_LKL4, 2, 1, nil, 0, 0, S_LKL404}
states[S_LKL404] = {SPR_LKL4, 3, 1, nil, 0, 0, S_LKL405}
states[S_LKL405] = {SPR_LKL4, 4, 1, nil, 0, 0, S_LKL406}
states[S_LKL406] = {SPR_LKL4, 5, 1, nil, 0, 0, S_LKL407}
states[S_LKL407] = {SPR_LKL4, 6, 1, nil, 0, 0, S_LKL408}
states[S_LKL408] = {SPR_LKL4, 7, 1, nil, 0, 0, S_LKL409}
states[S_LKL409] = {SPR_LKL4, 8, 1, nil, 0, 0, S_LKL410}
states[S_LKL410] = {SPR_LKL4, 9, 1, nil, 0, 0, S_LKL411}
states[S_LKL411] = {SPR_LKL4, 10, 1, nil, 0, 0, S_LKL412}
states[S_LKL412] = {SPR_LKL4, 11, -1, nil, 0, 0, nil}

states[S_LKL501] = {SPR_LKL5, 0, 1, nil, 0, 0, S_LKL502}
states[S_LKL502] = {SPR_LKL5, 1, 1, nil, 0, 0, S_LKL503}
states[S_LKL503] = {SPR_LKL5, 2, 1, nil, 0, 0, S_LKL504}
states[S_LKL504] = {SPR_LKL5, 3, 1, nil, 0, 0, S_LKL505}
states[S_LKL505] = {SPR_LKL5, 4, 1, nil, 0, 0, S_LKL506}
states[S_LKL506] = {SPR_LKL5, 5, 1, nil, 0, 0, S_LKL507}
states[S_LKL507] = {SPR_LKL5, 6, 1, nil, 0, 0, S_LKL508}
states[S_LKL508] = {SPR_LKL5, 7, 1, nil, 0, 0, S_LKL509}
states[S_LKL509] = {SPR_LKL5, 8, 1, nil, 0, 0, S_LKL510}
states[S_LKL510] = {SPR_LKL5, 9, 1, nil, 0, 0, S_LKL511}
states[S_LKL511] = {SPR_LKL5, 10, 1, nil, 0, 0, S_LKL512}
states[S_LKL512] = {SPR_LKL5, 11, -1, nil, 0, 0, nil}

states[S_LKNL01] = {SPR_LKNL, 0, 1, nil, 0, 0, S_LKNL02}
states[S_LKNL02] = {SPR_LKNL, 1, 1, nil, 0, 0, S_LKNL03}
states[S_LKNL03] = {SPR_LKNL, 2, 1, nil, 0, 0, S_LKNL04}
states[S_LKNL04] = {SPR_LKNL, 3, 1, nil, 0, 0, S_LKNL05}
states[S_LKNL05] = {SPR_LKNL, 4, 1, nil, 0, 0, S_LKNL06}
states[S_LKNL06] = {SPR_LKNL, 5, 1, nil, 0, 0, S_LKNL07}
states[S_LKNL07] = {SPR_LKNL, 6, 1, nil, 0, 0, S_LKNL08}
states[S_LKNL08] = {SPR_LKNL, 7, 1, nil, 0, 0, S_LKNL09}
states[S_LKNL09] = {SPR_LKNL, 8, 1, nil, 0, 0, S_LKNL10}
states[S_LKNL10] = {SPR_LKNL, 9, 1, nil, 0, 0, S_LKNL11}
states[S_LKNL11] = {SPR_LKNL, 10, 1, nil, 0, 0, S_LKNL12}
states[S_LKNL12] = {SPR_LKNL, 11, -1, nil, 0, 0, nil}

states[S_LKFL01] = {SPR_LKFL, 0, 16, nil, 0, 0, S_LKFL02}
states[S_LKFL02] = {SPR_LKFL, 1, 1, nil, 0, 0, S_LKFL03}
states[S_LKFL03] = {SPR_LKFL, 2, 1, nil, 0, 0, S_LKFL04}
states[S_LKFL04] = {SPR_LKFL, 3, 1, nil, 0, 0, S_LKFL05}
states[S_LKFL05] = {SPR_LKFL, 4, 1, nil, 0, 0, S_LKFL06}
states[S_LKFL06] = {SPR_LKFL, 5, 1, nil, 0, 0, S_LKFL07}
states[S_LKFL07] = {SPR_LKFL, 6, 1, nil, 0, 0, S_LKFL08}
states[S_LKFL08] = {SPR_LKFL, 7, 1, nil, 0, 0, S_LKFL09}
states[S_LKFL09] = {SPR_LKFL, 8, 1, nil, 0, 0, S_LKFL10}
states[S_LKFL10] = {SPR_LKFL, 9, 1, nil, 0, 0, S_LKFL11}
states[S_LKFL11] = {SPR_LKFL, 10, 1, nil, 0, 0, S_LKFL12}
states[S_LKFL12] = {SPR_LKFL, 11, 1, nil, 0, 0, S_LKFL13}
states[S_LKFL13] = {SPR_LKFL, 12, 1, nil, 0, 0, S_LKFL14}
states[S_LKFL14] = {SPR_LKFL, 13, 1, nil, 0, 0, S_LKFL15}
states[S_LKFL15] = {SPR_LKFL, 14, 1, nil, 0, 0, S_LKFL16}
states[S_LKFL16] = {SPR_LKFL, 15, -1, nil, 0, 0, nil}

-- array for lap count
local lktuLapCountStates = {S_LKL201, S_LKL301, S_LKL401, S_LKL501}
/*
[LAKITU CODE]

SPAWN LAKITU 73 TICS IN

IN 36 TICS:
Lakitu eases into the RIGHT of the player's position

x offset 25
y offset 22
z offset 56

AFTERWARDS; IN 21 TICS;

An animation plays, and he gets ready to count down

4 tic delay for each frame

On race start, he floats around the player before flying off*/

// first, I should figure out a code that can display HORIZONTAL and VERTICAL distance based on the player's camera's angle

// so this works:

local function getDistanceLockedToCameraX(p,xd,yd)
	local xDist = xd
	local yDist = yd
	local plCamAngle = 0
	
	plCamAngle = R_PointToAngle(p.mo.x, p.mo.y);
	
	local x1 = xDist*cos(plCamAngle-(90*ANG1))
	local y1 = xDist*sin(plCamAngle-(90*ANG1))
	local x2 = yDist*cos(plCamAngle)
	local y2 = yDist*sin(plCamAngle)
	
	local tx = x2+x1
	local ty = y2+y1
	
	return tx
end

local function getDistanceLockedToCameraY(p,xd,yd)
	local xDist = xd
	local yDist = yd
	local plCamAngle = 0
	
	plCamAngle = R_PointToAngle(p.mo.x, p.mo.y);
	
	local x1 = xDist*cos(plCamAngle-(90*ANG1))
	local y1 = xDist*sin(plCamAngle-(90*ANG1))
	local x2 = yDist*cos(plCamAngle)
	local y2 = yDist*sin(plCamAngle)
	
	local tx = x2+x1
	local ty = y2+y1
	
	return ty
end

local function getDistanceLockedToAngleX(p,xd,yd,angle)
	local xDist = xd
	local yDist = yd
	local lockAngle = angle
	
	local x1 = xDist*cos(lockAngle-(90*ANG1))
	local y1 = xDist*sin(lockAngle-(90*ANG1))
	local x2 = yDist*cos(lockAngle)
	local y2 = yDist*sin(lockAngle)
	
	local tx = x2+x1
	local ty = y2+y1
	
	return tx
end

local function getDistanceLockedToAngleY(p,xd,yd,angle)
	local xDist = xd
	local yDist = yd
	local lockAngle = angle
	
	local x1 = xDist*cos(lockAngle-(90*ANG1))
	local y1 = xDist*sin(lockAngle-(90*ANG1))
	local x2 = yDist*cos(lockAngle)
	local y2 = yDist*sin(lockAngle)
	
	local tx = x2+x1
	local ty = y2+y1
	
	return ty
end

local raceStartTic = 130

addHook("MobjThinker", function(mo)
	if (mo.valid)
	and (mo ~= nil)
	and (mo.target ~=  nil)
	and mo.target.valid
		local p = mo.target.player
		if (mo.dist == nil)
			mo.exitSpeed = 0
			mo.exitFactor = 0
			mo.lapSignal = false;
			mo.orbitAngle = 225;
			mo.lapDist = 125;
			mo.lapDist2 = 0;
			if (modeattacking)
				mo.dist = 0
			else
				mo.dist = 299
			end
		end
		local finalDist = ((mo.dist*mo.dist)/100)
		local lapFinalDist = ((mo.lapDist*mo.lapDist)/100)
		local lapFinalDist2 = ((mo.lapDist2*mo.lapDist2)/100)
		
		if p ~= displayplayers[0]
			mo.flags = $ | MF2_DONTDRAW
		end
		
		
		if (leveltime == 73)
				mo.flags = $ & ~MF2_DONTDRAW
		end
		
		if (leveltime > 73)
			if (mo.dist > 24)
				mo.dist = $1 - 8
			else
				if (mo.state == S_LKSTR1)
					mo.state = S_LKSTR2
				end
			end
		end
		
		mo.exitFactor = $1 + mo.exitSpeed
		
		if (p.rcwCountLap == true)
			if (mo.lapSignal ~= true)
				if ((p.currentLap-1) < (p.lkNumLaps - 1))
					mo.state = S_LKLAP1;
				else
					mo.state = S_LKFL01;
				end
				mo.lapSignal = true
			end

			if (mo.state == S_LKLAP5)
				if (p.currentLap <= 5)
					mo.state = lktuLapCountStates[p.currentLap-1]
				else
					mo.state = S_LKNL01;
				end
			end
			
			if ((mo.flags & MF2_DONTDRAW) != 0)
				mo.flags = ($ & ~MF2_DONTDRAW)
			end
			
			if ((mo.lapDist > 24) and (mo.orbitAngle > (-77)))
				mo.lapDist = $1 - 8
			elseif (mo.orbitAngle > (-77))
				mo.orbitAngle = $1 - 4;
			elseif (mo.lapDist2 < 210)
				mo.lapDist2 = $1 + 6
			else
				if ((mo.flags & MF2_DONTDRAW) == 0)
					mo.flags = ($ | MF2_DONTDRAW)
				end
				mo.orbitAngle = 225;
				mo.lapDist = 125;
				mo.lapDist2 = 0;
				mo.lapSignal = false;
				p.rcwCountLap = false;
			end
		end
		
		if (leveltime >= 245)
		and ((mo.flags & MF2_DONTDRAW) == 0)
			mo.exitSpeed = $1 + 1;
		end
		
		if ((leveltime == raceStartTic) and (mo.state == S_LKSTR8))
			mo.state = S_LKSTA1
		elseif ((leveltime == (raceStartTic+35)) and (mo.state == S_LKSTA8))
			mo.state = S_LKSTA1
		elseif ((leveltime == (raceStartTic+70)) and (mo.state == S_LKSTA8))
			mo.state = S_LKSTB1
		elseif ((leveltime >= (raceStartTic+100)) and (mo.state == S_LKSTB8))
			mo.state = S_LKSTC1
		end
	
		local tx = getDistanceLockedToCameraX(p,finalDist+22,(finalDist+25)-(mo.exitFactor/3))
		local ty = getDistanceLockedToCameraY(p,finalDist+22,(finalDist+25)-(mo.exitFactor/6))
		
		local lx = (25*cos(mo.orbitAngle*ANG1)/p.mo.scale);
		local ly = (25*sin(mo.orbitAngle*ANG1)/p.mo.scale);
		
		local tx2 = getDistanceLockedToCameraX(p,lapFinalDist+(-lapFinalDist2)+lx,(-lapFinalDist)+(-lapFinalDist2)+ly)
		local ty2 = getDistanceLockedToCameraY(p,lapFinalDist+(-lapFinalDist2)+lx,(-lapFinalDist)+(-lapFinalDist2)+ly)
	
		
		
		if (p.rcwCountLap ~= true)
			P_TeleportMove(mo, mo.target.x+tx, mo.target.y+ty, mo.target.z+((mo.exitFactor*mo.exitFactor)/350)+(4*sin((leveltime*8)*ANG1))+(20*FRACUNIT)+((finalDist*FRACUNIT)/2))
			if (mo.exitFactor >= 1081)
			and ((mo.flags & MF2_DONTDRAW) == 0)
				mo.exitfactor = 0
				mo.flags = ($ | MF2_DONTDRAW)
			end
		else
			P_TeleportMove(mo, mo.target.x+tx2, mo.target.y+ty2, mo.target.z+(24*FRACUNIT))
		end
	else
		P_RemoveMobj(mo)
	end
end, MT_K64LAKITU)

addHook("MobjThinker", function(mo)
	local p = mo.player
	
	if (leveltime < 4)
		p.hasLakitu = false
	end
	
	if (p.hasLakitu ~= true)
	and leveltime >= 4
	and (tonumber(gamemap) == 790)
		p.lkDoRaceStart = false
		p.lkDoLapAnim = false
		local lakitu = P_SpawnMobj(p.mo.x, p.mo.y, p.mo.z, MT_K64LAKITU)
		lakitu.target = mo
		p.hasLakitu = true
	end
	
	if (leveltime < 73)
		p.lkDoRaceStart = true
	end
end, MT_PLAYER)
