Tidy Spawn Hex Tutorial

The following tutorial is used to make sure that the spawn points in deathmatches (those hexagonal pads that litter up the deathmatches) tidy themselves up and disappear when they're not in use.

- Woebane (jasona@brimstone.com)


usage

When players enter the deathmatch, the ugly grey and red spawn point hexes will appear with them, and then disappear 10 seconds after the player entered the game.


new file: j_spawn.c


I use some utilities that were originally written by Tadao for the special effects of my spawn points disappearing. Use whatever special effects you desire. I would point you to Tadao's utility tutorials, but I can't find them at the old link I have for them.
Add the following two functions to a new file j_spawn.c:

/* 
 * Have a spawn point disappear on us ("Phase Out").
 *
 * I use the G_Spawn_Sparks() and the gi.sound() routines to make the spawn
 * point disappear with a flourish, but you don't have to use any special
 * effects. If you aren't going to use any, ignore the first four lines and
 * just keep the "ent->" and "gi.linkentity" lines.
 */
void SP_misc_spawn_point_phase_out (edict_t *ent)
{
	vec3_t movedir = {0, 0, 1};

	G_Spawn_Sparks(TE_SHIELD_SPARKS, ent->s.origin, movedir, ent->s.origin);
	G_Spawn_Sparks(TE_BULLET_SPARKS, ent->s.origin, movedir, ent->s.origin);

	gi.sound(ent, CHAN_BODY, gi.soundindex ("tank/pain.wav"), 1, ATTN_IDLE, 0);

	ent->solid = SOLID_NOT;
	ent->think = NULL;
	ent->svflags |= SVF_NOCLIENT;
	gi.linkentity (ent);
}

/* 
 * Spawn points start out invisible. When used they appear for 10 seconds.
 */
void SP_misc_phase_in_spawn_point (edict_t *ent)
{
	if (!ent)
		return;

	if (ent->solid != SOLID_NOT)
	{
		/*
		 * We've been called a second time on the same spawn point
		 * before it's had a chance to phase out. Let's make sure
		 * that it sticks around a little longer than the first spawn
		 * in time so that the 2nd spawn person isn't startled by an
		 * early disappearance.
		 */
		if (ent->think == SP_misc_spawn_point_phase_out)
			ent->nextthink = 10 + level.time;
		return;
	}

	/* make sure we don't exist, so we don't interfere with the KillBox */
	gi.unlinkentity (ent);
	KillBox (ent);

	ent->solid = SOLID_BBOX;
	ent->svflags &= ~SVF_NOCLIENT;
	ent->nextthink = 10 + level.time;
	ent->think = SP_misc_spawn_point_phase_out;
	gi.linkentity (ent);
}

file: g_misc.c


We'll need to inform the rest of the quake code about our new function to handle the disappearing spawn point hex.
Add the following line to the top of the file; right after the #include statements.

	extern void SP_misc_spawn_point_phase_out (edict_t *ent);

We will need to have the spawn points appear right before the player is placed on the map.
Add the following right after the if (!dest) {...} block and right before the gi.unlinkentity (other); line in the teleporter_touch() function:

	SP_misc_phase_in_spawn_point (dest);

When the spawn points are initially placed on the map, before even the first player is there, we make them invisible and intangible so as not to interfere with the fragging. It's the SP_misc_phase_in_spawn_point()'s function to make them visible when they're needed.
In the SP_misc_teleporter_dest() routine, replace the ent->solid = SOLID_BBOX; line with the following code:

 	ent->takedamage = DAMAGE_NO;
 	ent->movetype = MOVETYPE_NONE;
 	ent->solid = SOLID_NOT;
 	ent->think = NULL;
 	ent->svflags |= SVF_NOCLIENT;

And that should be it. Compile and play.

machiaphilia contact woebane brimstone