Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

How to find more then one brick?

Asked by 9 years ago

Ok so I'm trying to make a cell service with cell towers so when a player is close or far it will act like a cellphone but I'm having troubles finding more then one brick. How can I have this find more then one brick?

local part = game.Workspace.Cell:GetChildern() -- I want this to find everything in the Model Cell but don't know how to add it to the purtion of the script below...
while true do
    for i,v in pairs(game.Players:GetChildren()) do
        if (v.Character.Torso.Position - part.Position).magnitude <= 50 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "-----"
        elseif (v.Character.Torso.Position - part.Position).magnitude <= 100 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "----"
        elseif (v.Character.Torso.Position - part.Position).magnitude <= 150 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "---"
        elseif (v.Character.Torso.Position - part.Position).magnitude <= 200 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "--"
        elseif (v.Character.Torso.Position - part.Position).magnitude <= 250 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "-"
        elseif (v.Character.Torso.Position - part.Position).magnitude <= 300 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "No Service"
        end
    end
    wait()
end

2 answers

Log in to vote
1
Answered by
Goulstem 8144 Badge of Merit Moderation Voter Administrator Community Moderator
9 years ago

What you should do is, while you're iterating through the players then you need to iterate through the cell towers as well, store all the magnitudes in a table, then use the table.sort function to find the smallest index in the table(the first index).. and finally use your conditionals from line 4 - line 16.

local parts = workspace.Cell:GetChildren()

while wait() do
    --Iterate through players
    for i,v in pairs(game.Players:GetPlayers()) do
        --Define a table for all the magnitudes
        local mags = {}
        --Iterate through parts
        for a,b in pairs(parts) do
            --Make sure the character has a torso
            if v.Character:FindFirstChild('Torso') then
                --Get the distance
                local mag = (b.CFrame.p - v.Character.Torso.CFrame.p).magnitude
                --Insert the distance into the table
                table.insert(mags,mag)
            end
        end
        --Sort the table from least to greatest
        table.sort(mags)
        --Get the lowest value
        local val = mags[1]
        --Use the conditionals with the 'val' variable
        if val <= 50 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "-----"
        elseif val <= 100 and val > 50 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "----"
        elseif val <= 150 and val > 100 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "---"
        elseif val <= 200 and val > 150 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "--"
        elseif val <= 250 and val > 200 then
            v.PlayerGui.ScreenGui.TextLabel.Text = "-"
        else
            v.PlayerGui.ScreenGui.TextLabel.Text = "No Service"
        end
    end
end
0
Tried I got this error now attempt to compare two userdata values on line 20... Anciteify 70 — 9y
0
which on here is line 21 plr was not defined... Anciteify 70 — 9y
0
Edited Goulstem 8144 — 9y
0
Why use a table when you could just keep track of a "bestMagnitude" value? No need to sort a table of values that you aren't going to use. Further, what's the point of adding "and val > 50" on line 25? "val > 50" is guaranteed by line 23's conditional not being true. Also, any particular reason you're using .CFrame.p instead of .Position ? Finally, I'd recommend replacing line 33 with "else" chess123mate 5873 — 9y
View all comments (6 more)
0
This way I just though it would be easier, since the table.sort function exists. Idk, doesn't really matter. I'm using CFrame.p since I normally deal with CFrames, rather than Vectors - Just a habbit. That last suggestion was actually good. Why critisize my code if it works effectively and for the most part efficiently, though? Goulstem 8144 — 9y
0
There's no point in going for a slightly more efficient method when the readability is awful. People can understand my code better than yours and the changes you made aren't really worth changing. A few millaseconds worth of increased performance rate isn't worth making the code ugly. Goulstem 8144 — 9y
0
It just seems like unnecessary processing. Sorry, I suppose I'm "prematurely optimizing". chess123mate 5873 — 9y
0
What part of my code is so ugly? (If you just mean line 18, I can agree it's harder to understand (though potentially more powerful)) chess123mate 5873 — 9y
0
'ugly' is a strong word but yes.. 18 is harder to read / understand. But like I said, trading in readability for miniscule performance rate enhancement isn't worth it.. if you're giving an answer to the public. Goulstem 8144 — 9y
0
Thx Goulstem! Anciteify 70 — 9y
Ad
Log in to vote
1
Answered by 9 years ago

You need to add another loop.

while true do
    local cells = game.Workspace.Cell:GetChildern()
    local players = game.Players:GetChildren()
    for i = 1, #players do
        if players[i].Character and players[i].Character:FindFirstChild("Torso") then
            local pos = players[i].Character.Torso.Position
            local bestDist = 251 --since max signal distance is 250
            for j = 1, #cells do
                local dist = (cells[j].Position - pos).magnitude
                if dist < bestDist then
                    bestDist = dist
                    --If you want to store the closest cell tower, do so here (it will equal "cells[j]")
                end
            end
            if bestDist > 250 then
                players[i].PlayerGui.ScreenGui.TextLabel.Text = "No Service"
            else
                players[i].PlayerGui.ScreenGui.TextLabel.Text = string.rep("-", math.min(5, math.floor((300-bestDist)/50)))
            end
        end
    end
    wait()
end

Note that putting the "game.Workspace.Cell:GetChildern()" inside the while loop will mean that if you add/remove cell towers as the game progresses, the script will automatically adapt to that. If you don't intend to add/remove towers, this line can stay outside the while loop.

players[i].PlayerGui.ScreenGui.TextLabel.Text = string.rep("-", math.min(5, math.floor((300-bestDist)/50))) acts the same as the majority of the 'if' statements you had previously. Along with the if bestDist > 250 then, all cases are taken care of (whereas before, if 'magnitude' was 301, your if statements could not handle it and would not update the TextLabel).

Answer this question