/* =========== G_SelectInitialSpawnPoint Try to find a spawn point marked 'initial', otherwise use normal spawn selection. ============ */ gentity_t *G_SelectInitialSpawnPoint( vec3_t origin, vec3_t angles ) { gentity_t *spot; spot = NULL; while( ( spot = G_Find( spot, FOFS( classname ), "info_player_deathmatch" ) ) != NULL ) { if( spot->spawnflags & 1 ) break; } if( !spot || SpotWouldTelefrag( spot ) ) { return G_SelectSpawnPoint( vec3_origin, origin, angles ); } VectorCopy( spot->s.origin, origin ); origin[ 2 ] += 9; VectorCopy( spot->s.angles, angles ); return spot; }
/* * G_ClientRespawn_ * * The grunt work of putting the client into the server on [re]spawn. */ static void G_ClientRespawn_(g_edict_t *ent) { vec3_t spawn_origin, spawn_angles, old_angles; float height; g_client_t *cl; g_client_persistent_t locals; int i; // find a spawn point G_SelectSpawnPoint(ent, spawn_origin, spawn_angles); cl = ent->client; // retain last angles for delta VectorCopy(ent->client->cmd_angles, old_angles); // reset inventory, health, etc G_InitClientLocals(cl); // clear everything but locals locals = cl->persistent; memset(cl, 0, sizeof(*cl)); cl->persistent = locals; // clear entity values VectorScale(PM_MINS, PM_SCALE, ent->mins); VectorScale(PM_MAXS, PM_SCALE, ent->maxs); height = ent->maxs[2] - ent->mins[2]; ent->ground_entity = NULL; ent->take_damage = true; ent->move_type = MOVE_TYPE_WALK; ent->view_height = ent->mins[2] + (height * 0.75); ent->class_name = "player"; ent->mass = 200.0; ent->solid = SOLID_BOX; ent->dead = false; ent->clip_mask = MASK_PLAYER_SOLID; ent->pain = G_ClientPain; ent->die = G_ClientDie; ent->water_level = 0; ent->water_type = 0; ent->sv_flags = 0; // copy these back once they have been set in locals ent->health = ent->client->persistent.health; ent->max_health = ent->client->persistent.max_health; VectorClear(ent->velocity); ent->velocity[2] = 150.0; // clear player state values memset(&ent->client->ps, 0, sizeof(cl->ps)); cl->ps.pmove.origin[0] = spawn_origin[0] * 8.0; cl->ps.pmove.origin[1] = spawn_origin[1] * 8.0; cl->ps.pmove.origin[2] = spawn_origin[2] * 8.0; // clear entity state values ent->s.effects = 0; ent->s.model1 = 0xff; // use the client info model ent->s.model2 = 0; ent->s.model3 = 0; ent->s.model4 = 0; ent->s.client = ent - g_game.edicts - 1; G_SetAnimation(ent, ANIM_TORSO_STAND1, true); G_SetAnimation(ent, ANIM_LEGS_JUMP1, true); VectorCopy(spawn_origin, ent->s.origin); VectorCopy(ent->s.origin, ent->s.old_origin); // set the delta angle of the spawn point for (i = 0; i < 3; i++) { cl->ps.pmove.delta_angles[i] = ANGLE2SHORT(spawn_angles[i] - old_angles[i]); } VectorClear(cl->cmd_angles); VectorClear(cl->angles); VectorClear(ent->s.angles); // spawn a spectator if (cl->persistent.spectator) { cl->chase_target = NULL; cl->persistent.weapon = NULL; cl->persistent.team = NULL; cl->persistent.ready = false; ent->move_type = MOVE_TYPE_NO_CLIP; ent->solid = SOLID_NOT; ent->sv_flags |= SVF_NO_CLIENT; ent->take_damage = false; gi.LinkEntity(ent); return; } // or spawn a player ent->s.event = EV_TELEPORT; // hold in place briefly cl->ps.pmove.pm_flags = PMF_TIME_TELEPORT; cl->ps.pmove.pm_time = 20; cl->persistent.match_num = g_level.match_num; cl->persistent.round_num = g_level.round_num; gi.UnlinkEntity(ent); G_KillBox(ent); // telefrag anyone in our spot gi.LinkEntity(ent); // force the current weapon up cl->new_weapon = cl->persistent.weapon; G_ChangeWeapon(ent); }