Hi devs,
I am currently creating a game where there are characters who destroy the map, and there are a certain number of parts that can be destroyed. What i want is for the ui bar to fill up when a player destroys something, and to fill up only when all things are destroyed. For some reason, it fills up early, when there are still a few things left to destroy. Other than that it works fine. I want to say that my script organisation skills are quite bad so prepare yourselves I’m using ui gradient and altering its offset property to achieve this.
Heres my server script, it’s long and hard to understand, so any help is appreciated.
local mapFolder = game.Workspace.CurrentMap
local playerNum = 0
local maxHavoc = 2
local vulnerableNum = 3
local charEvent = game:GetService("ReplicatedStorage"):WaitForChild("CharChange")
local teams = {
"Destroyer",
"Destroyer"
}
local maxVulnerable
local parts = {}
local destroyedEvent = game.ServerStorage.DestroyedEvent
local wonEvent = game.ServerStorage.WonEvent
local highlight = game:GetService("ServerStorage").Highlight
local currentHavocNum = 2
local destroyedClientEvent = game.ReplicatedStorage.DestroyedEventClient
local function randomHighlight()
if #parts > 1 then
local ranNum = math.random(1, #parts)
local ranPart = parts[ranNum]
if ranPart and ranPart.Parent then
local newHighlight = highlight:Clone()
newHighlight.Parent = ranPart
ranPart:SetAttribute("Vulnerable", true)
table.remove(parts, ranNum)
end
elseif #parts == 1 then
local ranPart = parts[1]
local newHighlight = highlight:Clone()
newHighlight.Parent = ranPart
ranPart:SetAttribute("Vulnerable", true)
table.remove(parts, 1)
end
end
local function randomTeam(plr)
local ranNum = math.random(1, #teams)
local ranTeam = teams[ranNum]
if playerNum == 2 then
for i, v in game.Players:GetChildren() do
if ranNum == 1 then
v:WaitForChild("GameTeam").Value = "Destroyer"
else
v:WaitForChild("GameTeam").Value = "Protector"
end
end
else
if currentHavocNum == 0 and ranNum == 1 then
randomTeam()
else
plr:WaitForChild("GameTeam").Value = ranTeam
end
if ranTeam == "Destroyer" then
currentHavocNum -= 1
end
end
end
destroyedEvent.Event:Connect(function(destroyedPart)
destroyedPart:SetAttribute("Vulnerable", false)
local highlight = destroyedPart:FindFirstChild("Highlight")
if highlight then
randomHighlight(parts)
highlight:Destroy()
else
local index = table.find(parts, destroyedPart)
if index then
table.remove(parts, index)
end
end
destroyedClientEvent:FireAllClients(parts, false)
if #parts == 0 then
local vulnerableExists = false
for _, v in mapFolder:GetDescendants() do
if v:GetAttribute("Vulnerable") then
vulnerableExists = true
break
end
end
if not vulnerableExists then
wonEvent:Fire()
end
end
end)
mapFolder.ChildAdded:Connect(function(child)
currentHavocNum = maxHavoc
for i, plr in game.Players:GetChildren() do
playerNum += 1
randomTeam(plr)
end
for i, v in child:GetDescendants() do
if v:GetAttribute("Vulnerable") then
v:SetAttribute("Vulnerable", false)
table.insert(parts, v)
end
end
for i = 1, vulnerableNum do
randomHighlight(parts)
end
destroyedClientEvent:FireAllClients(parts, true, vulnerableNum)
end)
mapFolder.ChildRemoved:Connect(function()
for i, v in game.Players:GetChildren() do
v.GameTeam.Value = "No Team"
end
for i, v in workspace.InGameChars.Other:GetChildren() do
v:Destroy()
end
end)
game.Players.PlayerAdded:Connect(function(plr)
local val = Instance.new("StringValue")
val.Name = "GameTeam"
val.Parent = plr
local protChar = Instance.new("StringValue")
protChar.Name = "ProtectorCharacter"
protChar.Parent = plr
local destChar = Instance.new("StringValue")
destChar.Name = "DestroyerCharacter"
destChar.Parent = plr
val.Changed:Connect(function()
if val.Value == "Destroyer" or val.Value == "Protector" then
local char = plr.Character
char.Parent = game.Workspace.InGameChars:FindFirstChild(val.Value)
end
end)
end)
Ignore the majority of it, the most important part is parts where destroyedClientEvent
is called, as thats the event that gets fired to the client.
Here’s my local script that receives this event.
local destroyedEvent = game.ReplicatedStorage.DestroyedEventClient
local maxVulnerable
local currentVulnerable
local frame = script.Parent
local roundHandler = game.ReplicatedStorage.RoundHandler
destroyedEvent.OnClientEvent:Connect(function(partsTable, isMaxVulnerable, vulnerableNum)
if isMaxVulnerable == true then
maxVulnerable = #partsTable + vulnerableNum
frame.UIGradient.Offset = Vector2.new(0, 0)
frame.TextLabel.UIGradient.Offset = Vector2.new(0, 0)
else
currentVulnerable = #partsTable
local offset = (currentVulnerable / maxVulnerable)
frame.UIGradient.Offset = Vector2.new(1 - offset, 0)
frame.TextLabel.UIGradient.Offset = Vector2.new(1 - offset, 0)
end
end)
roundHandler.OnClientEvent:Connect(function(timeLeft, status, roundTime)
if status == "Game" then
frame.Parent.Visible = true
else
frame.Parent.Visible = false
end
end)
much shorter and more managable, i hope.
This is a very hard issue to fix, because my code probably is not easy at all to read.
Thanks in advance!!