local function allBacksidesExistAndArentLava(s)
	if not s then return end
	if not s.lines then return end

	for i = 0, #s.lines-1 do
		if s.lines[i] then
			if not s.lines[i].backsector then return false end
			if s.lines[i].backsector.floorpic == "LAVAR1_1" then return false end
			if s.lines[i].frontsector.floorpic == "LAVAR1_1" then return false end
		else
			print("Sector "..#s.." is missing line "..i.."...?")
		end
	end

	return true
end

local function shrinkThinker()
	server.removesectors = $ or {}

	if not (leveltime%200) and (leveltime > 6*TICRATE) then
		S_StartSound(nil, sfx_s3kd6l)

		for s in sectors.iterate do
			if s.floorpic ~= "LAVAR1_1" then
				if not allBacksidesExistAndArentLava(s) then
					s.floorpic = "REDNOISE"
					table.insert(server.removesectors, #s)
				end
			end
		end

		server.killtimer = 100
	end

	if server.killtimer then
		server.killtimer = $-1

		if server.killtimer <= 0 then
			S_StartSound(nil, sfx_crumbl)
			P_StartQuake(20*FRACUNIT, TICRATE)

			for i = 1, #server.removesectors
				if server.removesectors[i] and sectors[server.removesectors[i]]
					sectors[server.removesectors[i]].floorheight = -300*FRACUNIT
					sectors[server.removesectors[i]].floorpic = "LAVAR1_1"
				end
			end

			local possiblePlayers = {}
			for p in players.iterate do
				if validP(p) then table.insert(possiblePlayers, p.mo) end
			end

			if #possiblePlayers then
				local tmo = possiblePlayers[P_RandomRange(1, #possiblePlayers)]
				local item = P_SpawnMobj(tmo.x+P_RandomRange(-256, 256)*FRACUNIT, tmo.y+P_RandomRange(-256, 256)*FRACUNIT, tmo.z+300*FRACUNIT, MT_RANDOMITEM)
				item.scale = 1
				item.destscale = FRACUNIT
				item.flags = $ & ~MF_NOGRAVITY & ~MF_NOCLIPHEIGHT & ~MF_SLIDEME
			end

			server.killtimer = nil
		end
	end
	
	for p in players.iterate
		if p.spectator then continue end

		if p.mo.subsector.sector.floorpic == "LAVAR1_1"
		and p.boxdata and p.boxdata.out == false
		and p.mo.z <= p.mo.subsector.sector.floorheight
			p.boxdata.out = true
			p.boxdata.survivaltime = G_TicsToSeconds(leveltime-5*TICRATE)
			BX_ExplodeAndRespawn(p)

			print(p.name.." fell into a pit.")
		end
	end

	-- End Terms
	local playersLeft = {}
	for p in players.iterate
		if validP(p) and not p.boxdata.out then
			table.insert(playersLeft, p)
		end
	end

	server.ended = $ or false
	if #playersLeft <= 1 and server.ended == false
		playersLeft[1].marescore = 69420
		for p in players.iterate
			if p.boxdata.out == true
				p.marescore = p.boxdata.survivaltime or 0
			else
				p.marescore = 69420
			end
		end

		BX_EndBattle()
		server.ended = true
	end
	
	if (leveltime == 8*TICRATE) then
		S_ChangeMusic("CRUSHR")
		showMusicCredit()
	end
end

local function shrinkPush(p, inf, src)
	if p.mo and p.mo.valid and inf and inf.valid
		local ang = R_PointToAngle2(inf.x, inf.y, p.mo.x, p.mo.y)
		P_Thrust(p.mo, ang, 50*FRACUNIT)
	end
	
	return true
end

local function shrinkReset()
	server.removesectors = nil
	server.killtimer = nil
end

Box.Gamemodes[GM_SHRINK] = {
	name = "Floor Shrinking",
	hint = "Be the last one standing!",
	noBumpers = true,

	thinker = shrinkThinker,
	spinoutfunc = shrinkPush,
	squishfunc = shrinkPush,
	explodefunc = shrinkPush,
	resetfunc = shrinkReset,
}