Super-Nostalgia-Zone/Server/Scripts/BuildTools/init.server.lua

243 lines
5.2 KiB
Lua

local CollectionService = game:GetService("CollectionService")
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local loadBuildTools = ServerStorage:FindFirstChild("LoadBuildTools")
if not (loadBuildTools and loadBuildTools.Value) then
return
end
local looseBranches = ServerStorage:FindFirstChild("LooseBranches")
if looseBranches and looseBranches:IsA("BoolValue") then
looseBranches = looseBranches.Value
else
looseBranches = false
end
local toolList = loadBuildTools.Value
if toolList == true then -- If it's a BoolValue, load all of them.
toolList = "GameTool;Clone;Delete"
end
local DraggerService = Instance.new("Folder")
DraggerService.Name = "DraggerService"
DraggerService.Parent = ReplicatedStorage
local draggerGateway = Instance.new("RemoteFunction")
draggerGateway.Name = "DraggerGateway"
draggerGateway.Parent = DraggerService
local submitUpdate = Instance.new("RemoteEvent")
submitUpdate.Name = "SubmitUpdate"
submitUpdate.Parent = DraggerService
local draggerScript = script:WaitForChild("Dragger")
local activeKeys = {}
local debounce = {}
local weakTable = { __mode = 'k' }
local playerToKey = setmetatable({}, weakTable)
local partToKey = setmetatable({}, weakTable)
local SIMULATE_TAG = "SimulateAfterDrag"
local NO_BREAK_TAG = "GorillaGlue"
local function assertClass(obj, class)
assert(obj)
assert(typeof(obj) == "Instance")
assert(obj:IsA(class))
end
local function canGiveKey(player, part)
if part.Locked then
return false
end
local playerHasKey = playerToKey[player]
local partHasKey = partToKey[part]
if playerHasKey or partHasKey then
return false
end
return true
end
local function claimAssembly(player, part)
if part:CanSetNetworkOwnership() then
part:SetNetworkOwner(player)
end
end
local function removePartKey(key)
local data = activeKeys[key]
if data then
local player = data.Player
local part = data.Part
if player then
playerToKey[player] = nil
end
if part then
part:MakeJoints()
part.Anchored = data.Anchored
claimAssembly(player, part)
partToKey[part] = nil
end
activeKeys[key] = nil
end
end
function draggerGateway.OnServerInvoke(player, request, ...)
if request == "GetKey" then
local part, asClone = ...
assertClass(part, "BasePart")
if asClone then
local newPart = part:Clone()
newPart.Parent = workspace
newPart:BreakJoints()
newPart.CFrame = CFrame.new(part.Position + Vector3.new(0, part.Size.Y, 0))
local copySound = Instance.new("Sound")
copySound.SoundId = "rbxasset://sounds/electronicpingshort.wav"
copySound.PlayOnRemove = true
copySound.Parent = newPart
wait()
part = newPart
copySound:Destroy()
end
if canGiveKey(player, part) then
local key = HttpService:GenerateGUID(false)
claimAssembly(player, part)
playerToKey[player] = key
partToKey[part] = key
local anchored = part.Anchored
part.Anchored = true
part:BreakJoints()
activeKeys[key] =
{
Player = player;
Part = part;
Anchored = anchored;
}
return true, key, part
else
return false
end
elseif request == "ClearKey" then
local key = ...
if not key then
key = playerToKey[player]
end
if key then
local data = activeKeys[key]
if data then
local owner = data.Player
if player == owner then
removePartKey(key)
end
end
end
elseif request == "RequestDelete" then
if not debounce[player] then
local part = ...
assertClass(part, "BasePart")
debounce[player] = true
if canGiveKey(player, part) then
local e = Instance.new("Explosion")
e.BlastPressure = 0
e.Position = part.Position
e.Parent = workspace
local s = Instance.new("Sound")
s.SoundId = "rbxasset://sounds/collide.wav"
s.Volume = 1
s.PlayOnRemove = true
s.Parent = part
part:Destroy()
end
wait(.1)
debounce[player] = nil
end
end
end
local function onChildAdded(child)
if child:IsA("Backpack") then
for draggerTool in toolList:gmatch("[^;]+") do
local tool = Instance.new("Tool")
tool.Name = draggerTool
tool.RequiresHandle = false
tool.CanBeDropped = false
local newDragger = draggerScript:Clone()
newDragger.Parent = tool
newDragger.Disabled = false
tool.Parent = child
end
end
end
local function onPlayerAdded(player)
for _, v in pairs(player:GetChildren()) do
onChildAdded(v)
end
player.ChildAdded:Connect(onChildAdded)
end
local function onPlayerRemoved(player)
local key = playerToKey[player]
if key then
removePartKey(key)
end
end
local function onSubmitUpdate(player, key, cframe)
local keyData = activeKeys[key]
if keyData then
local owner = keyData.Player
if owner == player then
local part = keyData.Part
if part and part:IsDescendantOf(workspace) then
part:BreakJoints()
part.CFrame = cframe
end
end
end
end
for _, player in pairs(game.Players:GetPlayers()) do
onPlayerAdded(player)
end
submitUpdate.OnServerEvent:Connect(onSubmitUpdate)
Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoving:Connect(onPlayerRemoved)