DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
world.c File Reference
#include "quakedef.h"
#include "clvm_cmds.h"
#include "cl_collision.h"
#include "com_list.h"
+ Include dependency graph for world.c:

Go to the source code of this file.

Functions

void World_ClearLink (link_t *l)
 World_ClearLink is used for new headnodes.
 
void World_End (world_t *world)
 
int World_EntitiesInBox (world_t *world, const vec3_t requestmins, const vec3_t requestmaxs, int maxlist, prvm_edict_t **list)
 
void World_Init (void)
 
void World_InsertLinkBefore (link_t *l, link_t *before, int entitynumber)
 
void World_LinkEdict (world_t *world, prvm_edict_t *ent, const vec3_t mins, const vec3_t maxs, qbool link_solid_not)
 
static void World_LinkEdict_AreaGrid (world_t *world, prvm_edict_t *ent)
 
void World_PrintAreaStats (world_t *world, const char *worldname)
 
void World_RemoveLink (link_t *l)
 
void World_SetSize (world_t *world, const char *filename, const vec3_t mins, const vec3_t maxs, prvm_prog_t *prog)
 
void World_Shutdown (void)
 
void World_Start (world_t *world)
 
void World_UnlinkAll (world_t *world)
 unlinks all entities (used before reallocation of edicts)
 
void World_UnlinkEdict (prvm_edict_t *ent)
 

Function Documentation

◆ World_ClearLink()

void World_ClearLink ( link_t * l)

World_ClearLink is used for new headnodes.

Definition at line 79 of file world.c.

80{
81 l->entitynumber = 0;
82 l->list.prev = l->list.next = &l->list;
83}
struct llist_s * prev
Definition com_list.h:32
struct llist_s * next
Definition com_list.h:33

References link_t::entitynumber, link_t::list, llist_t::next, and llist_t::prev.

Referenced by World_SetSize().

◆ World_End()

void World_End ( world_t * world)

Definition at line 69 of file world.c.

70{
71#ifdef USEODE
72 World_Physics_End(world);
73#endif
74}
entity world

References world.

Referenced by CLVM_reset_cmd(), and SVVM_reset_cmd().

◆ World_EntitiesInBox()

int World_EntitiesInBox ( world_t * world,
const vec3_t requestmins,
const vec3_t requestmaxs,
int maxlist,
prvm_edict_t ** list )

Definition at line 188 of file world.c.

