Example #1
0
void G_DestroyFireteam(int entityNum)
{
	fireteamData_t *ft;

	if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client)
	{
		G_Error("G_DestroyFireteam: invalid client\n");
	}

	if (!G_IsFireteamLeader(entityNum, &ft))
	{
		G_ClientPrint(entityNum, "You are not the leader of a fireteam\n");
		return;
	}

	while (ft->joinOrder[0] != -1)
	{
		if (ft->joinOrder[0] != entityNum)
		{
#ifdef FEATURE_OMNIBOT
			Bot_Event_FireTeamDestroyed(ft->joinOrder[0]);
#endif
			trap_SendServerCommand(ft->joinOrder[0], "cpm \"The fireteam you are on has been disbanded\"");
		}

		G_RemoveClientFromFireteams(ft->joinOrder[0], qfalse, qfalse);
	}

	G_UpdateFireteamConfigString(ft);
}
Example #2
0
void G_KickFireTeamPlayer(int entityNum, int otherEntityNum) {
	fireteamData_t *ft, *ft2;

	if (entityNum == otherEntityNum) {
		return; // ok, stop being silly :p
	}

	if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) {
		G_Error("G_KickFireTeamPlayer: invalid client");
	}

	if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) {
		G_Error("G_KickFireTeamPlayer: invalid client");
	}

	if (!G_IsFireteamLeader(entityNum, &ft)) {
		G_ClientPrintAndReturn(entityNum, "You are not the leader of a fireteam");
	}

	if ((!G_IsOnFireteam(otherEntityNum, &ft2)) || ft != ft2) {
		G_ClientPrintAndReturn(entityNum, "You are not on the same Fireteam as the other player");
	}


	G_RemoveClientFromFireteams(otherEntityNum, qtrue, qfalse);

	G_ClientPrintAndReturn(otherEntityNum, "You have been kicked from the fireteam");
}
Example #3
0
/**
 * @brief Shuffle active players onto teams
 */
