AddCSLuaFile( "cl_init.lua" ) AddCSLuaFile( "shared.lua" ) include('shared.lua') ENT.WireDebugName = "TextReceiver" local MODEL = Model("models/jaanus/wiretool/wiretool_range.mdl") function ENT:Initialize() self.Entity:SetModel( MODEL ) self.Entity:PhysicsInit( SOLID_VPHYSICS ) self.Entity:SetMoveType( MOVETYPE_VPHYSICS ) self.Entity:SetSolid( SOLID_VPHYSICS ) Add_TextReceiver(self.Entity) self.Outputs = Wire_CreateOutputs(self.Entity, { "Error" }) end function ENT:Setup( liness, globall,OutputTextt,Holdd,Triggerr,SELFF,sensitivityy,togglee,utriggerr,parsetextt,secure,playerout) self.global = globall self.Hold = Holdd or 0.1 self.Trig = Triggerr or 1 self.Toggle = togglee self.UTrig = utriggerr or 0 self.Bytes = {} self.values = {} self.lines = {} self.CLines = {} self.CLines = table.Copy(liness) //Makes getting the lines easier self.Iself = SELFF self.char1 = string.Left(parsetextt,1) or '"' self.char2 = string.Right(parsetextt,1) or '"' self.Sensitivity = sensitivityy or 4 self.OutputText = OutputTextt or "" self.secure = secure self.playerout = playerout local onames = {} local i = 1 for k,o in pairs(liness) do self.lines[i] = {} self.lines[i].args = {} self.lines[i].line, self.lines[i].args,self.lines[i].toggle,self.lines[i].global,self.lines[i].on,self.lines[i].off,self.lines[i].Allow,self.lines[i].Deny,self.lines[i].TAllow,self.lines[i].TDeny, self.lines[i].Radius = self:SParseTextAndArgs(o,"<",">",0) self.lines[i].argsC = nil table.insert(onames, self.lines[i].line) for k2,o2 in pairs(self.lines[i].args) do o2.V = 0 table.insert(onames, o2.A) self.lines[i].argsC = true end self.lines[i].value = self.lines[i].off or self.UTrig self.lines[i].reset = 0 i = i + 1 end if (playerout == true) then table.insert(onames,"X") table.insert(onames,"Y") table.insert(onames,"Z") table.insert(onames,"EntId") end Wire_AdjustOutputs(self.Entity, onames) self.changed = false self.Bytes[1] = self.UTrig self.Bytes[2] = self.Trig self.Bytes[3] = self.Hold self.Bytes[4] = string.byte(self.char1) or 0 self.Bytes[5] = string.byte(self.char2) or 0 self.Bytes[6] = self.global self.Bytes[7] = self.Toggle self.Bytes[8] = self.OutputText self.Bytes[9] = self.Iself self.Bytes[10] = self.secure self.Bytes[11] = self.playerout self.Bytes[12] = self.Sensitivity self.Bytes[13] = 0 self.Bytes[14] = table.Count(self.CLines) local q = 15 for k,v in pairs(self.CLines) do self.Bytes[tonumber(q)] = #v for i = 1,#v do //String to table :P self.Bytes[tonumber(q + i)] = tonumber(string.byte(string.sub(v,i,i)) or 0) or 0 end q = q + #v end self:TriggerOutput() end function ENT:ParsePar(text) local y = string.find(text,"(",0,true) if (y == nil) then return nil end local z = string.find(text,")",y + 1,true) if (z == nil) then return nil end return tonumber(string.sub(text,y + 1, z - 1)) end function ENT:ParseFPar(text) local allow,deny = {},{} local p = string.find(text,"(",0,true) if (p == nil) then return {} end local n = string.find(text,")",p + 1,true) if (n == nil) then return {} end local args = string.Explode(",",string.sub(text,p + 1, n - 1)) for k,o in pairs(args) do if (o != nil) then if (string.sub(o,1,1)=="~") then table.insert(deny,string.sub(o,2)) else table.insert(allow,o) end end end return allow,deny end function ENT:SParseTextAndArgs(line,char1,char2,remov) if !(string.find(line,char1) && string.find(line,char2)) then return string.Trim(line),{nil} end local ret = {} local ret2 = string.Trim(string.sub(line,1,string.find(line,char1) - 1)) local p = string.find(line,char1) local n = 1 local i = 1 local toggle = false local global = false local on = nil local off = nil local allow = {} local deny = {} local tallow = {} local tdeny = {} local curarg = nil local radius = nil while(p) do n = string.find(line,char2,p + 1) curarg = string.sub(line,p + 1,n - 1) if (curarg == "t()") then toggle = true elseif (curarg == "g()") then global = true elseif (curarg == "") then elseif (string.sub(curarg,1,3) == "on(") then on = self:ParsePar(curarg) elseif (string.sub(curarg,1,4) == "off(") then off = self:ParsePar(curarg) elseif (string.sub(curarg,1,2) == "f(") then allow,deny = self:ParseFPar(curarg) elseif (string.sub(curarg,1,3) == "tf(") then tallow,tdeny = self:ParseFPar(curarg) elseif (string.sub(curarg,1,2) == "r(") then radius = self:ParsePar(curarg) elseif (string.sub(curarg,1,1) == "~") then ret[i] = {} ret[i].A = char1 .. (string.sub(line,p + 2 + remov,n - remov) or "") ret[i].V = 0 ret[i].R = true i = i + 1 else ret[i] = {} ret[i].A = string.sub(line,p + remov,n - remov) ret[i].V = 0 ret[i].R = false i = i + 1 end p = string.find(line,char1,n + 1) end return ret2,ret,toggle,global,on,off,allow,deny,tallow,tdeny,radius end //yay for while loops and Trim :D function ENT:ParseTextAndArgs(line,char1,char2,remov) if (line == nil) then return "",{} end if !(string.find(line,char1) && string.find(line,char2)) then return string.Trim(line),{nil} end local ret = {} local ret2 = string.Trim(string.sub(line,1,string.find(line,char1) - 1)) local ret3 = string.sub(line,1,string.find(line,char1) - 1) local p = string.find(line,char1) local n = 1 while(p) do n = string.find(line,char2,p + 1) if (string.sub(string.sub(line,p + 1,n - 1),1,1) == "#") then table.insert(ret,tonumber(string.byte(string.sub(line,p + 1 + remov,n - remov)) or 0)) ret3 = ret3 .. '"*"' else table.insert(ret,tonumber(string.sub(line,p + remov,n - remov)) or tonumber(string.byte(string.sub(line,p + remov,n - remov)) or 0)) ret3 = ret3 .. '"' .. (string.rep("*",string.len(string.sub(line,p + remov,n - remov))) or "") .. '"' end p = string.find(line,char1, n + 1) if (p!=nil) then ret3 = ret3 .. (string.sub(line,n+1,p-1) or "") end end return ret2,ret,ret3 end function ENT:Think() self.BaseClass.Think(self) if (self.Toggle == false) then for k,o in pairs(self.lines) do if !(o.toggle) then if (o.value != (o.off or self.UTrig) && CurTime() >= o.reset) then o.value = o.off or self.UTrig if (o.argsC) then for k2,o2 in pairs(o.args) do if (o2.R == true) then o2.V = 0 end end end self:TriggerOutput() end end end end self.Entity:NextThink(CurTime()+0.04) return true end function ENT:SensitivityCheck(text,line) if !(text || line) then return false end if (self.Sensitivity == 1) then if (text == line) then return true end elseif (self.Sensitivity == 2) then if (string.lower(text) == string.lower(line)) then return true end elseif (self.Sensitivity == 3) then if (string.find(text,line)) then return true end elseif (self.Sensitivity == 4) then if (string.find(string.lower(text), string.lower(line))) then return true end end return false end function ENT:CheckforChar(text,char1,char2) if (string.find(text,char1) && string.find(text,char2,string.find(text,char1)+1)) then return true end return false end function ENT:InRadius(plpos,selfpos,radius) if (radius == nil) then return true end if (selfpos:Distance(plpos) < radius) then return true else return false end end //All text is sent here now :D function ENT:TextReceived(pl,text) local i = 1 TextReceiversecuretext = nil for k,o in pairs(self.lines) do if (text != nil && o.line != nil) then TextReceivertext = text TextReceiverarg = nil if (self:InRadius(pl:GetPos(),self.Entity:GetPos(),o.Radius) == true) then if (o.argsC == true) then if (self:CheckforChar(TextReceivertext or "",self.char1,self.char2) == true) then TextReceiverarg = {} local temptext = nil TextReceivertext,TextReceiverarg,temptext = self:ParseTextAndArgs(text,self.char1,self.char2,1) if (TextReceiversecuretext==nil && self.secure == true) then TextReceiversecuretext = temptext end end end if (self:SensitivityCheck((TextReceivertext or ""),(o.line or ""))) then local allow = self:ParseNameandTeam(pl:Nick(),team.GetName(pl:Team()),o,self.global || o.global) if (allow == true || (self.Iself == true && self.pl == pl)) then if (self.playerout == true) then self.Caller = pl end if (TextReceiverarg != nil) then if (table.Count(TextReceiverarg) > 0) then for k = 1,table.Count(o.args) do o.args[k].V = (TextReceiverarg[k] or 0) end TextReceiverarg = {} end end if (self.Toggle || o.toggle) then if (o.value == o.on) then o.value = o.off or self.UTrig else o.value = o.on or self.Trig end o.reset = -1 else o.value = o.on or self.Trig o.reset = CurTime() + self.Hold end self:TriggerOutput() end end end end i = i + 1 end if (TextReceiversecuretext==nil) then return nil else return TextReceiversecuretext end end function ENT:ParseNameandTeam(name,TEAM,line,global) if (line.Allow != nil) then for k,o in pairs(line.Allow) do if (o==name) then return true end end end if (line.Deny != nil) then for k,o in pairs(line.Deny) do if(o==name) then return false end end end if (line.TAllow != nil) then for k,o in pairs(line.TAllow) do if (o==TEAM) then return true end end end if (line.TDeny != nil) then for k,o in pairs(line.TDeny) do if(o==TEAM) then return false end end end return global end function ENT:FOutText(text) return math.floor(text*10)/10 end function ENT:ReadCell(Addr) return self.Bytes[Addr+1] or 0 //Makes for faster reading :D end function ENT:ReloadLines() if (self.changed == false) then return end self.changed = false local onames = {} local lines = {} local i = 15 local line = "" while (self.Bytes[i]!=nil) do line = "" for q = 1,self.Bytes[i] do i = i + 1 line = line .. (string.char(self.Bytes[tonumber(i)] or 0) or "") end i = i + 1 if (line != nil && line != "") then table.insert(lines,line) end end i = 1 for k,o in pairs(lines) do self.lines[i] = {} self.lines[i].args = {} self.lines[i].line, self.lines[i].args,self.lines[i].toggle,self.lines[i].global,self.lines[i].on,self.lines[i].off,self.lines[i].Allow,self.lines[i].Deny,self.lines[i].TAllow,self.lines[i].TDeny, self.lines[i].Radius = self:SParseTextAndArgs(o,"<",">",0) self.lines[i].argsC = nil table.insert(onames, self.lines[i].line) for k2,o2 in pairs(self.lines[i].args) do o2.V = 0 table.insert(onames, o2.A) self.lines[i].argsC = true end self.lines[i].value = self.lines[i].off or self.UTrig self.lines[i].reset = 0 i = i + 1 end if (self.playerout == true) then table.insert(onames,"X") table.insert(onames,"Y") table.insert(onames,"Z") table.insert(onames,"EntId") end Wire_AdjustOutputs(self.Entity, onames) end function ENT:WriteCell(Addr,value) Addr = tonumber(Addr) if (Addr == 0) then self.Bytes[Addr+1] = value or 0 self.UTrig = value or 0 end if (Addr == 1) then self.Bytes[Addr+1] = value or 0 self.Trig = value or 0 end if (Addr == 2) then self.Bytes[Addr+1] = value or 0 self.Hold = value or 0 end if (Addr == 3) then self.Bytes[Addr+1] = string.char(value or 0) self.char1 = string.char(value or 0) end if (Addr == 4) then self.Bytes[Addr+1] = string.char(value or 0) self.char2 = string.char(value or 0) end if (Addr == 5) then self.Bytes[Addr+1] = value or 0 self.global = value or 0 end if (Addr == 6) then self.Bytes[Addr+1] = value or 0 self.Toggle = value or 0 end if (Addr == 7) then self.Bytes[Addr+1] = value or 0 self.OutputText = value or 0 end if (Addr == 8) then self.Bytes[Addr+1] = value or 0 self.Iself = value or 0 end if (Addr == 9) then self.Bytes[Addr+1] = value or 0 self.secure = value or 0 end if (Addr == 10) then self.Bytes[Addr+1] = value or 0 self.playerout = value or 0 end if (Addr == 11) then self.Bytes[Addr+1] = value or 0 self.Sensitivity = value or 0 end if (Addr == 12 && Value != 0) then self.Bytes[Addr+1] = value or 0 self:ReloadLines() end if (Addr >= 13) then self.Bytes[Addr+1] = value self.changed = true end self:TriggerOutput() return true end function ENT:TriggerOutput() self.OutText = "TextReceiver:" local pos = nil if (self.playerout == true && self.Caller != nil) then pos = self.Caller:GetPos() Wire_TriggerOutput(self.Entity,"X",pos.X) Wire_TriggerOutput(self.Entity,"Y",pos.Y) Wire_TriggerOutput(self.Entity,"Z",pos.Z) Wire_TriggerOutput(self.Entity,"EntId",self.Caller:EntIndex()) end local i = 1 for k,o in pairs(self.lines) do if (self.OutputText == true) then self.OutText = self.OutText .. "\n" .. (o.line or "") .. ":" .. (o.value or 0) end for q = 1, table.Count(o.args) do Wire_TriggerOutput(self.Entity,o.args[q].A,(o.args[q].V or 0)) if (self.OutputText == true) then self.OutText =self.OutText .. " " .. (o.args[q].A or "") .. ":" .. (o.args[q].V or 0) end end Wire_TriggerOutput(self.Entity,o.line,o.value) i = i + 1 end if (self.playerout == true) then //We want it to trigger first BUT display last. if (pos != nil) then self.OutText = self.OutText .. "\nPos: " .. self:FOutText(pos.X or 0) .. ", " .. self:FOutText(pos.Y or 0) .. ", " .. self:FOutText(pos.Z or 0) .. "\nEntId: " else self.OutText = self.OutText .. "\nPos: 0, 0, 0\nEntId: " end if (self.Caller != nil) then self.OutText = self.OutText .. self.Caller:EntIndex() else self.OutText = self.OutText .. "0" end end /*if (self.NoFilter == false) then self.OutText = "\nBuddyList: " .. string.Implode(" ",self.Allow) .. "\nIgnoreList: " .. string.Implode(" ",self.Deny) end*/ self:SetOverlayText(self.OutText) end