// --------------------------------------
// Lua_Stone
// Stone ability!
// --------------------------------------
local stonetable = {}
stonetable[0] = 40	// Stone						Kibito
stonetable[1] = 10	// 8-bit Kirby					Maximus
stonetable[2] = 4	// T-Pose						Maxiums
stonetable[3] = 1	// Kirby is inevitable			Maximus
stonetable[4] = 20	// Panel de pon garbage block	Maximus
stonetable[5] = 20	// Spike ball					Maximus
stonetable[6] = 20	// Kirby						Kibito	
stonetable[7] = 15	// Sonic						Kibito
stonetable[8] = 10	// Ristar						HattyBoyo
stonetable[9] = 4	// Saturn on 8-ton weight		Tripel
stonetable[10] = 5	// Robobot armor				Kibito
stonetable[11] = 10	// Muscle man					Kibito
local numstone = 12
// Set up drop table
local totalstoneslots = 0
local stoneraritytable = {}
local snum = 0
local srindex = 0
while(snum < numstone)
	totalstoneslots = $1 + stonetable[snum]
	local sdnum = 0
	while(sdnum < stonetable[snum])
		stoneraritytable[srindex] = snum
		sdnum = $1 + 1
		srindex = $1 + 1
	end
	snum = $1 + 1
end

// Debug
if(totalstoneslots > 255)
	print("TOO MANY STONE SLOTS!\nToo large by: "+(numstone-255))
end

// Stone should no longer do this???
/*
<Hydro> i cant jump
<Hydro> help
*/

local function buttonPressed(player, button)
	if(player.cmd.buttons & button)
		and not(player.kvars.prevcmd & button)
		return true
	end
	return false
end

local function lockControl(player)
	if(player.powers[pw_nocontrol] <= 2)
		player.powers[pw_nocontrol] = 2
	end
	player.pflags = $1|PF_STASIS
end

local sparklecolors = {}
sparklecolors[0] = SKINCOLOR_BROWN
sparklecolors[1] = SKINCOLOR_BEIGE
sparklecolors[2] = SKINCOLOR_PINK
local nspc = 3
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 = sparklecolors[P_RandomByte()%nspc]
end

