Skip to content
Denneisk edited this page Oct 21, 2023 · 7 revisions

Table of Contents

Quota

There is a limit to how many find operations you can do over time.
By default this is up to 10 operations per chip, which regenerate at a rate of 20 per second.

This means you can run up to 10 operations at once, and it will take 500ms to completely fill the qouta back up.
You could also constantly run one operation every 50ms (about once every 4 ticks).

findCanQuery() will return if you can currently query at least once, findCount() will get you the currently remaining calls.
findMax() and findUpdateRate() will get you the max find amount and regeneration rate (time in seconds to regenerate by one) respectively.

Note: findPlayerBy* work seperately from the filter systems, but share the same quota, so make sure to use these functions as sparingly as possible and cache the results.

Usage

Pretty much all remaining find functions can be divided into 4 groups and only work correctly when used in order:

  • 1: First you can setup a whitelist and/or blacklist.
  • 2: Then you have to call one find operation
  • 3: Now you can clip the results as often as you want, and/or sortByDistance
  • 4: Finally you should retrieve the results (else it was all for nothing, right?)
  • (5:) You may now go back to any previous point and continue again from there. Black/whitelist and last results are stored until you change them again (or reset the E2).

1. Whitelist and Blacklist

Filters

Filters you can use in the whitelist and blacklist are:

Filter Input Info
Class string Uses lua patterns, see note below
Model string Uses lua patterns, see note below
Entity entity
Entities array (of entities) same list as Entity
PlayerProps entity (player) props owned by that player

Note

Class and Model filters will use Luas string.match to check if the class/model matches a whitelist entry, which uses patterns, which are similar to RegEx, but less powerful.
This means that if you put just "prop", it will match as long as "prop" anywhere in the class/model. See the examples below for some common usecases.

Below those filters are replaced with *, so findInclude* refers to findIncludeClass/findIncludeModel/...

All these function have no return value.

Whitelist

findInclude* will add a filter to the whitelist, that all following find operations will obey. You can add as many filter criteriums as you want, but they will be additive, so all entites that fit any of the filters will be allowed.

If you leave a filter type empty it will allow everything by default. You can clear the whitelist with findClearWhitelist() or findClearWhite*List().

To remove a specific filter from the whitelist you can use findDisallow*. This has to match an existing filter entry to work.

The Whitelist will stays as you set it up until you change it again or reset the E2. It persists through executions, so make sure to clear it if you want to use a different filter set..

Example

findIncludeClass("prop") # All entites whose class contains "prop", ie "prop_physics" or "prop_vehicle"
findIncludeClass("^prop_physics$") # Matching exactly "prop_physics", ie not "physics_prop_entity" 
findIncludeClass("^gmod_wire_[eh]") # Class begins with "gmod_wire_e" or "gmod_wire_h" (Using lua patterns)
findIncludeEntity(entity():isWeldedTo()) # Entity the E2 is placed on
findIncludePlayerProps(owner()) # All props owned by E2 owner

This whitelist will allow any entities that fit ANY (but at least one) of the above filters, so all your things, the entity the E2 is placed on as well as any entities which fit one of the class filters.

Blacklist

The blacklist works identical to the whitelist, except it will block props that match one it's filters instead of allowing only those. As above, a empty filter type will allow anything. The functions are findExclude* to add, findAllow* to remove, as well as findClearBlacklist() and findClearBlack*List().

2. Actual Find Operation

These are the functions that will actually search and filter for the entities, and the only ones that actually count against the quota. They are just proxies for lua functions, so check those out for more in-depth information.

All these function return the number of entities found, see below on how to get actual entities to use in E2.

Function Parameters Explaination Lua backend
findByName string Name finds all entites with the given name ents.FindByName
findByModel string Model finds all entites with the given model, supports * wildcards ents.FindByModel
findByClass string Class finds all entites with the given class, supports * wildcards ents.FindByClass
findInSphere vector Center, number Radius finds all entities with the radius around the center ents.findInSphere
findInBox vector min, vector max finds all entities inside the world-axis aligned box (min <= pos <= max for X, Y and Z) ents.findInBox
findInCone vector tip, vector direction, number length, number degree See below custom implementation

