so i made 2 module to load food item and melee item.
id like to know what you guys things of them and how they could be improved or change
and if you see anything that could potentially break
the script invoking the module already make sure the tool cant be loaded on double
and it call clear when the player die to reset the module.
--(melee module)
--!strict
--// Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")
--// Remote
local MeleeEvent = ReplicatedStorage:WaitForChild("MeleeEvent")
--// Player
local LocalPlayer = Players.LocalPlayer
local Character = workspace:WaitForChild(LocalPlayer.Name, 5)
local Humanoid = Character and Character:WaitForChild("Humanoid", 5)
local Animator = Humanoid and Humanoid:WaitForChild("Animator") :: Animator
--// Folder
local Client = ReplicatedStorage:WaitForChild("Client")
local Animations = Client:WaitForChild("Animations")
local Sound = Client:WaitForChild("Sound")
--// Tool
local CurrentTool : Tool = nil
local Blade : BasePart = nil
--// Table
local Module = {}
local ToolData: { [string]: { CanDamage: boolean, Debounce: boolean, TouchCon: RBXScriptConnection } } = {}
local SaveAnim: { [string]: AnimationTrack } = {}
local Connections: { RBXScriptConnection } = {}
--// General functions \--
local function LoadAnim(AnimationName)
if not SaveAnim[AnimationName] then
SaveAnim[AnimationName] = Humanoid:LoadAnimation(Animations:FindFirstChild(AnimationName))
end
return SaveAnim[AnimationName]
end
--// Function to handle Blade.Touched event (kept separate)
local function HandleTouch()
local ToolInfo = ToolData[CurrentTool.Name]
ToolInfo.TouchCon = Blade.Touched:Connect(function(Part)
if ToolInfo.CanDamage then
local Model = Part:FindFirstAncestorOfClass("Model")
local Target = Players:GetPlayerFromCharacter(Model)
if Model and Target then
ToolInfo.CanDamage = false
if LocalPlayer.Team ~= Target.Team then
MeleeEvent:FireServer(Target, CurrentTool)
end
elseif CurrentTool.Name == "Hammer" and Part.Parent.Name == "Toilet" and Model then
ToolInfo.CanDamage = false
print("Hit Toilet")
end
end
end)
end
--// Function to handle Attack
local function MeleeAttack(ActionName, InputState, InputObject)
local ToolInfo = CurrentTool and ToolData[CurrentTool.Name]
if InputState == Enum.UserInputState.Begin and not ToolInfo.Debounce then
ToolInfo.Debounce = true
local SlashAnim = LoadAnim(CurrentTool:GetAttribute("Animation"))
SlashAnim:Play()
if SlashAnim then
SlashAnim.KeyframeReached:Connect(function(Keyframe)
if Keyframe == "swing" then
ToolInfo.CanDamage = true
HandleTouch()
end
end)
task.wait(SlashAnim.Length+1)
end
ToolInfo.CanDamage = false
ToolInfo.Debounce = false
end
end
--// Reset function to disconnect all connections
function Module.Reset()
for _, ToolInfo in pairs(ToolData) do
if ToolInfo.TouchCon then
ToolInfo.TouchCon:Disconnect()
end
end
table.clear(Connections)
table.clear(SaveAnim)
table.clear(ToolData)
end
Module.Initialise = function(Tool: Tool)
--// LocalPlayer update
Character = workspace:WaitForChild(LocalPlayer.Name)
Humanoid = Character and Character:WaitForChild("Humanoid") :: Humanoid
Animator = Humanoid and Humanoid:WaitForChild("Animator") :: Animator
local ActionName = Tool.Name.."_Action"
if not ToolData[Tool.Name] then
ToolData[Tool.Name] = {
CanDamage = false,
Debounce = false,
TouchCon = nil,
}
end
Tool.Equipped:Connect(function()
CurrentTool = Tool
Blade = Tool:FindFirstChild("Blade") :: BasePart
ContextActionService:BindAction(ActionName, MeleeAttack, false, Enum.UserInputType.MouseButton1, Enum.KeyCode.ButtonL3)
end)
Tool.Unequipped:Connect(function()
local ToolInfo = ToolData[Tool.Name]
ToolInfo.CanDamage = false
if ToolInfo.TouchCon then
ToolInfo.TouchCon:Disconnect()
end
CurrentTool = nil
Blade = nil
ContextActionService:UnbindAction(ActionName)
end)
end
return Module
\ ------------------------------------------------ /
--!strict
--(food module)
--// Services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ContextActionService = game:GetService("ContextActionService")
local Debris = game:GetService("Debris")
--// Player
local LocalPlayer = Players.LocalPlayer
local Character = LocalPlayer.Character or workspace:WaitForChild(LocalPlayer.Name, 5)
local Humanoid = Character and Character:FindFirstChildOfClass("Humanoid")
local Animator = Humanoid and Humanoid:FindFirstChildOfClass("Animator")
--// Assets
local Client = ReplicatedStorage:WaitForChild("Client")
local Animations = Client:WaitForChild("Animations")
local Sounds = Client:WaitForChild("Sound")
--// Tool
local CurrentTool : Tool = nil
--// Module
local Module = {}
local ToolData: { [string]: { ConsumptionCount: number, Debounce: boolean } } = {}
local SaveAnim: { [string]: AnimationTrack } = {}
local Connections: { RBXScriptConnection } = {}
--// General functions \--
local function LoadAnim(AnimationName: string): AnimationTrack?
if not SaveAnim[AnimationName] and Humanoid then
local AnimObj = Animations:FindFirstChild(AnimationName) :: Animation
if AnimObj then
SaveAnim[AnimationName] = Humanoid:LoadAnimation(AnimObj)
end
end
return SaveAnim[AnimationName]
end
local function PlaySound(Tool: Tool, SoundName: string)
local SoundObj = Sounds:FindFirstChild(SoundName) :: Sound
if SoundObj and Tool:FindFirstChild("Handle") then
local Copy = SoundObj:Clone()
Copy.Parent = Tool.Handle
Copy:Play()
Debris:AddItem(Copy, 2)
end
end
local function ConsumeItem(ActionName: string, InputState: Enum.UserInputState)
local ToolInfo = CurrentTool and ToolData[CurrentTool.Name]
if not ToolInfo or InputState ~= Enum.UserInputState.Begin or ToolInfo.Debounce then return end
ToolInfo.Debounce = true
LoadAnim(CurrentTool:GetAttribute("Animation")):Play()
PlaySound(CurrentTool, CurrentTool:GetAttribute("Sound"))
task.wait(5)
ToolInfo.Debounce = false
ToolInfo.ConsumptionCount += 1
if ToolInfo.ConsumptionCount >= 3 then
CurrentTool:Destroy()
ToolData[ActionName] = nil
end
end
--// Reset function to disconnect all connections
function Module.Reset()
for _, Connection in pairs(Connections) do
Connection:Disconnect()
end
table.clear(Connections)
table.clear(SaveAnim)
table.clear(ToolData)
end
function Module.Initialise(Tool: Tool)
--// LocalPlayer update
Character = workspace:WaitForChild(LocalPlayer.Name)
Humanoid = Character and Character:WaitForChild("Humanoid") :: Humanoid
Animator = Humanoid and Humanoid:WaitForChild("Animator") :: Animator
local ActionName = Tool.Name.."_Action"
ToolData[Tool.Name] = {
ConsumptionCount = 0,
Debounce = false,
}
table.insert(Connections, Tool.Equipped:Connect(function()
CurrentTool = Tool
ContextActionService:BindAction(ActionName, ConsumeItem, false, Enum.UserInputType.MouseButton1, Enum.KeyCode.ButtonL3)
end))
table.insert(Connections, Tool.Unequipped:Connect(function()
CurrentTool = nil
ContextActionService:UnbindAction(ActionName)
end))
end
return Module