|
QuakeZone MOD Coding Tutorials
|
|
|
Introduction Pre-requisites Code Notes Exercises |
|
| Introduction |
|
|
Related Links
13 Original Spawn Points Tutorial 14 Tech Pick-ups Tutorial
| This tutorial describe show to generate a table of random spawn points, useful when spawning pick-up items, such as Tech pick-ups (cf). These spawn points are not strictly random as they are merely the spawn points of already existing items. In the case of this tutorial, they are those items that are not allowed to spawn (in Team Rocket, no weapons or ammo items are spawned, so their spawn points are used to build our table). This tutorial is an improvement over the original spawn points tutorial, #13. In this tutorial, the items
will merely drop at the point they are spawned. In the original, they are tossed, sometime causing them to be
half-embedded in walls. Also in this tutorial, the next spawn point will be used for a new item spawning rather
than a random point, thus avoiding the embarrassing situation of 2 items spawning in the same place.
|
| Pre-requisites |
|
|
| Code |
|
|
g_local.h At the end of structure level_locals_t, add the following 2 lines: vec3_t spawn_points[100]; // random spawn points int num_spawn_points; // number of spawn points g_spawn.c In procedure InitGame, add the following line at the indicated position:
skill = gi.cvar ("skill", "1", CVAR_LATCH);
maxentities = gi.cvar ("maxentities", "1024", CVAR_LATCH);
level.num_spawn_points = 0; // PJT - spawn points
g_items.c In procedure SpawnItem, add the following lines at the start of the procedure:
// PJT - spawn points
// create spawn points for disallowed items
// only spawn armour and health (but may still get disallowed by dm flags)
if (!(item->pickup == Pickup_Health || item->pickup == Pickup_Adrenaline ||
item->pickup == Pickup_AncientHead || item->pickup == Pickup_Armor ||
item->pickup == Pickup_PowerArmor))
{
// PJT - spawn rockets
if (level.num_spawn_points < 101)
{
level.num_spawn_points++;
VectorCopy(ent->s.origin, level.spawn_points[level.num_spawn_points - 1]);
}
// PJT
G_FreeEdict (ent);
return;
}
// PJT
Then add in the following new procedures near the end of the code:
// PJT - spawn rockets
edict_t *SelectRandomSpawnPoint(void)
{
edict_t *dest;
vec3_t rvect;
dest = SelectRandomDeathmatchSpawnPoint();
if (level.num_spawn_points)
{
VectorCopy(level.spawn_points[(int)(random()*level.num_spawn_points-1)] , rvect);
VectorCopy(rvect, dest->s.origin);
}
return dest;
}
// PJT - spawn points - overflow fix
int NextSpawnPoint(void)
{
level.next_spawn_point++;
if (level.next_spawn_point > level.num_spawn_points)
{
level.next_spawn_point = 1;
}
return level.next_spawn_point;
}
void RemoveSpawnPoint(void)
{
if (level.next_spawn_point < level.num_spawn_points)
VectorCopy(level.spawn_points[level.num_spawn_points], level.spawn_points[level.next_spawn_point]);
level.num_spawn_points--;
}
// PJT
Then, in your new "spawn_your_item" procedure, add the following code:
firstly, at top ......
int flag=1; // PJT <-- add these lines at start of your procedure
trace_t tr; // PJT
vec3_t dest1; // PJT
float *v; // PJT
then further down in code ........
// PJT - drop to floor code (overflow fix)
while (!flag == 0)
{
VectorCopy(level.spawn_points[NextSpawnPoint()] , rocket->s.origin); // PJT - overflow fix
v = tv(0,0,-128);
VectorAdd (rocket->s.origin, v, dest1);
tr = gi.trace (rocket->s.origin, rocket->mins, rocket->maxs, dest1, rocket, MASK_SOLID);
if (tr.startsolid) // PJT <-- shouldnt get on standard maps??
{
flag++;
if (flag > 10)
{
gi.dprintf ("droptofloor: %s startsolid at %s\n", rocket->classname, vtos(rocket->s.origin));
// RemoveSpawnPoint(); // PJT <-- remove duff start point ..or fix point somehow?
G_FreeEdict (rocket);
return;
}
}
else
flag = 0;
}
VectorCopy (tr.endpos, rocket->s.origin);
// PJT
|
| Notes |
|
|
g_local.h
g_spawn.c
g_items.c
|
| Exercises |
|
|