Skip to content

Commit

Permalink
Implemented ToolGun Loading into /entities
Browse files Browse the repository at this point in the history
  • Loading branch information
bleonheart authored Aug 20, 2024
1 parent e297e8d commit c5533c8
Show file tree
Hide file tree
Showing 3 changed files with 258 additions and 22 deletions.
5 changes: 3 additions & 2 deletions config.ld
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ custom_display_name_handler = function(item, default_handler)
return "playerMeta:" .. default_handler(item)
elseif item.module.kind == "inventory meta" then
return "inventoryMeta:" .. default_handler(item)
elseif item.module.kind == "tool meta" then
return "toolGunMeta:" .. default_handler(item)
elseif item.module.kind == "tool meta" then
return "ToolGunMeta:" .. default_handler(item)
end
end
return default_handler(item)
Expand All @@ -77,6 +77,7 @@ new_type("entitymeta", "Entity Meta", true)
new_type("itemmeta", "Item Meta", true)
new_type("playermeta", "Player Meta", true)
new_type("inventorymeta", "Inventory Meta", true)
new_type("toolmeta", "Tool Meta", true)
new_type("configuration", "Configurations", true)
new_type("structures", "Structures", true)
new_type("information", "Information", true)
Expand Down
78 changes: 58 additions & 20 deletions lilia/gamemode/libraries/includer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -252,58 +252,88 @@ end

lia.includeDir("lilia/gamemode/libraries/thirdparty", true, true)
lia.util.includeDir = lia.includeDir
--- Dynamically loads Lua files for entities, weapons, and effects into the server, client, or shared realm of a Garry's Mod Lua project.
-- This function iterates through a specified directory and its subdirectories, including Lua files for entities, weapons, and effects into the appropriate realm.
-- This function also has a legacy alias lia.util.loadEntities that can be used instead of lia.includeEntities.
--- Dynamically loads Lua files for entities, weapons, tools, and effects into the appropriate realm of a Garry's Mod Lua project.
-- This function iterates through a specified directory and its subdirectories, including Lua files for entities, weapons, tools, and effects into the server, client, or shared realm as needed.
-- The function automatically registers the entities, weapons, tools, and effects in the correct context (server, client, or shared).
-- A legacy alias `lia.util.loadEntities` is available, which can be used instead of `lia.includeEntities`.
-- @string path The directory containing the Lua files to be included.
-- @realm shared
function lia.includeEntities(path)
local LoadedTools
local files, folders
local function IncludeFiles(path2, clientOnly)
if (SERVER and file.Exists(path2 .. "init.lua", "LUA")) or (CLIENT and file.Exists(path2 .. "cl_init.lua", "LUA")) then
lia.include(path2 .. "init.lua", clientOnly and "client" or "server")
if SERVER and not clientOnly then
if file.Exists(path2 .. "init.lua", "LUA") then
lia.include(path2 .. "init.lua", "server")
elseif file.Exists(path2 .. "shared.lua", "LUA") then
lia.include(path2 .. "shared.lua", "shared")
end

if file.Exists(path2 .. "cl_init.lua", "LUA") then lia.include(path2 .. "cl_init.lua", "client") end
return true
elseif file.Exists(path2 .. "cl_init.lua", "LUA") then
lia.include(path2 .. "cl_init.lua", "client")
elseif file.Exists(path2 .. "shared.lua", "LUA") then
lia.include(path2 .. "shared.lua", "shared")
return true
end
return false
end

local function HandleEntityInclusion(folder, variable, register, default, clientOnly)
local function HandleEntityInclusion(folder, variable, register, default, clientOnly, create, complete)
files, folders = file.Find(path .. "/" .. folder .. "/*", "LUA")
default = default or {}
for _, v in ipairs(folders) do
local path2 = path .. "/" .. folder .. "/" .. v .. "/"
v = lia.util.stripRealmPrefix(v)
_G[variable] = table.Copy(default)
_G[variable].ClassName = v
if IncludeFiles(path2, clientOnly) then
if clientOnly then
if CLIENT then register(_G[variable], v) end
else
register(_G[variable], v)
end
if not isfunction(create) then
_G[variable].ClassName = v
else
create(v)
end

IncludeFiles(path2, clientOnly)
if clientOnly then
if CLIENT then register(_G[variable], v) end
else
register(_G[variable], v)
end

if isfunction(complete) then complete(_G[variable]) end
_G[variable] = nil
end

for _, v in ipairs(files) do
local niceName = string.StripExtension(v)
local niceName = lia.util.stripRealmPrefix(string.StripExtension(v))
_G[variable] = table.Copy(default)
_G[variable].ClassName = niceName
if not isfunction(create) then
_G[variable].ClassName = niceName
else
create(niceName)
end

