Example #1
0
/*
* G_TeleportPlayer
*/
void G_TeleportPlayer( edict_t *player, edict_t *dest )
{
	int i;
	vec3_t velocity;
	mat3_t axis;
	float speed;
	gclient_t *client = player->r.client;

	if( !dest ) {
		return;
	}
	if( !client ) {
		return;
	}

	// draw the teleport entering effect
	G_TeleportEffect( player, false );

	//
	// teleport the player
	//

	// from racesow - use old pmove velocity
	VectorCopy( client->old_pmove.velocity, velocity );

	velocity[2] = 0; // ignore vertical velocity
	speed = VectorLengthFast( velocity );

	AnglesToAxis( dest->s.angles, axis );
	VectorScale( &axis[AXIS_FORWARD], speed, client->ps.pmove.velocity );

	VectorCopy( dest->s.angles, client->ps.viewangles );
	VectorCopy( dest->s.origin, client->ps.pmove.origin );

	// set the delta angle
	for ( i = 0; i < 3; i++ )
		client->ps.pmove.delta_angles[i] = ANGLE2SHORT( client->ps.viewangles[i] ) - client->ucmd.angles[i];

	client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT;
	client->ps.pmove.pm_time = 1; // force the minimum no control delay
	player->s.teleported = true;

	// update the entity from the pmove
	VectorCopy( client->ps.viewangles, player->s.angles );
	VectorCopy( client->ps.pmove.origin, player->s.origin );
	VectorCopy( client->ps.pmove.origin, player->s.old_origin );
	VectorCopy( client->ps.pmove.origin, player->olds.origin );
	VectorCopy( client->ps.pmove.velocity, player->velocity );

	// unlink to make sure it can't possibly interfere with KillBox
	GClip_UnlinkEntity( player );

	// kill anything at the destination
	KillBox( player );

	GClip_LinkEntity( player );

	// add the teleport effect at the destination
	G_TeleportEffect( player, true );
}
Example #2
0
/*
* G_Teleport
* 
* Teleports client to specified position
* If client is not spectator teleporting is only done if position is free and teleport effects are drawn.
*/
static bool G_Teleport( edict_t *ent, vec3_t origin, vec3_t angles )
{
	int i;

	if( !ent->r.inuse || !ent->r.client )
		return false;

	if( ent->r.client->ps.pmove.pm_type != PM_SPECTATOR )
	{
		trace_t	tr;

		G_Trace( &tr, origin, ent->r.mins, ent->r.maxs, origin, ent, MASK_PLAYERSOLID );
		if( tr.fraction != 1.0f || tr.startsolid )
			return false;

		G_TeleportEffect( ent, false );
	}

	VectorCopy( origin, ent->s.origin );
	VectorCopy( origin, ent->s.old_origin );
	VectorCopy( origin, ent->olds.origin );
	ent->s.teleported = qtrue;

	VectorClear( ent->velocity );
	ent->r.client->ps.pmove.pm_time = 1;
	ent->r.client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT;

	if( ent->r.client->ps.pmove.pm_type != PM_SPECTATOR )
		G_TeleportEffect( ent, true );

	// set angles
	VectorCopy( angles, ent->s.angles );
	VectorCopy( angles, ent->r.client->ps.viewangles );

	// set the delta angle
	for( i = 0; i < 3; i++ )
		ent->r.client->ps.pmove.delta_angles[i] = ANGLE2SHORT( ent->r.client->ps.viewangles[i] ) - ent->r.client->ucmd.angles[i];

	return true;
}
Example #3
0
/*
* ClientDisconnect
* Called when a player drops from the server.
* Will not be called between levels.
*/
void ClientDisconnect( edict_t *ent, const char *reason )
{
	int team;

	if( !ent->r.client || !ent->r.inuse )
		return;

	// always report in RACE mode
	if( GS_RaceGametype() 
		|| ( ent->r.client->team != TEAM_SPECTATOR && ( GS_MatchState() == MATCH_STATE_PLAYTIME || GS_MatchState() == MATCH_STATE_POSTMATCH ) ) )
		G_AddPlayerReport( ent, GS_MatchState() == MATCH_STATE_POSTMATCH );

	for( team = TEAM_PLAYERS; team < GS_MAX_TEAMS; team++ )
		G_Teams_UnInvitePlayer( team, ent );

	if( !level.gametype.disableObituaries || !(ent->r.svflags & SVF_FAKECLIENT ) )
	{
		if( !reason )
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected\n", ent->r.client->netname );
		else
			G_PrintMsg( NULL, "%s" S_COLOR_WHITE " disconnected (%s" S_COLOR_WHITE ")\n", ent->r.client->netname, reason );
	}

	// send effect
	if( ent->s.team > TEAM_SPECTATOR )
		G_TeleportEffect( ent, false );

	ent->r.client->team = TEAM_SPECTATOR;
	G_ClientRespawn( ent, true ); // respawn as ghost
	ent->movetype = MOVETYPE_NOCLIP; // allow freefly

	// let the gametype scripts know this client just disconnected
	G_Gametype_ScoreEvent( ent->r.client, "disconnect", NULL );

	G_FreeAI( ent );
	AI_EnemyRemoved( ent );

	ent->r.inuse = false;
	ent->r.svflags = SVF_NOCLIENT;

	memset( ent->r.client, 0, sizeof( *ent->r.client ) );
	ent->r.client->ps.playerNum = PLAYERNUM( ent );

	trap_ConfigString( CS_PLAYERINFOS+PLAYERNUM( ent ), "" );
	GClip_UnlinkEntity( ent );

	G_Match_CheckReadys();
}
Example #4
0
static void old_teleporter_touch( edict_t *self, edict_t *other, cplane_t *plane, int surfFlags )
{
	edict_t	*dest;
	int i;
	vec3_t velocity, angles;
	mat3_t axis;
	float speed;
	vec3_t org;

	if( !other->r.client )
		return;
	if( self->s.team && self->s.team != other->s.team )
		return;
	if( other->r.client->ps.pmove.pm_type > PM_SPECTATOR )
		return;
	if( self->spawnflags & 1 && other->r.client->ps.pmove.pm_type != PM_SPECTATOR )
		return;

	// match countdown
	if( GS_MatchState() == MATCH_STATE_COUNTDOWN )
		return;

	// wait delay
	if( self->timeStamp > level.time )
		return;

	self->timeStamp = level.time + ( self->wait * 1000 );

	dest = G_Find( NULL, FOFS( targetname ), self->target );
	if( !dest )
	{
		if( developer->integer )
			G_Printf( "Couldn't find destination.\n" );
		return;
	}

	if( self->s.modelindex )
	{
		org[0] = self->s.origin[0] + 0.5 * ( self->r.mins[0] + self->r.maxs[0] );
		org[1] = self->s.origin[1] + 0.5 * ( self->r.mins[1] + self->r.maxs[1] );
		org[2] = self->s.origin[2] + 0.5 * ( self->r.mins[2] + self->r.maxs[2] );
	}
	else
		VectorCopy( self->s.origin, org );

	// play custom sound if any (played from the teleporter entrance)
	if( self->noise_index )
		G_PositionedSound( org, CHAN_AUTO, self->noise_index, ATTN_NORM );

	// draw the teleport entering effect
	G_TeleportEffect( other, false );

	//
	// teleport the player
	//

	VectorCopy( other->r.client->ps.pmove.velocity, velocity );

	velocity[2] = 0; // ignore vertical velocity
	speed = VectorLengthFast( velocity );

	// if someone enters a portal backwards, inverse the destination YAW angle
#if 0
	VectorCopy( other->s.angles, angles );
	angles[PITCH] = 0;
	AngleVectors( angles, axis[0], NULL, NULL );
	VectorSubtract( org, other->s.origin, org );

	VectorCopy( dest->s.angles, angles );
	if( DotProduct( org, axis[0] ) < 0 )
		angles[YAW] = anglemod( angles[YAW] - 180 );
#else
	VectorCopy( dest->s.angles, angles );
#endif

	AnglesToAxis( dest->s.angles, axis );
	VectorScale( &axis[AXIS_FORWARD], speed, other->r.client->ps.pmove.velocity );

	VectorCopy( angles, other->r.client->ps.viewangles );
	VectorCopy( dest->s.origin, other->r.client->ps.pmove.origin );

	// set the delta angle
	for( i = 0; i < 3; i++ )
		other->r.client->ps.pmove.delta_angles[i] = ANGLE2SHORT( other->r.client->ps.viewangles[i] ) - other->r.client->ucmd.angles[i];

	other->r.client->ps.pmove.pm_flags |= PMF_TIME_TELEPORT;
	other->s.teleported = qtrue;
	other->r.client->ps.pmove.pm_time = 1; // force the minimum no control delay

	// update the entity from the pmove
	VectorCopy( other->r.client->ps.viewangles, other->s.angles );
	VectorCopy( other->r.client->ps.pmove.origin, other->s.origin );
	VectorCopy( other->r.client->ps.pmove.origin, other->s.old_origin );
	VectorCopy( other->r.client->ps.pmove.origin, other->olds.origin );
	VectorCopy( other->r.client->ps.pmove.velocity, other->velocity );

	// unlink to make sure it can't possibly interfere with KillBox
	GClip_UnlinkEntity( other );

	// kill anything at the destination
	if( !KillBox( other ) )
	{
	}

	GClip_LinkEntity( other );

	// add the teleport effect at the destination
	G_TeleportEffect( other, true );
}