/*
Skateboard Lua
	by Lach

Intended for use in STHE123O's Sonic 06 mod.

Feel free to utilize in your own mods, but please give credit!
*/

local skatenum = 524

//Freeslots and SOC

freeslot("SPR_SKTB", "MT_SKATEBOARD", "S_SKATEBOARD", "S_BOARDOVERLAY")

states[S_SKATEBOARD] = {
	sprite = SPR_SKTB,
	frame = A,
	tics = -1
}

states[S_BOARDOVERLAY] = {
	sprite = SPR_SKTB,
	frame = B,
	tics = -1
}

mobjinfo[MT_SKATEBOARD] = {
	doomednum = skatenum,
	spawnstate = S_SKATEBOARD,
	reactiontime = 0,
	height = 5*FRACUNIT,
	radius = 8*FRACUNIT,
	flags = MF_SPECIAL
}

//Thinker for unobtained skateboards

addHook("MobjThinker", function(mo)
	if mo
		if not (mo.tracer)
			mo.color = 1 + (leveltime % 24)/8
			mo.angle = $1 + 2*ANG2
			if mo.eflags & MFE_VERTICALFLIP
				mo.z = mo.ceilingz - 12*FRACUNIT - 5*sin(mo.angle)
			else
				mo.z = mo.floorz + 12*FRACUNIT + 5*sin(mo.angle)
			end
			mo.flags = $1 | MF_NOGRAVITY
		elseif mo.reactiontime > 0
			mo.reactiontime = $1 - 1
		end
	end
end, MT_SKATEBOARD)

//Puts players in skatebord mode when they touch a skateboard

addHook("TouchSpecial", function(skate, mo)
	if mo and mo.player and not mo.skate and mo.type == MT_PLAYER and skate.reactiontime <= 0
		mo.player.pflags = $1 & ~PF_SPINNING
		mo.player.pflags = $1 & ~PF_JUMPED
		mo.skate = P_SpawnMobj(mo.x, mo.y, mo.z, MT_OVERLAY)
		mo.skate.target = mo
		mo.skate.state = S_BOARDOVERLAY
		if skate.tracer
			P_RemoveMobj(skate)
		end
	end
	return true
end, MT_SKATEBOARD)

//Resets the player when they get off the skateboard, and respawns a mountable skateboard.

local function stopSkate(player, mo, var)
	if var
		local skate
		if mo.eflags & MFE_VERTICALFLIP
			skate = P_SpawnMobj(mo.x, mo.y, mo.z + 36*FRACUNIT, MT_SKATEBOARD)
			skate.eflags = $1 | MFE_VERTICALFLIP
			skate.flags2 = $1 | MF2_OBJECTFLIP
		else
			skate = P_SpawnMobj(mo.x, mo.y, mo.z, MT_SKATEBOARD)
		end
		skate.reactiontime = TICRATE
		skate.tracer = mo
		skate.color = mo.color
		skate.angle = mo.angle
	end
	if mo.skate
		P_RemoveMobj(mo.skate)
		mo.skate = nil
	end
	//mo.skatespeed = nil
	mo.skatejump = nil
	player.jumpfactor = skins[mo.skin].jumpfactor
	player.charability = skins[mo.skin].ability
	player.charability2 = skins[mo.skin].ability2
end

//Resets players upon spawn

addHook("PlayerSpawn", function(player)
	if player.mo
		stopSkate(player, player.mo, false)
		//P_SpawnMobj(player.mo.x + 30*FRACUNIT, player.mo.y + 30*FRACUNIT, player.mo.z, MT_SKATEBOARD)
	end
end)

//Makes the player step off the skateboard when they press spin, as well as preventing spindash from occuring.

addHook("SpinSpecial", function(player)
	if player.mo and player.mo.skate
		if not (player.pflags & PF_USEDOWN)
			stopSkate(player, player.mo, true)
		end
		return true
	end
end)

//Makes the player jump!

addHook("JumpSpecial", function(player)
	if player.mo and player.mo.skate
		if not (player.pflags & PF_JUMPDOWN)
			local mo = player.mo
			if (mo.eflags & MFE_VERTICALFLIP) and mo.z >= mo.ceilingz - 10*FRACUNIT
				P_DoJump(player)
				mo.skatejump = true
			elseif not (mo.eflags & MFE_VERTICALFLIP) and mo.z <= mo.floorz + 10*FRACUNIT
				P_DoJump(player)
				mo.skatejump = true
			end
		end
		return true
	end
end)

//Deletes the skateboard when the player dies

addHook("MobjDeath", function(mo)
	if mo and mo.skate
		stopSkate(mo.player, mo, false)
	end
end, MT_PLAYER)

//Main thinker - I chose to have it modify the player since having it modify the skateboard instead would require modifications to the player anyway.

addHook("MobjThinker", function(mo)
	if mo and mo.player
		if not mo.skate then return end
		local player = mo.player
		
		mo.height = FixedMul(mobjinfo[MT_PLAYER].height, mo.scale)
		
		mo.skate.color = mo.color
		if mo.state == S_SKATEBOARD
			mo.skate.flags2 = $1 | MF2_DONTDRAW
		else mo.skate.flags2 = $1 & ~MF2_DONTDRAW
		end
		
		player.jumpfactor = 2*skins[mo.skin].jumpfactor/3
		player.charability = CA_NONE
		player.charability2 = CA2_NONE
		player.drawangle = mo.angle
		
		if not mo.skatejump
			if (mo.eflags & MFE_VERTICALFLIP) and mo.z >= mo.ceilingz - 10*FRACUNIT
				mo.z = mo.ceilingz - 10*FRACUNIT
				mo.momz = 0
				player.pflags = $1 & ~PF_JUMPED
			elseif not (mo.eflags & MFE_VERTICALFLIP) and mo.z <= mo.floorz + 10*FRACUNIT
				mo.z = mo.floorz + 10*FRACUNIT
				mo.momz = 0
				player.pflags = $1 & ~PF_JUMPED
			end
		end
		
		mo.skatejump = false
		
		//Skateboard physics!
			//I'm keeping this here because this code makes it play like SRB2CB's skateboard.
			//If you want to reuse this mod and have the skateboard be able to accelerate or decelerate:
				//1. uncomment the block below and the mo.skatespeed line in the stopSkate function
				//2. Delete that second P_InstaThrust
				//3. Include RedEchilada's LUA_CHKW as a lump before LUA_SKTB, which can be found in STHE123O's Heroes mod.
		
		/*if mo.skatespeed == nil
		or player.speed > 20*FRACUNIT
		and P_BlockingWall(mo, R_PointToAngle2(0,0, mo.momx, mo.momy), player.speed)
			mo.skatespeed = 700
		end	
		if mo.player.cmd.forwardmove > 0 and mo.skatespeed < 1750
			mo.skatespeed = $1 + 10
		elseif mo.player.cmd.forwardmove < 0 and mo.skatespeed > -350
			mo.skatespeed = $1 - 10
		end
		P_InstaThrust(mo, mo.angle, (mo.skatespeed*FRACUNIT)/36)*/
		P_InstaThrust(mo, mo.angle, 36*FRACUNIT)
		
	end
end, MT_PLAYER)