lia.include(path .. "/" .. folder .. "/" .. v, clientOnly and "client" or "shared")
if clientOnly then
if CLIENT then register(_G[variable], niceName) end
else
register(_G[variable], niceName)
end

if isfunction(complete) then complete(_G[variable]) end
_G[variable] = nil
end
end

local function RegisterTool(tool, className)
local gmodTool = weapons.GetStored("gmod_tool")
className = lia.util.stripRealmPrefix(className)
if gmodTool then
gmodTool.Tool[className] = tool
else
ErrorNoHalt(string.format("Attempted to register tool '%s' with invalid gmod_tool weapon", className))
end

LoadedTools = true
end

HandleEntityInclusion("entities", "ENT", scripted_ents.Register, {
Type = "anim",
Base = "base_gmodentity",
Expand All @@ -316,11 +346,19 @@ function lia.includeEntities(path)
Base = "weapon_base"
})

HandleEntityInclusion("tools", "TOOL", RegisterTool, {}, false, function(className)
className = lia.util.stripRealmPrefix(className)
TOOL = setmetatable({}, TOOL)
TOOL.Mode = className
TOOL:CreateConVars()
end)

HandleEntityInclusion("effects", "EFFECT", effects and effects.Register, nil, true)
if CLIENT and LoadedTools then RunConsoleCommand("spawnmenu_reload") end
end

lia.util.loadEntities = lia.includeEntities
lia.includeEntities("lilia/gamemode/objects/entities")
lia.includeEntities("lilia/gamemode/entities")
for _, filepath in ipairs(lia.FilesToLoad) do
if filepath.realm == "server" then
lia.include(filepath.path, "server")
Expand All @@ -329,4 +367,4 @@ for _, filepath in ipairs(lia.FilesToLoad) do
elseif filepath.realm == "shared" then
lia.include(filepath.path, "shared")
end
end
end
197 changes: 197 additions & 0 deletions lilia/gamemode/meta/tool.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
--[[--
A custom tool class based on the Base GMOD Toolgun, designed for integration with Lilia's framework.
The `ToolGun` class extends the functionality of the base GMOD toolgun, enabling seamless integration with Lilia's files and configuration. This custom tool class provides a flexible framework for creating and managing interactive tools within Garry's Mod, specifically tailored to work with Lilia's environment and system.
The `ToolGun` class is designed to work in conjunction with Lilia's file system and configuration setup. It allows for the implementation of toolguns that can be dynamically loaded and configured based on Lilia's files, offering a robust solution for extending tool functionalities in a modular way.
### Customization and Flexibility:
The `ToolGun` class provides a foundation for creating custom tools that integrate smoothly with Lilia's system. Developers can extend and modify the class to fit specific needs, leveraging Lilia's configuration files to dictate tool behavior and appearance. This approach ensures that tools can be easily adapted and updated in line with Lilia's framework, providing a consistent and maintainable tool environment.
By integrating with Lilia's files, the `ToolGun` class enables developers to build sophisticated tools that are fully compatible with Lilia's system, enhancing the overall gameplay experience and tool management within Garry's Mod.
]]
-- @toolmeta Framework
local ToolGunMeta = lia.meta.tool or {}

--- Creates a new tool object.
-- This method initializes a new tool object with default properties. It sets up the metatable and various default values such as `Mode`, `SWEP`, `Owner`, `ClientConVar`, `ServerConVar`, `Objects`, `Stage`, `Message`, `LastMessage`, and `AllowedCVar`.
-- @realm shared
-- @return table A new tool object with default properties.
function ToolGunMeta:Create()
local object = {}
setmetatable(object, self)
self.__index = self
object.Mode = nil
object.SWEP = nil
object.Owner = nil
object.ClientConVar = {}
object.ServerConVar = {}
object.Objects = {}
object.Stage = 0
object.Message = "start"
object.LastMessage = 0
object.AllowedCVar = 0
return object
end

--- Creates client and server convars for the tool.
-- This method generates convars (console variables) based on the tool's mode. Client convars are created on the client-side, while server convars are created on the server-side.
-- @realm shared
-- @see CreateClientConVar, CreateConVar
function ToolGunMeta:CreateConVars()
local mode = self:GetMode()
if CLIENT then
for cvar, default in pairs(self.ClientConVar) do
CreateClientConVar(mode .. "_" .. cvar, default, true, true)
end
return
else
self.AllowedCVar = CreateConVar("toolmode_allow_" .. mode, 1, FCVAR_NOTIFY)
end
end

--- Retrieves server-side information for a given property.
-- This method returns the value of a server-side convar associated with the tool's mode.
-- @realm shared
-- @string property The name of the property to retrieve.
-- @return string The value of the server convar.
function ToolGunMeta:GetServerInfo(property)
local mode = self:GetMode()
return ConVar(mode .. "_" .. property)
end

