Пример #1
0
int Pickup_PersistantPowerup( gentity_t *ent, gentity_t *other ) {
	float	handicap;
	int		max;

	other->player->ps.stats[STAT_PERSISTANT_POWERUP] = BG_ItemNumForItem( ent->item );
	other->player->persistantPowerup = ent;

	handicap = PlayerHandicap( other->player );

	switch( ent->item->giTag ) {
	case PW_GUARD:
		max = (int)(2 *  handicap);

		other->health = max;
		other->player->ps.stats[STAT_HEALTH] = max;
		other->player->ps.stats[STAT_MAX_HEALTH] = max;
		other->player->ps.stats[STAT_ARMOR] = max;
		other->player->pers.maxHealth = max;
		break;

	case PW_SCOUT:
		other->player->pers.maxHealth = handicap;
		other->player->ps.stats[STAT_ARMOR] = 0;
		break;

	case PW_AMMOREGEN:
		other->player->pers.maxHealth = handicap;
		memset(other->player->ammoTimes, 0, sizeof(other->player->ammoTimes));
		break;

	case PW_DOUBLER:
	default:
		other->player->pers.maxHealth = handicap;
		break;
	}

	return -1;
}
Пример #2
0
/*
===========
PlayerUserinfoChanged

Called from PlayerConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
void PlayerUserinfoChanged( int playerNum ) {
	gentity_t *ent;
	int		teamTask, teamLeader;
	char	*s;
	char	model[MAX_QPATH];
	char	headModel[MAX_QPATH];
	char	oldname[MAX_STRING_CHARS];
	gplayer_t	*player;
	char	c1[MAX_INFO_STRING];
	char	c2[MAX_INFO_STRING];
	char	userinfo[MAX_INFO_STRING];

	ent = g_entities + playerNum;
	player = ent->player;

	trap_GetUserinfo( playerNum, userinfo, sizeof( userinfo ) );

	// check for malformed or illegal info strings
	if ( !Info_Validate(userinfo) ) {
		strcpy (userinfo, "\\name\\badinfo");
		// don't keep those players and userinfo
		trap_DropPlayer(playerNum, "Invalid userinfo");
	}

	// check the item prediction
	s = Info_ValueForKey( userinfo, "cg_predictItems" );
	if ( !atoi( s ) ) {
		player->pers.predictItemPickup = qfalse;
	} else {
		player->pers.predictItemPickup = qtrue;
	}

	// check the anti lag
	s = Info_ValueForKey( userinfo, "cg_antiLag" );
	player->pers.antiLag = atoi( s );

	// set name
	Q_strncpyz ( oldname, player->pers.netname, sizeof( oldname ) );
	s = Info_ValueForKey (userinfo, "name");
	PlayerCleanName( s, player->pers.netname, sizeof(player->pers.netname) );

	if ( player->sess.sessionTeam == TEAM_SPECTATOR ) {
		if ( player->sess.spectatorState == SPECTATOR_SCOREBOARD ) {
			Q_strncpyz( player->pers.netname, "scoreboard", sizeof(player->pers.netname) );
		}
	}

	if ( player->pers.connected == CON_CONNECTED ) {
		if ( strcmp( oldname, player->pers.netname ) ) {
			trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " renamed to %s\n\"", oldname, 
				player->pers.netname) );
		}
	}

	// set max health
#ifdef MISSIONPACK
	if (player->ps.powerups[PW_GUARD]) {
		player->pers.maxHealth = 200;
	} else {
		player->pers.maxHealth = PlayerHandicap( player );
	}
#else
	player->pers.maxHealth = PlayerHandicap( player );
#endif
	player->ps.stats[STAT_MAX_HEALTH] = player->pers.maxHealth;

	// set model
	if( g_gametype.integer >= GT_TEAM ) {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "team_model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "team_headmodel"), sizeof( headModel ) );
	} else {
		Q_strncpyz( model, Info_ValueForKey (userinfo, "model"), sizeof( model ) );
		Q_strncpyz( headModel, Info_ValueForKey (userinfo, "headmodel"), sizeof( headModel ) );
	}

#ifdef MISSIONPACK
	if (g_gametype.integer >= GT_TEAM) {
		player->pers.teamInfo = qtrue;
	} else {
		s = Info_ValueForKey( userinfo, "teamoverlay" );
		if ( ! *s || atoi( s ) != 0 ) {
			player->pers.teamInfo = qtrue;
		} else {
			player->pers.teamInfo = qfalse;
		}
	}
#else
	// teamInfo
	s = Info_ValueForKey( userinfo, "teamoverlay" );
	if ( ! *s || atoi( s ) != 0 ) {
		player->pers.teamInfo = qtrue;
	} else {
		player->pers.teamInfo = qfalse;
	}
#endif
	/*
	s = Info_ValueForKey( userinfo, "cg_pmove_fixed" );
	if ( !*s || atoi( s ) == 0 ) {
		player->pers.pmoveFixed = qfalse;
	}
	else {
		player->pers.pmoveFixed = qtrue;
	}
	*/

	// team task (0 = none, 1 = offence, 2 = defence)
	teamTask = atoi(Info_ValueForKey(userinfo, "teamtask"));
	// team Leader (1 = leader, 0 is normal player)
	teamLeader = player->sess.teamLeader;

	// colors
	strcpy(c1, Info_ValueForKey( userinfo, "color1" ));
	strcpy(c2, Info_ValueForKey( userinfo, "color2" ));

	// send over a subset of the userinfo keys so other clients can
	// print scoreboards, display models, and play custom sounds
	if (ent->r.svFlags & SVF_BOT)
	{
		s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tt\\%d\\tl\\%d",
			player->pers.netname, player->sess.sessionTeam, model, headModel, c1, c2, 
			player->pers.maxHealth, player->sess.wins, player->sess.losses,
			Info_ValueForKey( userinfo, "skill" ), teamTask, teamLeader );
	}
	else
	{
		s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tt\\%d\\tl\\%d",
			player->pers.netname, player->sess.sessionTeam, model, headModel, c1, c2, 
			player->pers.maxHealth, player->sess.wins, player->sess.losses, teamTask, teamLeader);
	}

	trap_SetConfigstring( CS_PLAYERS+playerNum, s );

	// this is not the userinfo, more like the configstring actually
	G_LogPrintf( "PlayerUserinfoChanged: %i %s\n", playerNum, s );
}
Пример #3
0
/*
===========
PlayerSpawn

Called every time a player is placed fresh in the world:
after the first PlayerBegin, and after each respawn
Initializes all non-persistant parts of playerState
============
*/
void PlayerSpawn(gentity_t *ent) {
	int		index;
	vec3_t	spawn_origin, spawn_angles;
	gplayer_t	*player;
	int		i;
	playerPersistant_t	saved;
	playerSession_t		savedSess;
	int		persistant[MAX_PERSISTANT];
	gentity_t	*spawnPoint;
	gentity_t *tent;
	int		flags;
	int		savedPing;
//	char	*savedAreaBits;
	int		accuracy_hits, accuracy_shots;
	int		eventSequence;
	int 	startWeapon, startAmmo;

	index = ent - g_entities;
	player = ent->player;

	VectorClear(spawn_origin);

	// find a spawn point
	// do it before setting health back up, so farthest
	// ranging doesn't count this player
	if ( player->sess.sessionTeam == TEAM_SPECTATOR ) {
		spawnPoint = SelectSpectatorSpawnPoint ( 
						spawn_origin, spawn_angles);
	} else if (g_gametype.integer >= GT_CTF ) {
		// all base oriented team games use the CTF spawn points
		spawnPoint = SelectCTFSpawnPoint ( 
						player->sess.sessionTeam, 
						player->pers.teamState.state, 
						spawn_origin, spawn_angles,
						!!(ent->r.svFlags & SVF_BOT));
	}
	else
	{
		// the first spawn should be at a good looking spot
		if ( player->pers.initialSpawn && player->pers.localClient )
		{
			spawnPoint = SelectInitialSpawnPoint(spawn_origin, spawn_angles,
							     !!(ent->r.svFlags & SVF_BOT));
		}
		else
		{
			// don't spawn near existing origin if possible
			spawnPoint = SelectSpawnPoint ( 
				player->ps.origin, 
				spawn_origin, spawn_angles, !!(ent->r.svFlags & SVF_BOT));
		}
	}
	player->pers.teamState.state = TEAM_ACTIVE;

	// always clear the kamikaze flag
	ent->s.eFlags &= ~EF_KAMIKAZE;

	// toggle the teleport bit so the client knows to not lerp
	// and never clear the voted flag
	flags = ent->player->ps.eFlags & (EF_TELEPORT_BIT | EF_VOTED | EF_TEAMVOTED);
	flags ^= EF_TELEPORT_BIT;

	// clear everything but the persistant data

	saved = player->pers;
	savedSess = player->sess;
	savedPing = player->ps.ping;
//	savedAreaBits = player->areabits;
	accuracy_hits = player->accuracy_hits;
	accuracy_shots = player->accuracy_shots;
	for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
		persistant[i] = player->ps.persistant[i];
	}
	eventSequence = player->ps.eventSequence;

	Com_Memset (player, 0, sizeof(*player));

	player->pers = saved;
	player->sess = savedSess;
	player->ps.ping = savedPing;
//	player->areabits = savedAreaBits;
	player->accuracy_hits = accuracy_hits;
	player->accuracy_shots = accuracy_shots;
	player->lastkilled_player = -1;

	for ( i = 0 ; i < MAX_PERSISTANT ; i++ ) {
		player->ps.persistant[i] = persistant[i];
	}
	player->ps.eventSequence = eventSequence;
	// increment the spawncount so the client will detect the respawn
	player->ps.persistant[PERS_SPAWN_COUNT]++;
	player->ps.persistant[PERS_TEAM] = player->sess.sessionTeam;

	player->airOutTime = level.time + 12000;

	// set max health
	player->pers.maxHealth = PlayerHandicap( player );
	// clear entity values
	player->ps.stats[STAT_MAX_HEALTH] = player->pers.maxHealth;
	player->ps.eFlags = flags;
	player->ps.contents = CONTENTS_BODY;
	player->ps.collisionType = ( g_playerCapsule.integer == 1 ) ? CT_CAPSULE : CT_AABB;

	ent->s.groundEntityNum = ENTITYNUM_NONE;
	ent->player = &level.players[index];
	ent->takedamage = qtrue;
	ent->inuse = qtrue;
	ent->classname = "player";
	ent->clipmask = MASK_PLAYERSOLID;
	ent->die = player_die;
	ent->waterlevel = 0;
	ent->watertype = 0;
	ent->flags = 0;
	ent->player->headless = qfalse;
	
	VectorCopy (playerMins, player->ps.mins);
	VectorCopy (playerMaxs, player->ps.maxs);

	player->ps.playerNum = index;

	if ( g_instaGib.integer == 1 ) {
		startWeapon = WP_RAILGUN;
		startAmmo = 50;
	} else if ( g_instaGib.integer == 2 ) {
		startWeapon = WP_ROCKET_LAUNCHER;
		startAmmo = 50;
	} else {
		startWeapon = WP_MACHINEGUN;
		startAmmo = 100;
	}

	player->ps.stats[STAT_WEAPONS] = ( 1 << startWeapon );

	player->ps.ammo[startWeapon] = startAmmo;

	player->ps.stats[STAT_WEAPONS] |= ( 1 << WP_GAUNTLET );
	player->ps.ammo[WP_GAUNTLET] = -1;
	player->ps.ammo[WP_GRAPPLING_HOOK] = -1;

	// health will count down towards max_health
	ent->health = player->ps.stats[STAT_HEALTH] = player->ps.stats[STAT_MAX_HEALTH] = MAX_HEALTH;

	G_SetOrigin( ent, spawn_origin );
	VectorCopy( spawn_origin, player->ps.origin );

	// the respawned flag will be cleared after the attack and jump keys come up
	player->ps.pm_flags |= PMF_RESPAWNED;

	trap_GetUsercmd( player - level.players, &ent->player->pers.cmd );
	SetPlayerViewAngle( ent, spawn_angles );
	// don't allow full run speed for a bit
	player->ps.pm_flags |= PMF_TIME_KNOCKBACK;
	player->ps.pm_time = 100;

	player->respawnTime = level.time;
	player->inactivityTime = level.time + g_inactivity.integer * 1000;
	player->latched_buttons = 0;

	// set default animations
	player->ps.torsoAnim = TORSO_STAND;
	player->ps.legsAnim = LEGS_IDLE;

	if (!level.intermissiontime) {
		if (ent->player->sess.sessionTeam != TEAM_SPECTATOR) {
			G_KillBox(ent);
			// force the base weapon up
			player->ps.weapon = startWeapon;
			player->ps.weaponstate = WEAPON_READY;
			// fire the targets of the spawn point
			G_UseTargets(spawnPoint, ent);
			// select the highest weapon number available, after any spawn given items have fired
			player->ps.weapon = 1;

			for (i = WP_NUM_WEAPONS - 1 ; i > 0 ; i--) {
				if (player->ps.stats[STAT_WEAPONS] & (1 << i)) {
					player->ps.weapon = i;
					break;
				}
			}
			// positively link the player, even if the command times are weird
			VectorCopy(ent->player->ps.origin, ent->r.currentOrigin);

			tent = G_TempEntity(ent->player->ps.origin, EV_PLAYER_TELEPORT_IN);
			tent->s.playerNum = ent->s.playerNum;

			trap_LinkEntity (ent);
		}
	} else {
		// move players to intermission
		MovePlayerToIntermission(ent);
	}
	// run a player frame to drop exactly to the floor,
	// initialize animations and other things
	player->ps.commandTime = level.time - 100;
	ent->player->pers.cmd.serverTime = level.time;
	PlayerThink( ent-g_entities );
	// run the presend to set anything else, follow spectators wait
	// until all players have been reconnected after map_restart
	if ( ent->player->sess.spectatorState != SPECTATOR_FOLLOW ) {
		PlayerEndFrame( ent );
	}

	// clear entity state values
	BG_PlayerStateToEntityState( &player->ps, &ent->s, qtrue );

	// we don't want players being backward-reconciled to the place they died
	G_ResetHistory( ent );
}