rawset(_G, "K_Stone", function(checkflags, destroy, late, player)
	if(checkflags)
		if(player.kvars.ablstate)
			return AF_NOFLOAT|AF_NODUCK|AF_NOSWIM|AF_NODROP
		end
		return 0
	end
	if(destroy)
		if(player.mo.state == S_KIRBY_STONE)
			player.mo.state = S_PLAY_FALL
		end
		if(player.kvars.ablstate)
			player.mo.flags = $1 & !MF_PUSHABLE
			player.mo.flags = $1|MF_SHOOTABLE
			player.pflags = ($1 & !PF_JUMPED)|PF_NOJUMPDAMAGE
		end
		return
	end
	if(late)
		return
	end
	
	if(player.powers[pw_carry] or (player.mo.eflags & MFE_SPRUNG))
		and(player.kvars.ablstate)
		player.kvars.ablstate = 0
		player.kvars.ablvar2 = 0
		player.mo.flags = $1 & !MF_PUSHABLE
		player.mo.flags = $1|MF_SHOOTABLE
		player.pflags = ($1 & !PF_JUMPED)|PF_NOJUMPDAMAGE
	end
	
	if(player.kvars.industdevil)
		and(player.mo.flags & MF_PUSHABLE)
		player.mo.flags = $1 & !MF_PUSHABLE
	end
	
	if(P_IsObjectOnGround(player.mo))
		and not(player.kvars.prevground)
		and(player.kvars.ablstate)
		and not(P_CheckDeathPitCollide(player.mo))
		S_StartSound(player.mo, sfx_stone)
		local dnum = 0
		local rotnum = 16
		local rotadd = FixedAngle((360*FRACUNIT)/rotnum)
		while(dnum < rotnum)
			local dust = P_SPMAngle(player.mo, MT_KIRBYHAMMERDUST, rotadd*dnum, 0)
			if(dust and dust.valid)
				local mul = ((P_RandomByte()*FRACUNIT/512)+(FRACUNIT))*2
				dust.momx = FixedMul(mul, $1)
				dust.momy = FixedMul(mul, $1)
				dust.momx = $1 + player.mo.momx
				dust.momy = $1 + player.mo.momy
				if(player.mo.eflags & MFE_UNDERWATER)
			//		or(player.mo.eflags & MFE_TOUCHWATER)
					dust.state = S_SPINDUST_BUBBLE1
				end
			end
			dnum = $1 + 1
		end
	end
	
	if(player.kvars.ablvar2)
		SpawnSparkles(player.mo, 30)
		player.kvars.ablvar2 = $1 - 1
		if not(player.kvars.ablstate)
			if(player.kvars.ablvar2)
				if not(player.kvars.ablvar2%3 == 2)
					player.mo.state = S_PLAY_FALL
				else
					player.mo.state = S_KIRBY_STONE
					player.mo.frame = player.kvars.ablvar1
				end
			else
				player.mo.state = S_PLAY_FALL
			end
		end
	end
	
	if(buttonPressed(player, BT_USE))
		and not(player.kvars.ducking)
		and not(player.kvars.floating)
		and not(player.exiting)
		and not(player.pflags & PF_STASIS)
		and not(player.kvars.industdevil)
		and not(player.powers[pw_carry])	// How did I miss that?!
		if not(player.kvars.ablstate)
			player.kvars.ablvar2 = TICRATE/3
			player.kvars.ablstate = 1
			player.mo.momz = 0
			S_StartSound(player.mo, sfx_rock)
			player.kvars.ablvar1 = stoneraritytable[P_RandomByte()%totalstoneslots]
		else
			player.kvars.ablvar2 = TICRATE/6
			player.kvars.ablstate = 0
			player.mo.flags = $1 & !MF_PUSHABLE
			player.mo.flags = $1|MF_SHOOTABLE
			player.pflags = ($1 & !PF_JUMPED)|PF_NOJUMPDAMAGE
			if(P_IsObjectOnGround(player.mo))
				player.mo.momz = 5*player.mo.scale*P_MobjFlip(player.mo)
			end
			S_StartSound(player.mo, sfx_unrock)
			P_TeleportMove(player.mo, player.mo.x, player.mo.y, player.mo.z+P_MobjFlip(player.mo))
	//		player.mo.state = S_PLAY_FALL
		end
	end
	
	if(player.kvars.ablstate)
		player.mo.friction = FRACUNIT*59/60	// Slide down slopes
		
		if(player.kvars.ablvar2%3 == 2)
			player.mo.state = S_KIRBY_STONETRANS
		else
			player.mo.state = S_KIRBY_STONE
			player.mo.frame = player.kvars.ablvar1
		end
		
		player.mo.flags = $1|MF_PUSHABLE
		player.mo.flags = $1 & !MF_SHOOTABLE
		if(P_CheckDeathPitCollide(player.mo))
			player.mo.flags = $1 & !MF_PUSHABLE
			player.mo.flags = $1|MF_SHOOTABLE
		end
		player.pflags = ($1|PF_JUMPED) & !PF_NOJUMPDAMAGE
		
		lockControl(player)
		if(player.kvars.ablstate < TICRATE/3)
			if not(P_IsObjectOnGround(player.mo))
				player.mo.momx = $1 - player.cmomx
				player.mo.momy = $1 - player.cmomy
				player.mo.momx = $1 * 4/5
				player.mo.momy = $1 * 4/5
				player.mo.momx = $1 + player.cmomx
				player.mo.momy = $1 + player.cmomy
				player.mo.momz = 0
			end
			player.kvars.ablstate = $1 + 1
		else
			if not(P_IsObjectOnGround(player.mo))
				and(player.mo.momz*P_MobjFlip(player.mo) <= 0)
				player.mo.momx = player.cmomx
				player.mo.momy = player.cmomy
				player.mo.momz = -40*player.mo.scale*P_MobjFlip(player.mo)
			end
		end
		
		// Destroy bustable floors (or ceilings I guess)
		if not(P_IsObjectOnGround(player.mo))
			or not(player.kvars.prevground)
			for rover in player.mo.subsector.sector.ffloors()
				if(rover.flags & FF_EXISTS)			// Needs to exist!
					and(rover.flags & FF_BUSTUP)	// And breakable!
					local oldflags = rover.flags
					rover.flags = $1 & !(FF_BLOCKPLAYER|FF_BLOCKOTHERS)		// Make it non solid so we can check if we're inside it!
					if(P_InsideANonSolidFFloor(player.mo, rover))				// Inside it?
						rover.flags = oldflags								// Restore its solidity!
						EV_CrumbleChain(nil, rover)		// Bust it!
						// Run a linedef executor??
						if(rover.master.flags & ML_EFFECT5)
							P_LinedefExecute(P_AproxDistance(rover.master.dx, rover.master.dy)>>FRACBITS, player.mo, player.mo.subsector.sector)
						end
						S_StartSound(player.mo, sfx_stoneb)
					else
						rover.flags = oldflags									// Restore its solidity!
					end
				end
			end
		end
	end
	
end)
