// ------------------------------------------
// Lua_Feet
// Kirby's feet!
// Backported... or, forwardported I guess?
// from kart!
// ------------------------------------------
local charskin = "kirby"				// Set this to your character's skin (MUST BE ALL LOWWER CASE!)

// Sprite to overlay sprite table
local overlaysprites = {}
overlaysprites[SPR_PLAY] = SPR_PLAY
overlaysprites[SPR_KFBL] = SPR_FFBL
overlaysprites[SPR_KICE] = SPR_FICE
overlaysprites[SPR_KHLP] = SPR_FHLP
overlaysprites[SPR_KSPR] = SPR_FSPK
overlaysprites[SPR_KNDL] = SPR_FNDL
overlaysprites[SPR_KTRN] = SPR_FTRN
overlaysprites[SPR_KSWR] = SPR_FSWR
overlaysprites[SPR_KHMR] = SPR_FHMR
overlaysprites[SPR_KDST] = SPR_FDST
overlaysprites[SPR_KSPT] = SPR_FSPT
overlaysprites[SPR_KSLP] = SPR_FSLP
overlaysprites[SPR_KGUN] = SPR_FGUN
overlaysprites[SPR_KYAH] = SPR_FYAH
overlaysprites[SPR_KLEG] = SPR_FLEG
overlaysprites[SPR_FATL] = SPR_FLEG

rawset(_G, "K_AddCustomFeet", function(kirbysprite, feetsprite)
	overlaysprites[kirbysprite] = feetsprite
end)

