CCCPaste

Capture System Fixed

local CaptureDistance = 40
local UpdateRate = 0.5
local MAIN_MENU_PLACE_ID = 118884121023860
local TELEPORT_DELAY_AFTER_SOUND = 3

local PLAYER_WEIGHT = 1
local DEFENDER_NPC_WEIGHT = 0.6
local ATTACKER_NPC_WEIGHT = 0.6
 
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local TeamsService = game:GetService("Teams")
local RunService = game:GetService("RunService")
local TeleportService = game:GetService("TeleportService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local PointChangedEvent = ReplicatedStorage:FindFirstChild("PointChanged")
if not PointChangedEvent then
	PointChangedEvent = Instance.new("BindableEvent")
	PointChangedEvent.Name = "PointChanged"
	PointChangedEvent.Parent = ReplicatedStorage
end

local CaptureValues = {}
local PartIndex = {}
local Locked = {}
local RobotsDefender = {}
local RobotsAttacker = {}

local parts = {}
for _, child in ipairs(script.Parent:GetChildren()) do
	if child:IsA("BasePart") or child:IsA("Part") then
		table.insert(parts, child)
	end
end
table.sort(parts, function(a,b) return a.Name < b.Name end)


local function Tween(Obj, Prop, New, Time)
	Time = Time or 0.1
	local Tweened = TweenService:Create(Obj, TweenInfo.new(Time, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), {[Prop] = New})
	Tweened:Play()
	return {Stop = function() Tweened:Cancel() end}
end


local function UpdateRobotList()
	RobotsDefender = {}
	RobotsAttacker = {}
	for _, v in ipairs(workspace:GetDescendants()) do
		if v:IsA("Model") and v:FindFirstChildOfClass("Humanoid") and v:FindFirstChild("HumanoidRootPart") then
			local name = v.Name or ""
			if name:find("Arctic Wolf") then
				table.insert(RobotsDefender, v)
			elseif name:find("SonsOfHorus") then
				table.insert(RobotsAttacker, v)
			elseif name:find("CT-") then
				table.insert(RobotsDefender, v)
			elseif name:find("B1-") or name:find("B2-") then
				table.insert(RobotsAttacker, v)
			end
		end
	end
end
UpdateRobotList()
 
Players.PlayerAdded:Connect(function(plr)
	plr.CharacterAdded:Connect(function()
		task.delay(2, UpdateRobotList)
	end)
end)

local function GetPlayersNear(Pos)
	local DefenderCount = 0
	local AttackerCount = 0
	
	for _, player in ipairs(Players:GetPlayers()) do
		if player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character:FindFirstChildOfClass("Humanoid") then
			if (player.Character.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
				if player.Team then
					if player.Team.Name == "Emperor" then
						DefenderCount = DefenderCount + PLAYER_WEIGHT
					elseif player.Team.Name == "Horus" then
						AttackerCount = AttackerCount + PLAYER_WEIGHT
					end
				end
			end
		end
	end
	
	return DefenderCount, AttackerCount
end
 
local function GetDefenderNPCsNear(Pos)
	local Near = 0
	for _, ally in ipairs(RobotsDefender) do
		if ally and ally.Parent and ally:FindFirstChild("HumanoidRootPart") and ally:FindFirstChildOfClass("Humanoid") then
			if (ally.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
				Near = Near + DEFENDER_NPC_WEIGHT
			end
		end
	end
	return Near
end
 
local function GetAttackerNPCsNear(Pos)
	local Near = 0
	for _, enemy in ipairs(RobotsAttacker) do
		if enemy and enemy.Parent and enemy:FindFirstChild("HumanoidRootPart") and enemy:FindFirstChildOfClass("Humanoid") then
			if (enemy.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
				Near = Near + ATTACKER_NPC_WEIGHT
			end
		end
	end
	return Near
end

for index, part in ipairs(parts) do
	local capVal = part:FindFirstChild("Captured")
	local isRep = part:FindFirstChild("IsRepublic")
	local hudBar = nil
	if part:FindFirstChild("HUD") and part.HUD:FindFirstChild("Capturing") then
		hudBar = part.HUD.Capturing
	end
 
	if capVal and isRep and hudBar then
		capVal.Value = 100
		isRep.Value = true
		Locked[part] = false
		table.insert(CaptureValues, {Part = part, Captured = capVal, IsRepublic = isRep, HUD = hudBar})
		PartIndex[part] = #CaptureValues
	else
		warn("Capture part missing children:", part:GetFullName())
	end
end
 
local function PreviousIsCapturedByAttackers(index)
	if index <= 1 then return true end
	local prev = CaptureValues[index - 1]
	if prev then
		return (prev.Captured.Value >= 100) and (prev.IsRepublic.Value == false)
	end
	return false
end

local function ShowFallback(fallbackName)
	print("Showing fallback:", fallbackName)
	
	for _, player in ipairs(Players:GetPlayers()) do
		if player:FindFirstChild("PlayerGui") and player.PlayerGui:FindFirstChild("CaptureSystem") then
			local gui = player.PlayerGui.CaptureSystem
			if gui:FindFirstChild(fallbackName) then
				gui[fallbackName].Visible = true
				task.delay(4, function()
					if gui:FindFirstChild(fallbackName) then
						gui[fallbackName].Visible = false
					end
				end)
			end
		end
	end

	local fbSound = script.Parent:FindFirstChild("FallbackSound")
	if fbSound and fbSound:IsA("Sound") then
		fbSound:Play()
	end
end

local function Connection(entry)
	local Part = entry.Part
	local CapturedValue = entry.Captured
	local IsRepublic = entry.IsRepublic
	local HUDBar = entry.HUD
	local idx = PartIndex[Part]
 
	task.spawn(function()
		local LastCaptureValue = CapturedValue.Value
		while Part and Part.Parent do
			task.wait(0.1)
			if HUDBar and CapturedValue then
				if LastCaptureValue ~= CapturedValue.Value then
					local size = math.clamp(CapturedValue.Value / 100, 0, 1)
					Tween(HUDBar, "Size", UDim2.new(1, 0, size, 0), 0.12)
					LastCaptureValue = CapturedValue.Value
				end
			else
				break
			end
		end
	end)
 
	while Part and Part.Parent do
		task.wait(UpdateRate)
		if math.random(1, 12) == 1 then
			UpdateRobotList()
		end

		local playerDefenders, playerAttackers = GetPlayersNear(Part.Position)
		local defendersNearby = playerDefenders + GetDefenderNPCsNear(Part.Position)
		local attackersNearby = playerAttackers + GetAttackerNPCsNear(Part.Position)
 
		if CapturedValue.Value > 100 then CapturedValue.Value = 100 end
		if CapturedValue.Value < 0 then CapturedValue.Value = 0 end
 
		if CapturedValue.Value < 1 and not Locked[Part] then
			if defendersNearby > attackersNearby then
				IsRepublic.Value = true
			elseif attackersNearby > defendersNearby then
				IsRepublic.Value = false
			end
		end
 
		if IsRepublic.Value then
			HUDBar.BackgroundColor3 = Color3.fromRGB(131, 255, 251)
		else
			HUDBar.BackgroundColor3 = BrickColor.new("Earth green").Color
		end
 
		local attackersAllowedToProgress = PreviousIsCapturedByAttackers(idx)
		local isLocked = Locked[Part]
 
		if CapturedValue.Value < 100 then
			if IsRepublic.Value and defendersNearby > 0 and not isLocked then
				CapturedValue.Value = math.min(100, CapturedValue.Value + defendersNearby)
			elseif (not IsRepublic.Value) and attackersNearby > 0 then
				if attackersAllowedToProgress then
					CapturedValue.Value = math.min(100, CapturedValue.Value + attackersNearby)
				end
			elseif defendersNearby == 0 and attackersNearby == 0 and CapturedValue.Value > 0 and not isLocked then
				CapturedValue.Value = math.max(0, CapturedValue.Value - 0.5)
			end
		end
 
		if not isLocked then
			if IsRepublic.Value and attackersNearby > defendersNearby and CapturedValue.Value > 0 then
				CapturedValue.Value = math.max(0, CapturedValue.Value - attackersNearby)
			elseif (not IsRepublic.Value) and defendersNearby > attackersNearby and CapturedValue.Value > 0 then
				CapturedValue.Value = math.max(0, CapturedValue.Value - defendersNearby)
			end
		else
			if not IsRepublic.Value and attackersNearby > 0 and CapturedValue.Value < 100 and attackersAllowedToProgress then
				CapturedValue.Value = math.min(100, CapturedValue.Value + attackersNearby)
			end
		end
 
		if CapturedValue.Value >= 100 and IsRepublic.Value == false and not Locked[Part] then
			Locked[Part] = true
			IsRepublic.Value = false
			print(("Point %s locked to attackers"):format(Part.Name))

			local success, err = pcall(function()
				PointChangedEvent:Fire(Part.Name)
			end)
			if not success then
				warn("Failed firing PointChangedEvent:", err)
			end

			if Part.Name == "A" then
				ShowFallback("Fallback1")
			elseif Part.Name == "B" then
				ShowFallback("Fallback2")
			elseif Part.Name == "C" then
			end
		end
	end
end
 
for _, entry in ipairs(CaptureValues) do
	task.spawn(function()
		Connection(entry)
	end)
end

while task.wait(1) do
	local allCapturedByAttackers = true
	for _, entry in ipairs(CaptureValues) do
		if not (entry.Captured.Value >= 100 and entry.IsRepublic.Value == false) then
			allCapturedByAttackers = false
			break
		end
	end
 
	if allCapturedByAttackers then
		for _, player in ipairs(Players:GetPlayers()) do
			if player:FindFirstChild("PlayerGui") and player.PlayerGui:FindFirstChild("CaptureSystem") then
				local gui = player.PlayerGui.CaptureSystem
				
				if player.Team and player.Team.Name == "Emperor" then
					if gui:FindFirstChild("Lost") then
						gui.Lost.Visible = true
					end
				elseif player.Team and player.Team.Name == "Horus" then
					if gui:FindFirstChild("Won") then
						gui.Won.Visible = true
					end
				end
			end
		end
 
		local soundObj = script.Parent:FindFirstChild("VictorySound")
		if soundObj and soundObj.Play then
			soundObj:Play()
		end
 
		task.wait(TELEPORT_DELAY_AFTER_SOUND)
		for _, player in ipairs(Players:GetPlayers()) do
			if player and player.Parent then
				local success, err = pcall(function()
					TeleportService:Teleport(MAIN_MENU_PLACE_ID, player)
				end)
				if not success then
					warn("Teleport failed for", player.Name, err)
				end
				task.wait(0.2)
			end
		end
		while true do task.wait(1) end
	end
end