// Hello! I see you looking through here. 
// This was originally intended for a physics mod, PiSRB2. Might return to it someday.
// This is the shared imigination of myself and PencilVoid. Enjoy!
// I originally ported the Air Drill from C to Lua due to the request of a now banned community member.
// The Drop Dash code here later became the basis of MCSonic's Drop Dash code.

freeslot(
"S_DROPDASH",
"SPR_DRPD",
"sfx_drpdsh"
)

states[S_DROPDASH] = {
	sprite = SPR_DRPD,
	frame = FF_ANIMATE,
	tics = -1,
	var1 = 5,
	var2 = 1,
	nextstate = S_PLAY_ROLL
}

sfxinfo[sfx_drpdsh] = {
	singular = false,
	caption = "Dropdash"
}

// Air Drill! Sonic's main ability got swapped out with this.

local function AirDrillMain(p)
	if not p.mo and p.mo.valid return end
	
	if p.mo.skin != "sonic" return end
	
	if not (p.pflags & PF_THOKKED)
	or p.charflags & SF_MULTIABILITY
		if p.powers[pw_super]
			p.airflyangle = 56 + (60-(p.actionspd>>FRACBITS))/3
		else
			p.airflyangle = 42 + (60-(p.actionspd>>FRACBITS))/3
		end
		p.pflags = $1|PF_THOKKED
		S_StartSound(p.mo, sfx_thok, p)
	end
	return true
end 

addHook("AbilitySpecial", AirDrillMain)

local function AirDrillThink(p)
	if not p.mo and p.mo.valid return end

	if p.mo.skin != "sonic" return end

	if p.airdrilltimer == nil
		p.airdrilltimer = 0
	end
	
	if p.dropstart == nil
		p.dropstart = false
	end
	
	if p.droptimer == nil
		p.droptimer = 0
	end
	
	if p.triedtodash == nil
		p.triedtodash = false
	end
	
	if P_IsObjectOnGround(p.mo)
	or P_PlayerInPain(p)
	or p.powers[pw_carry]
	or p.powers[pw_justsprung]
		p.airdrilltimer = 0
		p.airflyangle = 0
	end
	
	if not (p.pflags & PF_THOKKED)
		p.drillspeed = p.speed
	end

	if p.pflags & PF_JUMPED	
		if (p.cmd.buttons & BT_SPIN and p.airdrilltimer < 42)
			p.airdrilltimer = $ + 1
		end
		
		if (p.airflyangle > 0 and p.pflags & PF_THOKKED)
			p.airflyangle = $ - 1
			
			P_SetObjectMomZ(p.mo, ((p.airflyangle-24 - p.airdrilltimer*3)*((p.actionspd>>FRACBITS)/12 + 1)<<FRACBITS)/7, false)
			
			local trail = P_SpawnGhostMobj(p.mo)
			
			for i = 0,9
				trail.fuse = 9
				trail.state = S_THOK
				trail.scale = FRACUNIT - (i * FRACUNIT/240)
				trail.destscale = 0
			end
			
			P_InstaThrust(p.mo, p.mo.angle, FixedMul(p.drillspeed, p.mo.scale))
	
			p.drawangle = p.mo.angle
		end
	end
	
	if p.airflyangle
	and p.pflags & PF_USEDOWN
		if not p.dropstart
			p.dropspeed = 36*FRACUNIT
		end
		p.dropstart = true
	end
	
	if P_PlayerInPain(p) or not (p.playerstate == PST_LIVE) or p.exiting or p.powers[pw_nocontrol]
		p.triedtodash = false
		p.droptimer = 0
		p.dropstart = false