--- Builds a list of client-side convars.
-- This method constructs a table of convars by appending the mode prefix to each convar name.
-- @realm shared
-- @return table A table containing the mode-prefixed convars.
function ToolGunMeta:BuildConVarList()
local mode = self:GetMode()
local convars = {}
for k, v in pairs(self.ClientConVar) do
convars[mode .. "_" .. k] = v
end
return convars
end

--- Retrieves client-side information for a given property.
-- This method returns the value of a client-side convar associated with the tool's mode.
-- @realm shared
-- @string property The name of the property to retrieve.
-- @return string The value of the client convar.
function ToolGunMeta:GetClientInfo(property)
return self:GetOwner():GetInfo(self:GetMode() .. "_" .. property)
end

--- Retrieves a numerical value from client-side convars.
-- This method returns the value of a client-side convar as a number, or a default value if the convar does not exist.
-- @realm shared
-- @string property The name of the property to retrieve.
-- @number default The default value to return if the convar is not found.
-- @return number The numerical value of the client convar.
function ToolGunMeta:GetClientNumber(property, default)
return self:GetOwner():GetInfoNum(self:GetMode() .. "_" .. property, tonumber(default) or 0)
end

--- Checks if the tool is allowed on the server.
-- This method returns whether the tool is allowed based on the server convar `AllowedCVar`. It always returns true on the client-side.
-- @realm shared
-- @return boolean True if the tool is allowed, false otherwise.
function ToolGunMeta:Allowed()
if CLIENT then return true end
return self.AllowedCVar:GetBool()
end

--- Placeholder for initializing the tool.
-- This method is intended to be overridden if initialization logic is needed when the tool is created.
-- @realm shared
function ToolGunMeta:Init()
end

--- Retrieves the mode of the tool.
-- This method returns the current mode of the tool, which is a string representing the specific operation the tool is set to perform.
-- @realm shared
-- @return string The current mode of the tool.
function ToolGunMeta:GetMode()
return self.Mode
end

--- Retrieves the SWEP (Scripted Weapon) associated with the tool.
-- This method returns the SWEP object, which is typically the weapon the player is holding while using the tool.
-- @realm shared
-- @return SWEP The SWEP object associated with the tool.
function ToolGunMeta:GetSWEP()
return self.SWEP
end

--- Retrieves the owner of the tool.
-- This method returns the player who owns the tool by accessing the SWEP's `Owner` property.
-- @realm shared
-- @return Player The player who owns the tool.
function ToolGunMeta:GetOwner()
return self:GetSWEP().Owner or self:GetOwner()
end

--- Retrieves the weapon associated with the tool.
-- This method returns the weapon associated with the tool by accessing the SWEP's `Weapon` property or the tool's own `Weapon` property.
-- @realm shared
-- @return Weapon The weapon object associated with the tool.
function ToolGunMeta:GetWeapon()
return self:GetSWEP().Weapon or self.Weapon
end

--- Handles the left-click action with the tool.
-- This method is intended to be overridden to define what happens when the player left-clicks with the tool. By default, it does nothing and returns false.
-- @realm shared
-- @return boolean False by default, indicating no action was taken.
function ToolGunMeta:LeftClick()
return false
end

--- Handles the right-click action with the tool.
-- This method is intended to be overridden to define what happens when the player right-clicks with the tool. By default, it does nothing and returns false.
-- @realm shared
-- @return boolean False by default, indicating no action was taken.
function ToolGunMeta:RightClick()
return false
end

--- Handles the reload action with the tool.
-- This method clears the objects that the tool is currently manipulating when the player reloads with the tool.
-- @realm shared
function ToolGunMeta:Reload()
self:ClearObjects()
end

--- Deploys the tool.
-- This method is called when the player equips the tool. It releases any ghost entities associated with the tool.
-- @realm shared
function ToolGunMeta:Deploy()
self:ReleaseGhostEntity()
return
end

--- Holsters the tool.
-- This method is called when the player unequips the tool. It releases any ghost entities associated with the tool.
-- @realm shared
function ToolGunMeta:Holster()
self:ReleaseGhostEntity()
return
end

--- Handles the tool's "think" logic.
-- This method is called periodically to perform updates. By default, it releases any ghost entities associated with the tool.
-- @realm shared
function ToolGunMeta:Think()
self:ReleaseGhostEntity()
end

--- Checks the validity of objects the tool is manipulating.
-- This method iterates over the tool's objects and clears them if they are no longer valid, such as if the entity is no longer part of the world or is invalid.
-- @realm shared
function ToolGunMeta:CheckObjects()
for _, v in pairs(self.Objects) do
if not v.Ent:IsWorld() and not v.Ent:IsValid() then self:ClearObjects() end
end
end

lia.meta.tool = ToolGunMeta

0 comments on commit c5533c8

Please sign in to comment.