These were my first E2 functions. They are the setEye(A) and the E:setDriverEye(A). They are fairly simple, but with some creativity, they could be very useful. setEye(A) sets the owner’s eye angle (where you are looking at) and E:setDriverEye(A) sets the driver of entity E:’s eye angle to angle A. These might be useful for targeting, for mouse controlled ships, and for an eye pod like effect. E:setDriverEye(A) takes the entity of the vehicle before the function, and the angle you want to look at in the parameters. setEye(A) takes the angle you want to look at.
Here is the code:
Code:
AddCSLuaFile('SetEye.lua')
/********************************************************************************/
registerFunction("setDriverEye", "e:a", "", function(self, args)
local op1, op2 = args[2], args[3]
local rv1, rv2 = op1[1](self, op1), op2[1](self, op2)
if(!rv1 or !validEntity(rv1) or !rv1:IsVehicle()) then return end
if(!isOwner(self, rv1)) then return end
local ply = rv1:GetDriver()
if(!ply:IsValid()) then return end
ply:SetEyeAngles( Angle(rv2[1],rv2[2],rv2[3]) )
end)
registerFunction("setEye", "a", "", function(self, args)
local op1 = args[2]
local rv1 = op1[1](self, op1)
if(!rv1) then return end
self.player:SetEyeAngles( Angle(rv1[1],rv1[2],rv1[3]) )
end) Also, the code is in addon format as an attachment. Just extract to your addons folder.
Here is an example of setEye(A)’s use: (it makes you look at Target entity)
Code:
@name LookAt Test
@inputs Target:entity On
@outputs
@persist
@trigger all
interval(10)
if(On)
{
Diff = owner():pos() - Target:pos()
setEye(Diff:toAngle())
} Here is an example of E:setDriverEye: (it gives an Eye Pod like effect, but more jerky)
Code:
@name Ship_Eye_Control
@inputs Chair:entity
@outputs Bearing Elevation
@persist Bearing Elevation Run
@trigger all
interval(30)
if(Chair:driver():isPlayer())
{
if(!Run)
{
timer("Delay",500)
}
if(clk("Delay"))
{
Run = 1
}
if(Run)
{
DriverAng = Chair:driver():eye():toAngle()
Bearing = angnorm(Bearing + round( DriverAng:yaw() - Chair:angles():yaw()) )
Elevation = angnorm(Elevation - round( DriverAng:pitch() - Chair:angles():pitch() ) )
Chair:setDriverEye( ang(0,0,0) )
}
}
Run = 0 Under the suggestion form, Divran suggested that the E2 be able to wire two wire entities together, so I thought I would try to accomplish this. After a little bit of work, I created exactly what the suggestion wanted. It actually is very useful. I have two types of wire creator functions. One that creates invisible wires, and one where you input the width of the wire, the color as a vector, and the material as a string. I also have one function to delete a wire from the entity. In addition to all of this, I have four helper functions that get the names and types of an entity’s Inputs and Outputs.
Here are the seven functions:
Call the E:createWire(E,S,S) function to create an invisible wire between the two entities
E: is the input entity
E is the output entity
S is the name of the input of the input entity
S is the name of the output of the output entity
returns 1 if it succeeds, 0 if it fails
Call the E:createWire(E,S,S,N,V,S) function to create an wire between the two entities,
E: is the input entity
E is the output entity
S is the name of the input of the input entity
S is the name of the output of the output entity
N is the width of the wire (Clamped between 0 and 10)
V is the color of the wire in Vector( R,G,B) form
S is the material of the wire. (Note that you do not have to put the "cable/" or "arrowire/" extension in the material)
Returns 1 if it succeeds, 0 if it fails
The E:deleteWire(S) function deletes the wire leading to entity E:, input S
E: is the entity
S is the input name
Returns 1 if it succeeds, 0 if it fails
The E:getWireInputs() function that gets a string array of the inputs of the entity
E: is the entity
returns the inputs if it succeeds, an empty array if it fails
The E:getWireOutputs() function that gets a string array of the outputs of the entity
E: is the entity
returns the outputs if it succeeds, an empty array if it fails
The E:getWireInputType(S) function that gets the wire type of input S of the entity as a string
E: is the entity
S is the name of the input
returns the input type if it succeeds, an empty string if it fails
The E:getWireOutputType(S) function that gets the wire type of output S of the entity as a string
E: is the entity
S is the name of the output
Returns the output type if it succeeds, an empty string if it fails
Here is the lua code: (Also, the code is in addon format as an attachment. Just extract to your addons folder.)
Code:
AddCSLuaFile('Wiring.lua')
/******************************************************************************\
This is the wiring addon, created by Jeremydeath , thanks to Divran for the idea :)
Call the E:createWire(E,S,S) function to create an invisible wire between the two entitys
E: is the input entity
E is the output entity
S is the name of the input of the input entity
S is the name of the output of the output entity
returns 1 if it succeds, 0 if it fails
Call the E:createWire(E,S,S,N,V,S) function to create an wire between the two entities,
E: is the input entity
E is the output entity
S is the name of the input of the input entity
S is the name of the output of the output entity
N is the width of the wire (Clamped between 0 and 10)
V is the color of the wire in Vector( R,G,B) form
S is the material of the wire. (Note that you do not have to put the "cable/" or "arrowire/" extension in the material)
returns 1 if it succeds, 0 if it fails
Call the E:deleteWire(S) function to delete wire leading to entity E:, input S
E: is the entity
S is the input name
Returns 1 if it succeeds, 0 if it fails
Call the E:getWireInputs() function to get a string array of the inputs of the entity
E: is the entity
returns the inputs if it succeds, an empty array if it fails
Call the E:getWireOutputs() function to get a string array of the outputs of the entity
E: is the entity
returns the outputs if it succeds, an empty array if it fails
Call the E:getWireInputType(S) function to get the wire type of inputS of the entity as a string
E: is the entity
S is the name of the input
returns the input type if it succeds, an empty string if it fails
Call the E:getWireOutputType(S) function to get the wire type of output S of the entity as a string
E: is the entity
S is the name of the output
returns the output type if it succeds, an empty string if it fails
\******************************************************************************/
registerFunction("createWire", "e:ess", "n", function(self,args)
local op1, op2, op3, op4 = args[2], args[3], args[4], args[5]
local rv1, rv2, rv3, rv4 = op1[1](self,op1), op2[1](self,op2), op3[1](self,op3), op4[1](self,op4)
if(!validEntity(rv1) or !validEntity(rv2)) then return 0 end
if(!isOwner(self, rv1) or !isOwner(self, rv2)) then return 0 end
local EntInput = rv1
local EntOutput = rv2
local Input = rv3
local Output = rv4
if (CLIENT) then return end
if(!EntInput.Inputs or !EntOutput.Outputs) then return 0 end
if(Input == "" or Output == "") then return 0 end
if(!EntInput.Inputs[Input] or !EntOutput.Outputs[Output]) then return 0 end
if(EntInput.Inputs[Input].Src) then
local CheckInput = EntInput.Inputs[Input]
if(CheckInput.SrcId == Output and CheckInput.Src == EntOutput) then return 0 end
end
Wire_Link_Start(self.player:UniqueID(), EntInput, EntInput:WorldToLocal(EntInput:GetPos()), Input, "cable/rope", Vector(255,255,255), 0)
Wire_Link_End(self.player:UniqueID(), EntOutput, EntOutput:WorldToLocal(EntOutput:GetPos()), Output, self.player)
return 1
end)
registerFunction("createWire", "e:essnvs", "n", function(self,args)
local op1, op2, op3, op4, op5, op6, op7 = args[2], args[3], args[4], args[5], args[6], args[7] , args[8]
local rv1, rv2, rv3, rv4, rv5, rv6, rv7 = op1[1](self,op1), op2[1](self,op2), op3[1](self,op3), op4[1](self,op4), op5[1](self,op5), op6[1](self,op6), op7[1](self,op7)
if(!validEntity(rv1) or !validEntity(rv2)) then return 0 end
if(!isOwner(self, rv1) or !isOwner(self, rv2)) then return 0 end
if(!rv5 or !rv7) then return 0 end
local EntInput = rv1
local EntOutput = rv2
local Input = rv3
local Output = rv4
local Width = rv5
local Color = Vector(rv6[1],rv6[2],rv6[3])
local WireMaterial = rv7
local ValidWireMat = {"cable/rope", "cable/cable2", "cable/xbeam", "cable/redlaser", "cable/blue_elec", "cable/physbeam", "cable/hydra", "arrowire/arrowire", "arrowire/arrowire2"}
if(!table.HasValue(ValidWireMat,WireMaterial)) then
if(table.HasValue(ValidWireMat,"cable/"..WireMaterial)) then
WireMaterial = "cable/"..WireMaterial
elseif(table.HasValue(ValidWireMat,"arrowire/"..WireMaterial)) then
WireMaterial = "arrowire/"..WireMaterial
else
return 0
end
end
Width = math.Clamp(Width, 0, 10)
if (CLIENT) then return end
if(!EntInput.Inputs or !EntOutput.Outputs) then return 0 end
if(Input == "" or Output == "") then return 0 end
if(!EntInput.Inputs[Input] or !EntOutput.Outputs[Output]) then return 0 end
if(EntInput.Inputs[Input].Src) then
local CheckInput = EntInput.Inputs[Input]
if(CheckInput.SrcId and CheckInput.Src == EntOutput) then return 0 end
end
Wire_Link_Start(self.player:UniqueID(), EntInput, EntInput:WorldToLocal(EntInput:GetPos()), Input, WireMaterial, Color, Width)
Wire_Link_End(self.player:UniqueID(), EntOutput, EntOutput:WorldToLocal(EntOutput:GetPos()), Output, self.player)
return 1
end)
registerFunction("deleteWire", "e:s", "n", function(self,args)
local op1, op2 = args[2], args[3]
local rv1, rv2 = op1[1](self,op1), op2[1](self,op2)
if(!validEntity(rv1) or !rv2) then return 0 end
if(!isOwner(self, rv1)) then return 0 end
local TargetEnt = rv1
local Input = rv2
if(!TargetEnt.Inputs) then return 0 end
if(Input == "") then return 0 end
if(!TargetEnt.Inputs[Input]) then return 0 end
if(TargetEnt.Inputs[Input].Src) then
Wire_Link_Clear(TargetEnt, Input)
return 1
end
return 0
end)
registerFunction("getWireInputs", "e:", "r", function(self,args)
local op1= args[2]
local rv1= op1[1](self,op1)
if(!validEntity(rv1)) then return {} end
local EntInput = rv1
local InputNames = {}
if(EntInput.Inputs) then
local WireInputs = EntInput.Inputs
local Count = 0
for k,v in pairs(WireInputs) do
if(k != "") then
Count = Count + 1
InputNames[Count] = k
end
end
return InputNames
end
return {}
end)
registerFunction("getWireOutputs", "e:", "r", function(self,args)
local op1= args[2]
local rv1= op1[1](self,op1)
if(!validEntity(rv1)) then return {} end
local EntOutput = rv1
local OutputNames = {}
if(EntOutput.Outputs) then
local WireOutputs = EntOutput.Outputs
local Count = 0
for k,v in pairs(WireOutputs) do
if(k != "") then
Count = Count + 1
OutputNames[Count] = k
end
end
return OutputNames
end
return {}
end)
registerFunction("getWireInputType", "e:s", "s", function(self,args)
local op1, op2 = args[2], args[3]
local rv1, rv2 = op1[1](self,op1), op2[1](self,op2)
if(!validEntity(rv1)) then return "" end
local EntInput = rv1
if(!EntInput.Inputs) then return "" end
if(!EntInput.Inputs[rv2]) then return "" end
local WireInput = EntInput.Inputs[rv2]
local Type = WireInput.Type
if(Type) then return Type end
return ""
end)
registerFunction("getWireOutputType", "e:s", "s", function(self,args)
local op1= args[2]
local rv1= op1[1](self,op1)
if(!validEntity(rv1)) then return "" end
local EntOutput = rv1
if(!EntOutput.Outputs) then return "" end
if(!EntOutput.Outputs[rv2]) then return "" end
local WireOutput = EntOutput.Outputs[rv2]
local Type = WireOutput.Type
if(Type) then return Type end
return ""
end)
Here are some E2 examples:
Create wire example: (this one automatically wire’s itself to the closest button owned by you within 500 units of the gate)
Code:
@name createWire Example
@inputs A
@outputs B
@persist Button:entity
@trigger all
interval(500)
findInSphere(entity():pos(), 500)
findClipToClass("gmod_wire_button")
findSortByDistance(entity():pos())
Button = find()
entity():createWire(Button, "A", "Out", 2, vec(255,255,255), "arrowire2")
Self = entity()
B = A*5 getWireInputs example: (this one take an inputted entity and outputs a list of its inputs)
Code:
@name Find Inputs
@inputs Target:entity
@outputs Inputs:string
@trigger all
interval(50)
Inputs = Target:getWireInputs():concat(" ") This function was in response to a request on the forum about the E2’s concommand function. Right now, conncomands are an opt-in feature, and it is very difficult if all you wanted to do was to get someone to say something. With this function though, you have the ability get another player to say a string of text with little to no minging possible.
There are MANY restrictions and escape codes in this function in order to prevent minging. They are:
1. There is a built in timer so that this can only be run once every X seconds on a single E2 Gate
This delay time (in seconds) is determined by the convar "wire_expression2_say_delay" which defaults to 5 seconds.
2. This function has a client side covar that determines if a player will allow you to run this command on them
This is stored in the convar "wire_expression2_allow_say' and defaults to 1 (so it is opt-out rather than opt-in)
3. This function automatically removes any characters that are not alpha-numeric or a space (i.e. a-z, A-Z, 0-9," ")
4. This function automatically checks for a list of banned words on the server
This file will be found in garrysmod/data/Expression2_Banned_Words/banned_words_list.txt after you install this and run gmod at least once
Syntax for the file:
*word* will ban any string of characters with the group or characters "word" in them anywhere in the string
*word will ban any string ending in "word"
word* will ban any string begining in "word"
word will ban any string that is equal to "word"
Here is how it would be used: (This example takes a button (with the output EntID: checked) and tells anyone who presses it to respect your button.

)
Code:
@name Say Example
@inputs Button EID
@outputs Name:string
@persist
@trigger all
interval(20)
Entity = entity(EID)
Name = Entity:name()
if(Button & Entity:id() != EID)
{
WhatToSay = "Respect " + owner():name() + "s Button or you die"
Entity:say(WhatToSay)
} Here is the LUA Code for the function (also in add-on format at the bottom) that goes in addons->wire->lua->entities->gmod_wire_expression2->core->custom->SayCommand.lua:
Code:
AddCSLuaFile('SayCommand.lua')
/********************************************************************************
This is the expression 2 gate's E:say(S) command
E is the player that you want to say the string
S is the string you want them to say
There are MANY restrictions and escape codes in this function in order to prevent minging
1. There is a built in timer so that this can only be run once every X seconds on a single E2 Gate
This delay time (in seconds) is determined by the convar "wire_expression2_say_delay" which defaults to 5 seconds.
2. This function has a client side covar that determines if a player will allow you to run this command on them
This is stored in the convar "wire_expression2_allow_say' and defaults to 1 (so it is opt-out rather than opt-in)
3. This function automatically removes any characters that are not alpha-numeric or a space (i.e. a-z, A-Z, 0-9," ")
4. This function automatically checks for a list of banned words on the server
This file will be found in garrysmod/data/Expression2_Banned_Words/banned_words_list.txt after you install this and run gmod at least once
Syntax for the file:
*word* will ban any string of characters with the group or characters "word" in them anywhere in the string
*word will ban any string ending in "word"
word* will ban any string beginning in "word"
word will ban any string that is equal to "word"
*********************************************************************************/
if(CLIENT) then
CreateClientConVar("wire_expression2_allow_say", 1, true, true)
end
if(SERVER) then
if(!ConVarExists("wire_expression2_say_delay")) then
CreateConVar("wire_expression2_say_delay","5",FCVAR_NOTIFY)
end
if(!file.Exists("Expression2_Banned_Words/banned_words_list.txt")) then
file.Write("Expression2_Banned_Words/banned_bords_list.txt"," \n")
end
end
registerFunction("say", "e:s", "n", function(self, args)
local op1, op2 = args[2], args[3]
local rv1, rv2 = op1[1](self, op1), op2[1](self, op2)
if(!rv2 or rv2 == "") then return 0 end
if(!rv1) then return 0 end
local ply = rv1
if(!ply:IsPlayer()) then return 0 end
local WordToSay = rv2
local ValidChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "
local FirstRun = 0
if(self.NoMingeTimer == nil) then
self.NoMingeTimer = CurTime()
FirstRun = 1
end
if(ply:GetInfoNum("wire_expression2_allow_say") != 1) then return 0 end
if( (CurTime() - self.NoMingeTimer) > GetConVar("wire_expression2_say_delay"):GetInt() or FirstRun == 1) then
FirstRun = 0
local i = 1
repeat
local CharToFind = string.sub(WordToSay,i,i)
local ByteForm = string.byte(string.sub(WordToSay,i,i))
if(ByteForm == 40 or ByteForm == 94 or ByteForm == 37 or ByteForm == 36 or ByteForm == 46 or ByteForm == 91) then
CharToFind = "%"..CharToFind
end
if(!string.find(ValidChars, CharToFind)) then
WordToSay = string.Replace(WordToSay,string.sub(WordToSay,i,i),"")
i = i-1
end
i = i+1
until (i > string.len(WordToSay))
if(WordToSay == "") then return 0 end
local FileContents = file.Read("Expression2_Banned_Words/banned_words_list.txt")
local ContentList = string.Explode("\n",FileContents)
if(ContentList != nil) then
for i,v in pairs(ContentList) do
ContentList[i] = string.Trim(ContentList[i])
if(ContentList[i] != "") then
if(string.sub(ContentList[i],1,1)=="*" and string.sub(ContentList[i],-1,-1)=="*") then
local Remove = string.Replace(ContentList[i],"*","")
if(Remove != "" and string.find(WordToSay,Remove)) then
WordToSay = string.Replace(WordToSay,Remove,"")
end
elseif(string.sub(ContentList[i],1,1)=="*") then
local Remove = string.Replace(ContentList[i],"*","")..'$'
if(Remove != "" and string.find(WordToSay,Remove)) then
return 0
end
elseif(string.sub(ContentList[i],-1,-1)=="*") then
local Remove = '^'..string.Replace(ContentList[i],"*","")..'+'
if(Remove != "" and string.find(WordToSay,Remove)) then
return 0
end
else
local Remove = ContentList[i]
if(Remove != "" and WordToSay == Remove) then
return 0
end
end
end
end
end
ply:ConCommand("say "..WordToSay)
self.NoMingeTimer = CurTime()
return 1
end
return 2
end) Enjoy!
This is my version of the wired wirer. After I created my E2 Wiring functions, I decided to create an entity version to do much the same thing. I think that the result turned out great. Anyway, here it is:
How to use:
(Download as part of the
UWSVN)
I made this to be user friendly, but to retain the ability to do advanced things. First off, to create a basic wire, the tool has a built in panel like the Wire
Tool has to choose wire width, color, and material. These are automatically loaded into the entity when it is spawned or updated. Above these wire choices are the model choices for the entity, and right below that is the slider to choose the range of the wirer. On the bottom is a check box allowing you to change the properties of the wire created through wire.
Once you spawn the entity, the inputs are:
Wire, Input [STRING], Output [STRING], X, Y, TargetAssist, ClearWire, and CreateWirelink Wire tells the wirer to start or finish a wire or if the wire is already started, you can create a wire node to “Pretty Wire”
Input [STRING] is the name of the input you want to wire up (NOTE: you do not put the [<Input Type>] at the end of the name)
Output [STRING] it the name of the output you want to wire to (NOTE: you do not put the [<Output Type>] at the end of the name)
X is the x-portion of the skew of the trace (like the ranger)
Y is the y-portion of the skew of the trace (like the ranger)
TargetAssist is the input to turn on targeting assist (see below)
ClearWire clears the current wire with input Input [STRING] or cancels the link if one has been started
CreateWirelink creates a [WIRELINK] type output on the targeted wire entity if one does not already exist (Note that this output is always called “link”)
The optional inputs (based on the "Take Inputs for Wire Type" check box) are:
WireWidth, WireMaterial [STRING], and WireColor [VECTOR] WireWidth changes the width of the wire (clamped to below 15)
WireMaterial [STRING] changes the material of the wire (note that you do not have to put the "cable/" or "arrowire/" extensions)
WireColor [VECTOR] changes the color of the wire where the x component is green (0-255), the x component is red (0-255), and the z component is blue (0-255)
The outputs are:
Stage, Success, TargetInputs, and TargetOutputs Stage is the current wiring stage (0 if no wire has been started yet, 1 if one has been started but has not been wired up to an output)
Success is the state of the trace (0 if it is not hitting anything that is wire and owned by you, 1 if it is hitting something that is wire and owned by you, 2 if it is hitting something that is wire and owned by you and it has the correct Input/Output, 3 if Stage is 1 and it is not hitting anything that is wire and owned by you)
TargetInputs is a list of all of the inputs of the entity that the trace is currently hitting, separated by ", " (one comma followed by a space), note that these do not have the types after the names of the inputs
TargetOutputs is a list of all of the outputs of the entity that the trace is currently hitting, separated by ", " (one comma followed by a space), note that these do not have the types after the names of the outputs
Target Assist:
(Download as part of the
UWSVN)
Target assist is a feature of the wirer that makes it MUCH easier to wire small parts (I once wired two nano chips together from across flatgrass!). Once activated, it will target and change the trace to the wire entity owned by you in its range that is closest to its current trace line (in other words if you get the beam sort-of close to the entity you want to wire up, it will automatically target that entity for wiring). Also, if you have the wirer's Input and Output inputs wired up, it will try to target the entity with that input or output in its list. This is based also on the stage so that it will switch between checking the input and checking the output based on what it is looking for. This also works with this X and Y skew inputs by taking the entity closest to the line defined by them when they are wired up.
Color Change and Other Visual Effects:
(Download as part of the
UWSVN)
The wired wirer uses visual color change to indicate what state the wirer is in.
White represents that the trace is not hitting anything that is wire and owned by you and that it is not in the process of wiring anything (Success = 0)
Yellow represents that the trace is hitting something that is wire and owned by you (Success = 1)
Green represents that the trace is hitting something that is wire and owned by you and it has the correct input/output (Success = 2)
Blue represents that the trace is if it is in the process of wiring something and it is not hitting anything that is wire and owned by you
In addition to these colors, there are small spark effects that are played when something is wired, a wire is deleted, a wire is canceled, a wire node is created, or a wirelink output is added.
Use Pictures:
(Download as part of the
UWSVN)
The starting of the wire (Target Assist used):
Showing the stage 1 wire in progress blue (No Target Assist):
Finished the wire showing output and re-targeting the screen (Target Assist used):
(Download as part of the
UWSVN)Enjoy!
Change Log:5-20-09: Ver. 1.0 – Initial release
5-22-09: Ver. 1.1 – Fixed minor errors and removed some unused debug code
6-1-09: Ver. 1.2 – Added “CreateWirelink” feature
Added ability to create wire nodes for “Pretty Wiring”
Added “TargetInputs” and “TargetOutputs” that output names of Inputs/Outputs
Fixed some aiming issues and optimized code a little
Fixed instability in aiming at entities
Removed more debug code and added some more comments in the code
Bookmarks