MysteriaFool

Checkpoint System

Oct 24th, 2025
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.87 KB | None | 0 0
  1.  
  2. local CaptureDistance = 40
  3. local UpdateRate = 0.5
  4. local MAIN_MENU_PLACE_ID = 118884121023860
  5. local TELEPORT_DELAY_AFTER_SOUND = 3
  6.  
  7.  
  8. local PLAYER_WEIGHT = 1
  9. local DEFENDER_NPC_WEIGHT = 0.6
  10. local ATTACKER_NPC_WEIGHT = 0.6
  11.  
  12. local TweenService = game:GetService("TweenService")
  13. local Players = game:GetService("Players")
  14. local TeamsService = game:GetService("Teams")
  15. local RunService = game:GetService("RunService")
  16. local TeleportService = game:GetService("TeleportService")
  17. local ReplicatedStorage = game:GetService("ReplicatedStorage")
  18.  
  19. local PointChangedEvent = ReplicatedStorage:FindFirstChild("PointChanged")
  20. if not PointChangedEvent then
  21.     PointChangedEvent = Instance.new("BindableEvent")
  22.     PointChangedEvent.Name = "PointChanged"
  23.     PointChangedEvent.Parent = ReplicatedStorage
  24. end
  25.  
  26. local CaptureValues = {}
  27. local PartIndex = {}
  28. local Locked = {}
  29. local RobotsDefender = {}
  30. local RobotsAttacker = {}
  31.  
  32. local parts = {}
  33. for _, child in ipairs(script.Parent:GetChildren()) do
  34.     if child:IsA("BasePart") or child:IsA("Part") then
  35.         table.insert(parts, child)
  36.     end
  37. end
  38. table.sort(parts, function(a,b) return a.Name < b.Name end)
  39.  
  40. local function Tween(Obj, Prop, New, Time)
  41.     Time = Time or 0.1
  42.     local Tweened = TweenService:Create(Obj, TweenInfo.new(Time, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), {[Prop] = New})
  43.     Tweened:Play()
  44.     return {Stop = function() Tweened:Cancel() end}
  45. end
  46.  
  47. local function UpdateRobotList()
  48.     RobotsDefender = {}
  49.     RobotsAttacker = {}
  50.     for _, v in ipairs(workspace:GetDescendants()) do
  51.         if v:IsA("Model") and v:FindFirstChildOfClass("Humanoid") and v:FindFirstChild("HumanoidRootPart") then
  52.             local name = v.Name or ""
  53.             if name:find("Arctic Wolf") then
  54.                 table.insert(RobotsDefender, v)
  55.             elseif name:find("SonsOfHorus") then
  56.                 table.insert(RobotsAttacker, v)
  57.             elseif name:find("CT-") then
  58.                 table.insert(RobotsDefender, v)
  59.             elseif name:find("B1-") or name:find("B2-") then
  60.                 table.insert(RobotsAttacker, v)
  61.             end
  62.         end
  63.     end
  64. end
  65. UpdateRobotList()
  66.  
  67. Players.PlayerAdded:Connect(function(plr)
  68.     plr.CharacterAdded:Connect(function()
  69.         task.delay(2, UpdateRobotList)
  70.     end)
  71. end)
  72.  
  73. local function GetPlayersNear(Pos)
  74.     local DefenderCount = 0
  75.     local AttackerCount = 0
  76.    
  77.     for _, player in ipairs(Players:GetPlayers()) do
  78.         if player.Character and player.Character:FindFirstChild("HumanoidRootPart") and player.Character:FindFirstChildOfClass("Humanoid") then
  79.             if (player.Character.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
  80.                 if player.Team then
  81.                     if player.Team.Name == "Emperor" then
  82.                         DefenderCount = DefenderCount + PLAYER_WEIGHT
  83.                     elseif player.Team.Name == "Horus" then
  84.                         AttackerCount = AttackerCount + PLAYER_WEIGHT
  85.                     end
  86.                 end
  87.             end
  88.         end
  89.     end
  90.    
  91.     return DefenderCount, AttackerCount
  92. end
  93.  
  94. local function GetDefenderNPCsNear(Pos)
  95.     local Near = 0
  96.     for _, ally in ipairs(RobotsDefender) do
  97.         if ally and ally.Parent and ally:FindFirstChild("HumanoidRootPart") and ally:FindFirstChildOfClass("Humanoid") then
  98.             if (ally.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
  99.                 Near = Near + DEFENDER_NPC_WEIGHT
  100.             end
  101.         end
  102.     end
  103.     return Near
  104. end
  105.  
  106. local function GetAttackerNPCsNear(Pos)
  107.     local Near = 0
  108.     for _, enemy in ipairs(RobotsAttacker) do
  109.         if enemy and enemy.Parent and enemy:FindFirstChild("HumanoidRootPart") and enemy:FindFirstChildOfClass("Humanoid") then
  110.             if (enemy.HumanoidRootPart.Position - Pos).Magnitude <= CaptureDistance then
  111.                 Near = Near + ATTACKER_NPC_WEIGHT
  112.             end
  113.         end
  114.     end
  115.     return Near
  116. end
  117.  
  118. for index, part in ipairs(parts) do
  119.     local capVal = part:FindFirstChild("Captured")
  120.     local isRep = part:FindFirstChild("IsRepublic")
  121.     local hudBar = nil
  122.     if part:FindFirstChild("HUD") and part.HUD:FindFirstChild("Capturing") then
  123.         hudBar = part.HUD.Capturing
  124.     end
  125.  
  126.     if capVal and isRep and hudBar then
  127.         capVal.Value = 100
  128.         isRep.Value = true
  129.         Locked[part] = false
  130.         table.insert(CaptureValues, {Part = part, Captured = capVal, IsRepublic = isRep, HUD = hudBar})
  131.         PartIndex[part] = #CaptureValues
  132.     else
  133.         warn("Capture part missing children:", part:GetFullName())
  134.     end
  135. end
  136.  
  137. local function PreviousIsCapturedByAttackers(index)
  138.     if index <= 1 then return true end
  139.     local prev = CaptureValues[index - 1]
  140.     if prev then
  141.         return (prev.Captured.Value >= 100) and (prev.IsRepublic.Value == false)
  142.     end
  143.     return false
  144. end
  145.  
  146. local function ShowFallback(fallbackName)
  147.     print("Showing fallback:", fallbackName)
  148.    
  149.     for _, player in ipairs(Players:GetPlayers()) do
  150.         if player:FindFirstChild("PlayerGui") and player.PlayerGui:FindFirstChild("CaptureSystem") then
  151.             local gui = player.PlayerGui.CaptureSystem
  152.             if gui:FindFirstChild(fallbackName) then
  153.                 gui[fallbackName].Visible = true
  154.                 task.delay(4, function()
  155.                     if gui:FindFirstChild(fallbackName) then
  156.                         gui[fallbackName].Visible = false
  157.                     end
  158.                 end)
  159.             end
  160.         end
  161.     end
  162.  
  163.     local fbSound = script.Parent:FindFirstChild("FallbackSound")
  164.     if fbSound and fbSound:IsA("Sound") then
  165.         fbSound:Play()
  166.     end
  167. end
  168.  
  169. local function Connection(entry)
  170.     local Part = entry.Part
  171.     local CapturedValue = entry.Captured
  172.     local IsRepublic = entry.IsRepublic
  173.     local HUDBar = entry.HUD
  174.     local idx = PartIndex[Part]
  175.  
  176.     task.spawn(function()
  177.         local LastCaptureValue = CapturedValue.Value
  178.         while Part and Part.Parent do
  179.             task.wait(0.1)
  180.             if HUDBar and CapturedValue then
  181.                 if LastCaptureValue ~= CapturedValue.Value then
  182.                     local size = math.clamp(CapturedValue.Value / 100, 0, 1)
  183.                     Tween(HUDBar, "Size", UDim2.new(1, 0, size, 0), 0.12)
  184.                     LastCaptureValue = CapturedValue.Value
  185.                 end
  186.             else
  187.                 break
  188.             end
  189.         end
  190.     end)
  191.  
  192.     while Part and Part.Parent do
  193.         task.wait(UpdateRate)
  194.         if math.random(1, 12) == 1 then
  195.             UpdateRobotList()
  196.         end
  197.  
  198.         local playerDefenders, playerAttackers = GetPlayersNear(Part.Position)
  199.         local defendersNearby = playerDefenders + GetDefenderNPCsNear(Part.Position)
  200.         local attackersNearby = playerAttackers + GetAttackerNPCsNear(Part.Position)
  201.  
  202.         if CapturedValue.Value > 100 then CapturedValue.Value = 100 end
  203.         if CapturedValue.Value < 0 then CapturedValue.Value = 0 end
  204.  
  205.         if CapturedValue.Value < 1 and not Locked[Part] then
  206.             if defendersNearby > attackersNearby then
  207.                 IsRepublic.Value = true
  208.             elseif attackersNearby > defendersNearby then
  209.                 IsRepublic.Value = false
  210.             end
  211.         end
  212.  
  213.         if IsRepublic.Value then
  214.             HUDBar.BackgroundColor3 = Color3.fromRGB(131, 255, 251)
  215.         else
  216.             HUDBar.BackgroundColor3 = BrickColor.new("Earth green").Color
  217.         end
  218.  
  219.         local attackersAllowedToProgress = PreviousIsCapturedByAttackers(idx)
  220.         local isLocked = Locked[Part]
  221.  
  222.         if CapturedValue.Value < 100 then
  223.             if IsRepublic.Value and defendersNearby > 0 and not isLocked then
  224.                 CapturedValue.Value = math.min(100, CapturedValue.Value + defendersNearby)
  225.             elseif (not IsRepublic.Value) and attackersNearby > 0 then
  226.                 if attackersAllowedToProgress then
  227.                     CapturedValue.Value = math.min(100, CapturedValue.Value + attackersNearby)
  228.                 end
  229.             elseif defendersNearby == 0 and attackersNearby == 0 and CapturedValue.Value > 0 and not isLocked then
  230.                 CapturedValue.Value = math.max(0, CapturedValue.Value - 0.5)
  231.             end
  232.         end
  233.  
  234.         if not isLocked then
  235.             if IsRepublic.Value and attackersNearby > defendersNearby and CapturedValue.Value > 0 then
  236.                 CapturedValue.Value = math.max(0, CapturedValue.Value - attackersNearby)
  237.             elseif (not IsRepublic.Value) and defendersNearby > attackersNearby and CapturedValue.Value > 0 then
  238.                 CapturedValue.Value = math.max(0, CapturedValue.Value - defendersNearby)
  239.             end
  240.         else
  241.             if not IsRepublic.Value and attackersNearby > 0 and CapturedValue.Value < 100 and attackersAllowedToProgress then
  242.                 CapturedValue.Value = math.min(100, CapturedValue.Value + attackersNearby)
  243.             end
  244.         end
  245.  
  246.         if CapturedValue.Value >= 100 and IsRepublic.Value == false and not Locked[Part] then
  247.             Locked[Part] = true
  248.             IsRepublic.Value = false
  249.             print(("Point %s locked to attackers"):format(Part.Name))
  250.  
  251.             local nextPoint = nil
  252.             if Part.Name == "A" then
  253.                 nextPoint = "B"
  254.                 ShowFallback("Fallback1")
  255.             elseif Part.Name == "B" then
  256.                 nextPoint = "C"
  257.                 ShowFallback("Fallback2")
  258.             elseif Part.Name == "C" then
  259.                 nextPoint = nil
  260.             end
  261.  
  262.             if nextPoint then
  263.                 local success, err = pcall(function()
  264.                     PointChangedEvent:Fire(nextPoint)
  265.                 end)
  266.                 if not success then
  267.                     warn("Failed firing PointChangedEvent:", err)
  268.                 end
  269.             end
  270.         end
  271.     end
  272. end
  273.  
  274. for _, entry in ipairs(CaptureValues) do
  275.     task.spawn(function()
  276.         Connection(entry)
  277.     end)
  278. end
  279.  
  280. while task.wait(1) do
  281.     local allCapturedByAttackers = true
  282.     for _, entry in ipairs(CaptureValues) do
  283.         if not (entry.Captured.Value >= 100 and entry.IsRepublic.Value == false) then
  284.             allCapturedByAttackers = false
  285.             break
  286.         end
  287.     end
  288.  
  289.     if allCapturedByAttackers then
  290.         for _, player in ipairs(Players:GetPlayers()) do
  291.             if player:FindFirstChild("PlayerGui") and player.PlayerGui:FindFirstChild("CaptureSystem") then
  292.                 local gui = player.PlayerGui.CaptureSystem
  293.                
  294.                 if player.Team and player.Team.Name == "Emperor" then
  295.                     if gui:FindFirstChild("Lost") then
  296.                         gui.Lost.Visible = true
  297.                     end
  298.                 elseif player.Team and player.Team.Name == "Horus" then
  299.                     if gui:FindFirstChild("Won") then
  300.                         gui.Won.Visible = true
  301.                     end
  302.                 end
  303.             end
  304.         end
  305.  
  306.         local soundObj = script.Parent:FindFirstChild("VictorySound")
  307.         if soundObj and soundObj.Play then
  308.             soundObj:Play()
  309.         end
  310.  
  311.         task.wait(TELEPORT_DELAY_AFTER_SOUND)
  312.         for _, player in ipairs(Players:GetPlayers()) do
  313.             if player and player.Parent then
  314.                 local success, err = pcall(function()
  315.                     TeleportService:Teleport(MAIN_MENU_PLACE_ID, player)
  316.                 end)
  317.                 if not success then
  318.                     warn("Teleport failed for", player.Name, err)
  319.                 end
  320.                 task.wait(0.2)
  321.             end
  322.         end
  323.         while true do task.wait(1) end
  324.     end
  325. end
Advertisement
Add Comment
Please, Sign In to add comment