It’s supposed to be a relatively simple concept, a /handto script that allows a player to give someone else the tool they’re currently holding, yet somehow it’s almost 200 lines? Did I overcomplicate this, and if so how could I make this better? Performance tips would also be appreciated.
--txciove
local playerService = game:GetService("Players")
local constantsModule = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("constantsModule"))
local foodItemGiverModule = require(game:GetService("ServerScriptService"):WaitForChild("Modules"):WaitForChild("foodItemGiver"))
local serverStorage = game:GetService("ServerStorage")
local textChatService = game:GetService("TextChatService")
local runService = game:GetService("RunService")
local generalChannel = textChatService:WaitForChild("TextChannels"):WaitForChild("RBXGeneral")
local incomingHandToEvent = game:GetService("ReplicatedStorage"):WaitForChild("remoteEvents"):WaitForChild("incomingHandTo")
local handToResponseEvent = game:GetService("ReplicatedStorage"):WaitForChild("remoteEvents"):WaitForChild("handToResponse")
local occuringHandtos = {}
local function canPlayerRunCommand(playerTalking : Player) : boolean -- checks if the player can use the command
if playerTalking:GetRankInGroup(constantsModule.groupId) >= 40 then
print("player is authorized to use command")
return true
end
return true
end
local function isStringValidCommand(stringToCheck : string) : boolean -- checks if the message starts with /handto
local splitString = string.split(stringToCheck," ")
if splitString[1] == "/handto" then
print("string is valid")
return true
else
warn("string is not valid")
return false
end
end
local function returnToolFromName(toolName) -- returns the tool instance from a string
print(toolName)
return serverStorage.foodItems:FindFirstChild(toolName)
end
local function findToolBeingHeld(player : Player) : boolean -- finds the tool being held by a specific player
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if tool and returnToolFromName(tool.Name) then
print("Found tool!")
return tool
else
warn("Couldn't find tool.")
return false
end
end
local function findToolInPlayer(player : Player, toolName : string) -- finds the tool inside the player (backpack or character)
if player.Character:FindFirstChild(toolName) then
return player.Character:FindFirstChild(toolName)
end
if player.Backpack:FindFirstChild(toolName) then
return player.Backpack:FindFirstChild(toolName)
end
return nil
end
local function findPlayer(queryString : string) -- finds a player using a string
if queryString == nil then return end
queryString = string.lower(queryString)
for index, player in playerService:GetPlayers() do
local searchString = string.sub(player.Name, 1, string.len(queryString))
if string.lower(searchString) == queryString then
print("Found player!")
return player
end
searchString = string.sub(player.DisplayName, 1, string.len(queryString))
if string.lower(searchString) == queryString then
print("Found player!")
return player
end
end
return nil
end
local function registerHandto(playerRegistering : Player, playerTarget : Player, Item : string) -- stores information of the handto
print("Registering handout")
table.insert(occuringHandtos, {playerRegistering, playerTarget, Item})
local tool = findToolInPlayer(playerRegistering, Item)
if tool then
tool:Remove()
end
end
local function isPlayerInvovledInHandto(playerToSearchFor) -- looks for a players handto information
for index, information in occuringHandtos do
if information[1] == playerToSearchFor or information[2] == playerToSearchFor then
print("Found relevent handto information!")
return index
end
end
warn("Could not find relevent handto information!")
return nil
end
local function carryOutHandout(index : number) -- executes the handto
print("Carrying out handout")
if occuringHandtos[index][1] ~= nil and occuringHandtos[index][2] ~= nil and returnToolFromName(occuringHandtos[index][3]) then
foodItemGiverModule.giveItem(occuringHandtos[index][2],occuringHandtos[index][3])
end
table.remove(occuringHandtos, index)
end
local function cancelHandout(index : number) -- cancels it
print("Cancelling handout")
if occuringHandtos[index][1] ~= nil and returnToolFromName(occuringHandtos[index][3]) then
foodItemGiverModule.giveItem(occuringHandtos[index][1],occuringHandtos[index][3])
end
table.remove(occuringHandtos, index)
end
playerService.PlayerAdded:Connect(function(player) -- (doesn't work in normal test mode, have to start a local server for it to run)
if canPlayerRunCommand(player) then
player.Chatted:Connect(function(messsage)
if isStringValidCommand(messsage) then
local targetPlayer = findPlayer(string.split(messsage," ")[2])
local tool = findToolBeingHeld(player)
if not tool then return end
if targetPlayer ~= nil and not isPlayerInvovledInHandto(targetPlayer) then
incomingHandToEvent:FireClient(targetPlayer, {player, tool.Name})
registerHandto(player, targetPlayer, tool.Name)
end
end
end)
end
end)
handToResponseEvent.OnServerEvent:Connect(function(playerWhoFired, response) -- handles handto target response
print("response recieved")
if response == true then
local index = isPlayerInvovledInHandto(playerWhoFired)
if index then
carryOutHandout(index)
end
else
local index = isPlayerInvovledInHandto(playerWhoFired)
if index then
cancelHandout(index)
end
end
end)
generalChannel.ShouldDeliverCallback = function(textChatMessage, textSource) -- if the command is a valid /handto command, doesn't display it for users
print(textChatMessage.Text)
if canPlayerRunCommand(playerService:GetPlayerByUserId(textSource.UserId)) and isStringValidCommand(textChatMessage.Text) then
return false
else
return true
end
end