//serval lua wise fwom yor gwave
//by freeman2651 for pippu because i think he's cute and funny and so is hoshino
//originally when we were working on a sprite for Serval and Kaban in the same kart
//we featurecreeped an entire animation handler that included dynamic tail animations for serval
//and dynamic ear animation speed based on current velocity, but because we hadn't closely studied
//that kemono tails go UNDER the skirt and not outside it, animating it like we thought turned out to be impossible

//so ive pretty much recycled that work from 3 years ago into this little mobj overlay project
//this handles an idle animation and some noises that makes koyuki fall asleep if the player
//gives no inputs for several seconds

local FRACUNIT = FRACUNIT
local TICRATE = TICRATE
local MF2_OBJECTFLIP = MF2_OBJECTFLIP
local MFE_VERTICALFLIP = MFE_VERTICALFLIP
local frameangle = frameangle

freeslot("MT_HOSHINOZZZ","S_HOSHZZZ","SPR_HOSZ") //the stuff for the "ZZZ" animation
freeslot("MT_HOSHINOHALO","S_HOSHINOHALO","SPR_HOSA") //the stuff for her halo
freeslot("sfx_hoshz1","sfx_hoshz2","sfx_hoshz3","sfx_hoshz4","sfx_hoshz5","sfx_hoshzz","sfx_hosuhe") //various noises recorded from a gremlin
local idlenoises = {sfx_hoshz1,sfx_hoshz2,sfx_hoshz3,sfx_hoshz4,sfx_hoshz5}
local transrelative = {0,FF_TRANS10,FF_TRANS20,FF_TRANS30,FF_TRANS40,
						FF_TRANS50,FF_TRANS60,FF_TRANS70,FF_TRANS80,FF_TRANS90}

mobjinfo[MT_HOSHINOZZZ] = {
	doomednum = -1,
	spawnstate = S_HOSHZZZ,
	radius = FRACUNIT,
	height = FRACUNIT,
	flags = MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY,
}
states[S_HOSHZZZ] = {
	sprite = SPR_HOSZ,
	tics = -1,
	frame = FF_TRANS20|FF_ANIMATE|A,
	var1 = 3, //animate 3 other frames
	var2 = 25, //25 tics per frame
}

mobjinfo[MT_HOSHINOHALO] = {
	doomednum = -1,
	spawnstate = S_HOSHINOHALO,
	radius = FRACUNIT,
	height = FRACUNIT,
	flags = MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP|MF_NOBLOCKMAP|MF_NOCLIP|MF_SCENERY,
}
states[S_HOSHINOHALO] = {
	sprite = SPR_HOSA,
	tics = 0,
}

local idletimeout = 10*TICRATE //10 seconds until actually triggering sleep
local idletimeoutpre = (7*TICRATE)/2 //3.5 seconds before above we'll trigger a noise

local pmo = nil //quick pointer to player's mobj
local zzz = nil //quick pointer to the "ZZZ" mobj
local halo = nil //quick pointer to the halo mobj
local testz = nil //holder reference for where to display the mobjs if the player is flipped
local idlediff = nil //holder reference for the amount of time since starting transition into idling (for animations)

