// --------------------------------------
// Lua_Ball
// Ball ability!
// --------------------------------------
local function buttonPressed(player, button)
	if(player.cmd.buttons & button)
		and not(player.kvars.prevcmd & button)
		return true
	end
	return false
end

local function RandomOff(num)
	return (P_RandomByte()%num)-(num/2)
end
local function SpawnSparkles(mobj, spriteheight)
	local stype = MT_BALLSPARKLE
	local zoff = 8*mobj.scale*P_MobjFlip(mobj)
	local sparkle = P_SpawnMobj(mobj.x+(RandomOff(30)*mobj.scale), mobj.y+(RandomOff(30)*mobj.scale), mobj.z+(mobj.height/2)+(RandomOff(spriteheight)*mobj.scale)+zoff, stype)
	sparkle.scale = mobj.scale
	if(mobj.eflags & MFE_VERTICALFLIP)
		sparkle.eflags = $1|MFE_VERTICALFLIP
	end
	sparkle.color = SKINCOLOR_AZURE
end

rawset(_G, "K_Ball", function(checkflags, destroy, late, player)
	if(checkflags)
		if(player.kvars.ablstate)
			return AF_NOFLOAT|AF_NODUCK|AF_NOJUMP|AF_NOSWIM|AF_NODROP
		end
		return 0
	end
	if(destroy)
		player.mo.flags = $1 & !MF_BOUNCE
		return
	end
	if(late)
		return
	end
	
	if(buttonPressed(player, BT_USE))
		and not(player.kvars.ducking)
		and not(player.kvars.floating)
		and not(player.pflags & PF_SLIDING)
		and not(player.powers[pw_carry] or player.kvars.prevcarry)
		and not(player.exiting)
		and not(player.pflags & PF_STASIS)
		and not(player.powers[pw_nocontrol])
		and not(player.kvars.industdevil)
		and not(player.kvars.inmud)
		if not(player.kvars.ablstate)
			player.kvars.ablstate = 1
			if(P_IsObjectOnGround(player.mo))
				player.mo.state = S_KIRBY_BALL_SD
				player.kvars.sucktime = -5*player.mo.scale*P_MobjFlip(player.mo)
				player.kvars.ablvar3 = -2
			else
				player.mo.state = S_KIRBY_BALL_TA
			end
		else
			if(P_IsObjectOnGround(player.mo))
				player.mo.momz = 5*player.mo.scale*P_MobjFlip(player.mo)
				player.kvars.ablvar3 = -1
				player.mo.state = S_KIRBY_BALL_SD
			else
				player.kvars.ablstate = 0
				player.mo.state = S_KIRBY_BALL_TB
				player.mo.flags = $1 & !MF_BOUNCE
				player.pflags = ($1 & !PF_JUMPED)|PF_NOJUMPDAMAGE
			end
		end
	end
	
	// Force exit
	if(player.pflags & PF_SLIDING)
		or(player.powers[pw_carry] or player.kvars.prevcarry)
		or(player.kvars.inmud)
		if(player.kvars.inmud)
			player.mo.state = S_PLAY_STND
		end
		player.kvars.ablstate = 0
		player.mo.flags = $1 & !MF_BOUNCE
	end
	
	if(player.kvars.ablstate)
		if(player.kvars.ablstate == 2)
			and(leveltime & 1)
			SpawnSparkles(player.mo, 30)
		end
		player.charflags = $1|SF_NOSKID
		player.mo.flags = $1|MF_BOUNCE
		if not(player.mo.state == S_KIRBY_BALL_SD)
			and not(player.mo.state == S_KIRBY_BALL_SU)
			and not(player.mo.state == S_KIRBY_BALL_TA)
			player.mo.state = S_KIRBY_BALL1+(player.kvars.ablvar3/10)
			player.mo.tics = 10-(player.kvars.ablvar3%10)
			
			local speed = R_PointToDist2(0, 0, R_PointToDist2(player.cmomx, player.cmomy, player.mo.momx, player.mo.momy), player.mo.momz)/player.mo.scale
			if(P_IsObjectOnGround(player.mo))
				and(speed)
				player.drawangle = R_PointToAngle2(player.cmomx, player.cmomy, player.mo.momx, player.mo.momy)
			end
			
			player.kvars.ablvar3 = ($1 + speed/2)%80
			if(abs(player.kvars.sucktime) > 5*player.mo.scale)
				if(player.mo.z <= player.mo.floorz)
					and(player.kvars.sucktime < 0)
					if(P_MobjFlip(player.mo) > 0)
						player.mo.state = S_KIRBY_BALL_SD
					else
						player.mo.state = S_KIRBY_BALL_SU
					end
				end
				if(player.mo.z+player.mo.height >= player.mo.ceilingz)
					and(player.kvars.sucktime > 0)
					if(P_MobjFlip(player.mo) < 0)
						player.mo.state = S_KIRBY_BALL_SD
					else
						player.mo.state = S_KIRBY_BALL_SU
					end
				end
			elseif(player.cmd.buttons & BT_JUMP)
				and(P_IsObjectOnGround(player.mo))
				and not(player.pflags & PF_SLIDING)
				and not(player.powers[pw_carry] or player.kvars.prevcarry)
				and not(player.exiting)
				and not(player.pflags & PF_STASIS)
				and not(player.powers[pw_nocontrol])
				and not(player.kvars.industdevil)
				player.kvars.sucktime = -6*player.mo.scale*P_MobjFlip(player.mo)
				player.mo.state = S_KIRBY_BALL_SD
			end
		end
		
		if not(P_IsObjectOnGround(player.mo))
			player.pflags = ($1|PF_JUMPED) & !PF_NOJUMPDAMAGE
			player.jumping = false
		end
	end
	
	if not(player.mo.state == S_KIRBY_BALL_SD or player.mo.state == S_KIRBY_BALL_SU)
		player.kvars.ablvar1 = player.mo.momx-player.cmomx
		player.kvars.ablvar2 = player.mo.momy-player.cmomy
		player.kvars.sucktime = player.mo.momz
	else
		player.mo.momx = player.cmomx
		player.mo.momy = player.cmomy
		player.mo.momz = 0
		if(player.mo.tics <= 1)
			player.mo.momx = player.kvars.ablvar1+player.cmomx
			player.mo.momy = player.kvars.ablvar2+player.cmomy
			if(player.kvars.ablvar3 == -1)
				player.kvars.ablstate = 0
				player.kvars.ablvar3 = 0
				player.mo.state = S_PLAY_FALL
				player.mo.flags = $1 & !MF_BOUNCE
				player.mo.momz = 5*player.mo.scale*P_MobjFlip(player.mo)
				player.pflags = ($1 & !PF_JUMPED)|PF_NOJUMPDAMAGE
			elseif(player.kvars.ablvar3 == -2)
				player.mo.momz = -player.kvars.sucktime
				player.kvars.ablvar3 = 0
			else
				if(player.cmd.buttons & BT_JUMP)
					player.kvars.ablstate = 2
					S_StartSound(player.mo, sfx_hijump)
					player.mo.momz = -player.kvars.sucktime*3/2
					if(player.mo.momz > 30*player.mo.scale)
						player.mo.momz = 30*player.mo.scale
					end
					if(player.mo.momz < -30*player.mo.scale)
						player.mo.momz = -30*player.mo.scale
					end
				else
					player.kvars.ablstate = 1
					S_StartSound(player.mo, sfx_kflat)
					player.mo.momz = -player.kvars.sucktime*2/3
				end
			end
		//	P_TeleportMove(player.mo, player.mo.x+player.mo.momx, player.mo.y+player.mo.momy, player.mo.z+player.mo.momz)
		end
	end
end)

addHook("MobjThinker", function(sparkle)
	if(sparkle.target and sparkle.target.valid)
		P_TeleportMove(sparkle, sparkle.target.x+sparkle.offx, sparkle.target.y+sparkle.offy, sparkle.target.z+sparkle.offz)
	end
end, MT_BALLSPARKLE)
