-- Motobug's Stuff --

-- DROP DASH
local dropdashchar = function(player)
	return (player.mo.skin == "motobug")
end

addHook("PreThinkFrame", function()
	for player in players.iterate()
		local mo = player.mo
		if not (mo and dropdashchar(player)) then 
			player.dropswap = 0
		continue end
		if player.dropswap == nil then
			player.dropswap = 0
		end
		if P_IsObjectOnGround(mo) then
			player.dropswap = 0
		end
	end
end)

addHook("JumpSpecial", function(player)
	local mo = player.mo
	if dropdashchar(player) and player.pflags&PF_JUMPED and not(player.pflags&PF_JUMPDOWN) and not (player.powers[pw_carry] == CR_MACESPIN)
	and not(player.dropswap)
		mo.dropprep = 1
		mo.dropmomz = 0
	return true end
	
end)

local StopDropDash = function(player)
	local mo = player.mo
	if not(mo.dropprep) then return end
	mo.dropprep = 0
	if player.pflags&(PF_SPINNING) or (player.pflags&PF_JUMPED and not(player.pflags&PF_NOJUMPDAMAGE))
		mo.state = S_PLAY_ROLL
	end
end


addHook("AbilitySpecial", function(player)
	if player.mo.skin == "motobug"
		player.mo.dropprep = min(1, $)
	end
end)

addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "motobug"
		if player.mo.dropprep == nil then
			player.mo.dropprep = 0
			player.mo.dropmomz = 0
		end
		if P_PlayerInPain(player) or not(player.playerstate == PST_LIVE) or player.exiting or player.powers[pw_nocontrol] or (player.powers[pw_carry] == CR_MACESPIN)
			StopDropDash(player)
		end
		local mo = player.mo
		if (not(player.cmd.buttons & BT_JUMP) and mo.dropprep)
		or mo.eflags & MFE_SPRUNG
		or P_PlayerInPain(player)
		or (not (mo.eflags & MFE_JUSTHITFLOOR) and not((player.pflags & PF_JUMPED) & ~PF_NOJUMPDAMAGE))
			StopDropDash(player)
		return end
		if player.charability == CA_NONE and player.charability2 == CA2_SPINDASH 
			if mo.dropprep
				and not(mo.state >= S_PLAY_SUPER_TRANS1 and mo.state <= S_PLAY_SUPER_TRANS1+5)
				if not (mo.eflags & MFE_JUSTHITFLOOR)
					if player.cmd.buttons & BT_JUMP
						if mo.dropprep < 100
							mo.dropprep = $+100/10
							if mo.dropprep >= 100
								S_StartSound(mo, sfx_moddsh, player)
								mo.dropprep = 100
							end
						end
						if mo.dropprep == 100
							mo.dropmomz = mo.momz
							mo.thoklayer = P_SpawnGhostMobj(mo)
							mo.thoklayer.fuse = 5
							mo.thoklayer.state = S_THOK
						end
					end
				else
					if player.cmd.buttons & BT_JUMP and mo.dropprep == 100
						mo.state = S_PLAY_ROLL
						player.pflags = $1|PF_SPINNING
						S_StartSound(mo, sfx_zoom, player)
						local speed = abs(mo.dropmomz/2) + FixedHypot(player.rmomx, player.rmomy)
						local actionspd = player.actionspd
						if player.powers[pw_super] then
							actionspd = $*3/2
							P_Earthquake(player.mo, player.mo, 1000*FRACUNIT)
							S_StartSound(mo, sfx_s3k5d, player)
						end
						if mo.eflags & MFE_UNDERWATER then actionspd = $*2/3 end
						P_InstaThrust(mo, mo.angle, max(actionspd,speed))
						local function r(mo, value)
							local w = mo.radius/FRACUNIT/2
							return value + P_RandomRange(-w, w)*FRACUNIT
						end
						for n = 1,4
							local d = P_SpawnMobj(r(mo, mo.x),r(mo, mo.y), mo.z, MT_SPINDUST)
							d.extravalue1 = FRACUNIT
							d.extravalue2 = FRACUNIT
							if P_MobjFlip(mo) == -1 then
								d.eflags = $|MFE_VERTICALFLIP
							end
							P_SetObjectMomZ(d, FRACUNIT*2)
							local l = 90*n/4
							P_InstaThrust(d, mo.angle + ANGLE_135 + l*ANG1, actionspd/2)
						end
					end
					StopDropDash(player)
				end
			end
		end
	end
