// --------------------------------------
// Lua_Hammer
// Hammer ability!
// --------------------------------------
local function lockControl(player)
	if(player.powers[pw_nocontrol] <= 2)
		player.powers[pw_nocontrol] = 2
	end
	player.pflags = $1|PF_STASIS
end

local dustangle = {}
dustangle[0] = 0
dustangle[1] = ANGLE_22h
dustangle[2] = -ANGLE_22h

rawset(_G, "K_Hammer", 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)
		return
	end
	if(late)
		return
	end
	
	// Mud
	if(player.kvars.inmud)
		and(player.kvars.ablstate)
		player.kvars.ablstate = 0
		player.mo.state = S_PLAY_STND
	end
	
	if(player.kvars.ablstate)
		and(P_IsObjectOnGround(player.mo))
		S_StartSound(player.mo, sfx_stone)
		player.mo.state = S_KIRBY_HAMMERLAND1
		if(player.kvars.ablstate == 2)
			if(player.mo.momx-player.cmomx or player.mo.momy-player.cmomy)
				player.drawangle = R_PointToAngle2(player.cmomx, player.cmomy, player.mo.momx, player.mo.momy)
			else
				player.drawangle = player.mo.angle
			end
		end
		player.kvars.ablstate = 0
		
		// Hammer dust
		local dnum = 0
		while(dnum < 3)
			local dust = P_SPMAngle(player.mo, MT_KIRBYHAMMERDUST, player.drawangle+dustangle[dnum], 0)
			if(dust and dust.valid)
				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
				if(player.mo.eflags & MFE_VERTICALFLIP)
					dust.eflags = $1|MFE_VERTICALFLIP
					dust.flags2 = $1|MF2_OBJECTFLIP
				end
			end
			dnum = $1 + 1
		end
		// Destroy bustable floors
		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
					else
						rover.flags = oldflags									// Restore its solidity!
					end
				end
			end
		end
	end
	
	// Temp twirl
	if(player.mo.state == S_KIRBY_HAMMERS)
		if not(player.powers[pw_justsprung])
			player.powers[pw_justsprung] = 1
		end
		player.drawangle = $1 + ANGLE_45
	end
	
	if(player.kvars.ablstate)
		and not(player.mo.state >= S_KIRBY_HAMMER1 and player.mo.state <= S_KIRBY_HAMMERS)
		player.kvars.ablstate = 0
	end
	
	if(player.mo.state >= S_KIRBY_HAMMERLAND1 and player.mo.state <= S_KIRBY_HAMMERLAND2)
		lockControl(player)
	end
	
	if(player.cmd.buttons & BT_USE)
		and not(player.kvars.prevcmd & 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.ablstate)
		and not(player.kvars.inmud)
		if(P_IsObjectOnGround(player.mo))
			player.mo.momz = 2*player.mo.scale*P_MobjFlip(player.mo)
			player.mo.state = S_KIRBY_HAMMER1
			player.kvars.ablstate = 1
		else
			S_StartSound(player.mo, sfx_hamers)
			player.mo.state = S_KIRBY_HAMMERS
			player.kvars.ablstate = 2
		end
	end
	
	if(player.mo.state >= S_KIRBY_HAMMER1 and player.mo.state <= S_KIRBY_HAMMERS)
		player.charability = CA_GLIDEANDCLIMB
		player.pflags = ($1|PF_JUMPED) & !PF_NOJUMPDAMAGE
		player.kvars.ablvar1 = 1
	elseif(player.kvars.ablvar1)
		player.pflags = ($1|PF_NOJUMPDAMAGE) & !PF_JUMPED
		player.kvars.ablvar1 = 0
	end
end)

local function KirbySpikeCollide(mobj, spike)
	if not(mobj.player and mobj.player.valid)
		or not(mobj.skin == "kirby")
		or not(mobj.player.kvars)
		or not(mobj.player.kvars.ability == 11 or mobj.player.kvars.ability == 3)	// Makes it work for stone too, because why not
		or(mobj.player.kvars.secretability)
		or not(mobj.player.kvars.ablstate or (mobj.state >= S_KIRBY_HAMMER1 and mobj.state <= S_KIRBY_HAMMERS))
		return
	end
	
	if(spike and spike.valid)
		and(spike.type == MT_SPIKE or spike.type == MT_WALLSPIKE)
		and(mobj.z+mobj.height+mobj.momz >= spike.z)
		and(mobj.z+mobj.momz <= spike.z+spike.height)
		P_KillMobj(spike)
	end
end
local function KirbySpikeCollideDust(mobj, spike)
	if(spike and spike.valid)
		and(spike.type == MT_SPIKE or spike.type == MT_WALLSPIKE)
		and(mobj.z+mobj.height+mobj.momz >= spike.z)
		and(mobj.z+mobj.momz <= spike.z+spike.height)
		P_KillMobj(spike)
	end
end
addHook("MobjCollide", KirbySpikeCollide, MT_PLAYER)
addHook("MobjMoveCollide", KirbySpikeCollide, MT_PLAYER)
/*addHook("MobjCollide", KirbySpikeCollideDust, MT_KIRBYHAMMERDUST)
addHook("MobjMoveCollide", KirbySpikeCollideDust, MT_KIRBYHAMMERDUST)*/
