/* * ==================== * SV_AreaEdicts_r * * ==================== */ void SV_AreaEdicts_r(areanode_t *node) { link_t *l, *next, *start; edict_t *check; int count; count = 0; // touch linked edicts if (area_type == AREA_SOLID) { start = &node->solid_edicts; } else { start = &node->trigger_edicts; } for (l = start->next; l != start; l = next) { next = l->next; check = EDICT_FROM_AREA(l); if (check->solid == SOLID_NOT) { continue; // deactivated } if ((check->absmin[0] > area_maxs[0]) || (check->absmin[1] > area_maxs[1]) || (check->absmin[2] > area_maxs[2]) || (check->absmax[0] < area_mins[0]) || (check->absmax[1] < area_mins[1]) || (check->absmax[2] < area_mins[2])) { continue; // not touching } if (area_count == area_maxcount) { Com_Printf("SV_AreaEdicts: MAXCOUNT\n"); return; } area_list[area_count] = check; area_count++; } if (node->axis == -1) { return; // terminal node } // recurse down both sides if (area_maxs[node->axis] > node->dist) { SV_AreaEdicts_r(node->children[0]); } if (area_mins[node->axis] < node->dist) { SV_AreaEdicts_r(node->children[1]); } }
static void SV_AreaEdicts_r(areanode_t *node) { link_t *start; // touch linked edicts if (area_type == AREA_SOLID) { #if AREA_EDICTS_OPT if (!node->numSolidEdicts) return; #endif start = &node->solidEdicts; } else // AREA_TRIGGERS { #if AREA_EDICTS_OPT if (!node->numTrigEdicts) return; #endif start = &node->trigEdicts; } link_t *next; for (link_t *l = start->next; l != start; l = next) { next = l->next; edict_t *check = EDICT_FROM_AREA(l); if (check->solid == SOLID_NOT) continue; // deactivated if (check->absBounds.mins[2] > area_bounds.maxs[2] || check->absBounds.maxs[2] < area_bounds.mins[2] || check->absBounds.mins[0] > area_bounds.maxs[0] || check->absBounds.maxs[0] < area_bounds.mins[0] || check->absBounds.mins[1] > area_bounds.maxs[1] || check->absBounds.maxs[1] < area_bounds.mins[1]) continue; // not touching if (area_count == area_maxcount) { appWPrintf("SV_AreaEdicts: MAXCOUNT\n"); return; } area_list[area_count++] = check; } if (node->axis == -1) return; // terminal node if (area_bounds.maxs[node->axis] > node->dist) SV_AreaEdicts_r(node->children[0]); if (area_bounds.mins[node->axis] < node->dist) SV_AreaEdicts_r(node->children[1]); }
/* ==================== SV_AreaEdicts_r ==================== */ static void SV_AreaEdicts_r(areanode_t *node) { list_t *start; edict_t *check; // touch linked edicts if (area_type == AREA_SOLID) start = &node->solid_edicts; else start = &node->trigger_edicts; LIST_FOR_EACH(edict_t, check, start, area) { if (check->solid == SOLID_NOT) continue; // deactivated if (check->absmin[0] > area_maxs[0] || check->absmin[1] > area_maxs[1] || check->absmin[2] > area_maxs[2] || check->absmax[0] < area_mins[0] || check->absmax[1] < area_mins[1] || check->absmax[2] < area_mins[2]) continue; // not touching if (area_count == area_maxcount) { Com_WPrintf("SV_AreaEdicts: MAXCOUNT\n"); return; } area_list[area_count] = check; area_count++; } if (node->axis == -1) return; // terminal node // recurse down both sides if (area_maxs[node->axis] > node->dist) SV_AreaEdicts_r(node->children[0]); if (area_mins[node->axis] < node->dist) SV_AreaEdicts_r(node->children[1]); }
/* ================ SV_AreaEdicts ================ */ int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, int maxcount, int areatype) { area_mins = mins; area_maxs = maxs; area_list = list; area_count = 0; area_maxcount = maxcount; area_type = areatype; SV_AreaEdicts_r (sv_areanodes); return area_count; }
int SV_AreaEdicts(const CVec3 &mins, const CVec3 &maxs, edict_t **list, int maxcount, int areatype) { guard(SV_AreaEdicts); area_bounds.mins = mins; area_bounds.maxs = maxs; area_list = list; area_count = 0; area_maxcount = maxcount; area_type = areatype; SV_AreaEdicts_r(areaNodes); return area_count; unguard; }