From 4ce007470c1496a3ff4574075281e6912019e533 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sun, 13 Mar 2016 18:46:40 +1100 Subject: [PATCH] FOREACH_ENTITY_RADIUS --- qcsrc/common/debug.qh | 96 ++++++++++---------- qcsrc/common/effects/qc/damageeffects.qc | 13 +-- qcsrc/common/physics/movetypes/movetypes.qc | 15 ++-- qcsrc/common/physics/movetypes/push.qc | 33 ++++--- qcsrc/common/t_items.qc | 16 ++-- qcsrc/common/triggers/teleporters.qc | 4 +- qcsrc/lib/iter.qh | 15 ++++ qcsrc/lib/warpzone/common.qc | 99 ++++++++++----------- qcsrc/server/anticheat.qc | 11 +-- qcsrc/server/anticheat.qh | 2 +- 10 files changed, 147 insertions(+), 157 deletions(-) diff --git a/qcsrc/common/debug.qh b/qcsrc/common/debug.qh index e1d43f34f..eb77d7bce 100644 --- a/qcsrc/common/debug.qh +++ b/qcsrc/common/debug.qh @@ -69,83 +69,81 @@ bool autocvar_debugdraw; FOREACH_ENTITY(true, LAMBDA( if (it.debugdraw_last == debugdraw_frame) continue; int ofs = 0; - for (entity e = findradius(it.origin, 100); e; e = e.chain) - { - if (e.debugdraw_last == debugdraw_frame) continue; - e.debugdraw_last = debugdraw_frame; - vector rgb = (e.debug) ? '0 0 1' : '1 0 0'; - if (autocvar_debugdraw_filterout != "" && strhasword(autocvar_debugdraw_filterout, e.classname)) continue; - if (autocvar_debugdraw_filter != "" && !strhasword(autocvar_debugdraw_filter, e.classname)) continue; + FOREACH_ENTITY_RADIUS(it.origin, 100, it.debugdraw_last != debugdraw_frame, { + it.debugdraw_last = debugdraw_frame; + vector rgb = (it.debug) ? '0 0 1' : '1 0 0'; + if (autocvar_debugdraw_filterout != "" && strhasword(autocvar_debugdraw_filterout, it.classname)) continue; + if (autocvar_debugdraw_filter != "" && !strhasword(autocvar_debugdraw_filter, it.classname)) continue; if (autocvar_debugdraw == 3) { - if (!e.entnum) continue; + if (!it.entnum) continue; } if (autocvar_debugdraw == 4) { - if (e.origin) continue; + if (it.origin) continue; } if (autocvar_debugdraw == 5) { - if (!e.debug) continue; + if (!it.debug) continue; } else if (autocvar_debugdraw > 5) { bool flag = true; do { -// if (e.modelindex) break; -// if (e.absmin) break; -// if (e.absmax) break; -// if (e.entnum) break; -// if (e.drawmask) break; -// if (e.predraw) break; -// if (e.movetype) break; - if (e.solid) break; -// if (e.origin) break; -// if (e.oldorigin) break; -// if (e.velocity) break; -// if (e.angles) break; -// if (e.avelocity) break; -// if (e.classname) break; -// if (e.model) break; -// if (e.frame) break; -// if (e.skin) break; -// if (e.effects) break; -// if (e.mins) break; -// if (e.maxs) break; -// if (e.size) break; -// if (e.touch) break; -// if (e.use) break; -// if (e.think) break; -// if (e.blocked) break; -// if (e.nextthink) break; -// if (e.chain) break; -// if (e.netname) break; -// if (e.enemy) break; -// if (e.flags) break; -// if (e.colormap) break; -// if (e.owner) break; +// if (it.modelindex) break; +// if (it.absmin) break; +// if (it.absmax) break; +// if (it.entnum) break; +// if (it.drawmask) break; +// if (it.predraw) break; +// if (it.movetype) break; + if (it.solid) break; +// if (it.origin) break; +// if (it.oldorigin) break; +// if (it.velocity) break; +// if (it.angles) break; +// if (it.avelocity) break; +// if (it.classname) break; +// if (it.model) break; +// if (it.frame) break; +// if (it.skin) break; +// if (it.effects) break; +// if (it.mins) break; +// if (it.maxs) break; +// if (it.size) break; +// if (it.touch) break; +// if (it.use) break; +// if (it.think) break; +// if (it.blocked) break; +// if (it.nextthink) break; +// if (it.chain) break; +// if (it.netname) break; +// if (it.enemy) break; +// if (it.flags) break; +// if (it.colormap) break; +// if (it.owner) break; flag = false; } while (0); if (!flag) continue; } - else if (is_pure(e)) + else if (is_pure(it)) { if (autocvar_debugdraw < 2) continue; rgb.y = 1; } - vector o = e.origin; - if (e.tag_entity) - o += e.tag_entity.origin; + vector o = it.origin; + if (it.tag_entity) + o += it.tag_entity.origin; vector pos = project_3d_to_2d(o); if (pos.z < 0) continue; pos.z = 0; pos.y += ofs * sz; drawcolorcodedstring2(pos, - sprintf("%d: '%s'@%s", (e.debug ? e.sv_entnum : etof(e)), - e.classname, e.sourceLoc), + sprintf("%d: '%s'@%s", (it.debug ? it.sv_entnum : etof(it)), + it.classname, it.sourceLoc), sz * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL); ++ofs; - } + }); )); } #endif diff --git a/qcsrc/common/effects/qc/damageeffects.qc b/qcsrc/common/effects/qc/damageeffects.qc index 06f8ea464..ba60e51bd 100644 --- a/qcsrc/common/effects/qc/damageeffects.qc +++ b/qcsrc/common/effects/qc/damageeffects.qc @@ -223,15 +223,10 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew) else forcemul = 1; - for(entity e = findradius(w_org, rad + MAX_DAMAGEEXTRARADIUS); e; e = e.chain) - { - setself(e); - // attached ents suck - if(self.tag_entity) - continue; - + FOREACH_ENTITY_RADIUS(w_org, rad + MAX_DAMAGEEXTRARADIUS, !it.tag_entity, { + setself(it); vector nearest = NearestPointOnBox(self, w_org); - if(rad) + if (rad) { thisdmg = ((vlen (nearest - w_org) - bound(MIN_DAMAGEEXTRARADIUS, self.damageextraradius, MAX_DAMAGEEXTRARADIUS)) / rad); if(thisdmg >= 1) @@ -275,7 +270,7 @@ NET_HANDLE(ENT_CLIENT_DAMAGEINFO, bool isNew) if(self.isplayermodel) hitplayer = true; // this impact damaged a player - } + }); setself(this); if(DEATH_ISVEHICLE(w_deathtype)) diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index ce469ed6a..2c9c5894b 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -343,11 +343,10 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr entity oldother = other; - for (entity e = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); e; e = e.chain) - { - if(e.solid == SOLID_TRIGGER && e != this) - if(e.move_nomonsters != MOVE_NOMONSTERS && e.move_nomonsters != MOVE_WORLDONLY) - if(e.move_touch && boxesoverlap(e.absmin, e.absmax, this.absmin, this.absmax)) + FOREACH_ENTITY_RADIUS(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, { + if (it.solid == SOLID_TRIGGER && it != this) + if (it.move_nomonsters != MOVE_NOMONSTERS && it.move_nomonsters != MOVE_WORLDONLY) + if (it.move_touch && boxesoverlap(it.absmin, it.absmax, this.absmin, this.absmax)) { other = this; @@ -356,14 +355,14 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGr trace_fraction = 1; trace_inwater = false; trace_inopen = true; - trace_endpos = e.move_origin; + trace_endpos = it.move_origin; trace_plane_normal = '0 0 1'; trace_plane_dist = 0; trace_ent = this; - WITH(entity, self, e, e.move_touch()); + WITH(entity, self, it, it.move_touch()); } - } + }); other = oldother; } diff --git a/qcsrc/common/physics/movetypes/push.qc b/qcsrc/common/physics/movetypes/push.qc index dc455944c..dd89a4099 100644 --- a/qcsrc/common/physics/movetypes/push.qc +++ b/qcsrc/common/physics/movetypes/push.qc @@ -53,9 +53,8 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove if (this.move_movetype != MOVETYPE_FAKEPUSH) { - for (entity check = findradius(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin)); check; check = check.chain) - { - switch (check.move_movetype) + FOREACH_ENTITY_RADIUS(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, { + switch (it.move_movetype) { case MOVETYPE_NONE: case MOVETYPE_PUSH: @@ -67,17 +66,17 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove break; } - if (check.owner == this) + if (it.owner == this) continue; - if (this.owner == check) + if (this.owner == it) continue; - vector pivot = check.mins + 0.5 * (check.maxs - check.mins); + vector pivot = it.mins + 0.5 * (it.maxs - it.mins); vector move; if (rotated) { - vector org = (check.move_origin - this.move_origin) + pivot; + vector org = (it.move_origin - this.move_origin) + pivot; vector org2; org2.x = org * v_forward; org2.y = org * v_right; @@ -90,34 +89,34 @@ void _Movetype_PushMove(entity this, float dt) // SV_PushMove } // physics objects need better collisions than this code can do - if (check.move_movetype == 32) // MOVETYPE_PHYSICS + if (it.move_movetype == 32) // MOVETYPE_PHYSICS { - check.move_origin = check.move_origin + move; - _Movetype_LinkEdict(check, true); + it.move_origin = it.move_origin + move; + _Movetype_LinkEdict(it, true); continue; } // try moving the contacted entity this.solid = SOLID_NOT; bool flag = false; - flag = _Movetype_PushEntity(check, move, true); + flag = _Movetype_PushEntity(it, move, true); if (!flag) { - // entity "check" got teleported - check.move_angles_y += trace_fraction * moveangle.y; + // entity "it" got teleported + it.move_angles_y += trace_fraction * moveangle.y; this.solid = savesolid; continue; // pushed enough } // FIXME: turn players specially - check.move_angles_y += trace_fraction * moveangle.y; + it.move_angles_y += trace_fraction * moveangle.y; this.solid = savesolid; // this trace.fraction < 1 check causes items to fall off of pushers // if they pass under or through a wall // the groundentity check causes items to fall off of ledges - if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != this)) - check.move_flags &= ~FL_ONGROUND; - } + if (it.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || it.move_groundentity != this)) + it.move_flags &= ~FL_ONGROUND; + }); } this.move_angles_x -= 360.0 * floor(this.move_angles.x * (1.0 / 360.0)); diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index ef7438c96..1d3ce373d 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -1155,16 +1155,12 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(autocvar_spawn_debug >= 2) { - for(entity otheritem = findradius(this.origin, 3); otheritem; otheritem = otheritem.chain) - { - // why not flags & fl_item? - if(otheritem.is_item) - { - LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); - LOG_TRACE(" vs ", otheritem.netname, vtos(otheritem.origin), "\n"); - error("Mapper sucks."); - } - } + // why not flags & fl_item? + FOREACH_ENTITY_RADIUS(this.origin, 3, it.is_item, { + LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); + LOG_TRACE(" vs ", it.netname, vtos(it.origin), "\n"); + error("Mapper sucks."); + }); this.is_item = true; } diff --git a/qcsrc/common/triggers/teleporters.qc b/qcsrc/common/triggers/teleporters.qc index 801776857..40ba61f65 100644 --- a/qcsrc/common/triggers/teleporters.qc +++ b/qcsrc/common/triggers/teleporters.qc @@ -304,9 +304,7 @@ void WarpZone_PostTeleportPlayer_Callback(entity pl) Reset_ArcBeam(pl, v_forward); UpdateCSQCProjectileAfterTeleport(pl); UpdateItemAfterTeleport(pl); - { - WITH(entity, self, pl, anticheat_fixangle()); - } + if (IS_PLAYER(pl)) anticheat_fixangle(pl); #endif // "disown" projectiles after teleport if(pl.owner) diff --git a/qcsrc/lib/iter.qh b/qcsrc/lib/iter.qh index f5200a41a..89b455ab5 100644 --- a/qcsrc/lib/iter.qh +++ b/qcsrc/lib/iter.qh @@ -107,6 +107,21 @@ noref string _FOREACH_ENTITY_mutex; } MACRO_END +#ifndef MENUQC +entity(vector org, float rad, .entity tofield) _findradius_tofield = #22; +#define FOREACH_ENTITY_RADIUS(org, dist, cond, body) FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) +.entity _FOREACH_ENTITY_RADIUS_next; +noref string _FOREACH_ENTITY_RADIUS_mutex; +#define FOREACH_ENTITY_RADIUS_UNORDERED(org, dist, cond, body) \ + MACRO_BEGIN { \ + if (_FOREACH_ENTITY_RADIUS_mutex) LOG_SEVEREF("Loop mutex held by %s", _FOREACH_ENTITY_RADIUS_mutex); \ + _FOREACH_ENTITY_RADIUS_mutex = __FUNC__; \ + entity _foundchain_first = _findradius_tofield(org, dist, _FOREACH_ENTITY_RADIUS_next); \ + FOREACH_LIST(_foundchain, _FOREACH_ENTITY_RADIUS_next, cond, body); \ + _FOREACH_ENTITY_RADIUS_mutex = string_null; \ + } MACRO_END +#endif + #define FOREACH_ENTITY_CLASS(class, cond, body) ORDERED(FOREACH_ENTITY_CLASS)(class, cond, body) #define FOREACH_ENTITY_CLASS_ORDERED(class, cond, body) FOREACH_ENTITY_ORDERED(it.classname == class && (cond), body) diff --git a/qcsrc/lib/warpzone/common.qc b/qcsrc/lib/warpzone/common.qc index b3332f36f..99332dba6 100644 --- a/qcsrc/lib/warpzone/common.qc +++ b/qcsrc/lib/warpzone/common.qc @@ -572,8 +572,8 @@ vector WarpZoneLib_NearestPointOnBox(vector mi, vector ma, vector org) bool WarpZoneLib_BadEntity(entity e) { - string s = e.classname; if (is_pure(e)) return true; + string s = e.classname; switch (s) { // case "net_linked": // actually some real entities are linked without classname, fail @@ -590,68 +590,62 @@ bool WarpZoneLib_BadEntity(entity e) .float WarpZone_findradius_hit; .entity WarpZone_findradius_next; -void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, vector transform, vector shift, float needlineofsight) -// blast origin of current search original blast origin how to untransform (victim to blast system) -{ - vector org_new; - vector org0_new; - vector shift_new, transform_new; - vector p; - entity e, e0; - entity wz; - if(rad <= 0) - return; - e0 = findradius(org, rad); - wz = world; - - for(e = e0; e; e = e.chain) - { - if(WarpZoneLib_BadEntity(e)) - continue; - p = WarpZoneLib_NearestPointOnBox(e.origin + e.mins, e.origin + e.maxs, org0); - if(needlineofsight) +void WarpZone_FindRadius_Recurse( + /** blast origin of current search */ + vector org, + float rad, + /** original blast origin */ + vector org0, + /** how to untransform (victim to blast system) */ + vector transform, + vector shift, + bool needlineofsight) +{ + if (rad <= 0) return; + entity wz = NULL; + FOREACH_ENTITY_RADIUS(org, rad, !WarpZoneLib_BadEntity(it), { + vector p = WarpZoneLib_NearestPointOnBox(it.origin + it.mins, it.origin + it.maxs, org0); + if (needlineofsight) { - traceline(org, p, MOVE_NOMONSTERS, e); - if(trace_fraction < 1) - continue; + traceline(org, p, MOVE_NOMONSTERS, it); + if (trace_fraction < 1) continue; } - if(!e.WarpZone_findradius_hit || vlen2(e.WarpZone_findradius_dist) > vlen2(org0 - p)) + if (!it.WarpZone_findradius_hit || vlen2(it.WarpZone_findradius_dist) > vlen2(org0 - p)) { - e.WarpZone_findradius_nearest = p; - e.WarpZone_findradius_dist = org0 - p; - e.WarpZone_findradius_findorigin = org; - e.WarpZone_findradius_findradius = rad; - if(e.classname == "warpzone_refsys") + it.WarpZone_findradius_nearest = p; + it.WarpZone_findradius_dist = org0 - p; + it.WarpZone_findradius_findorigin = org; + it.WarpZone_findradius_findradius = rad; + if (it.classname == "warpzone_refsys") { // ignore, especially: do not overwrite the refsys parameters } - else if(e.classname == "trigger_warpzone") + else if (it.classname == "trigger_warpzone") { - e.WarpZone_findradius_next = wz; - wz = e; - e.WarpZone_findradius_hit = 1; - e.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again - e.enemy.WarpZone_findradius_hit = 1; + it.WarpZone_findradius_next = wz; + wz = it; + it.WarpZone_findradius_hit = 1; + it.enemy.WarpZone_findradius_dist = '0 0 0'; // we don't want to go through this zone ever again + it.enemy.WarpZone_findradius_hit = 1; } else { - e.warpzone_transform = transform; - e.warpzone_shift = shift; - e.WarpZone_findradius_hit = 1; + it.warpzone_transform = transform; + it.warpzone_shift = shift; + it.WarpZone_findradius_hit = 1; } } - } - for(e = wz; e; e = e.WarpZone_findradius_next) + }); + for(entity e = wz; e; e = e.WarpZone_findradius_next) { - if(WarpZoneLib_BadEntity(e)) - continue; + if (WarpZoneLib_BadEntity(e)) continue; - org0_new = WarpZone_TransformOrigin(e, org); + vector org0_new = WarpZone_TransformOrigin(e, org); traceline(e.warpzone_targetorigin, org0_new, MOVE_NOMONSTERS, e); - org_new = trace_endpos; + vector org_new = trace_endpos; - transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform); - shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift); + vector transform_new = AnglesTransform_Multiply(e.warpzone_transform, transform); + vector shift_new = AnglesTransform_Multiply_GetPostShift(e.warpzone_transform, e.warpzone_shift, transform, shift); WarpZone_FindRadius_Recurse( org_new, bound(0, rad - vlen(org_new - org0_new), rad - 8), @@ -662,14 +656,13 @@ void WarpZone_FindRadius_Recurse(vector org, float rad, vector org0, e.enemy.WarpZone_findradius_hit = 0; } } -entity WarpZone_FindRadius(vector org, float rad, float needlineofsight) +entity WarpZone_FindRadius(vector org, float rad, bool needlineofsight) { - entity e0, e; + if (!warpzone_warpzones_exist && !needlineofsight) return findradius(org, rad); WarpZone_FindRadius_Recurse(org, rad, org, '0 0 0', '0 0 0', needlineofsight); - e0 = findchainfloat(WarpZone_findradius_hit, 1); - for(e = e0; e; e = e.chain) - e.WarpZone_findradius_hit = 0; - return e0; + entity list_first = findchainfloat(WarpZone_findradius_hit, 1); + FOREACH_LIST(list, chain, true, it.WarpZone_findradius_hit = 0); + return list_first; } .entity WarpZone_refsys; diff --git a/qcsrc/server/anticheat.qc b/qcsrc/server/anticheat.qc index d076994a7..0e0121db6 100644 --- a/qcsrc/server/anticheat.qc +++ b/qcsrc/server/anticheat.qc @@ -225,17 +225,14 @@ void anticheat_startframe() anticheat_div0_evade_evasion_delta += frametime * (0.5 + random()); } -void anticheat_fixangle() -{SELFPARAM(); - CS(self).anticheat_fixangle_endtime = servertime + ANTILAG_LATENCY(self) + 0.2; +void anticheat_fixangle(entity this) +{ + CS(this).anticheat_fixangle_endtime = servertime + ANTILAG_LATENCY(this) + 0.2; } void anticheat_endframe() {SELFPARAM(); - FOREACH_CLIENT(true, LAMBDA( - if(it.fixangle) - WITH(entity, self, it, anticheat_fixangle()); - )); + FOREACH_CLIENT(it.fixangle, anticheat_fixangle(it)); anticheat_div0_evade_evasion_delta += frametime * (0.5 + random()); } diff --git a/qcsrc/server/anticheat.qh b/qcsrc/server/anticheat.qh index 3bb5d251e..e1055ac44 100644 --- a/qcsrc/server/anticheat.qh +++ b/qcsrc/server/anticheat.qh @@ -13,5 +13,5 @@ float anticheat_getvalue(string name); void anticheat_startframe(); void anticheat_endframe(); -void anticheat_fixangle(); +void anticheat_fixangle(entity this); #endif -- 2.39.2