void G_shuffleTeams(void)
{
	int       i;
	team_t    cTeam; //, cMedian = level.numNonSpectatorClients / 2;
	int       cnt = 0;
	int       sortClients[MAX_CLIENTS];
	gclient_t *cl;

	G_teamReset(TEAM_AXIS, qtrue);
	G_teamReset(TEAM_ALLIES, qtrue);

	for (i = 0; i < level.numConnectedClients; i++)
	{
		cl = level.clients + level.sortedClients[i];

		if (cl->sess.sessionTeam != TEAM_AXIS && cl->sess.sessionTeam != TEAM_ALLIES)
		{
			continue;
		}

		sortClients[cnt++] = level.sortedClients[i];
	}

	qsort(sortClients, cnt, sizeof(int), G_SortPlayersByXP);

	for (i = 0; i < cnt; i++)
	{
		cl = level.clients + sortClients[i];

		//	cTeam = (i % 2) + TEAM_AXIS;
		cTeam = (((i + 1) % 4) - ((i + 1) % 2)) / 2 + TEAM_AXIS;

		if (cl->sess.sessionTeam != cTeam)
		{
			G_LeaveTank(g_entities + sortClients[i], qfalse);
			G_RemoveClientFromFireteams(sortClients[i], qtrue, qfalse);
			if (g_landminetimeout.integer)
			{
				G_ExplodeMines(g_entities + sortClients[i]);
			}
			G_FadeItems(g_entities + sortClients[i], MOD_SATCHEL);
		}

		cl->sess.sessionTeam = cTeam;

		G_UpdateCharacter(cl);
		ClientUserinfoChanged(sortClients[i]);
		ClientBegin(sortClients[i]);
	}

	AP("cp \"^1Teams have been shuffled!\n\"");
}
Example #4
0
// The only way a client should be removed from a fireteam
void G_RemoveClientFromFireteams( int entityNum, qboolean update, qboolean print ) {
	fireteamData_t* ft;
	int i, j;

	if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
		G_Error( "G_RemoveClientFromFireteams: invalid client" );
	}

	if ( G_IsOnFireteam( entityNum, &ft ) ) {
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( ft->joinOrder[i] == entityNum ) {
				if ( i == 0 ) {
					if ( ft->joinOrder[1] == -1 ) {
						ft->inuse = qfalse;
						ft->ident = -1;
					} else {
						// TODO: Inform client of promotion to leader
					}
				}
				for ( j = i; j < MAX_CLIENTS - 1; j++ ) {
					ft->joinOrder[j] = ft->joinOrder[j + 1];
				}
				ft->joinOrder[MAX_CLIENTS - 1] = -1;

				break;
			}
		}
	} else {
		return;
	}

	if ( ft->joinOrder[0] != -1 ) {
		if ( g_entities[(int)ft->joinOrder[0]].r.svFlags & SVF_BOT ) {
			G_RemoveClientFromFireteams( ft->joinOrder[0], qfalse, qfalse );
		}
	}

	if ( print ) {
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( ft->joinOrder[i] == -1 ) {
				break;
			}

			trap_SendServerCommand( ft->joinOrder[i], va( "cpm \"%s has left the Fireteam\"\n", level.clients[entityNum].pers.netname ) );
		}
	}

	if ( update ) {
		G_UpdateFireteamConfigString( ft );
	}
}
Example #5
0
void G_DestroyFireteam( int entityNum ) {
	fireteamData_t* ft;

	if ( ( entityNum < 0 || entityNum >= MAX_CLIENTS ) || !g_entities[entityNum].client ) {
		G_Error( "G_DestroyFireteam: invalid client" );
	}

	if ( !G_IsFireteamLeader( entityNum, &ft ) ) {
		G_ClientPrintAndReturn( entityNum, "You are not the leader of a fireteam" );
	}

	while ( ft->joinOrder[0] != -1 ) {
		if ( ft->joinOrder[0] != entityNum ) {
			trap_SendServerCommand( ft->joinOrder[0], "cpm \"The Fireteam you are on has been disbanded\"\n" );
		}

		G_RemoveClientFromFireteams( ft->joinOrder[0], qfalse, qfalse );
	}

	G_UpdateFireteamConfigString( ft );
}
Example #6
0
// Command handler
void Cmd_FireTeam_MP_f( gentity_t* ent ) {
	char command[32];
	int i;

	if ( trap_Argc() < 2 ) {
		G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam <create|leave|apply|invite>" );
	}

	trap_Argv( 1, command, 32 );

	if ( !Q_stricmp( command, "create" ) ) {
		G_RegisterFireteam( ent - g_entities );
	} else if ( !Q_stricmp( command, "disband" ) ) {
		G_DestroyFireteam( ent - g_entities );
	} else if ( !Q_stricmp( command, "leave" ) ) {
		G_RemoveClientFromFireteams( ent - g_entities, qtrue, qtrue );
	} else if ( !Q_stricmp( command, "apply" ) ) {
		char namebuffer[32];
		int fireteam;

		if ( trap_Argc() < 3 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam apply <fireteamname|fireteamnumber>" );
		}

		trap_Argv( 2, namebuffer, 32 );
		fireteam = G_FireteamNumberForString( namebuffer, ent->client->sess.sessionTeam );

		if ( fireteam <= 0 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam apply <fireteamname|fireteamnumber>" );
		}

		G_ApplyToFireTeam( ent - g_entities, fireteam - 1 );
	} else if ( !Q_stricmp( command, "invite" ) ) {
		char namebuffer[32];
		int clientnum = 0;

		if ( trap_Argc() < 3 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam invite <clientname|clientnumber>" );
		}

		trap_Argv( 2, namebuffer, 32 );
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( !g_entities[i].inuse || !g_entities[i].client ) {
				continue;
			}

			if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
				clientnum = i + 1;
			}
		}

		if ( clientnum <= 0 ) {
			clientnum = atoi( namebuffer );

			if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
				G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
			}
		}

		if ( clientnum <= 0 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam invite <clientname|clientnumber>" );
		}

		G_InviteToFireTeam( ent - g_entities, clientnum - 1 );
	} else if ( !Q_stricmp( command, "warn" ) ) {
		char namebuffer[32];
		int clientnum = 0;

		if ( trap_Argc() < 3 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam warn <clientname|clientnumber>" );
		}

		trap_Argv( 2, namebuffer, 32 );
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( !g_entities[i].inuse || !g_entities[i].client ) {
				continue;
			}

			if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
				clientnum = i + 1;
			}
		}

		if ( clientnum <= 0 ) {
			clientnum = atoi( namebuffer );

			if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
				G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
			}
		}

		if ( clientnum <= 0 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam warn <clientname|clientnumber>" );
		}

		G_WarnFireTeamPlayer( ent - g_entities, clientnum - 1 );
	} else if ( !Q_stricmp( command, "kick" ) ) {
		char namebuffer[32];
		int clientnum = 0;

		if ( trap_Argc() < 3 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam kick <clientname|clientnumber>" );
		}

		trap_Argv( 2, namebuffer, 32 );
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( !g_entities[i].inuse || !g_entities[i].client ) {
				continue;
			}

			if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
				clientnum = i + 1;
			}
		}

		if ( clientnum <= 0 ) {
			clientnum = atoi( namebuffer );

			if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
				G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
			}
		}

		if ( clientnum <= 0 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam kick <clientname|clientnumber>" );
		}

		G_KickFireTeamPlayer( ent - g_entities, clientnum - 1 );
	} else if ( !Q_stricmp( command, "propose" ) ) {
		char namebuffer[32];
		int clientnum = 0;

		if ( trap_Argc() < 3 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam propose <clientname|clientnumber>" );
		}

		trap_Argv( 2, namebuffer, 32 );
		for ( i = 0; i < MAX_CLIENTS; i++ ) {
			if ( !g_entities[i].inuse || !g_entities[i].client ) {
				continue;
			}

			if ( !Q_stricmp( g_entities[i].client->pers.netname, namebuffer ) ) {
				clientnum = i + 1;
			}
		}

		if ( clientnum <= 0 ) {
			clientnum = atoi( namebuffer );

			if ( ( clientnum <= 0 || clientnum > MAX_CLIENTS ) || !g_entities[clientnum - 1].inuse || !g_entities[clientnum - 1].client ) {
				G_ClientPrintAndReturn( ent - g_entities, "Invalid client selected" );
			}
		}

		if ( clientnum <= 0 ) {
			G_ClientPrintAndReturn( ent - g_entities, "usage: fireteam propose <clientname|clientnumber>" );
		}

		G_ProposeFireTeamPlayer( ent - g_entities, clientnum - 1 );
	}
}
Example #7
0
/*
===========
ClientDisconnect

Called when a player drops from the server.
Will not be called between levels.

This should NOT be called directly by any game logic,
call trap_DropClient(), which will call this and do
server system housekeeping.
============
*/
void ClientDisconnect(int clientNum) {
	gentity_t *ent;
	gentity_t *flag = NULL;
	gitem_t   *item = NULL;
	vec3_t    launchvel;
	int       i;

	ent = g_entities + clientNum;
	if (!ent->client) {
		return;
	}

	G_RemoveClientFromFireteams(clientNum, qtrue, qfalse);
	G_RemoveFromAllIgnoreLists(clientNum);
	G_LeaveTank(ent, qfalse);

	// Nico, remove the client from all specInvited lists
	for (i = 0; i < level.numConnectedClients; ++i) {
		COM_BitClear(level.clients[level.sortedClients[i]].sess.specInvitedClients, clientNum);
	}

	// stop any following clients
	for (i = 0 ; i < level.numConnectedClients ; i++) {
		flag = g_entities + level.sortedClients[i];
		if (flag->client->sess.sessionTeam == TEAM_SPECTATOR
		    && flag->client->sess.spectatorState == SPECTATOR_FOLLOW
		    && flag->client->sess.spectatorClient == clientNum) {
			StopFollowing(flag);
		}
		if (flag->client->ps.pm_flags & PMF_LIMBO
		    && flag->client->sess.spectatorClient == clientNum) {
			Cmd_FollowCycle_f(flag, 1);
		}
	}

	G_FadeItems(ent, MOD_SATCHEL);

	// remove ourself from teamlists
	{
		mapEntityData_t      *mEnt;
		mapEntityData_Team_t *teamList;

		for (i = 0; i < 2; i++) {
			teamList = &mapEntityData[i];

			if ((mEnt = G_FindMapEntityData(&mapEntityData[0], ent - g_entities)) != NULL) {
				G_FreeMapEntityData(teamList, mEnt);
			}

			mEnt = G_FindMapEntityDataSingleClient(teamList, NULL, ent->s.number, -1);

			while (mEnt) {
				mapEntityData_t *mEntFree = mEnt;

				mEnt = G_FindMapEntityDataSingleClient(teamList, mEnt, ent->s.number, -1);

				G_FreeMapEntityData(teamList, mEntFree);
			}
		}
	}

	// send effect if they were completely connected
	if (ent->client->pers.connected == CON_CONNECTED
	    && ent->client->sess.sessionTeam != TEAM_SPECTATOR
	    && !(ent->client->ps.pm_flags & PMF_LIMBO)) {

		// They don't get to take powerups with them!
		// Especially important for stuff like CTF flags
		// New code for tossing flags
		if (ent->client->ps.powerups[PW_REDFLAG]) {
			item = BG_FindItem("Red Flag");
			if (!item) {
				item = BG_FindItem("Objective");
			}

			ent->client->ps.powerups[PW_REDFLAG] = 0;
		}
		if (ent->client->ps.powerups[PW_BLUEFLAG]) {
			item = BG_FindItem("Blue Flag");
			if (!item) {
				item = BG_FindItem("Objective");
			}

			ent->client->ps.powerups[PW_BLUEFLAG] = 0;
		}

		if (item) {
			// OSP - fix for suicide drop exploit through walls/gates
			launchvel[0] = 0;    //crandom()*20;
			launchvel[1] = 0;    //crandom()*20;
			launchvel[2] = 0;    //10+random()*10;

			flag                = LaunchItem(item, ent->r.currentOrigin, launchvel, ent - g_entities);
			flag->s.modelindex2 = ent->s.otherEntityNum2;    // JPW NERVE FIXME set player->otherentitynum2 with old modelindex2 from flag and restore here
			flag->message       = ent->message; // DHM - Nerve :: also restore item name
			// Clear out player's temp copies
			ent->s.otherEntityNum2 = 0;
			ent->message           = NULL;
		}
	}

	G_LogPrintf("ClientDisconnect: %i\n", clientNum);

	trap_UnlinkEntity(ent);
	ent->s.modelindex                     = 0;
	ent->inuse                            = qfalse;
	ent->classname                        = "disconnected";
	ent->client->pers.connected           = CON_DISCONNECTED;
	ent->client->ps.persistant[PERS_TEAM] = TEAM_FREE;
	i                                     = ent->client->sess.sessionTeam;
	ent->client->sess.sessionTeam         = TEAM_FREE;
	ent->active                           = 0;

	trap_SetConfigstring(CS_PLAYERS + clientNum, "");

	CalculateRanks();
}