dobrograd-13-06-2022/garrysmod/addons/feature-wire/lua/entities/gmod_wire_textentry.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

273 lines
7.1 KiB
Lua

-- Author: mitterdoo (with help from Divran)
AddCSLuaFile()
DEFINE_BASECLASS( "base_wire_entity" )
ENT.PrintName = "Text Entry (Wire)"
ENT.WireDebugName = "Text Entry"
function ENT:SetupDataTables()
self:NetworkVar("Float",0,"Hold")
self:NetworkVar("Bool",0,"DisableUse")
end
if CLIENT then
local panel
----------------------------------------------------
-- Show the prompt
----------------------------------------------------
net.Receive("wire_textentry_show",function()
local self=net.ReadEntity()
if !IsValid(self) then return end
panel = Derma_StringRequest(
"Wire Text Entry",
"Enter text below",
"",
function(text)
net.Start("wire_textentry_action")
net.WriteEntity(self)
net.WriteBool(true)
net.WriteString(text)
net.SendToServer()
end,
function()
net.Start("wire_textentry_action")
net.WriteEntity(self)
net.WriteBool(false)
net.WriteString("")
net.SendToServer()
end,
"Enter","Cancel"
)
end)
net.Receive( "wire_textentry_kick", function()
if IsValid( panel ) then
panel:Remove()
end
end)
return
end
----------------------------------------------------
-- UpdateOverlay
----------------------------------------------------
function ENT:UpdateOverlay()
local hold = math.Round(math.max(self:GetHold(),0),1)
local txt = "Hold Length: " .. (hold > 0 and hold or "Forever")
if self.BlockInput then
txt = txt.."\nBlocking Input"
elseif IsValid(self.User) then
txt = txt.."\nIn use by: " .. self.User:Nick()
end
if self:GetDisableUse() then
txt = txt .. "\nUse disabled"
end
self:SetOverlayText(txt)
end
----------------------------------------------------
-- Initialize
----------------------------------------------------
function ENT:Initialize()
self:PhysicsInit(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.Inputs=WireLib.CreateInputs(self,{"Block Input","Prompt"})
self.Outputs=WireLib.CreateOutputs(self,{"In Use","Text [STRING]","User [ENTITY]"})
self.BlockInput=false
self.NextPrompt = 0
self:UpdateOverlay()
end
----------------------------------------------------
-- Vehicle linking
----------------------------------------------------
function ENT:TriggerInput(name,value)
if name == "Block Input" then
self.BlockInput = value~=0
self:UpdateOverlay()
if IsValid( self.User ) then self:Unprompt( true ) end
elseif name == "Prompt" then
if value ~= 0 then self:Prompt() end
end
end
----------------------------------------------------
-- Vehicle linking
----------------------------------------------------
function ENT:UnlinkEnt(ent)
if not IsValid( ent ) then return false, "Invalid entity specified" end
if IsValid(self.Vehicle) then
self.Vehicle:RemoveCallOnRemove( "wire_textentry_onremove" )
self.Vehicle.WireTextEntry = nil
end
self.Vehicle = nil
WireLib.SendMarks( self, {} )
return true
end
function ENT:LinkEnt(ent)
if not IsValid( ent ) then return false, "Invalid entity specified" end
if not ent:IsVehicle() then return false, "Entity must be a vehicle" end
if IsValid( self.Vehicle ) then -- remove old callback
self.Vehicle:RemoveCallOnRemove( "wire_textentry_onremove" )
self.Vehicle.WireTextEntry = nil
end
self.Vehicle = ent
self.Vehicle.WireTextEntry = self
-- add new callback
self.Vehicle:CallOnRemove( "wire_textentry_onremove", function()
self:UnlinkEnt( ent )
end)
WireLib.SendMarks( self, { ent } )
return true
end
function ENT:ClearEntities()
self:UnlinkEnt(self.Vehicle)
end
function ENT:OnRemove()
if IsValid( self.Vehicle ) then -- remove callback
self.Vehicle:RemoveCallOnRemove( "wire_textentry_onremove" )
self.Vehicle.WireTextEntry = nil
end
self:Unprompt( true )
end
----------------------------------------------------
-- Receiving text from client
----------------------------------------------------
util.AddNetworkString("wire_textentry_action")
net.Receive("wire_textentry_action",function(len,ply)
local self=net.ReadEntity()
if not IsValid( self ) or not IsValid( ply ) or ply ~= self.User then return end
local ok = net.ReadBool()
local text = net.ReadString()
self:Unprompt() -- in all cases, make text entry available for use again
if ok and not self.BlockInput then
WireLib.TriggerOutput( self, "Text", text )
local timername = "wire_textentry_" .. self:EntIndex()
timer.Remove( timername )
if math.max(self:GetHold(),0) > 0 then
timer.Create( timername, math.max(self:GetHold(),0), 1, function()
if IsValid( self ) then
WireLib.TriggerOutput( self, "User", nil )
WireLib.TriggerOutput( self, "Text", "" )
end
end)
end
end
self:UpdateOverlay()
end)
----------------------------------------------------
-- Prompt
-- Sends prompt to user etc
----------------------------------------------------
util.AddNetworkString("wire_textentry_show")
function ENT:Prompt( ply )
if ply then
if CurTime() < self.NextPrompt then return end -- anti spam
self.NextPrompt = CurTime() + 0.1
if self.BlockInput or IsValid( self.User ) then
WireLib.AddNotify(ply,"That text entry is not accepting input right now!",NOTIFY_ERROR,5,6)
return
end
self.User = ply
WireLib.TriggerOutput( self, "User", ply )
WireLib.TriggerOutput( self, "In Use", 1 )
local timername = "wire_textentry_" .. self:EntIndex()
timer.Remove( timername )
net.Start( "wire_textentry_show" )
net.WriteEntity( self )
net.Send( ply )
self:UpdateOverlay()
elseif IsValid( self.Vehicle ) and IsValid( self.Vehicle:GetDriver() ) then -- linked
self:Prompt( self.Vehicle:GetDriver() ) -- prompt for driver
else -- not linked
self:Prompt( self:GetPlayer() ) -- prompt for owner
end
end
----------------------------------------------------
-- Unprompt
-- Unsets user, making the text entry usable by other users
----------------------------------------------------
util.AddNetworkString("wire_textentry_kick")
function ENT:Unprompt( kickuser )
if IsValid( self.User ) and kickuser then
net.Start( "wire_textentry_kick" ) net.Send( self.User )
end
local timername = "wire_textentry_" .. self:EntIndex()
timer.Remove( timername )
self.User = nil
WireLib.TriggerOutput( self, "In Use", 0 )
self:UpdateOverlay()
end
----------------------------------------------------
-- PlayerLeaveVehicle
----------------------------------------------------
hook.Add( "PlayerLeaveVehicle", "wire_textentry_leave_vehicle", function( ply, vehicle )
if vehicle.WireTextEntry and IsValid( vehicle.WireTextEntry ) and
IsValid( vehicle.WireTextEntry.User ) and vehicle.WireTextEntry.User == ply then
vehicle.WireTextEntry:Unprompt( true )
end
end)
----------------------------------------------------
-- Use
----------------------------------------------------
function ENT:Use(ply)
if self:GetDisableUse() or not IsValid( ply ) then return end
self:Prompt( ply )
end
----------------------------------------------------
-- Setup
----------------------------------------------------
function ENT:Setup(hold,disableuse)
hold = tonumber(hold)
if hold then
self:SetHold( math.max( hold, 0 ) )
end
disableuse = tobool(disableuse)
if disableuse ~= nil then
self:SetDisableUse( disableuse )
end
self:UpdateOverlay()
end
duplicator.RegisterEntityClass("gmod_wire_textentry",WireLib.MakeWireEnt,"Data")