// Array of colors!
// List cant be copied from kart oops
local overlaycolors = {}
overlaycolors[SKINCOLOR_WHITE] = SKINCOLOR_RED			// Snow (Amazing Mirror)
overlaycolors[SKINCOLOR_BONE] = SKINCOLOR_CLOUDY		// White (Squeak Squad)
overlaycolors[SKINCOLOR_CLOUDY] = SKINCOLOR_CARBON		// Kirby (Dream Land US) / Chalk (Amazing Mirror)
overlaycolors[SKINCOLOR_GREY] = nil
overlaycolors[SKINCOLOR_SILVER] = nil
overlaycolors[SKINCOLOR_CARBON] = SKINCOLOR_ORANGE		// Carbon (Amazing Mirror)
overlaycolors[SKINCOLOR_JET] = nil
overlaycolors[SKINCOLOR_BLACK] = SKINCOLOR_BLACK		// Shadow (Amazing Mirror)
overlaycolors[SKINCOLOR_AETHER] = SKINCOLOR_SILVER		// Suguri
overlaycolors[SKINCOLOR_SLATE] = nil
overlaycolors[SKINCOLOR_BLUEBELL] = nil
overlaycolors[SKINCOLOR_PINK] = SKINCOLOR_CRIMSON		// Right back at ya
overlaycolors[SKINCOLOR_YOGURT] = nil
overlaycolors[SKINCOLOR_BROWN] = SKINCOLOR_RUST			// Chocolate (Amazing Mirror)
overlaycolors[SKINCOLOR_BRONZE] = nil
overlaycolors[SKINCOLOR_TAN] = SKINCOLOR_BROWN			// Ivory (Squeak Squad)
overlaycolors[SKINCOLOR_BEIGE] = nil
overlaycolors[SKINCOLOR_MOSS] = nil
overlaycolors[SKINCOLOR_AZURE] = nil
overlaycolors[SKINCOLOR_LAVENDER] = SKINCOLOR_MAGENTA	// Purple
overlaycolors[SKINCOLOR_RUBY] = SKINCOLOR_SAPPHIRE		// Ruby/Sapphire
overlaycolors[SKINCOLOR_SALMON] = SKINCOLOR_CRIMSON		// Red (Melee)
overlaycolors[SKINCOLOR_RED] = SKINCOLOR_MAGENTA		// Red (Amazing Mirror)
overlaycolors[SKINCOLOR_CRIMSON] = SKINCOLOR_BLACK		// Edge (SRB2)
overlaycolors[SKINCOLOR_FLAME] = nil
overlaycolors[SKINCOLOR_KETCHUP] = nil
overlaycolors[SKINCOLOR_PEACHY] = nil
overlaycolors[SKINCOLOR_QUAIL] = nil
overlaycolors[SKINCOLOR_SUNSET] = SKINCOLOR_CARBON		// Sora (10k years)
overlaycolors[SKINCOLOR_COPPER] = nil
overlaycolors[SKINCOLOR_APRICOT] = SKINCOLOR_ORANGE		// Orange (Amazing Mirror)
overlaycolors[SKINCOLOR_ORANGE] = SKINCOLOR_RED			// Orange (Smash)
overlaycolors[SKINCOLOR_RUST] = nil
overlaycolors[SKINCOLOR_GOLD] = SKINCOLOR_BLACK			// Fancy (SRB2)
overlaycolors[SKINCOLOR_SANDY] = nil
overlaycolors[SKINCOLOR_YELLOW] = SKINCOLOR_APRICOT		// Yellow (Amazing Mirror)
overlaycolors[SKINCOLOR_OLIVE] = nil
overlaycolors[SKINCOLOR_LIME] = SKINCOLOR_EMERALD		// Citrus (Squeak Squad)
overlaycolors[SKINCOLOR_PERIDOT] = nil
overlaycolors[SKINCOLOR_APPLE] = nil
overlaycolors[SKINCOLOR_GREEN] = SKINCOLOR_ORANGE		// Green (Amazing Mirror)
overlaycolors[SKINCOLOR_FOREST] = nil
overlaycolors[SKINCOLOR_EMERALD] = SKINCOLOR_FOREST		// Green (Melee)
overlaycolors[SKINCOLOR_MINT] = SKINCOLOR_SKY 			// Green + Blue :ohh_yeah:
overlaycolors[SKINCOLOR_SEAFOAM] = nil
overlaycolors[SKINCOLOR_AQUA] = SKINCOLOR_APRICOT		// Emerald (Amazing Mirror)
overlaycolors[SKINCOLOR_TEAL] = nil
overlaycolors[SKINCOLOR_WAVE] = nil
overlaycolors[SKINCOLOR_CYAN] = SKINCOLOR_BLUE			// Blue (Melee)
overlaycolors[SKINCOLOR_SKY] = SKINCOLOR_LIME			// Sora (Military, blue outfit + green light thingy)
overlaycolors[SKINCOLOR_CERULEAN] = nil
overlaycolors[SKINCOLOR_ICY] = SKINCOLOR_PURPLE			// Ice (Super Star)
overlaycolors[SKINCOLOR_SAPPHIRE] = SKINCOLOR_RUBY		// Ruby/Sapphire
overlaycolors[SKINCOLOR_CORNFLOWER] = SKINCOLOR_RED		// Sonic (SRB2)
overlaycolors[SKINCOLOR_BLUE] = SKINCOLOR_NEON			// Indigo 
overlaycolors[SKINCOLOR_COBALT] = SKINCOLOR_PURPLE		// Meta Knight
overlaycolors[SKINCOLOR_VAPOR] = SKINCOLOR_SAPPHIRE		// Ocean (Amazing Mirror)
overlaycolors[SKINCOLOR_DUSK] = SKINCOLOR_PURPLE		// Sapphire (Amazing Mirror)
overlaycolors[SKINCOLOR_PASTEL] = nil
overlaycolors[SKINCOLOR_PURPLE] = SKINCOLOR_NEON		// Grape (Amazing Mirror)
overlaycolors[SKINCOLOR_BUBBLEGUM] = SKINCOLOR_MINT		// Cherry (Amazing Mirror)
overlaycolors[SKINCOLOR_MAGENTA] = nil
overlaycolors[SKINCOLOR_NEON] = nil
overlaycolors[SKINCOLOR_VIOLET] = nil
overlaycolors[SKINCOLOR_LILAC] = nil
overlaycolors[SKINCOLOR_PLUM] = nil
overlaycolors[SKINCOLOR_RASPBERRY] = nil
overlaycolors[SKINCOLOR_ROSY] = SKINCOLOR_RED			// Kirby

// -----------------------------------------------------------------------------
// Starting here, nothing else needs to be modified for your character to work
// -----------------------------------------------------------------------------
// Overlay object!
// Uses a global variable to store the object number, so there's only one object no matter how many sc characters you have.
// Different versions of second color will use different objects (and therefore globals)
// to ensure characters with different versions are still compatable with eachother.
if(overlayobj_v2 == nil)
	freeslot("MT_SECONDCOLOROVERLAY_V2")
	rawset(_G, "overlayobj_v2", MT_SECONDCOLOROVERLAY_V2)
	mobjinfo[overlayobj_v2].doomednum = -1
	mobjinfo[overlayobj_v2].spawnstate = S_PLAY_STND
	mobjinfo[overlayobj_v2].spawnhealth = 1
	mobjinfo[overlayobj_v2].seestate = S_PLAY_WALK
	mobjinfo[overlayobj_v2].seesound = sfx_none
	mobjinfo[overlayobj_v2].reactiontime = 0
	mobjinfo[overlayobj_v2].attacksound = sfx_thok
	mobjinfo[overlayobj_v2].painstate = S_PLAY_PAIN
	mobjinfo[overlayobj_v2].painchance = MT_THOK
	mobjinfo[overlayobj_v2].painsound = sfx_none
	mobjinfo[overlayobj_v2].meleestate = S_NULL
	mobjinfo[overlayobj_v2].missilestate = S_NULL
	mobjinfo[overlayobj_v2].deathstate = S_PLAY_PAIN
	mobjinfo[overlayobj_v2].xdeathstate = S_NULL
	mobjinfo[overlayobj_v2].deathsound = sfx_none
	mobjinfo[overlayobj_v2].speed = 1
	mobjinfo[overlayobj_v2].radius = 16*FRACUNIT
	mobjinfo[overlayobj_v2].height = 48*FRACUNIT
	mobjinfo[overlayobj_v2].dispoffset = 0
	mobjinfo[overlayobj_v2].mass = 1000
	mobjinfo[overlayobj_v2].damage = MT_THOK
	mobjinfo[overlayobj_v2].activesound = sfx_none
	mobjinfo[overlayobj_v2].flags = MF_NOGRAVITY|MF_NOCLIPTHING
	mobjinfo[overlayobj_v2].raisestate = MT_THOK
	
	// Remove the overlay when we no longer need it!
	addHook("MobjThinker", function(scoverlay)
		scoverlay.tics = $1 + 1
		if(scoverlay.timer)
			scoverlay.timer = $1 - 1
		else
			P_RemoveMobj(scoverlay)
		end
	end, overlayobj_v2)
end

// Garbage
local function setStateSafe(mobj, state)
	local defaultaction = states[state].action
	states[state].action = nil
	mobj.state = state
	states[state].action = defaultaction
end

// -------------------------------------------
// Overlay function
// -------------------------------------------
local function doOverlay(mobj, slopestick, addtotarget)
	// Create the overlay
	if not(mobj.scoverlay and mobj.scoverlay.valid)
		mobj.scoverlay = P_SpawnMobj(mobj.x, mobj.y, mobj.z, overlayobj_v2)
	end
	
	local matchmobj = mobj
	if(addtotarget)
		matchmobj = mobj.target
	end
	
	if not(matchmobj and matchmobj.valid)
		return
	end
	
	// Set the overlay's tracer
	mobj.scoverlay.tracer = matchmobj
//	mobj.scoverlay.flags2 = $1|MF2_LINKDRAW
	
	// Set the overlay's frame to the player's frame! (and tics)
	local height = 0
	if not(addtotarget)
		setStateSafe(mobj.scoverlay, mobj.state)
		mobj.scoverlay.frame = mobj.frame
		mobj.scoverlay.tics = mobj.tics
		mobj.scoverlay.anim_duration = mobj.anim_duration
	else
		if(states[mobj.state].var2)
			height = states[mobj.state].var2*FRACUNIT*P_MobjFlip(matchmobj)
		else
			height = states[mobjinfo[matchmobj.type].seestate].var2*FRACUNIT*P_MobjFlip(matchmobj)
		end
		setStateSafe(mobj.scoverlay, mobj.state)
		mobj.scoverlay.frame = mobj.frame
		mobj.scoverlay.tics = mobj.tics
		mobj.scoverlay.anim_duration = mobj.anim_duration
	end
	
	// Match the overlay to the player
	P_TeleportMove(mobj.scoverlay, mobj.x, mobj.y, matchmobj.z+height)
	mobj.scoverlay.momx = matchmobj.momx
	mobj.scoverlay.momy = matchmobj.momy
	mobj.scoverlay.momz = matchmobj.momz
	if(matchmobj.player and matchmobj.player.valid)
		mobj.scoverlay.angle = matchmobj.player.drawangle
	else
		mobj.scoverlay.angle = matchmobj.angle
	end
	mobj.scoverlay.scale = matchmobj.scale
	mobj.scoverlay.radius = matchmobj.radius
	mobj.scoverlay.height = matchmobj.height
	
	// Match the colors!
	if(mobj.colorized)
		mobj.scoverlay.color = mobj.color
	elseif(mobj.player)
		and(mobj.player.scoverlaycol)
		mobj.scoverlay.color = mobj.player.overlaycol
	else
		if(overlaycolors[mobj.color] == nil)
			if(mobj.color <= 0 or mobj.color >= MAXSKINCOLORS)
				mobj.scoverlay.color = mobj.color
			else
				mobj.scoverlay.color = ColorOpposite(mobj.color)
			end
		else
			mobj.scoverlay.color = overlaycolors[mobj.color]
		end
	end
	mobj.scoverlay.colorized = mobj.colorized
	
	// Set the overlay's sprite
	mobj.scoverlay.skin = mobj.skin
	if(overlaysprites[mobj.sprite])
		mobj.scoverlay.sprite = overlaysprites[mobj.sprite]
	end
	mobj.scoverlay.sprite2 = mobj.sprite2|FF_SPR2SUPER
	
	// Match sprite rotation
	mobj.scoverlay.rollangle = matchmobj.rollangle
	
	// REVERSE GRAVITY WOAAAAAH
	if(mobj.eflags & MFE_VERTICALFLIP)
		mobj.scoverlay.eflags = $1|MFE_VERTICALFLIP
	else
		mobj.scoverlay.eflags = $1 & !MFE_VERTICALFLIP
	end
	
	// MF2_DONTDRAW WOAAAAAH
	if not(addtotarget)
		if(mobj.flags2 & MF2_DONTDRAW)
			or not(overlaysprites[mobj.sprite])
			or(addtotarget and not mobj.sprite == SPR_PLAY)
			mobj.scoverlay.flags2 = $1|MF2_DONTDRAW
		else
			mobj.scoverlay.flags2 = $1 & !MF2_DONTDRAW
		end
	else
		if(mobj.flags2 & MF2_DONTDRAW)
			or(mobj.target.sprite == SPR_PINV)
			mobj.scoverlay.flags2 = $1|MF2_DONTDRAW
		else
			mobj.scoverlay.flags2 = $1 & !MF2_DONTDRAW
		end
	end
	
	// MF2_SHADOW WOAAAAAH
	if(mobj.flags2 & MF2_SHADOW)
		and(leveltime or mobj.type != MT_PLAYER)	// Weird bug?
		mobj.scoverlay.flags2 = $1|MF2_SHADOW
	else
		mobj.scoverlay.flags2 = $1 & !MF2_SHADOW
	end
	
	if not(slopestick)
		mobj.scoverlay.flags = $1|MF_NOCLIP|MF_NOCLIPHEIGHT
	end
	
	mobj.scoverlay.flags = ($1 & !FF_TRANSMASK)|(mobj.flags & FF_TRANSMASK)
	
	// Keep the overlay in the world!
	mobj.scoverlay.timer = 1
