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
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)
if(self.isplayermodel)
hitplayer = true; // this impact damaged a player
- }
+ });
setself(this);
if(DEATH_ISVEHICLE(w_deathtype))
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;
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;
}
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:
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;
}
// 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));
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;
}
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)
} 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)
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
.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),
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;
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());
}
void anticheat_startframe();
void anticheat_endframe();
-void anticheat_fixangle();
+void anticheat_fixangle(entity this);
#endif