findInCone is a complicated one, it finds all entities which are within a certain angle from the direction and within the length.
It is much easier to just show an example usecase:

findInCone( Player:shootPos(), Player:eye(), 1000, 10) will find all props that are within a 10 degrees circle of the players crosshair direction and within 1000 units.

See the wiremod source for more info.

Note that the E2 will never find itself or certain "weird" entities from the hardcoded blacklist, like spawnpoints or the physgun beam.

3. Clipping

After a find operation the results are stored internally, and can efficiently be filtered by lua using the findClipFrom* (to exclude something) and findClipTo* (to exclude everything else).
You won't need these for most things, so feel free to skip this section.

These function will return the remaining number of entities after filtering. You can use any filters from the whitelist and blacklist and some additional ones:

findClipTo/FromName(string Name) to filter the name. Just like the whitelist and blacklist filters for class and model you can also use partial strings or patterns here.

findClipTo/FromSphere(vector Center, number Radius) to only allow entities inside or outside the defined sphere.

findClipTo/FromBox(vector Min, vector Max) to only allow entities inside or outside the defined box.

findClipToRegion(vector Origin, vector Normal) to only allow entities on one side of a plane defined by origin and normal.
Internally it checks if the direction from Origin to the entity is within 90 degrees of the Normal, or - for the math fans - (entpos-origin):normalized():dot(normal) > 0.
Note that there is no findClipFromRegion, as you just have to negate the direction vector to get the opposite side of the plane. Again a practical example: (Player:shootPos(), vec(0,0,1)) would mean everything "above" (but not just straight above) the players eye position.

4. Results

findSortByDistance(vector position) doesn't strictly fit in this phase, but it is quite useful. It will sort all entities in the result list by their distance from the given position from near to far and also return the number of entities in the list.

You can get the results from a find operation in a few different ways, depending on what you need:

find() will get you the first entity from the top of the list, and findResult(N) will give you the N-th entity.

findClosest(vector position) will get you the entity that is closest to the position.

findToArray() and findToTable() allow you to retrieve the full result list, either as array or in the numeric part of a table.

You can call as many functions to retrieve results as you want, and even refine the results furthing by clipping or sorting. This will not count against the find quota, so sometimes find operations can be "saved" by smart usage of clipping.

Examples

Find entities in a box

if (first()) {  # only run the following code on chip spawn, as it creates holos
  local Size = 1000  # Corner distance from chip. This is half the length of the created cube

  local Chip = entity()
  local MinCorner = Chip:pos() - vec(Size)  # note that findInBox is always axis aligned and the second vector must be greater in all axis
  local MaxCorner = Chip:pos() + vec(Size)

  holoCreate(1, MinCorner, vec(1 + Size*0.0015))
  holoCreate(2, MaxCorner, vec(1 + Size*0.0015))

  findExcludeEntity(Chip) # Blacklist the chip from being found
  findExcludeClass("gmod_wire_hologram") # Blacklist any entities with the class 'gmod_wire_hologram'

  local NumInBox = findInBox(MinCorner, MaxCorner)  # do the actual find operation, get number of results
  findSortByDistance(Chip:pos())  # sort results by distance
  local Results = findToArray()  # export the (now sorted) results to an array

  print(format("Found %u entities in the box! Closest one is a %s", NumInBox, Results[1,entity]:type()))
}

Expression 2 ⚛️

Tutorials (In learning order) 🎓

Extras ❔

Tools 🛠️

Click To Expand

Advanced

Beacon 💡

Control 🎛️

Data 💿

Detection 👀

Display 💻

Render

I/O 🔌

Physics 🚀

Utilities 🛠️

RFID

Wireless 🛜

Gates 🚥

Click To Expand

TBD

Clone this wiki locally