addHook("ThinkFrame", function()//you can't force me to learn playerthink
	if leveltime <= 2 then return end //the invisible two or three frames while everything loads is literally electronic satan
	for p in players.iterate
		if p and p.valid and (leveltime == 3 or leveltime%TICRATE*10 == 0) then //this just periodically refreshes everyone's eepy noise for F L A V O R
			p.hoshsleepnoise = idlenoises[P_RandomRange(1,#idlenoises)]
		end
		if p and p.valid and p.mo and p.mo.valid and not p.specatator then
			//print(leveltime..": sanity checked")
			pmo = p.mo
			zzz = p.hoshz
			halo = p.hoshhalo
			if pmo.skin ~= "hoshino" then
				//print(leveltime..": NOT hoshino killing overlay")
				if p.hoshz and p.hoshz.valid then P_RemoveMobj(p.hoshz) end
				if p.hoshhalo and p.hoshhalo.valid then P_RemoveMobj(p.hoshhalo) end
				return
			else
				if (not zzz or (not zzz.valid)) or (not halo or (not halo.valid)) then
					//print(leveltime..": hoshino detected but no overlays, making a new one")
					p.hoshz = P_SpawnMobj(0,0,0,MT_HOSHINOZZZ)
					zzz = p.hoshz
					zzz.target = pmo
					zzz.idlecounter = 0
					p.hoshhalo = P_SpawnMobj(0,0,0,MT_HOSHINOHALO)
					halo = p.hoshhalo
					halo.target = pmo
					continue
				end
			end
			if not(p.cmd.buttons&(BT_ACCELERATE|BT_BRAKE|BT_ATTACK)) then
				zzz.idlecounter = $+1
				if leveltime%35 == 0 then
					//print(p.name.." getting eepy: "..zzz.idlecounter)
				end
			else
				//print(leveltime..": awaken my masters")
				if zzz.idlecounter>=idletimeout then
					S_StartSound(pmo,sfx_hosuhe)
					zzz.fadeintimer = 1*TICRATE
				end
				zzz.idlecounter = 0
			end
			//play funne sounds at certain idle timer points
			//if zzz.idlecounter == idletimeout then S_StartSound(pmo,sfx_hoshzz)
			if zzz.idlecounter == idletimeout-idletimeoutpre then S_StartSound(pmo,p.hoshsleepnoise) end

			zzz.scale = pmo.scale/3
			zzz.flags2 = pmo.flags2
			zzz.eflags = pmo.eflags
			zzz.color = pmo.color
			zzz.target = pmo //this here so when respawning overlays dont die JESUS DICK
			zzz.angle = pmo.angle

			testz = pmo.z + pmo.height + (FRACUNIT*45)
			if zzz.flags2 & MF2_OBJECTFLIP or zzz.eflags & MFE_VERTICALFLIP then testz = pmo.z - (FRACUNIT*45) end
			P_MoveOrigin(zzz,pmo.x - FixedMul(zzz.scale, FixedMul(FRACUNIT*1, cos(p.frameangle))),
			pmo.y - FixedMul(zzz.scale, FixedMul(FRACUNIT*1,sin(p.frameangle))),testz)
			if pmo.state == S_INVISIBLE or pmo.flags2 & MF2_DONTDRAW or zzz.idlecounter < idletimeout then zzz.sprite = SPR_NULL else zzz.sprite = SPR_HOSZ end

			halo.scale = pmo.scale
			halo.flags2 = pmo.flags2
			halo.eflags = pmo.eflags
			halo.color = pmo.color
			halo.target = pmo //this here so when respawning overlays dont die JESUS DICK
			halo.angle = pmo.angle
			halo.frame = pmo.frame

			testz = pmo.z
			if halo.flags2 & MF2_OBJECTFLIP or halo.eflags & MFE_VERTICALFLIP then testz = pmo.z end
			P_MoveOrigin(halo,pmo.x - FixedMul(halo.scale, FixedMul(FRACUNIT*1, cos(p.frameangle))),
			pmo.y - FixedMul(halo.scale, FixedMul(FRACUNIT*1,sin(p.frameangle))),testz)


			if pmo.state == S_INVISIBLE or pmo.flags2&MF2_DONTDRAW or zzz.idlecounter>=idletimeout then
				halo.sprite = SPR_NULL
			else
				halo.sprite = SPR_HOSA
				if zzz.idlecounter>(idletimeout-idletimeoutpre) then
					idlediff = zzz.idlecounter-(idletimeout-idletimeoutpre)
					//print(leveltime.." - counter: "..zzz.idlecounter..", idletimeout and pre:"..idletimeout.."/"..idletimeoutpre..", idlediff:"..idlediff)
					//122 frames until actually being idle
					//10 levels of transluency available
					halo.frame = $|transrelative[min(max(1,idlediff/12),#transrelative)]
					//this means if I put all the transparency flags in a small table and essentially ease this over
					//122 frames over 10 states by dividing it by 12 it should fade over the 3 seconds right?? I think.
				elseif zzz.fadeintimer then
					zzz.fadeintimer = max($-1,0)
					halo.frame = $|transrelative[min(max(1,zzz.fadeintimer/3),#transrelative)]
					//and TECHNICALLY I can do this in reverse by counting down instead of up RIGHT??
				else
					halo.frame = pmo.frame
				end
			end
		end
	end
end)