
Posted by WarZone (209.223.137.*) on March 26,
1999 at 20:34:40:
qboolean findspawnpoint (edict_t *ent)
{
vec3_t loc = {0,0,0};
vec3_t floor;
int i;
int j = 0;
int k = 0;
trace_t tr;
do {
j++;
for (i = 0; i < 3;
i++)
loc[i] =
rand() % (8192 + 1) - 4096;
if (gi.pointcontents(loc) == 0)
{
VectorCopy(loc, floor);
floor[2]
= -4096;
tr =
gi.trace (loc, vec3_origin, vec3_origin, floor, NULL, MASK_SOLID);
k++;
if
(tr.surface & MASK_WATER)
continue;
VectorCopy (tr.endpos, loc);
loc[2] +=
ent->maxs[2] - ent->mins[2]; // make sure the entity can fit!
}
} while (gi.pointcontents(loc)
> 0 && j < 1000 && k < 500);
if (j >= 1000 || k >= 500)
return false;
VectorCopy(loc,ent->s.origin);
VectorCopy(loc,ent->s.old_origin);
return true;
}
This function does all the
work of placing an entity for you! Paste this function in g_utils.c, and add
this line near the other g_utils.c function definitions in g_local.h (or at the
bottom if you're lazy).
qboolean findspawnpoint (edict_t *ent);
Then when you spawn an
entity, call this function on the entity before its origin gets set. Here's an
example that will spawn players in random locations!
void PutClientInServer (edict_t *ent)
{
vec3_t mins = {-16, -16, -24};
vec3_t maxs = {16, 16, 32};
int index;
vec3_t spawn_origin, spawn_angles;
gclient_t *client;
int i;
client_persistant_t saved;
client_respawn_t resp;
//
find a spawn point
//
do it before setting health back up, so farthest
//
ranging doesn't count this client
/*--------------------------------*/
/* new code
starts here
*/
/*--------------------------------*/
VectorCopy (mins, ent->mins);
VectorCopy (maxs, ent->maxs);
if (findspawnpoint(ent)) // new line
{
VectorCopy(ent->s.origin,
spawn_origin);
VectorClear
(spawn_angles);
spawn_angles[yaw]
= rand() % 360 - 180; // face a random direction
}
else // couldn't find a good spot, so...
SelectSpawnPoint
(ent, spawn_origin, spawn_angles);
/*--------------------------------*/
/* new code ends
here */
/*--------------------------------*/
index
= ent-g_edicts-1;
client
= ent->client;
I tested this code about
100 times on q2dm1 and it works perfectly!! The only hitch is that sometimes I
spawned in mid-wall. That's because this code only check in an entity can
"fit" in vertically, not horizontally. So, I'll leave that bit an an
excercise for you to do.
You can use this code in a
similar manner as the above example when spawning ANYTHING. You can now have
weapons, armor, QUADs, techs, etc. spawning in completely random locations.
Cool! When spawning in items, you should always check to see that
findspawnpoint() returns true -- if not, that means that a decent spawn point
couldn't be found. So, you'll probably need to assign the item its default
spawn point in that case. Then again, if you want to risk an infinite loop
(unlikely, but possible), you could do this:
while (findspawnpoint(ent) == false)
{} // loop until a point is found..
If you've got any questions,
feel free to ask.
Enjoy!
-- WarZone