//		player.mo.state = S_PLAY_ROLL
	end
	
	if p.triedtodash
		p.droptimer = 0
		p.mo.state = S_PLAY_JUMP
		p.dropstart = false
	else
		if p.dropstart
		and p.pflags & PF_USEDOWN
			p.droptimer = $ + 1
			if (p.dropspeed < 72*FRACUNIT and not p.hyper)
			or (p.hyper and p.dropspeed < 144*FRACUNIT)
				if p.powers[pw_super]
					p.dropspeed = $ + FRACUNIT * 34 / 12
				else
					p.dropspeed = $ + FRACUNIT * 17 / 12
				end
			end
		elseif p.droptimer > 0
		and not (p.pflags & PF_USEDOWN)
			p.droptimer = 0
			p.triedtodash = true
			p.dropstart = false
		end
	end
	
	if p.droptimer == 1
		p.mo.state = S_DROPDASH
		S_StartSound(p.mo, sfx_drpdsh, p)
	end
	
	if p.mo.state == S_DROPDASH
	and not (p.pflags & PF_USEDOWN)
		p.mo.state = S_PLAY_ROLL
	end
	
	if p.powers[pw_justsprung]
	or p.powers[pw_carry]
//	or P_PlayerInPain(p)
		p.triedtodash = false
		p.droptimer = 0
		p.dropstart = false
	end
	
	if (p.mo.eflags & MFE_JUSTHITFLOOR or P_IsObjectOnGround(p.mo)) then
		if p.droptimer
			p.mo.state = S_PLAY_ROLL
			p.pflags = $1|PF_SPINNING
			local radius = p.mo.radius >> FRACBITS
			P_SpawnMobjFromMobj(p.mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST)
			P_SpawnMobjFromMobj(p.mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST)
			P_SpawnMobjFromMobj(p.mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST)
			P_SpawnMobjFromMobj(p.mo, P_RandomRange(-radius, radius) << FRACBITS, P_RandomRange(-radius, radius) << FRACBITS, 0, MT_SPINDUST)
			P_InstaThrust(p.mo, p.mo.angle, FixedMul(p.dropspeed + p.speed / 6, p.mo.scale))
			S_StartSound(p.mo, sfx_zoom, p)
		end
		p.triedtodash = false
		p.droptimer = 0
		p.dropstart = false
	end	
	
	// Air Drill bonking.
	
	if lines[p.lastlinehit] and lines[p.lastlinehit].valid
		p.playerline = lines[p.lastlinehit]
	
		p.bounceside = P_PointOnLineSide(p.mo.x, p.mo.y, p.playerline)
		
		if p.airflyangle
		and not p.exiting
		and p.powers[pw_pushing]
			p.mo.state = S_PLAY_FALL
			p.pflags = $ & ~PF_JUMPED
			p.pflags = $ & ~PF_SPINNING
			p.airdrilltimer = 0
			p.airflyangle = 0
			p.dropstart = false
			p.droptimer = 0
			if p.bounceside == 1
				P_InstaThrust(p.mo, R_PointToAngle2(p.playerline.v1.x, p.playerline.v1.y, p.playerline.v2.x, p.playerline.v2.y)+ANGLE_90, p.drillspeed /2 )
			else
				P_InstaThrust(p.mo, R_PointToAngle2(p.playerline.v1.x, p.playerline.v1.y, p.playerline.v2.x, p.playerline.v2.y)+ANGLE_90, -p.drillspeed / 2)
			end
			P_SetObjectMomZ(p.mo, 8*FRACUNIT, false)
			S_StartSound(p.mo, sfx_s3k5d, p)
		end
		if p.playerline.special == 41 return end
	end
	if p.airflyangle
	and not (p.powers[pw_super])
		p.charflags = $1 & ~SF_SUPER
	else
		p.charflags = $1|SF_SUPER
	end
	
	if p.powers[pw_super]
	and p.mo.skin == "sonic"
		p.actionspd = skins[p.mo.skin].actionspd * 3 / 2
	elseif p.mo.skin == "sonic"
	and not (p.powers[pw_super])
		p.actionspd = skins[p.mo.skin].actionspd
	end
end
	
addHook("PlayerThink", AirDrillThink)
	
local function EnemyKillDrill(enemy, mo, source, damage)
	if not mo or not mo.valid return end
	if mo.skin != "sonic" return end
	local player = mo.player
	if (player == nil) or (player.playerstate != PST_LIVE) return end	
	if not enemy and enemy.valid return end
	
	if enemy.flags & (MF_ENEMY|MF_MONITOR)
		if player.airflyangle
		and not (damage == DMG_NUKE and player.hyper)
			player.airdrilltimer = 0
			player.airflyangle = 0
		end
	end
end

addHook("MobjDeath", EnemyKillDrill)