end

// -------------------------------------------
// Adding overlays to objects!
// -------------------------------------------
// Players
addHook("PreThinkFrame", function()
	for player in players.iterate
		if(player.mo and player.mo.valid and player.mo.prevspr2)
			player.mo.sprite2 = player.mo.prevspr2
			player.mo.prevspr2 = nil
		end
	end
end)
addHook("PostThinkFrame", function()
	for player in players.iterate
		if(player.mo and player.mo.valid and player.mo.skin == charskin)
			doOverlay(player.mo, true, false)
			player.mo.prevspr2 = player.mo.sprite2
			player.mo.sprite2 = $1 & !FF_SPR2SUPER	// Just in case
		end
	end
end)
addHook("PlayerSpawn", function(player)
	if(player.mo and player.mo.valid and player.mo.skin == charskin)
		doOverlay(player.mo, true, false)
		player.mo.prevspr2 = player.mo.sprite2
		player.mo.sprite2 = $1 & !FF_SPR2SUPER	// Just in case
	end
end)

// Ghosts
addHook("MobjThinker", function(ghost)
	if(ghost and ghost.valid and ghost.skin == charskin)
		doOverlay(ghost, false, false)
		ghost.sprite2 = $1 & !FF_SPR2SUPER	// Just in case
	end
end, MT_GHOST)
addHook("MobjFuse", function(ghost)
	if(ghost.skin == charskin)
		and(ghost.scoverlay and ghost.scoverlay.valid)
		P_RemoveMobj(ghost.scoverlay)	// Make sure to remove it properly so it doesn't linger 1 frame after
	end
end, MT_GHOST)

// Signposts (and 1-up monitors for normal SRB2)
local queuedforoverlay = {}
local numqueued = 0
addHook("MobjThinker", function(overlay)
	if(overlay.skin == charskin)
		and(overlay.target and overlay.target.valid)
		queuedforoverlay[numqueued] = overlay
		overlay.overlaydone = false
		numqueued = $1 + 1
	elseif(overlay.scoverlay)
		P_RemoveMobj(overlay.scoverlay)
		overlay.scoverlay = nil
	end
end, MT_OVERLAY)

addHook("PostThinkFrame", function()
	local onum = 0
	while(onum < numqueued)
		if(queuedforoverlay[onum] and queuedforoverlay[onum].valid)
			if not(queuedforoverlay[onum].overlaydone)
				doOverlay(queuedforoverlay[onum], false, true)
			end
			queuedforoverlay[onum].overlaydone = true
		end
		onum = $1 + 1
	end
	queuedforoverlay = nil
	queuedforoverlay = {}
	numqueued = 0
end)
