So I was bored this weekend and implemented dynamic target selectors, like Mincraft has them for SourceMod. This means there are now 4 new target selectors you can filter.
@pNearest player (sort=nearest,limit=1)@rRandom player (sort=random,limit=1)@sSelf (equal to @me, but filterable)@!sEveryone but Self (equal to @!me, but filterable)@aEveryone (no sorting or limit; equal to @all, but filterable)
These will populate the base list of targets that can then be filtered.
Filters are specified in square brackes and can not contains spaces, more square brackets, quotes, or argument/value separators. Specify As many or little as you want, duplicate argument will use the last value.
Arguments available by default:
sort=SortingSorting being one of:nearest,nearNearest players firstfurthest,farFurthest players firstrandom,rngRandom target sortingarbitrary,anyUndefined order
limit=NumberNumber of targets to return (positive integer)c=Numbercombination ofsortandlimit- positive is nearest N players
- positive is furthest -N players
r=NumberMaximum distance to caller in HUrm=NumberMinimum distance to caller in HUdistance=RangeDistance range to caller in HUx=RangeThe targets x coordinate has to be within the rangey=RangeThe targets y coordinate has to be within the rangez=RangeThe targets z coordinate has to be within the rangedx=RangeDistance between targets x and callers x has to be within rangedy=RangeDistance between targets y and callers y has to be within rangedz=RangeDistance between targets z and callers z has to be within rangeteam=TeamTeam specifyer (can be negated with ! prefix)0,noneUnassigned1,specSpectators2,T,RED,survivor,combinefor Team 23,CT,BLU,infected,rebelfor Team 3
flag=FlagsCheck for all admin flags (can be negted with ! prefix)hp=RangeTarget health has to be within range
Range values are formatted according to this list and can be negated using a ! prefix:
- A literal value: attrib=100
- An upper bound: attrib=..100
- A lower bound: attrib=100..
- Both bounds: attribg=-100..100
If a plugin appears to be broken when using a dynamic selector, or if you dont want to re-type
the selector every time you run a batch of commands, you can use @selected and @macro.
/macroselect stores any arbitrary argument as target parameter, later accessible as @macro.
/select will store the current set of matching players to reuse later with @selected.
The two use cases are random selections and negations. Using @r with /macroselect will pick
a new random player every call, it just stores @r. If you want everyone but staff for example,
this works better because it will retarget every time you run a command, even if players join or
leave. /select on the other hand stores the set of players immediately, and @selected returns
every player from the time of selection, that is still on the server when running a command. So
@r will behave consistently, but players joining after /select are never targeted with @selected.
/macroselect and /select are by default accessible to everyone. For example:
sm_select @r[flag=!z]; sm_slay @selected
This still uses target selectors, so you can't just make commands magically longer!
Plugins can also register additional argument parsers with these natives:
OnPluginStart() {
DTS_RegisterTargetFilter("hp", dts_healthFilter);
}
OnPluginEnd() {
DTS_DropTargetFilter();
}
bool dts_healthFilter(int caller, int target, const char[] key, const char[] value) {
if (!IsClientInGame(target)) return false;
int result = DTS_IntInRange(GetClientHealth(target), value);
if (result == -1) {
SetFilterError("Invalid value for argument 'hp', value or range expected!");
return result == 1;
}Full command example: sm_slay @a[rm=100,team=BLU]