end)

-- MISC. FUNCTIONS
addHook("PlayerThink", function(player)
	if player.mo and player.mo.skin == "motobug"
		if player.powers[pw_sneakers] or player.powers[pw_super]
			player.normalspeed = 36*FRACUNIT
		else
			player.normalspeed = 26*FRACUNIT
		end
		if player.mo.spindashtimer == nil
			player.mo.spindashtimer = 0
		end
		if player.pflags & PF_STARTDASH
			if player.mo.spindashtimer < 60
				player.mo.spindashtimer = $1 + 1
			end
		end
		if player.mo.spindashtimer >= 1
			if not ((player.mo.state >= S_MBSPINDASH1) and (player.mo.state <= S_MBSPINDASH4))
				player.mo.state = S_MBSPINDASH1
			end
		end
		if (P_PlayerInPain(player))
		or (player.playerstate == PST_DEAD)
			player.mo.spindashtimer = 0
		end
		if player.pflags & ~PF_STARTDASH
			player.mo.spindashtimer = 0
		end
		if player.pflags & PF_SPINNING
		and not (player.powers[pw_carry] == CR_ZOOMTUBE)
		and not (player.pflags & PF_STARTDASH)
		and P_IsObjectOnGround(player.mo) then
			if player.cmd.forwardmove ~= 0
			or player.cmd.sidemove ~= 0
			or player.camangle == nil
			or player.mo.eflags & MFE_SPRUNG then
				player.camangle = player.cmd.angleturn<<16 + R_PointToAngle2(0, 0, player.cmd.forwardmove*FRACUNIT, -player.cmd.sidemove<<16)
			end
			player.movespd = R_PointToDist2(player.mo.x, player.mo.y, player.mo.x + player.mo.momx, player.mo.y + player.mo.momy)
			P_InstaThrust(player.mo,R_PointToAngle2(player.mo.x - player.mo.momx,player.mo.y - player.mo.momy,player.mo.x + P_ReturnThrustX(player.mo,player.camangle,player.movespd),player.mo.y + P_ReturnThrustY(player.mo,player.camangle,player.movespd)),player.movespd)
		else
			player.camangle = nil
		end
		player.powers[pw_spacetime] = 0
		if player.mo.state == S_PLAY_SUPER_TRANS1
			S_StartSound(player.mo, sfx_mosoup)
		end
	end
end)

-- SPINDASH VULNERABILITY
addHook("PlayerCanDamage", function(player, mohit)
	if player.mo.skin == "motobug"
		if (player.pflags & PF_STARTDASH)
		and not (player.powers[pw_super])
			if mohit.flags & MF_ENEMY
			or mohit.flags & MF_MONITOR
			or mohit.flags & MF_SHOOTABLE
			or mohit.flags & MF_BOSS
				return false
			end
		end
	end
end)

-- SPIKE DESTROYING
local killspikes2 = function(thing, tmthing)
	if thing and thing.valid and tmthing and tmthing.valid
	and tmthing.player and tmthing.skin == "motobug"
	and ((tmthing.player.pflags & PF_SPINNING)
	or (tmthing.player.powers[pw_super]))
	and thing.z - thing.scale <= tmthing.z + tmthing.height + (tmthing.player and P_MobjFlip(tmthing) or tmthing.momz)
	and thing.z + thing.height + thing.scale >= tmthing.z + (tmthing.player and P_MobjFlip(tmthing) or tmthing.momz)
		P_KillMobj(thing, tmthing)
		return true
	end
end

addHook("MobjCollide", function(thing, tmthing) killspikes2(thing, tmthing) end, MT_SPIKE)

-- DEATH SEQUENCE
addHook("MobjDeath", function(dead)
	if dead.skin == "motobug" then
		local player = dead.player
		if gametype == 0 then
			player.lives = $1 - 1
			if player.lives < 1 then
				S_ChangeMusic("_GOVER", false, player)
			end
		end
		dead.momx, dead.momy, dead.momz = 0, 0, 0
		dead.state = S_INVISIBLE
		S_StartSound(dead, sfx_pop)
		local cexplode = P_SpawnMobj(dead.x, dead.y, dead.z, MT_EXPLODE)
		cexplode.state = S_XPLD_FLICKY
		return true
	end
end, MT_PLAYER)