Players = {}

CellSize = 1024
ShroudRange = 50
ShroudImploderDuration = 20
InitialBlue = 1
InitialAmbience = 1

ShroudImploderLaunchedForPlayer = {}
HaveShroudImploderLighting = false

ChangeMCV = function(player)
	local mcv = player.GetActorsByType("mcv")[1]
	local faction = player.Faction
	if faction == "germany" then
		local actor = Actor.Create("gmcv", true, { Owner = player, Location = mcv.Location, Facing = Angle.South })
	elseif faction == "england" then
		local actor = Actor.Create("emcv", true, { Owner = player, Location = mcv.Location, Facing = Angle.South })
	elseif faction == "france" then
		local actor = Actor.Create("fmcv", true, { Owner = player, Location = mcv.Location, Facing = Angle.South })
	elseif faction == "russia" then
		local actor = Actor.Create("rmcv", true, { Owner = player, Location = mcv.Location, Facing = Angle.South })
	elseif faction == "ukraine" then
		local actor = Actor.Create("umcv", true, { Owner = player, Location = mcv.Location, Facing = Angle.South })
	end
	mcv.Destroy()
end

StartShroudImploderLighting = function()
	Lighting.Blue = 1.5
	Lighting.Ambient = 0.6
	HaveShroudImploderLighting = true
end

UpdateShroudImploderLighting = function()
	-- Only change the lighting randomly on some ticks.
	if Utils.RandomInteger(1, 11) <= 2 then
		-- This will be either a step up or down.
		local delta = (Utils.RandomInteger(0, 2) * 2 - 1) * 0.07
		-- Let the brightness wander within a range.
		Lighting.Ambient = math.min(0.9, math.max(0.4, Lighting.Ambient + delta))
	end
end

EndShroudImploderLighting = function()
	Lighting.Blue = InitialBlue
	Lighting.Ambient = InitialAmbience
	HaveShroudImploderLighting = false
end

SetUpShroudImploderSound = function()
	for i = 0, ShroudImploderDuration / 2 - 1 do
		Trigger.AfterDelay(25 * 2 * i, function()
			Media.PlaySound("shroudImploderEffect.wav")
		end)
	end
	Trigger.AfterDelay(25 * ShroudImploderDuration, function()
		Media.PlaySound("shroudImploderEnd.wav")
	end)
end

AddDummyGapsForPlayer = function(player)
	local maxX = math.ceil(Map.BottomRight.X / (CellSize * ShroudRange)) * ShroudRange
	local maxY = math.ceil(Map.BottomRight.Y / (CellSize * ShroudRange)) * ShroudRange
	local maxPlaceableX = math.floor(Map.BottomRight.X / CellSize)
	local maxPlaceableY = math.floor(Map.BottomRight.Y / CellSize)
	local x = 0
	while x <= maxX do
		local y = 0
		while y <= maxY do
			if (x + y) % (2 * ShroudRange) == 0 then
				local cpos = CPos.New(math.min(x, maxPlaceableX), math.min(y, maxPlaceableY))
				Actor.Create("dummygap", true, { Owner = player, Location = cpos })
			end
			y = y + ShroudRange
		end
		x = x + ShroudRange
	end
end

Tick = function()
	local shroudImploderActive = false
	for i = 1, #Players do
		local player = Players[i]
		local dummyspawners = player.GetActorsByType("dummyspawner")
		local dummygaps = player.GetActorsByType("dummygap")
		if #dummyspawners > 0 and #dummygaps == 0 then
			if not ShroudImploderLaunchedForPlayer[i] then
				Media.PlaySound("shroudImploderLaunch.wav")
				ShroudImploderLaunchedForPlayer[i] = true
				Trigger.AfterDelay(25, function()
					AddDummyGapsForPlayer(player)
					SetUpShroudImploderSound()
				end)
			end
		elseif #dummygaps > 0 then
			if #dummyspawners == 0 then
				for j = 1, #dummygaps do
					dummygaps[j].Destroy()
				end
				ShroudImploderLaunchedForPlayer[i] = false
			else
				shroudImploderActive = true
			end
		end
	end
	-- Handle lighting effects
	if shroudImploderActive then
		if not HaveShroudImploderLighting then
			StartShroudImploderLighting()
		else
			UpdateShroudImploderLighting()
		end
	elseif HaveShroudImploderLighting then
		EndShroudImploderLighting()
	end
end

WorldLoaded = function()
	InitialAmbience = Lighting.Ambient
	InitialBlue = Lighting.Blue
	
	local allActors = Map.ActorsInWorld
	local allMcvs = {}
	local mcvLoop = 1
	for i = 1, #allActors do
		if allActors[i].Type == "mcv" then
			allMcvs[mcvLoop] = allActors[i]
			mcvLoop = mcvLoop + 1
		end
	end
	for i = 1, #allMcvs do
		Players[i] = allMcvs[i].EffectiveOwner
	end

	for i = 1, #Players do
		ShroudImploderLaunchedForPlayer[i] = false
	end
	local eliteText = ""
	local testText = ""
	for i = 1, #Players do
		testText = string.sub(Players[i].InternalName, 6)
		eliteText = "elite" .. testText
		if Map.LobbyOption(eliteText) == "yes" then
			Players[i].GrantCondition("elite")
			Media.DisplayMessage("Elite faction enabled for " .. Players[i].Name .. "!")
			ChangeMCV(Players[i])
		else
			Media.DisplayMessage("Elite NOT enabled for " .. Players[i].Name .. "!")
		end
	end
end
