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

Holo Map ]] How to run multiple holo maps at the same time?

Asked by 8 years ago

So, basically one part of this script will remove the clone of a current map and run a different map. The process goes as it follows, me : r2/map1 (map1 is loaded) me : r2/map2 (map1 is removed and map2 is loaded) What I want, me : r2/map1 (map1 is loaded) me : r2/map2 (map2 loaded) A part of the script below removes the current map when I say r2/(map) Anyway how to edit this?

Permission = {"PLAYER","PLAYER","PLAYER"} -- Players who can run/stop the maps.
RunText = "r2/" -- Text the Players have to say to run the maps. (MAP NAME AFTER)
StopText = "cl2/" -- Text the Players have to say to stop the maps. (MAP NAME AFTER)

game.Players.ChildAdded:connect(function(Player)
    Player.Chatted:connect(function(Chat)
        for i = 1, #Permission do
            if Player.Name == Permission[i] then
                if Chat:lower():sub(1,RunText:len()) == RunText then
                    Map = game.ServerStorage:FindFirstChild(Chat.sub(Chat,1+RunText:len()))
                    if Map ~= nil then
                        for i,v in pairs(game.ServerStorage:GetChildren()) do
                            if v:IsA("Model") then
                                if game.Workspace:FindFirstChild(v.Name) then
                                    game.Workspace:FindFirstChild(v.Name):remove()
                                end
                            end
                        end
                        Map:Clone().Parent = game.Workspace
                    end
                end
                if Chat:lower():sub(1,StopText:len()) == StopText then
                    Map = game.ServerStorage:FindFirstChild(Chat.sub(Chat,1+StopText:len()))
                    if Map ~= nil then
                        Clone = game.Workspace:FindFirstChild(Chat.sub(Chat,1+StopText:len()))
                        if Clone ~= nil then
                            Clone:remove()
                        end
                    end
                end
            end
        end
    end)
end)
0
please use Destroy() and not remove() unmiss 337 — 8y
0
why? KoreanBBQ 301 — 8y

1 answer

Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
8 years ago

Improving Organization / Cleanup

  • It's a bad sign that you are indented 9 levels deep.
  • It's awful that you're using string methods using .. You can use # instead of :len().
  • You should use local variables for variables inside functions -- this actually matters a lot.
  • There's no reason to say ~= nil.
  • You should use :Remove() instead of :remove(), but anyway :Destroy() instead of :Remove().
  • You can use workspace instead of game.Workspace.

Applying these changes, we get this:

Permission = {"PLAYER","PLAYER2","PLAYER3"} -- Players who can run/stop the maps.
RunText = "r2/" -- Text the Players have to say to run the maps. (MAP NAME AFTER)
StopText = "cl2/" -- Text the Players have to say to stop the maps. (MAP NAME AFTER)

function speak(Chat)
    if Chat:lower():sub(1, #RunText) == RunText then
        local Map = game.ServerStorage:FindFirstChild(Chat:sub(1+#RunText))
        if Map then
            for _, v in pairs(game.ServerStorage:GetChildren()) do
                if v:IsA("Model") then
                    if workspace:FindFirstChild(v.Name) then
                        workspace:FindFirstChild(v.Name):Destroy()
                    end
                end
            end
            Map:Clone().Parent = workspace
        end
    end
    if Chat:lower():sub(1, #StopText) == StopText then
        local Map = game.ServerStorage:FindFirstChild(Chat:sub(1+#StopText))
        if Map then
            local Clone = workspace:FindFirstChild(Chat:sub(1+#StopText))
            if Clone then
                Clone:Destroy()
            end
        end
    end
end

game.Players.ChildAdded:connect(function(Player)
    for _, authedName in pairs(Permission) do
        if authedName:lower() == Player.Name:lower() then
            Player.Chatted:connect(speak)
        end
    end
end)

Simplifying String Stuffs

There's a lot of repetition going on. Let's observe that we are processing messages in this way:

  • Does it start with x?
    • Then I need to use the remainder of the string.

Let's make a function that deals with that, then:

function afterPrefix(text, pre)
    if text:sub(1, #pre) == pre then
        return text:sub(#pre + 1)
    end
end

We can use afterPrefix to simplify the rest of the speak function. We should also probably break the speak up into different functions, one for each command -- since the commands have no overlap, it simplifies understanding.

function runCommand(cmd)
    local Map = game.ServerStorage:FindFirstChild(cmd)
    if Map then
        for _, v in pairs(game.ServerStorage:GetChildren()) do
            if v:IsA("Model") then
                if workspace:FindFirstChild(v.Name) then
                    workspace:FindFirstChild(v.Name):Destroy()
                end
            end
        end
        Map:Clone().Parent = workspace
    end
end

function stopCommand(cmd)
    local Map = game.ServerStorage:FindFirstChild(cmd)
    if Map then
        local Clone = workspace:FindFirstChild(cmd)
        if Clone then
            Clone:Destroy()
        end
    end
end

function speak(Chat)
    local run = afterPrefix(Chat:lower(), RunText)
    if run then
        runCommand(run)
    end
    local stop = afterPrefix(Chat:lower(), StopText)
    if stop then
        stopCommand(stop)
    end
end

Question

runCommand very obviously deletes all of the current maps. Instead, we should just delete the current map. Instead of repeating ourselves, we can just invoke stopCommand.


function runCommand(cmd) stopCommand(cmd) local Map = game.ServerStorage:FindFirstChild(cmd) if Map then Map:Clone().Parent = workspace end end
Ad

Answer this question