From c98bb7952507474a128d9b250abccb8a77bb6fd6 Mon Sep 17 00:00:00 2001 From: TimePath Date: Sun, 22 Nov 2015 16:10:52 +1100 Subject: [PATCH] lib/iter: FOREACH_ENTITY --- qcsrc/client/view.qc | 8 +-- qcsrc/common/debug.qh | 9 ++- qcsrc/common/mutators/mutator/itemstime.qc | 47 +++----------- qcsrc/common/turrets/sv_turrets.qc | 27 +++----- qcsrc/lib/iter.qh | 33 ++++++++++ qcsrc/lib/warpzone/server.qc | 64 +++++++++---------- qcsrc/menu/command/menu_cmd.qc | 21 +++--- qcsrc/menu/menu.qc | 9 ++- qcsrc/server/command/vote.qc | 33 +++------- qcsrc/server/g_world.qc | 5 +- .../mutators/mutator/gamemode_assault.qc | 15 ++--- 11 files changed, 116 insertions(+), 155 deletions(-) diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 11c8f431f..41822f54b 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -1500,9 +1500,7 @@ void CSQC_UpdateView(float w, float h) mousepos = mousepos*0.5 + getmousepos(); */ - for(entity e = NULL; (e = nextent(e)); ) if (e.draw) { - WITH(entity, self, e, e.draw(e)); - } + FOREACH_ENTITY(it.draw, LAMBDA(WITH(entity, self, it, it.draw(it)))); addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS); renderscene(); @@ -1832,9 +1830,7 @@ void CSQC_UpdateView(float w, float h) } else */ // draw 2D entities - for (entity e = NULL; (e = nextent(e)); ) if (e.draw2d) { - WITH(entity, self, e, e.draw2d(e)); - } + FOREACH_ENTITY(it.draw2d, LAMBDA(WITH(entity, self, it, it.draw2d(it)))); Draw_ShowNames_All(); Debug_Draw(); diff --git a/qcsrc/common/debug.qh b/qcsrc/common/debug.qh index 7301489f3..76f582ee7 100644 --- a/qcsrc/common/debug.qh +++ b/qcsrc/common/debug.qh @@ -51,11 +51,10 @@ bool autocvar_debugdraw; static int debugdraw_frame; ++debugdraw_frame; const int size = 8; - for (entity e1 = NULL; (e1 = nextent(e1)); ) - { - if (e1.debugdraw_last == debugdraw_frame) continue; + FOREACH_ENTITY(true, LAMBDA( + if (it.debugdraw_last == debugdraw_frame) continue; int ofs = 0; - for (entity e = findradius(e1.origin, 100); e; e = e.chain) + for (entity e = findradius(it.origin, 100); e; e = e.chain) { if (e.debugdraw_last == debugdraw_frame) continue; e.debugdraw_last = debugdraw_frame; @@ -75,7 +74,7 @@ bool autocvar_debugdraw; size * '1 1 0', rgb, 0.5, DRAWFLAG_NORMAL); ++ofs; } - } + )); } #endif diff --git a/qcsrc/common/mutators/mutator/itemstime.qc b/qcsrc/common/mutators/mutator/itemstime.qc index d6b256af3..975eb29f3 100644 --- a/qcsrc/common/mutators/mutator/itemstime.qc +++ b/qcsrc/common/mutators/mutator/itemstime.qc @@ -118,36 +118,13 @@ void Item_ItemsTime_SetTimesForAllPlayers() float Item_ItemsTime_UpdateTime(entity e, float t) { bool isavailable = (t == 0); - if (e.weapons & WEPSET_SUPERWEAPONS) - { - for (entity head = world; (head = nextent(head)); ) - { - if (clienttype(head) != CLIENTTYPE_NOTACLIENT || !(head.weapons & WEPSET_SUPERWEAPONS) || head.instanceOfWeapon) - continue; - if (e == head) - continue; - - if (head.scheduledrespawntime <= time) - isavailable = true; - else if (t == 0 || head.scheduledrespawntime < t) - t = head.scheduledrespawntime; - } - } - else - { - for (entity head = world; (head = nextent(head)); ) - { - if (head.itemdef != e.itemdef) - continue; - if (e == head) - continue; - - if (head.scheduledrespawntime <= time) - isavailable = true; - else if (t == 0 || head.scheduledrespawntime < t) - t = head.scheduledrespawntime; - } - } + FOREACH_ENTITY(it.itemdef == e.itemdef || ((it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT), LAMBDA( + if (e == it) continue; + if (it.scheduledrespawntime <= time) + isavailable = true; + else if (t == 0 || it.scheduledrespawntime < t) + t = it.scheduledrespawntime; + )); if (isavailable) t = -t; // let know the client there's another available item return t; @@ -158,13 +135,9 @@ MUTATOR_HOOKFUNCTION(itemstime, reset_map_global) Item_ItemsTime_ResetTimes(); // ALL the times need to be reset before .reset()ing each item // since Item_Reset schedules respawn of superweapons and powerups - for (entity e = NULL; (e = nextent(e)); ) - if (IS_NOT_A_CLIENT(e)) - { - setself(e); - if (self.reset) - Item_ItemsTime_SetTime(self, 0); - } + FOREACH_ENTITY(IS_NOT_A_CLIENT(it), LAMBDA( + if (it.reset) Item_ItemsTime_SetTime(it, 0); + )); Item_ItemsTime_SetTimesForAllPlayers(); } diff --git a/qcsrc/common/turrets/sv_turrets.qc b/qcsrc/common/turrets/sv_turrets.qc index 9ab9a3211..ed79df128 100644 --- a/qcsrc/common/turrets/sv_turrets.qc +++ b/qcsrc/common/turrets/sv_turrets.qc @@ -360,7 +360,7 @@ bool turret_send(entity this, entity to, float sf) return true; } -void load_unit_settings(entity ent, float is_reload) +void load_unit_settings(entity ent, bool is_reload) {SELFPARAM(); string unitname = ent.netname; string sbase; @@ -1200,25 +1200,18 @@ void turret_link() } void turrets_manager_think() -{SELFPARAM(); - self.nextthink = time + 1; +{ + SELFPARAM(); + this.nextthink = time + 1; - entity e; if (autocvar_g_turrets_reloadcvars == 1) { - e = nextent(world); - while (e) - { - if (IS_TURRET(e)) - { - load_unit_settings(e,1); - Turret tur = get_turretinfo(self.m_id); - tur.tr_think(tur); - } - - e = nextent(e); - } - cvar_set("g_turrets_reloadcvars","0"); + FOREACH_ENTITY(IS_TURRET(it), LAMBDA( + load_unit_settings(it, true); + Turret tur = get_turretinfo(it.m_id); + tur.tr_think(tur); + )); + cvar_set("g_turrets_reloadcvars", "0"); } } diff --git a/qcsrc/lib/iter.qh b/qcsrc/lib/iter.qh index f3214a248..57be59fcb 100644 --- a/qcsrc/lib/iter.qh +++ b/qcsrc/lib/iter.qh @@ -36,6 +36,39 @@ } \ while (0) +#if defined(CSQC) + entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403; +#elif defined(SVQC) + entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #403; +#elif defined(MENUQC) + entity(.entity fld, entity match, .entity tofield) findchainentity_tofield = #27; +#endif + +.entity _FOREACH_ENTITY_fld; +.entity _FOREACH_ENTITY_next; + +#define FOREACH_ENTITY_UNORDERED(cond, body) \ + do { \ + int i = 0; \ + for (entity it = findchainentity_tofield(_FOREACH_ENTITY_fld, NULL, _FOREACH_ENTITY_next); it; (it = it._FOREACH_ENTITY_next, ++i)) \ + { \ + if (cond) { body } \ + } \ + } \ + while (0) + +#define FOREACH_ENTITY_ORDERED(cond, body) \ + do { \ + int i = 0; \ + for (entity it = NULL; (it = nextent(it)); ++i) \ + { \ + if (cond) { body } \ + } \ + } \ + while (0) + +#define FOREACH_ENTITY(cond, body) FOREACH_ENTITY_UNORDERED(cond, body) + #define FOREACH(list, cond, body) FOREACH_LIST(list, enemy, cond, body) #endif diff --git a/qcsrc/lib/warpzone/server.qc b/qcsrc/lib/warpzone/server.qc index 0cd85cba6..342bc0c5a 100644 --- a/qcsrc/lib/warpzone/server.qc +++ b/qcsrc/lib/warpzone/server.qc @@ -782,55 +782,53 @@ void WarpZone_Think() } void WarpZone_StartFrame() -{SELFPARAM(); - entity e; - if(warpzone_initialized == 0) +{ + SELFPARAM(); + if (!warpzone_initialized) { - warpzone_initialized = 1; - for(setself(warpzone_first); self; setself(self.warpzone_next)) + warpzone_initialized = true; + for (setself(warpzone_first); self; setself(self.warpzone_next)) WarpZone_InitStep_FindOriginTarget(); - for(setself(warpzone_position_first); self; setself(self.warpzone_next)) + for (setself(warpzone_position_first); self; setself(self.warpzone_next)) WarpZonePosition_InitStep_FindTarget(); - for(setself(warpzone_first); self; setself(self.warpzone_next)) + for (setself(warpzone_first); self; setself(self.warpzone_next)) WarpZone_InitStep_UpdateTransform(); setself(this); WarpZones_Reconnect(); WarpZone_PostInitialize_Callback(); } - entity oldother; - oldother = other; - for(e = world; (e = nextent(e)); ) + entity oldother = other; + for (entity e = world; (e = nextent(e)); ) { - if(warpzone_warpzones_exist) { WarpZone_StoreProjectileData(e); } - - if(IS_REAL_CLIENT(e)) + if (warpzone_warpzones_exist) WarpZone_StoreProjectileData(e); + if (IS_REAL_CLIENT(e)) { - if(e.solid == SOLID_NOT) // not spectating? - if(e.movetype == MOVETYPE_NOCLIP || e.movetype == MOVETYPE_FLY || e.movetype == MOVETYPE_FLY_WORLDONLY) // not spectating? (this is to catch observers) + if (e.solid == SOLID_NOT) // not spectating? + if (e.movetype == MOVETYPE_NOCLIP || e.movetype == MOVETYPE_FLY || e.movetype == MOVETYPE_FLY_WORLDONLY) // not spectating? (this is to catch observers) { other = e; // player // warpzones - if(warpzone_warpzones_exist) { - setself(WarpZone_Find(e.origin + e.mins, e.origin + e.maxs)); - if(self) - if(!WarpZoneLib_ExactTrigger_Touch()) - if(WarpZone_PlaneDist(self, e.origin + e.view_ofs) <= 0) - WarpZone_Teleport(self, e, -1, 0); } // NOT triggering targets by this! + if (warpzone_warpzones_exist) { + setself(WarpZone_Find(e.origin + e.mins, e.origin + e.maxs)); + if (self) + if (!WarpZoneLib_ExactTrigger_Touch()) + if (WarpZone_PlaneDist(self, e.origin + e.view_ofs) <= 0) + WarpZone_Teleport(self, e, -1, 0); // NOT triggering targets by this! + } // teleporters setself(Teleport_Find(e.origin + e.mins, e.origin + e.maxs)); - if(self) - if(!WarpZoneLib_ExactTrigger_Touch()) + if (self) + if (!WarpZoneLib_ExactTrigger_Touch()) Simple_TeleportPlayer(self, other); // NOT triggering targets by this! } } - - if(IS_NOT_A_CLIENT(e)) + else if (IS_NOT_A_CLIENT(e)) { - if(warpzone_warpzones_exist) - for (; (e = nextent(e)); ) + if (warpzone_warpzones_exist) + while ((e = nextent(e))) WarpZone_StoreProjectileData(e); break; } @@ -840,14 +838,12 @@ void WarpZone_StartFrame() } .float warpzone_reconnecting; -float visible_to_some_client(entity ent) +bool visible_to_some_client(entity ent) { - entity e; - for(e = nextent(world); !IS_NOT_A_CLIENT(e); e = nextent(e)) - if(IS_PLAYER(e) && IS_REAL_CLIENT(e)) - if(checkpvs(e.origin + e.view_ofs, ent)) - return 1; - return 0; + FOREACH_ENTITY(!IS_NOT_A_CLIENT(it), LAMBDA( + if (IS_PLAYER(it) && IS_REAL_CLIENT(it) && checkpvs(it.origin + it.view_ofs, ent)) return true; + )); + return false; } void trigger_warpzone_reconnect_use() {SELFPARAM(); diff --git a/qcsrc/menu/command/menu_cmd.qc b/qcsrc/menu/command/menu_cmd.qc index 5a5fe26a6..46f7f9a91 100644 --- a/qcsrc/menu/command/menu_cmd.qc +++ b/qcsrc/menu/command/menu_cmd.qc @@ -77,22 +77,17 @@ void GameCommand(string theCommand) if (argc == 1) { LOG_INFO(_("Available options:\n")); - float i; - entity e; - string s; - for (i = 0, e = NULL; (e = nextent(e)); ) - if (e.classname != "vtbl" && e.name != "") + FOREACH_ENTITY_ORDERED(it.name != "", LAMBDA( + if (it.classname == "vtbl") continue; + string s = it.name; + if (filter) { - s = e.name; - if (filter) - { - if (substring(s, 0, strlen(filter)) != filter) continue; - s = substring(s, strlen(filter), strlen(s) - strlen(filter)); - } - LOG_INFO(strcat(" ", s, "\n")); - ++i; + if (!startsWith(s, filter)) continue; + s = substring(s, strlen(filter), strlen(s) - strlen(filter)); } + LOG_INFOF(" %s\n", s); + )); } else if (argc == 2 && !isdemo()) // don't allow this command in demos { diff --git a/qcsrc/menu/menu.qc b/qcsrc/menu/menu.qc index 899de0ec9..5e98da110 100644 --- a/qcsrc/menu/menu.qc +++ b/qcsrc/menu/menu.qc @@ -863,11 +863,10 @@ void m_toggle(int mode) void Shutdown() { m_hide(); - for (entity e = NULL; (e = nextent(e)); ) - { - if (e.classname == "vtbl") continue; - if (e.destroy) e.destroy(e); - } + FOREACH_ENTITY_ORDERED(it.destroy, LAMBDA( + if (it.classname == "vtbl") continue; + it.destroy(it); + )); } void m_focus_item_chain(entity outermost, entity innermost) diff --git a/qcsrc/server/command/vote.qc b/qcsrc/server/command/vote.qc index eb9c24d67..a023594a5 100644 --- a/qcsrc/server/command/vote.qc +++ b/qcsrc/server/command/vote.qc @@ -349,33 +349,20 @@ void reset_map(bool dorespawn) MUTATOR_CALLHOOK(reset_map_global); - for (entity e = world; (e = nextent(e)); ) - { - if (IS_NOT_A_CLIENT(e)) + FOREACH_ENTITY_ORDERED(IS_NOT_A_CLIENT(it), LAMBDA( + if (it.reset) { - if (e.reset) - { - WITH(entity, self, e, e.reset(e)); - continue; - } - if (e.team_saved) e.team = e.team_saved; - if (e.flags & FL_PROJECTILE) remove(e); // remove any projectiles left + WITH(entity, self, it, it.reset(it)); + continue; } - } + if (it.team_saved) it.team = it.team_saved; + if (it.flags & FL_PROJECTILE) remove(it); // remove any projectiles left + )); // Waypoints and assault start come LAST - for (entity e = world; (e = nextent(e)); ) - { - setself(e); - if (IS_NOT_A_CLIENT(self)) - { - if (self.reset2) - { - self.reset2(); - continue; - } - } - } + FOREACH_ENTITY_ORDERED(IS_NOT_A_CLIENT(it), LAMBDA( + if (it.reset2) WITH(entity, self, it, it.reset2()); + )); entity e; FOR_EACH_PLAYER(e) diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 85f1ce163..de20273b8 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -577,13 +577,10 @@ spawnfunc(worldspawn) compressShortVector_init(); - entity head; - head = nextent(world); maxclients = 0; - while(head) + for (entity head = nextent(world); head; head = nextent(head)) { ++maxclients; - head = nextent(head); } server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? true : false); diff --git a/qcsrc/server/mutators/mutator/gamemode_assault.qc b/qcsrc/server/mutators/mutator/gamemode_assault.qc index 68d23f486..471af3219 100644 --- a/qcsrc/server/mutators/mutator/gamemode_assault.qc +++ b/qcsrc/server/mutators/mutator/gamemode_assault.qc @@ -294,17 +294,10 @@ void assault_new_round() else assault_attacker_team = NUM_TEAM_1; - entity ent; - for(ent = world; (ent = nextent(ent)); ) - { - if(clienttype(ent) == CLIENTTYPE_NOTACLIENT) - { - if(ent.team_saved == NUM_TEAM_1) - ent.team_saved = NUM_TEAM_2; - else if(ent.team_saved == NUM_TEAM_2) - ent.team_saved = NUM_TEAM_1; - } - } + FOREACH_ENTITY(clienttype(it) == CLIENTTYPE_NOTACLIENT, LAMBDA( + if (it.team_saved == NUM_TEAM_1) it.team_saved = NUM_TEAM_2; + else if (it.team_saved == NUM_TEAM_2) it.team_saved = NUM_TEAM_1; + )); // reset the level with a countdown cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60)); -- 2.39.2