273 lines
7.1 KiB
Lua
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")
|