-- Motobug's Stuff --
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

local function MotobugKillSpikes(thing, tmthing)
	if thing and thing.valid and tmthing and tmthing.valid
	and (srb2p and tmthing.player and tmthing.skin == "motobug" and (tmthing.player.pflags & PF_SPINNING)) 
	and thing.z - thing.scale <= tmthing.z + tmthing.height + (tmthing and P_MobjFlip(tmthing) or tmthing.momz)
	and thing.z + thing.height + thing.scale >= tmthing.z + (tmthing and P_MobjFlip(tmthing) or tmthing.momz)
		P_KillMobj(thing, tmthing)
		return true
	end
end

local function MotobugVariableReset(player, health)
	if (player.motobugvars == nil)
		player.motobugvars = {}
	end
	player.thrustjumped = 0
	player.thrusttimer = 0
end

addHook("MapLoad", function()
	for player in players.iterate
		MotobugVariableReset(player, false)
	end
end)

addHook("PreThinkFrame", function()
	for player in players.iterate()
		local mo = player.mo
		if not (mo and mo.skin == "motobug") 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 mo.skin == "motobug" and player.pflags&PF_JUMPED and not(player.pflags&PF_JUMPDOWN) and not (player.powers[pw_carry] == CR_MACESPIN) and not P_PlayerInPain(player) and not player.gotflag
	and not(player.dropswap)
		mo.dropprep = 1
		mo.dropmomz = 0
	return true end
end)

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

addHook("JumpSpinSpecial", function(player)
	if player.mo and player.mo.skin == "motobug" 
		if (player.powers[pw_shield] == SH_NONE 
		or player.powers[pw_shield] == SH_PITY 
		or player.powers[pw_super]) 
		and (player.thrustjumped == 0) 
		and (player.thrusttimer <= 15) 
		and not (player.pflags & PF_JUMPDOWN)
			player.mo.state = S_THRUSTJUMP_PREP
			return true
		end
	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 (player.motobugvars == nil)
			MotobugVariableReset(player, true)
		end
		player.powers[pw_spacetime] = 0
		if (player.pflags & PF_SPINNING) and not srb2p
			player.powers[pw_strong] = STR_ANIM|STR_SPIKE
		elseif player.powers[pw_super] and not srb2p
			player.powers[pw_strong] = STR_SPIKE
		end
		if (player.pflags & PF_SPINNING) and not P_IsObjectOnGround(player.mo)
			player.pflags = $ & ~PF_SPINNING
			player.mo.state = S_PLAY_JUMP
		end
		if player.mo.spindashtimer == nil 
		or P_PlayerInPain(player) 
		or player.playerstate == PST_DEAD 
		or player.pflags & ~PF_STARTDASH
			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 player.pflags & PF_SPINNING
		and not (player.powers[pw_carry] == CR_ZOOMTUBE)
		and not (player.pflags & PF_STARTDASH) 
		and not (player.mo.flags2 & MF2_TWOD) 
		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
		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
		if P_IsObjectOnGround(player.mo)
			player.thrustjumped = 0
			player.thrusttimer = 0
		end
		if player.mo.state == S_THRUSTJUMP_PREP
			player.thrusttimer = $ + 1
			player.mo.momx = 0*FRACUNIT
			player.mo.momy = 0*FRACUNIT
			P_SetObjectMomZ(player.mo, 0*FRACUNIT)
			if player.thrusttimer >= 20 or not (player.cmd.buttons & BT_USE)
				player.mo.state = S_THRUSTJUMP_GO
			end
		end
		if player.thrusttimer == 1
			S_StartSound(player.mo, sfx_cdfm11)
		end
		if player.mo.state == S_THRUSTJUMP_GO
			P_SetObjectMomZ(player.mo, 5*FRACUNIT)
			if player.thrusttimer >= 15	
				if player.powers[pw_super]
					P_InstaThrust(player.mo, player.drawangle, 60*FRACUNIT)
				else
					P_InstaThrust(player.mo, player.drawangle, 45*FRACUNIT)
				end
				S_StartSound(player.mo, sfx_cdfm01)
			else
				if player.powers[pw_super]
					P_InstaThrust(player.mo, player.drawangle, 45*FRACUNIT)
				else
					P_InstaThrust(player.mo, player.drawangle, 30*FRACUNIT)
				end
				S_StartSound(player.mo, sfx_cdfm62)
			end
			player.thrustjumped = 1
		end
		if player.mo.state == S_PLAY_SUPER_TRANS1
			S_StartSound(player.mo, sfx_mosoup)
		end
	end
end)

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)

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)

addHook("MobjCollide", MotobugKillSpikes, MT_SPIKE)
addHook("MobjCollide", MotobugKillSpikes, MT_WALLSPIKE)

addHook("MusicChange", function(oldname, newname)
	if consoleplayer
		local character = skins[consoleplayer.skin].name
		if character == "motobug"
			if newname == "_super"
				return "MANSUP"
			end
		end
	end
end)