189{
190 prvm_prog_t *prog = world->prog;
191 int numlist;
192 link_t *grid;
193 link_t *l;
194 prvm_edict_t *ent;
195 vec3_t paddedmins, paddedmaxs;
196 int igrid[3], igridmins[3], igridmaxs[3];
197
198 // avoid crash in showtex code on level change
199 if (prog == NULL || prog->num_edicts < 1)
200 return 0;
201
202 // LadyHavoc: discovered this actually causes its own bugs (dm6 teleporters being too close to info_teleport_destination)
203 //VectorSet(paddedmins, requestmins[0] - 1.0f, requestmins[1] - 1.0f, requestmins[2] - 1.0f);
204 //VectorSet(paddedmaxs, requestmaxs[0] + 1.0f, requestmaxs[1] + 1.0f, requestmaxs[2] + 1.0f);
205 VectorCopy(requestmins, paddedmins);
206 VectorCopy(requestmaxs, paddedmaxs);
207
208 // FIXME: if areagrid_marknumber wraps, all entities need their
209 // ent->priv.server->areagridmarknumber reset
210 world->areagrid_stats_calls++;
211 world->areagrid_marknumber++;
212 igridmins[0] = (int) floor((paddedmins[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]);
213 igridmins[1] = (int) floor((paddedmins[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]);
214 //igridmins[2] = (int) ((paddedmins[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]);
215 igridmaxs[0] = (int) floor((paddedmaxs[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]) + 1;
216 igridmaxs[1] = (int) floor((paddedmaxs[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]) + 1;
217 //igridmaxs[2] = (int) ((paddedmaxs[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]) + 1;
218 igridmins[0] = max(0, igridmins[0]);
219 igridmins[1] = max(0, igridmins[1]);
220 //igridmins[2] = max(0, igridmins[2]);
221 igridmaxs[0] = min(AREA_GRID, igridmaxs[0]);
222 igridmaxs[1] = min(AREA_GRID, igridmaxs[1]);
223 //igridmaxs[2] = min(AREA_GRID, igridmaxs[2]);
224
225 // paranoid debugging
226 //VectorSet(igridmins, 0, 0, 0);VectorSet(igridmaxs, AREA_GRID, AREA_GRID, AREA_GRID);
227
228 numlist = 0;
229 // add entities not linked into areagrid because they are too big or
230 // outside the grid bounds
231 if (world->areagrid_outside.list.next)
232 {
233 grid = &world->areagrid_outside;
234 List_For_Each_Entry(l, &grid->list, link_t, list)
235 {
237 if (ent->priv.server->areagridmarknumber != world->areagrid_marknumber)
238 {
239 ent->priv.server->areagridmarknumber = world->areagrid_marknumber;
240 if (!ent->free && BoxesOverlap(paddedmins, paddedmaxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
241 {
242 if (numlist < maxlist)
243 list[numlist] = ent;
244 numlist++;
245 }
246 world->areagrid_stats_entitychecks++;
247 }
248 }
249 }
250 // add grid linked entities
251 for (igrid[1] = igridmins[1];igrid[1] < igridmaxs[1];igrid[1]++)
252 {
253 grid = world->areagrid + igrid[1] * AREA_GRID + igridmins[0];
254 for (igrid[0] = igridmins[0];igrid[0] < igridmaxs[0];igrid[0]++, grid++)
255 {
256 if (grid->list.next)
257 {
258 List_For_Each_Entry(l, &grid->list, link_t, list)
259 {
261 if (ent->priv.server->areagridmarknumber != world->areagrid_marknumber)
262 {
263 ent->priv.server->areagridmarknumber = world->areagrid_marknumber;
264 if (!ent->free && BoxesOverlap(paddedmins, paddedmaxs, ent->priv.server->areamins, ent->priv.server->areamaxs))
265 {
266 if (numlist < maxlist)
267 list[numlist] = ent;
268 numlist++;
269 }
270 //Con_Printf("%d %f %f %f %f %f %f : %d : %f %f %f %f %f %f\n", BoxesOverlap(mins, maxs, ent->priv.server->areamins, ent->priv.server->areamaxs), ent->priv.server->areamins[0], ent->priv.server->areamins[1], ent->priv.server->areamins[2], ent->priv.server->areamaxs[0], ent->priv.server->areamaxs[1], ent->priv.server->areamaxs[2], PRVM_NUM_FOR_EDICT(ent), mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]);
271 }
272 world->areagrid_stats_entitychecks++;
273 }
274 }
275 }
276 }
277 return numlist;
278}
#define List_For_Each_Entry(pos, head, type, member)
Definition com_list.h:121
static int(ZEXPORT *qz_inflate)(z_stream *strm
#define max(A, B)
Definition mathlib.h:38
#define min(A, B)
Definition mathlib.h:37
#define BoxesOverlap(a, b, c, d)
Definition mathlib.h:122
#define VectorCopy(in, out)
Definition mathlib.h:101
float floor(float f)
#define PRVM_EDICT_NUM(n)
Definition progsvm.h:867
#define NULL
Definition qtypes.h:12
vec_t vec3_t[3]
Definition qtypes.h:71
qbool free
true if this edict is unused
Definition progsvm.h:93
union prvm_edict_t::@29 priv
struct edict_engineprivate_s * server
FIXME: this server pointer really means world, not server (it is used by both server qc and client qc...
Definition progsvm.h:106
int num_edicts
copies of some vars that were former read from sv
Definition progsvm.h:671
#define AREA_GRID
Definition world.h:34

References AREA_GRID, BoxesOverlap, link_t::entitynumber, floor(), prvm_edict_t::free, int(), link_t::list, List_For_Each_Entry, max, min, llist_t::next, NULL, prvm_prog_t::num_edicts, prvm_edict_t::priv, PRVM_EDICT_NUM, prvm_edict_t::server, VectorCopy, and world.

Referenced by CL_Cache_TraceLineSurfaces(), CL_TraceBox(), CL_TraceLine(), CL_TracePoint(), SV_EntitiesInBox(), VM_CL_findbox(), and VM_CL_findradius().

◆ World_Init()

void World_Init ( void )

Definition at line 38 of file world.c.

39{
41#ifdef USEODE
42 World_Physics_Init();
43#endif
44}
void Collision_Init(void)
Definition collision.c:25

References Collision_Init().

Referenced by Host_Init().

◆ World_InsertLinkBefore()

void World_InsertLinkBefore ( link_t * l,
link_t * before,
int entitynumber )

Definition at line 90 of file world.c.

91{
92 l->entitynumber = entitynumber;
93 List_Add_Tail(&l->list, &before->list);
94}
static void List_Add_Tail(llist_t *node, llist_t *head)
Definition com_list.h:249

References link_t::entitynumber, link_t::list, and List_Add_Tail().

Referenced by World_LinkEdict_AreaGrid().

◆ World_LinkEdict()

void World_LinkEdict ( world_t * world,
prvm_edict_t * ent,
const vec3_t mins,
const vec3_t maxs,
qbool link_solid_not )

Definition at line 320 of file world.c.

321{
322 prvm_prog_t *prog = world->prog;
323 // unlink from old position first
324 if (ent->priv.server->areagrid[0].list.prev)
326
327 // some games don't want SOLID_NOT entities linked
328 if (!link_solid_not && PRVM_serveredictfloat(ent, solid) == SOLID_NOT)
329 return;
330
331 // don't add the world
332 if (ent == prog->edicts)
333 return;
334
335 // don't add free entities
336 if (ent->free)
337 return;
338
339 VectorCopy(mins, ent->priv.server->areamins);
340 VectorCopy(maxs, ent->priv.server->areamaxs);
342}
vector mins
vector maxs
float solid
#define PRVM_serveredictfloat(ed, fieldname)
Definition progsvm.h:172
#define SOLID_NOT
no interaction with other objects
Definition server.h:332
prvm_edict_t * edicts
Definition progsvm.h:680
static void World_LinkEdict_AreaGrid(world_t *world, prvm_edict_t *ent)
Definition world.c:280
void World_UnlinkEdict(prvm_edict_t *ent)
Definition world.c:178

References prvm_prog_t::edicts, prvm_edict_t::free, maxs, mins, prvm_edict_t::priv, PRVM_serveredictfloat, prvm_edict_t::server, solid, SOLID_NOT, VectorCopy, world, World_LinkEdict_AreaGrid(), and World_UnlinkEdict().

Referenced by CL_LinkEdict(), and SV_LinkEdict().

◆ World_LinkEdict_AreaGrid()

static void World_LinkEdict_AreaGrid ( world_t * world,
prvm_edict_t * ent )
static

Definition at line 280 of file world.c.

281{
282 prvm_prog_t *prog = world->prog;
283 link_t *grid;
284 int igrid[3], igridmins[3], igridmaxs[3], gridnum, entitynumber = PRVM_NUM_FOR_EDICT(ent);
285
286 if (entitynumber <= 0 || entitynumber >= prog->max_edicts || PRVM_EDICT_NUM(entitynumber) != ent)
287 {
288 Con_Printf ("World_LinkEdict_AreaGrid: invalid edict %p (edicts is %p, edict compared to prog->edicts is %i)\n", (void *)ent, (void *)prog->edicts, entitynumber);
289 return;
290 }
291
292 igridmins[0] = (int) floor((ent->priv.server->areamins[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]);
293 igridmins[1] = (int) floor((ent->priv.server->areamins[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]);
294 //igridmins[2] = (int) floor((ent->priv.server->areamins[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]);
295 igridmaxs[0] = (int) floor((ent->priv.server->areamaxs[0] + world->areagrid_bias[0]) * world->areagrid_scale[0]) + 1;
296 igridmaxs[1] = (int) floor((ent->priv.server->areamaxs[1] + world->areagrid_bias[1]) * world->areagrid_scale[1]) + 1;
297 //igridmaxs[2] = (int) floor((ent->priv.server->areamaxs[2] + world->areagrid_bias[2]) * world->areagrid_scale[2]) + 1;
298 if (igridmins[0] < 0 || igridmaxs[0] > AREA_GRID || igridmins[1] < 0 || igridmaxs[1] > AREA_GRID || ((igridmaxs[0] - igridmins[0]) * (igridmaxs[1] - igridmins[1])) > ENTITYGRIDAREAS)
299 {
300 // wow, something outside the grid, store it as such
301 World_InsertLinkBefore (&ent->priv.server->areagrid[0], &world->areagrid_outside, entitynumber);
302 return;
303 }
304
305 gridnum = 0;
306 for (igrid[1] = igridmins[1];igrid[1] < igridmaxs[1];igrid[1]++)
307 {
308 grid = world->areagrid + igrid[1] * AREA_GRID + igridmins[0];
309 for (igrid[0] = igridmins[0];igrid[0] < igridmaxs[0];igrid[0]++, grid++, gridnum++)
310 World_InsertLinkBefore (&ent->priv.server->areagrid[gridnum], grid, entitynumber);
311 }
312}
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
Definition console.c:1514
#define ENTITYGRIDAREAS
Definition progs.h:27
#define PRVM_NUM_FOR_EDICT(e)
Definition progsvm.h:870
int max_edicts
number of edicts for which space has been (should be) allocated
Definition progsvm.h:673
void World_InsertLinkBefore(link_t *l, link_t *before, int entitynumber)
Definition world.c:90

References AREA_GRID, Con_Printf(), prvm_prog_t::edicts, ENTITYGRIDAREAS, floor(), int(), prvm_prog_t::max_edicts, prvm_edict_t::priv, PRVM_EDICT_NUM, PRVM_NUM_FOR_EDICT, prvm_edict_t::server, world, and World_InsertLinkBefore().

Referenced by World_LinkEdict().

◆ World_PrintAreaStats()

void World_PrintAreaStats ( world_t * world,
const char * worldname )

Definition at line 104 of file world.c.

105{
106 Con_Printf("%s areagrid check stats: %d calls %d nodes (%f per call) %d entities (%f per call)\n", worldname, world->areagrid_stats_calls, world->areagrid_stats_nodechecks, (double) world->areagrid_stats_nodechecks / (double) world->areagrid_stats_calls, world->areagrid_stats_entitychecks, (double) world->areagrid_stats_entitychecks / (double) world->areagrid_stats_calls);
107 world->areagrid_stats_calls = 0;
108 world->areagrid_stats_nodechecks = 0;
109 world->areagrid_stats_entitychecks = 0;
110}

References Con_Printf(), and world.

Referenced by CL_AreaStats_f(), and SV_AreaStats_f().

◆ World_RemoveLink()

void World_RemoveLink ( link_t * l)

Definition at line 85 of file world.c.

86{
87 List_Delete(&l->list);
88}
static void List_Delete(llist_t *node)
Definition com_list.h:274

References link_t::list, and List_Delete().

Referenced by World_UnlinkEdict().

◆ World_SetSize()

void World_SetSize ( world_t * world,
const char * filename,
const vec3_t mins,
const vec3_t maxs,
prvm_prog_t * prog )

Definition at line 118 of file world.c.

119{
120 int i;
121
122 dp_strlcpy(world->filename, filename, sizeof(world->filename));
123 VectorCopy(mins, world->mins);
124 VectorCopy(maxs, world->maxs);
125 world->prog = prog;
126
127 // the areagrid_marknumber is not allowed to be 0
128 if (world->areagrid_marknumber < 1)
129 world->areagrid_marknumber = 1;
130 // choose either the world box size, or a larger box to ensure the grid isn't too fine
131 world->areagrid_size[0] = max(world->maxs[0] - world->mins[0], AREA_GRID * sv_areagrid_mingridsize.value);
132 world->areagrid_size[1] = max(world->maxs[1] - world->mins[1], AREA_GRID * sv_areagrid_mingridsize.value);
133 world->areagrid_size[2] = max(world->maxs[2] - world->mins[2], AREA_GRID * sv_areagrid_mingridsize.value);
134 // figure out the corners of such a box, centered at the center of the world box
135 world->areagrid_mins[0] = (world->mins[0] + world->maxs[0] - world->areagrid_size[0]) * 0.5f;
136 world->areagrid_mins[1] = (world->mins[1] + world->maxs[1] - world->areagrid_size[1]) * 0.5f;
137 world->areagrid_mins[2] = (world->mins[2] + world->maxs[2] - world->areagrid_size[2]) * 0.5f;
138 world->areagrid_maxs[0] = (world->mins[0] + world->maxs[0] + world->areagrid_size[0]) * 0.5f;
139 world->areagrid_maxs[1] = (world->mins[1] + world->maxs[1] + world->areagrid_size[1]) * 0.5f;
140 world->areagrid_maxs[2] = (world->mins[2] + world->maxs[2] + world->areagrid_size[2]) * 0.5f;
141 // now calculate the actual useful info from that
142 VectorNegate(world->areagrid_mins, world->areagrid_bias);
143 world->areagrid_scale[0] = AREA_GRID / world->areagrid_size[0];
144 world->areagrid_scale[1] = AREA_GRID / world->areagrid_size[1];
145 world->areagrid_scale[2] = AREA_GRID / world->areagrid_size[2];
146 World_ClearLink(&world->areagrid_outside);
147 for (i = 0;i < AREA_GRIDNODES;i++)
148 World_ClearLink(&world->areagrid[i]);
150 Con_DPrintf("areagrid settings: divisions %ix%ix1 : box %f %f %f : %f %f %f size %f %f %f grid %f %f %f (mingrid %f)\n", AREA_GRID, AREA_GRID, world->areagrid_mins[0], world->areagrid_mins[1], world->areagrid_mins[2], world->areagrid_maxs[0], world->areagrid_maxs[1], world->areagrid_maxs[2], world->areagrid_size[0], world->areagrid_size[1], world->areagrid_size[2], 1.0f / world->areagrid_scale[0], 1.0f / world->areagrid_scale[1], 1.0f / world->areagrid_scale[2], sv_areagrid_mingridsize.value);
151}
#define dp_strlcpy(dst, src, dsize)
Definition common.h:303
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
Definition console.c:1544
cvar_t developer_extra
Definition host.c:49
#define VectorNegate(a, b)
Definition mathlib.h:95
int i
cvar_t sv_areagrid_mingridsize
Definition sv_main.c:75
float value
Definition cvar.h:74
int integer
Definition cvar.h:73
void World_ClearLink(link_t *l)
World_ClearLink is used for new headnodes.
Definition world.c:79
#define AREA_GRIDNODES
Definition world.h:35

References AREA_GRID, AREA_GRIDNODES, Con_DPrintf(), developer_extra, dp_strlcpy, i, cvar_t::integer, max, maxs, mins, sv_areagrid_mingridsize, cvar_t::value, VectorCopy, VectorNegate, world, and World_ClearLink().

Referenced by CL_SetupWorldModel(), and SV_SpawnServer().

◆ World_Shutdown()

void World_Shutdown ( void )

Definition at line 49 of file world.c.

50{
51#ifdef USEODE
52 World_Physics_Shutdown();
53#endif
54}

◆ World_Start()

void World_Start ( world_t * world)

Definition at line 59 of file world.c.

60{
61#ifdef USEODE
62 World_Physics_Start(world);
63#endif
64}

References world.

Referenced by CL_SetupWorldModel(), and SV_SpawnServer().

◆ World_UnlinkAll()

void World_UnlinkAll ( world_t * world)

unlinks all entities (used before reallocation of edicts)

Definition at line 159 of file world.c.

160{
161 prvm_prog_t *prog = world->prog;
162 int i;
163 link_t *grid;
164 // unlink all entities one by one
165 grid = &world->areagrid_outside;
166 while (grid->list.next != &grid->list)
167 World_UnlinkEdict(PRVM_EDICT_NUM(List_Entry(grid->list.next, link_t, list)->entitynumber));
168 for (i = 0, grid = world->areagrid;i < AREA_GRIDNODES;i++, grid++)
169 while (grid->list.next != &grid->list)
170 World_UnlinkEdict(PRVM_EDICT_NUM(List_Entry(grid->list.next, link_t, list)->entitynumber));
171}
#define List_Entry(ptr, type, member)
Definition com_list.h:44

References AREA_GRIDNODES, i, link_t::list, List_Entry, llist_t::next, PRVM_EDICT_NUM, world, and World_UnlinkEdict().

Referenced by CLVM_begin_increase_edicts(), SV_Loadgame_f(), and SVVM_begin_increase_edicts().

◆ World_UnlinkEdict()

void World_UnlinkEdict ( prvm_edict_t * ent)

Definition at line 178 of file world.c.

179{
180 int i;
181 for (i = 0;i < ENTITYGRIDAREAS;i++)
182 {
183 if (ent->priv.server->areagrid[i].list.prev)
184 World_RemoveLink (&ent->priv.server->areagrid[i]);
185 }
186}
void World_RemoveLink(link_t *l)
Definition world.c:85

References ENTITYGRIDAREAS, i, prvm_edict_t::priv, prvm_edict_t::server, and World_RemoveLink().

Referenced by CLVM_free_edict(), SVVM_free_edict(), World_LinkEdict(), and World_UnlinkAll().