Skip to content

Instantly share code, notes, and snippets.

@SigmaThetaTech
Last active May 17, 2023 21:17
Show Gist options
  • Save SigmaThetaTech/d3aa43f5f2b2670c520150d1c295b0da to your computer and use it in GitHub Desktop.
Save SigmaThetaTech/d3aa43f5f2b2670c520150d1c295b0da to your computer and use it in GitHub Desktop.
--!strict
--October 07, 2022
-- By SigmaTech
--[[
BaseTool.lua
To provide a basic code foundation for all the tools in the game
Tools will inherit this base tool and add functionality on top of it.
[API]
Equip: (BaseTool, player: Player) -> ();
Unequip: (BaseTool, ) -> ();
Activate: (BaseTool, ) -> ();
Deactivate: (BaseTool, ) -> ();
GetModelTemplate: (BaseTool, ) -> (Model);
IsEquipped: (BaseTool, ) -> (boolean);
Destroy: (BaseTool, ) -> ();
--]]
--// Services //--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--// References //--
local Packages = ReplicatedStorage.Packages
local Shared = ReplicatedStorage.Source.Shared
--// Requires //--
local Knit = require(Packages.Knit)
local Types = require(Shared.Core.Types)
local Constants = require(Shared.Core.Constants)
local CustomEnums = require(Shared.Core.CustomEnums)
--// Types //--
--// Constants //--
--// Volatiles //--
--// Setup Code //--
--------------------------------------------------------------------------------
--// Class Declaration //--
--------------------------------------------------------------------------------
--// Required Packages //--
local BaseObject = require(Shared.Core.BaseObject)
local Signal = require(Packages.Signal)
local ParentClass = BaseObject -- Change this to the parent class
--// Class Type Declarations //--
export type BaseTool = {
ClassName: "BaseTool",
Events: {
};
} & ParentClass.BaseTool
--// Class Setup //--
local BaseTool = setmetatable({}, ParentClass)
BaseTool.ClassName = "BaseTool"
BaseTool.__index = BaseTool
--------------------------------------------------------------------------------
--// Private Functions //--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--// Class Constructor/Deconstructor //--
--------------------------------------------------------------------------------
--[[
The constructor for a BaseTool Object.
@return BaseTool
--]]
function BaseTool.new(accessory: Accessory): BaseTool
local self: BaseTool = setmetatable(ParentClass.new(), BaseTool)
self:RegisterEvent("Activated")
self:RegisterEvent("Deactivated")
self:RegisterEvent("Equipped")
self:RegisterEvent("Unequipped")
self:RegisterEvent("Pickup")
self:RegisterEvent("Drop")
self._CurrentPlayer = nil
self._IsEquipped = false
self._CanPickup = true
self._CanDrop = true
if accessory then
self.Name = accessory.Name
self._Accessory = accessory
self._Handle = accessory:FindFirstChild("Handle")
else
warn("Created a BaseTool object without a physical accessory")
end
self:_Initialize()
print(self)
return self
end
--[[ Pickup: (BaseTool, ) -> ();
A description of why this method exists, what it does, and how to use it.
--]]
function BaseTool:Pickup(player: Player): ()
-- Claim ownership
self._CurrentPlayer = player
-- Add tool to backpack
local CustomPlayerService = Knit.GetService("CustomPlayerService")
CustomPlayerService:GetCustomPlayer(player):andThen(function(customPlayer)
customPlayer:GetBackpack():AddTool(self)
end)
-- Fire event
self.Events.Pickup:Fire(player)
self:Equip()
end
--[[ Drop: (BaseTool, ) -> ();
A description of why this method exists, what it does, and how to use it.
--]]
function BaseTool:Drop(): ()
-- Relinquish ownership
local previousOwner = self._CurrentPlayer
self._CurrentPlayer = nil
-- Remove tool from backpack
local CustomPlayerService = Knit.GetService("CustomPlayerService")
CustomPlayerService:GetCustomPlayer(previousOwner)
:andThen(function(customPlayer)
customPlayer:GetBackpack():RemoveTool(self)
end)
-- Fire event
self.Events.Drop:Fire()
self:Unequip()
end
--[[
Equips the tool to the player's humanoid
@param player: Player
--]]
function BaseTool:Equip(player: Player): ()
local player = player or self._CurrentPlayer
-- Attach the tool to the player's humanoid
local PlayerConnectionService = Knit.GetService("PlayerConnectionService")
PlayerConnectionService:GetCharacter(player)
:andThen(function(character)
local humanoid = character:FindFirstChild("Humanoid")
if humanoid then
-- Attach the tool to the player's humanoid
humanoid:AddAccessory(self._Accessory)
end
end)
self.IsEquipped = true
self.Events.Equipped:Fire(player)
end
--[[
Unequips / destroys the tool
--]]
function BaseTool:Unequip(): ()
warn("Unequip not implemented")
self.IsEquipped = false
self.Events.Unequipped:Fire()
end
--[[
Call activate on tool object
--]]
function BaseTool:Activate(): ()
self.Events.Activated:Fire()
end
--[[
Call deactivate on tool object
--]]
function BaseTool:Deactivate(): ()
self.Events.Deactivated:Fire()
end
--[[
Returns the model template for the tool
@return Model
--]]
function BaseTool:GetModelTemplate(): (Model)
return self._Instance
end
--[[
Returns whether the tool is equipped or not
@return boolean
--]]
function BaseTool:IsEquipped(): (boolean)
return self._IsEquipped
end
--[[
The Deconstructor for a BaseTool Object.
--]]
function BaseTool:Destroy()
ParentClass.Destroy(self)
end
--------------------------------------------------------------------------------
--// Getters //--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--// Setters //--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--// Methods //--
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--// Initialization //--
--------------------------------------------------------------------------------
--[[
The Initialization method is called once an BaseTool Object
has reached the end of its constructor.
--]]
function BaseTool:_Initialize()
print("'BaseTool' Object Initialized!")
local function disconnectTouch()
if self._handleTouchConnection then
self._handleTouchConnection:Disconnect()
end
end
local function connectTouch()
if not self._Handle then return end -- If the tool doesn't have a handle, don't connect the touch event
local isProcessingTouch = false
self._handleTouchConnection = self._Handle.Touched:Connect(function(hit)
-- Debounce
if isProcessingTouch then return end
isProcessingTouch = true
-- Check if can pick up
if self._CanPickup then
-- Check if hit is a player
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
-- Pick up tool
self:Pickup(player)
-- Disconnect touch event
disconnectTouch()
end
end
isProcessingTouch = false
end)
end
self.Events.Drop:Connect(function()
-- Connect touch event
connectTouch()
end)
self.Events.Pickup:Connect(function()
-- Disconnect touch event
disconnectTouch()
end)
-- Connect touch event
connectTouch()
end
return BaseTool
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment