Skip to content

Instantly share code, notes, and snippets.

@RiRi-380
Created August 17, 2024 10:48
Show Gist options
  • Save RiRi-380/a74327cc992af327abb1c0dfb4c55150 to your computer and use it in GitHub Desktop.
Save RiRi-380/a74327cc992af327abb1c0dfb4c55150 to your computer and use it in GitHub Desktop.
TOOL.Category = "Construction"
TOOL.Name = "Smart Door Master"
TOOL.ClientConVar = {
["key"] = "0",
["use_timer"] = "0",
["timer"] = "0"
}
if CLIENT then
language.Add("tool.smart_door_master.name", "Smart Door Master")
language.Add("tool.smart_door_master.desc", "Control doors with a trigger key")
language.Add("tool.smart_door_master.0", "Left click: Add door to control, Right click: Remove door from control")
CreateClientConVar("smart_door_master_key", "0", true, true)
CreateClientConVar("smart_door_master_use_timer", "0", true, true)
CreateClientConVar("smart_door_master_timer", "0", true, true)
end
SmartDoorMaster = SmartDoorMaster or {}
SmartDoorMaster.Doors = SmartDoorMaster.Doors or {}
local function IsDoor(ent)
return IsValid(ent) and (ent:GetClass() == "prop_door_rotating" or ent:GetClass() == "func_door_rotating")
end
function TOOL:LeftClick(trace)
if CLIENT then return true end
local ply = self:GetOwner()
if not IsValid(ply) then return false end
local ent = trace.Entity
if not IsDoor(ent) then
self:Notify(ply, "Not a valid door", NOTIFY_ERROR)
return false
end
if not table.HasValue(SmartDoorMaster.Doors, ent) then
table.insert(SmartDoorMaster.Doors, ent)
self:SyncDoors()
self:Notify(ply, "Door added to control", NOTIFY_GENERIC)
else
self:Notify(ply, "Door already controlled", NOTIFY_ERROR)
end
return true
end
function TOOL:RightClick(trace)
if CLIENT then return true end
local ply = self:GetOwner()
if not IsValid(ply) then return false end
local ent = trace.Entity
if not IsDoor(ent) then return false end
for k, v in pairs(SmartDoorMaster.Doors) do
if v == ent then
table.remove(SmartDoorMaster.Doors, k)
self:SyncDoors()
self:Notify(ply, "Door removed from control", NOTIFY_GENERIC)
return true
end
end
self:Notify(ply, "Door not found in control", NOTIFY_ERROR)
return false
end
function TOOL:Notify(ply, message, type)
if SERVER and IsValid(ply) then
net.Start("SmartDoorMaster_Notify")
net.WriteString(message)
net.WriteUInt(type, 3)
net.Send(ply)
end
end
function SmartDoorMaster.ToggleDoor(door)
if not IsValid(door) then return end
door:Fire("Toggle")
end
if SERVER then
util.AddNetworkString("SmartDoorMaster_Notify")
util.AddNetworkString("SmartDoorMaster_SyncDoors")
util.AddNetworkString("SmartDoorMaster_SyncSettings")
function TOOL:SyncDoors()
net.Start("SmartDoorMaster_SyncDoors")
net.WriteTable(SmartDoorMaster.Doors)
net.Broadcast()
end
function TOOL:SyncSettings()
net.Start("SmartDoorMaster_SyncSettings")
net.WriteUInt(self:GetClientNumber("use_timer"), 1)
net.WriteFloat(self:GetClientNumber("timer"))
net.Broadcast()
end
hook.Add("PlayerButtonDown", "SmartDoorMaster_KeyPress", function(ply, button)
local toolKey = ply:GetInfoNum("smart_door_master_key", 0)
if button == toolKey and toolKey ~= 0 then
local useTimer = ply:GetInfoNum("smart_door_master_use_timer", 0) == 1
local timerDelay = useTimer and ply:GetInfoNum("smart_door_master_timer", 0) or 0
for _, door in pairs(SmartDoorMaster.Doors) do
if IsValid(door) then
timer.Simple(timerDelay, function()
if IsValid(door) then
SmartDoorMaster.ToggleDoor(door)
end
end)
end
end
end
end)
end
function TOOL:DrawHUD()
local ply = LocalPlayer()
local trace = ply:GetEyeTrace()
local ent = trace.Entity
if IsDoor(ent) then
local pos = ent:GetPos():ToScreen()
local text = "Door"
if table.HasValue(SmartDoorMaster.Doors, ent) then
text = text .. " (Controlled)"
end
draw.SimpleTextOutlined(text, "HudHintTextLarge", pos.x, pos.y, Color(255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, Color(0,0,0))
end
end
function TOOL.BuildCPanel(panel)
panel:ClearControls()
panel:AddControl("Header", {Description = "Control doors with a trigger key"})
panel:AddControl("Numpad", {
Label = "Trigger Key",
Command = "smart_door_master_key",
ButtonSize = 22
})
local timerCheckbox = panel:AddControl("CheckBox", {
Label = "Use Timer",
Command = "smart_door_master_use_timer"
})
local timerSlider = panel:AddControl("Slider", {
Label = "Timer",
Command = "smart_door_master_timer",
Type = "Float",
Min = 0,
Max = 10
})
local function UpdateTimerSlider()
timerSlider:SetEnabled(GetConVar("smart_door_master_use_timer"):GetBool())
end
timerCheckbox.OnChange = function(_, value)
UpdateTimerSlider()
if SERVER then
TOOL:SyncSettings()
end
end
timerSlider.OnValueChanged = function()
if SERVER then
TOOL:SyncSettings()
end
end
UpdateTimerSlider()
end
if CLIENT then
net.Receive("SmartDoorMaster_Notify", function()
local message = net.ReadString()
local type = net.ReadUInt(3)
notification.AddLegacy(message, type, 3)
end)
net.Receive("SmartDoorMaster_SyncDoors", function()
SmartDoorMaster.Doors = net.ReadTable()
end)
net.Receive("SmartDoorMaster_SyncSettings", function()
local useTimer = net.ReadUInt(1) == 1
local timerValue = net.ReadFloat()
RunConsoleCommand("smart_door_master_use_timer", useTimer and "1" or "0")
RunConsoleCommand("smart_door_master_timer", tostring(timerValue))
end)
hook.Add("HUDPaint", "SmartDoorMaster_DrawHUD", function()
local tool = LocalPlayer():GetTool("smart_door_master")
if tool then
tool:DrawHUD()
end
end)
end
function TOOL:Holster()
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment