// GOD. Most of this code is over a year old now, DO NOT use as reference... other than the Whirlwind part, since that's actually neat.

// Recreation of the Whirlwind Shield's slow fall in SRB1 1.4.

local function SlowFall(player)
	if not (player.mo and player.mo.valid) then return end 
	
	if player.powers[pw_shield] == SH_WHIRLWIND
		if player.pflags & PF_SHIELDABILITY
			if (P_MobjFlip(player.mo)*player.mo.momz < -gravity*8)
				player.mo.momz = P_MobjFlip(player.mo)*-gravity*8
			end
		end
	end
end

addHook("PlayerThink", SlowFall)

// The Force Shield's ability, which extends the player's hitbox and maintain your speed.

// The Elemental Shield's "Meteor Bounce" ability.
// This code is hellish. If anyone can improve it, please do.

local function P_IsObjectOnCeiling(mo)
	if P_IsObjectInGoop(mo) 
	and not (mo.player.pflags & PF_BOUNCING)
		return false
	end
	
	if (mo.eflags & MFE_VERTICALFLIP)
		if (mo.z <= mo.floorz)
			return true
		end
	else
		if (mo.z+mo.height >= mo.ceilingz)
			return true
		end
	end
	return false
end


local function ElementalOverride(player)
	if not (player.mo and player.mo.valid) then return end 
	
	if player.bouncing == nil
		player.bouncing = false
	end
	
	if player.powers[pw_shield] == SH_ELEMENTAL
		if not player.bouncing
			P_Thrust(player.mo, player.mo.angle, FixedMul(25*FRACUNIT, player.mo.scale))
			if (player.mo.eflags & MFE_VERTICALFLIP)
				player.mo.momz = 24*FRACUNIT
			else
				player.mo.momz = -24*FRACUNIT
			end
			player.bouncing = true
		end
		return true
	end
end

addHook("ShieldSpecial", ElementalOverride)

local function HowToClearBouncing(player)
	if not (player.mo and player.mo.valid) then return end 
	
	local previousz = player.mo.momz
	
	if lines[player.lastlinehit] and lines[player.lastlinehit].valid
		player.playerline = lines[player.lastlinehit]
		player.bounceside = P_PointOnLineSide(player.mo.x, player.mo.y, player.playerline)
	end
	
	if (player.powers[pw_justsprung]) then
		player.bouncing = false
		player.repeatbounce = false
	end
	
	
	if P_IsObjectOnGround(player.mo)
	and player.bouncing
		player.bouncing = false
		if player.powers[pw_shield] == SH_ELEMENTAL
			P_DoBubbleBounce(player)
			P_ElementalFire(player, true)
			player.pflags = $1 & ~PF_SPINNING
			player.repeatbounce = true
		end
	end
		

	if P_IsObjectOnGround(player.mo)
		if player.powers[pw_shield] == SH_ELEMENTAL
		and player.cmd.buttons & BT_USE
		and (player.pflags & PF_USEDOWN)
		and player.repeatbounce
			P_DoBubbleBounce(player)
			P_ElementalFire(player, true)
		else
			player.repeatbounce = false
		end
	elseif P_IsObjectOnCeiling(player.mo)
		if player.powers[pw_shield] == SH_ELEMENTAL
		and player.cmd.buttons & BT_USE
		and (player.pflags & PF_USEDOWN)
		and player.repeatbounce
			S_StartSound(player.mo, sfx_s3k44)
			P_SetObjectMomZ(player.mo, -10*FRACUNIT, false)
		else
			player.repeatbounce = false
		end
	end
	
	if not player.powers[pw_pushing]
		player.bouncespeed = player.speed
		player.bouncewall = false
	end
	
	if player.powers[pw_pushing]
		if player.powers[pw_shield] == SH_ELEMENTAL
		and player.cmd.buttons & BT_USE
		and (player.pflags & PF_USEDOWN)
		and player.repeatbounce
		and not player.bouncewall
			S_StartSound(player.mo, sfx_s3k44)
			if player.objectcollide
				P_InstaThrust(player.mo, player.mo.angle + ANGLE_180, player.bouncespeed)
			else
				if player.bounceside == 1
					P_InstaThrust(player.mo,R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_90, player.bouncespeed)
					player.drawangle = R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_90
				else
					P_InstaThrust(player.mo,R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_270, player.bouncespeed)
					player.drawangle = R_PointToAngle2(player.playerline.v1.x, player.playerline.v1.y, player.playerline.v2.x, player.playerline.v2.y)+ANGLE_270
				end
			end
			player.bouncewall = true
		else
//			player.repeatbounce = false
			player.bouncewall = false	
		end
	end
	
	if not player.powers[pw_pushing]
	and player.objectcollide
		player.objectcollide = false
	end
end

addHook("PlayerThink", HowToClearBouncing)

local function WeRamIntoObject(plmo, mo)
	if not (plmo and plmo.valid) return end
    if plmo.type ~= MT_PLAYER return end
    if plmo.z + plmo.height < mo.z
	or mo.z + mo.height < plmo.z return end
    local player = plmo.player --plmo is the player mobj, this gets the player
	player.objectcollide = true
end

addHook("MobjMoveCollide", WeRamIntoObject, MT_PLAYER)