+ Reply to Thread
Page 1 of 5 123 ... LastLast
Results 1 to 10 of 46

Thread: Built-In Ranger - Expression2

  1. #1
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Built-In Ranger - Expression2

    As of Version 1.6 this is now in the official Wire SVN
    I will be taking the download down now.

    Check out the new rangerOffset! Now you can make a trace between any two points of your own choosing!

    Alright, I know many of you have probably wanted this for a long time, and with such popularization of wire2 and being able to have a built-in ranger that way I thought it was about time this was released too.

    I have made some functions for the expression2 chip to take advantage of the code that Erkle already wrote. Honestly, all the credit for the method goes to Erkle.

    The ranger "beam" even though invisible comes out of the top of the expression2 chip. If you spawn it on the ground then the measuring trace would be going straight up. I'm not quite sure which way the x|y skew goes, just rotate it until it is correct.

    Special Thanks to Syranide! Always providing helpful advice and suitable ideas.

    Planned for next release (1.7)
    Nothing yet, any suggestions?

    Version History:
    Version 1.62 - Changed the global function to local, less chance of future conflicts
    Version 1.61 - Added support for hitNormal data access
    Version 1.6 - Added Angle support, think of the ranger skew of 1 being 45degrees, this goes all 360
    Version 1.5 - Fixed the hit() returning erros
    - Fixed the position() returning 0 instead of (0,0,0) or a real vector
    Version 1.4 - Added a new hit() checker, returns 1 for hit and 0 for not
    - Restored entity return function, entid can be found with it anyways
    - Fixed misplaced trace water mask. Now it will work correctly.
    - Changed the ranger options to more suitable/recognizable names
    Version 1.3 - Removed apparently useless functions and optimized others (Thanks Syranide!)
    - Corrected a datatype label mistake
    - Changed the syntax for extracting information from a rangerdata variable
    Version 1.2 - Complete rewrite of the function names and data handling
    - Added rangerOffset function
    - Changed entity return, it now returns entityID. (no nil returns now)
    - Added custom data type for ranger returns
    Version 1.1 - I accidentally left a print() command in there, it was supposed to be debug only, no more console spam
    Version 1.0 - Initial Release

    Syntax is as follows:
    -------------------------------------


    N - number, V - vector, E - entity, RD - rangerdata, None - no return

    -----Ranger Trace Options-----
    (Use these before you do the trace)

    rangerHitWater
    rangerHitWater(N) | None - Default is 0, if any other value is given it will hit water

    rangerIgnoreWorld
    rangerIgnoreWorld(N) | None - Default is 0, if any other value is given it will ignore world

    rangerDefaultZero
    rangerDefaultZero(N) | None - If given any value other than 0 it will default the distance data to zero when nothing is hit

    -----Getting Ranger Data-----

    ranger
    ranger(N) | RD - You input max range, it outputs ranger data
    ranger(N,N,N) | RD - Same as above with added inputs for X and Y skew

    rangerAngle
    rangerAngle(N,N,N) | RD - You input the distance, x-angle and y-angle (both in degrees)

    rangerOffset
    rangerOffset(vv) | RD - You input two vector points, it outputs ranger data
    rangerOffset(nvv) | RD - You input the range, a position vector, and a direction vector and it outputs ranger data

    -----Ranger Trace Retrieval-----
    (Use these after you do the trace)

    distance
    RD:distance() | N - Outputs the distance from the rangerdata input, else depends on rangerDefault setting

    position
    RD:position() | V - Outputs the position of the input ranger data trace IF it hit anything, else returns (0,0,0)

    entity
    RD:entity() | N - Returns the entity of the input ranger data trace IF it hit an entity, else returns nil

    hit
    RD:hit() | N - Returns 1 if the input ranger data hit anything and 0 if it didn't

    hitNormal
    RD:hitNormal() | V - Returns the hitNormal of the trace

    -------------------------------

    As always the code is available here, no need to open the lua:
    Code:
    AddCSLuaFile('ranger.lua')
    
    /******************************************************************************\
      Built-in Ranger support v1.61
    \******************************************************************************/
    
    //-------------------------//
    //--Client Function--//
    //-------------------------//
    
    local function ranger(self, type, range, p1, p2)
    	local trace = {}
    	local default = self.data['rangerdefault']
    	self.data['rangerdefault'] = 1
    	local world = self.data['rangerworld']
    	self.data['rangerworld']=0
    	local water = self.data['rangerwater']
    	self.data['rangerwater']=0
    	trace.start = self.entity:GetPos()
    	if (type==3) then
    		trace.start = Vector( p1[1], p1[2], p1[3] )
    		trace.endpos = trace.start + Vector( p2[1], p2[2], p2[3] )*range
    	elseif (type==2) then
    		if p1!=p2 then
    		range = math.sqrt(math.pow(p1[1]-p2[1],2)+math.pow(p1[2]-p2[2],2)+math.pow(p1[3]-p2[3],2))
    		else
    		range = 0
    		end
    		trace.start = Vector( p1[1], p1[2], p1[3] )
    		trace.endpos = Vector( p2[1], p2[2], p2[3] )
    	elseif ((type==1 && p1!=0) || (type==1 && p2!=0)) then
    		local zoff = math.cos(math.rad(p1))*range
    		local yoff = math.sin(math.rad(p1))*range
    		local xoff = math.cos(math.rad(p2+270))*zoff*(-1)
    		zoff = math.sin(math.rad(p2+270))*zoff*(-1)
    		trace.endpos = self.entity:LocalToWorld(Vector(xoff,yoff,zoff))
    	elseif ((type==0 && p1!=0) || (type==0 && p2!=0)) then
    		local skew = Vector(p1, p2, 1)
    			print(skew)
    		skew = skew*(range/skew:Length())
    			print(skew)
    		local beam_x = self.entity:GetRight()*skew.x
    		local beam_y = self.entity:GetForward()*skew.y
    		local beam_z = self.entity:GetUp()*skew.z
    			print(beam_x) print(beam_y) print(beam_z)
    		trace.endpos = trace.start + beam_x + beam_y + beam_z
    	else
    		trace.endpos = trace.start + self.entity:GetUp()*range
    	end
    	trace.filter = { self.entity }
    	if water==1 then trace.mask = -1 end
    	trace = util.TraceLine(trace)
    	local Entity = nil
    	local HitPos = trace.HitPos
    	local Hit = 0
    	if (trace.Hit) then Hit=1 end
    	if (!checkEntity(trace.Entity)) then
    		if (world!=0) then
    			range = range*default
    		end
    	else
    		Entity=trace.Entity
    	end
    	if (trace.Hit) then
    		return {trace.Fraction*range,HitPos,Entity,Hit,trace.HitNormal}
    	else
    		return {range*default,HitPos,Entity,Hit,trace.HitNormal}
    	end
    end
    
    /******************************************************************************/
    
    registerType("ranger", "xrd", {})
    
    /******************************************************************************/
    
    registerOperator("ass", "xrd", "xrd", function(self, args)
    	local op1, op2 = args[2], args[3]
    	local      rv2 = op2[1](self, op2)
    	self.vars[op1] = rv2
    	self.vclk[op1] = true
    	return rv2
    end)
    
    /******************************************************************************/
    
    registerFunction("ranger", "n", "xrd", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return ranger(self, 0, rv1, 0, 0)
    end)
    
    registerFunction("ranger", "nnn", "xrd", function(self, args)
        local op1, op2, op3 = args[2], args[3], args[4]
        local rv1, rv2, rv3 = op1[1](self, op1), op2[1](self, op2), op3[1](self, op3)
        return ranger(self, 0, rv1, rv2, rv3)
    end)
    
    registerFunction("rangerAngle", "nnn", "xrd", function(self, args)
        local op1, op2, op3 = args[2], args[3], args[4]
        local rv1, rv2, rv3 = op1[1](self, op1), op2[1](self, op2), op3[1](self, op3)
        return ranger(self, 1, rv1, rv2, rv3)
    end)
    
    registerFunction("rangerOffset", "vv", "xrd", function(self, args)
        local op1, op2 = args[2], args[3]
        local rv1, rv2 = op1[1](self, op1), op2[1](self, op2)
        return ranger(self, 2, 0, rv1, rv2)
    end)
    
    registerFunction("rangerOffset", "nvv", "xrd", function(self, args)
        local op1, op2, op3 = args[2], args[3], args[4]
        local rv1, rv2, rv3 = op1[1](self, op1), op2[1](self, op2), op3[1](self, op3)
        return ranger(self, 3, rv1, rv2, rv3)
    end)
    
    registerFunction("rangerHitWater", "n", "", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        if rv1!=0 then self.data['rangerwater']=1 end
    end)
    
    registerFunction("rangerIgnoreWorld", "n", "", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        if rv1!=0 then self.data['rangerworld']=1 end
    end)
    
    registerFunction("rangerDefaultZero", "n", "", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        if rv1!=0 then self.data['rangerdefault']=0 end
    end)
    
    registerFunction("distance","xrd:","n", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return rv1[1]
    end)
    
    registerFunction("position", "xrd:", "v", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return rv1[2]
    end)
    
    registerFunction("entity", "xrd:", "e", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return rv1[3]
    end)
    
    registerFunction("hit", "xrd:", "n", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return rv1[4]
    end)
    
    registerFunction("hitNormal", "xrd:", "v", function(self, args)
        local op1 = args[2]
        local rv1 = op1[1](self, op1)
        return rv1[5]
    end)
    
    /******************************************************************************/
    
    registerCallback("construct", function(self)
    	self.data['rangerwater'] = 0
    	self.data['rangerworld'] = 0
    	self.data['rangerdefault'] = 1
    end)
    I'm sorry for the drastic syntax changes but bear with them, they are better suited for a great many things, if you absolutely abhore them then you can always keep the original ranger.lua
    Bug reports if you have any please, I will fix them or admit stupidity.

    As always, enjoy! ^_^
    Last edited by ZeikJT; 01-24-2009 at 11:59 PM. Reason: Version 1.62, made functions local
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  2. #2
    Wire Sofaking oenmaster's Avatar
    Join Date
    Jan 2008
    Location
    fak where is my satnav (NL)
    Posts
    717
    Blog Entries
    1

    Default Re: Built-In Ranger - Expression2

    nice!

  3. #3
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by oenmaster View Post
    nice!
    Oh, almost forgot, the ranger comes out of the top of the expression2 chip.
    So if you want it to measure distance from a phx square to the floor put it underneath facing down. (The default paste should position it correctly in this case).

    If you spawn it on the floor it will be measuring up.
    I'll add this info to first post.

    Enjoy!
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  4. #4
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: Built-In Ranger - Expression2

    A recommendation would be to construct this similarily to how trace internally works in gmod, and how some other functions work. Namely that instead of having one function for all the different possible results, you return a new datatype that holds all of these, and then people can query this multiple times instead.

    EDIT: Or for that matter, only output the entity (or NIL), because that will provide the same information, "if entity exists" is already available, "position" is available from the entity, and you already have the entity itself.

  5. #5
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by Syranide View Post
    A recommendation would be to construct this similarily to how trace internally works in gmod, and how some other functions work. Namely that instead of having one function for all the different possible results, you return a new datatype that holds all of these, and then people can query this multiple times instead.

    EDIT: Or for that matter, only output the entity (or NIL), because that will provide the same information, "if entity exists" is already available, "position" is available from the entity, and you already have the entity itself.
    If it's still on the same interval then it doesn't do another trace (unless you change the parameters to require a new one), it uses the same data. It will do a new trace next cycle without question because things may have moved/changed then. Plus, I thought using one big function was a huge triumph, the code used to be twice or three times as long before I unified it.

    Although I do see that stuffing more parameters into a return could work too, using a table you think? Maybe as a new function I could. I'll look into it.

    I think people can figure out that by getting an entity they can query it's position too. The pos can be used for many things other than just entities.

    I was using holoemitters one time and since I had the rangerPos I could tell it exactly where to put the spot, and it wasn't hitting an entity so that wouldn't have helped.
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  6. #6
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by ZeikJT View Post
    If it's still on the same interval then it doesn't do another trace (unless you change the parameters to require a new one), it uses the same data. It will do a new trace next cycle without question because things may have moved/changed then. Plus, I thought using one big function was a huge triumph, the code used to be twice or three times as long before I unified it.
    Yeah, having one big internal function is good, it wasn't that, what I was referring to is that you know have 9 functions, 3 for each possible return. Instead of 3 functions that returns the 3 values (pos, hit, ent). So if you add one more type (say, reflection vector/hit angle), if will become 12 functions, one more, 15 functions, etc. EDIT: If you want to be able to input vectors and have 4 return types, it is suddenly 16 functions. It becomes unmanageable if you were to extend it.

    Quote Originally Posted by ZeikJT View Post
    Although I do see that stuffing more parameters into a return could work too, using a table you think? Maybe as a new function I could. I'll look into it.
    My recommendation would be to create your own datatype (like vector/table), that holds the necessary information and provides, for instance 3 functions: entity(), pos() and hit() (hit() isn't strictly necessary because you can do checks on the data type itself, to see if it is true or false, but that might be confusing for some, or unknown to many).

    It isn't hard at all.

    Quote Originally Posted by ZeikJT View Post
    I think people can figure out that by getting an entity they can query it's position too. The pos can be used for many things other than just entities.

    I was using holoemitters one time and since I had the rangerPos I could tell it exactly where to put the spot, and it wasn't hitting an entity so that wouldn't have helped.
    Yeah, I forgot about that, yeah, querying the entity for position would not be the same thing.

    Also, I'm not sure if you can use equality on the gmod-vector, I think it will return true only if both reference the same object.

    Perhaps it would also be more meaningful to actually input actual angles instead of the odd and restricted X/Y-skewing. Could be something to think about. EDIT: Or for that matter, be able to provide an actual vector instead (relative to the entity).
    Last edited by Syranide; 01-15-2009 at 05:15 AM.

  7. #7
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by Syranide View Post
    Yeah, having one big internal function is good, it wasn't that, what I was referring to is that you know have 9 functions, 3 for each possible return. Instead of 3 functions that returns the 3 values (pos, hit, ent). So if you add one more type (say, reflection vector/hit angle), if will become 12 functions, one more, 15 functions, etc. EDIT: If you want to be able to input vectors and have 4 return types, it is suddenly 16 functions. It becomes unmanageable if you were to extend it.

    My recommendation would be to create your own datatype (like vector/table), that holds the necessary information and provides, for instance 3 functions: entity(), pos() and hit() (hit() isn't strictly necessary because you can do checks on the data type itself, to see if it is true or false, but that might be confusing for some, or unknown to many).

    It isn't hard at all.
    Wow, I hadn't even fathomed my own data type. I'll look into it, if it can compress my existing functions down AND make it more modular then I'm all for it.
    Also, I had a rangerHit function for a while, but I decided it was overkill and they could just look at the ranger distance return instead. If I did this datatype conversion then it wouldn't be unreasonable to reinclude it. After all, I could provide all the data that the trace could dish out and then some.

    Quote Originally Posted by Syranide View Post
    Yeah, I forgot about that, yeah, querying the entity for position would not be the same thing.

    Also, I'm not sure if you can use equality on the gmod-vector, I think it will return true only if both reference the same object.

    Perhaps it would also be more meaningful to actually input actual angles instead of the odd and restricted X/Y-skewing. Could be something to think about. EDIT: Or for that matter, be able to provide an actual vector instead (relative to the entity).
    Alright, I wanted to keep the skew the same just for the sake of smooth transition for programs already written around using regular rangers, but I can try my hand at making it more intuitive with angles.

    Actual vector? You mean a direction vector? Essentially pointing at the object and not just a position? Yeah, that's simple just take the hit.position and subtract the entity position. You could even normalize it if you wanted to (Vector thruster?).
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  8. #8
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by ZeikJT View Post
    Wow, I hadn't even fathomed my own data type. I'll look into it, if it can compress my existing functions down AND make it more modular then I'm all for it.
    Also, I had a rangerHit function for a while, but I decided it was overkill and they could just look at the ranger distance return instead. If I did this datatype conversion then it wouldn't be unreasonable to reinclude it. After all, I could provide all the data that the trace could dish out and then some.



    Alright, I wanted to keep the skew the same just for the sake of smooth transition for programs already written around using regular rangers, but I can try my hand at making it more intuitive with angles.

    Actual vector? You mean a direction vector? Essentially pointing at the object and not just a position? Yeah, that's simple just take the hit.position and subtract the entity position. You could even normalize it if you wanted to (Vector thruster?).
    Keep skew, it's good, but you can add more ways, what you want to use depends on your application, angles can be good for contraptions, X/Y-skew good for cameras.

    What I meant is, currently you define the vector from the entity/E2 by X/Y-skew and distance. Why not allow the user to define the vector instead, meaning that vector(0,0,Distance) would be your "default "case, vector(Distance,0,0) would cause it to go straight in the X-direction (relative to the E2). It should be pretty straight forward to implement. What you currently do is basically vector(X,Y,Distance), although not exactly.
    Last edited by Syranide; 01-15-2009 at 05:53 AM.

  9. #9
    Wire Sofaking ZeikJT's Avatar
    Join Date
    Dec 2008
    Location
    California
    Posts
    1,391

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by Syranide View Post
    Keep skew, it's good, but you can add more ways, what you want to use depends on your application, angles can be good for contraptions, X/Y-skew good for cameras.
    Will do! ^_^

    Quote Originally Posted by Syranide View Post
    What I meant currently you define the vector from the entity/E2 by X/Y-skew and distance. Why not allow the user to define the vector instead, meaning that vector(0,0,Distance) would be your "default "case, vector(Distance,0,0) would cause it to go straight in the X-direction (relative to the E2). It should be pretty straight forward to implement. What you currently do is basically vector(X,Y,Distance), although not exactly.
    Ah yes it is very simple indeed. Traces use start and end positions so adding the vector to the current entity position would make it work exactly as you describe, consider it guaranteed in the next update. Suddenly vectors sound like a fantastic idea.

    Thanks for all the suggestions! You've always got good ones

    Also, I was thinking of being able to input a destination position on the map directly, how does that sound? Naturally it would come in distance limiting and free range flavors.
    Against stupidity the Gods themselves contend in vain.
    -Friedrich Schiller

    The flame puts me in the mood to "Do it!".
    -Dart, Legend of Dragoon

  10. #10
    Expressionism 2.0 Syranide's Avatar
    Join Date
    Mar 2007
    Location
    Sweden
    Posts
    4,573

    Default Re: Built-In Ranger - Expression2

    Quote Originally Posted by ZeikJT View Post
    Ah yes it is very simple indeed. Traces use start and end positions so adding the vector to the current entity position would make it work exactly as you describe, consider it guaranteed in the next update. Suddenly vectors sound like a fantastic idea.
    Not just add, you also need to rotate, or use LocalToWorld() on it so it is relative to the E2/gate (so that the vector isn't just world axes), alternatively, multiply right/front/up vectors with X/Y/Z.

    Quote Originally Posted by ZeikJT View Post
    Thanks for all the suggestions! You've always got good ones
    Just happy to help ^_^

    Quote Originally Posted by ZeikJT View Post
    Also, I was thinking of being able to input a destination position on the map directly, how does that sound? Naturally it would come in distance limiting and free range flavors.
    Yeah, that works too, I thought about that before too, but I'm not sure what it would be useful for, but it never hurts, and someone will probably find some use for it. One thing that I know some people would love though is basically deferred traces, so you can specify startpos and endpos yourself, could allow for some very complex things.

+ Reply to Thread
Page 1 of 5 123 ... LastLast

Similar Threads

  1. Wire built into map
    By Schilcote in forum Installation and Malfunctions Support
    Replies: 7
    Last Post: 03-18-2009, 07:03 PM
  2. E2: Built In text-receiver
    By ahref in forum Ideas & Suggestions
    Replies: 16
    Last Post: 03-08-2009, 05:05 PM
  3. Expression2 Debugger EXE
    By emspike in forum Ideas & Suggestions
    Replies: 11
    Last Post: 03-05-2009, 03:12 PM
  4. How do I get a number pad input built into an Expression
    By Xtensity in forum Installation and Malfunctions Support
    Replies: 4
    Last Post: 05-06-2008, 04:28 PM
  5. Negate Built into thrusters.
    By CBBP in forum Ideas & Suggestions
    Replies: 2
    Last Post: 05-29-2007, 11:47 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
proceed-collector
proceed-collector
proceed-collector
proceed-collector
linguistic-parrots
linguistic-parrots
linguistic-parrots
linguistic-parrots