// only way a client should ever join a fireteam, other than creating one void G_AddClientToFireteam(int entityNum, int leaderNum) { fireteamData_t *ft; int i; if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_AddClientToFireteam: invalid client\n"); } if ((leaderNum < 0 || leaderNum >= MAX_CLIENTS) || !g_entities[leaderNum].client) { G_Error("G_AddClientToFireteam: invalid client\n"); } if (g_entities[leaderNum].client->sess.sessionTeam != g_entities[entityNum].client->sess.sessionTeam) { G_ClientPrint(entityNum, "You are not on the same team as that fireteam"); return; } if (!G_IsFireteamLeader(leaderNum, &ft)) { G_ClientPrint(entityNum, "The leader has now left the fireteam you applied to"); return; } if (G_IsOnFireteam(entityNum, NULL)) { G_ClientPrint(entityNum, "You are already on a fireteam"); return; } if (G_CountFireteamMembers(ft) >= MAX_FIRETEAM_MEMBERS) { G_ClientPrint(entityNum, "Too many players already on this fireteam"); return; } for (i = 0; i < MAX_CLIENTS; i++) { if (ft->joinOrder[i] == -1) { // found a free position ft->joinOrder[i] = entityNum; #ifdef FEATURE_OMNIBOT Bot_Event_JoinedFireTeam(entityNum, &g_entities[leaderNum]); #endif G_UpdateFireteamConfigString(ft); return; } } }
void G_GiveAdminOfFireTeam(int entityNum, int otherEntityNum) { fireteamData_t *ft, *ft2; char tempArray[MAX_CLIENTS]; int i, x; if (entityNum == otherEntityNum) { return; } if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_KickFireTeamPlayer: invalid client\n"); } if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) { G_Error("G_KickFireTeamPlayer: invalid client\n"); } if (!G_IsFireteamLeader(entityNum, &ft)) { G_ClientPrint(entityNum, "You must be a fireteam admin to give admin rights to someone else"); return; } if ((!G_IsOnFireteam(otherEntityNum, &ft2)) || ft != ft2) { G_ClientPrint(entityNum, "The other player must be on the same fireteam for you to give admin rights to"); return; } tempArray[0] = otherEntityNum; tempArray[1] = entityNum; x = 2; for (i = 1; i < MAX_FIRETEAM_MEMBERS; i++) { if (ft->joinOrder[i] != otherEntityNum || ft->joinOrder[i] == -1) { tempArray[x++] = ft->joinOrder[i]; continue; } } for (i = 0; i < MAX_FIRETEAM_MEMBERS; i++) { ft->joinOrder[i] = tempArray[i]; } ft->leader = otherEntityNum; G_UpdateFireteamConfigString(ft); G_ClientPrint(otherEntityNum, "You have been given fireteam admin rights"); G_ClientPrint(entityNum, "You have been been stripped of fireteam admin rights"); }
// The only way a client should ever be invited to join a team void G_InviteToFireTeam(int entityNum, int otherEntityNum) { fireteamData_t *ft; if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_InviteToFireTeam: invalid client\n"); } if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) { G_Error("G_InviteToFireTeam: invalid client\n"); } if (!G_IsFireteamLeader(entityNum, &ft)) { G_ClientPrint(entityNum, "You are not the leader of a fireteam"); return; } if (g_entities[entityNum].client->sess.sessionTeam != g_entities[otherEntityNum].client->sess.sessionTeam) { G_ClientPrint(entityNum, "You are not on the same team as the other player"); return; } if (G_IsOnFireteam(otherEntityNum, NULL)) { G_ClientPrint(entityNum, "The other player is already on a fireteam"); return; } if (G_CountFireteamMembers(ft) >= MAX_FIRETEAM_MEMBERS) { G_ClientPrint(entityNum, "Too many players already on this fireteam"); return; } if (g_entities[otherEntityNum].r.svFlags & SVF_BOT) { // bots auto join G_AddClientToFireteam(otherEntityNum, entityNum); } else { trap_SendServerCommand(entityNum, va("invitation -1")); trap_SendServerCommand(otherEntityNum, va("invitation %i", entityNum)); g_entities[otherEntityNum].client->pers.invitationClient = entityNum; g_entities[otherEntityNum].client->pers.invitationEndTime = level.time + 20500; } #ifdef FEATURE_OMNIBOT Bot_Event_InviteFireTeam(entityNum, otherEntityNum); #endif }
void G_ProposeFireTeamPlayer(int entityNum, int otherEntityNum) { fireteamData_t *ft; gentity_t *leader; if (entityNum == otherEntityNum) { return; // ok, stop being silly :p } if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_ProposeFireTeamPlayer: invalid client\n"); } if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) { G_Error("G_ProposeFireTeamPlayer: invalid client\n"); } if (G_IsOnFireteam(otherEntityNum, NULL)) { G_ClientPrint(entityNum, "The other player is already on a fireteam"); return; } if (!G_IsOnFireteam(entityNum, &ft)) { G_ClientPrint(entityNum, "You are not on a fireteam"); return; } if (ft->joinOrder[0] == entityNum) { // you are the leader so just invite them G_InviteToFireTeam(entityNum, otherEntityNum); return; } leader = &g_entities[(int)ft->joinOrder[0]]; if (!leader->client) { G_Error("G_ProposeFireTeamPlayer: invalid client\n"); } trap_SendServerCommand(entityNum, va("proposition -1")); trap_SendServerCommand(leader - g_entities, va("proposition %i %i", otherEntityNum, entityNum)); leader->client->pers.propositionClient = otherEntityNum; leader->client->pers.propositionClient2 = entityNum; leader->client->pers.propositionEndTime = level.time + 20000; #ifdef FEATURE_OMNIBOT Bot_Event_FireTeam_Proposal(leader - g_entities, otherEntityNum); #endif }
// The only way a client should ever apply to join a team void G_ApplyToFireTeam(int entityNum, int fireteamNum) { gentity_t *leader; fireteamData_t *ft; if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_AddClientToFireteam: invalid client\n"); } if (G_IsOnFireteam(entityNum, NULL)) { G_ClientPrint(entityNum, "You are already on a fireteam"); return; } ft = &level.fireTeams[fireteamNum]; if (!ft->inuse) { G_ClientPrint(entityNum, "The fireteam you requested does not exist"); return; } if (ft->joinOrder[0] < 0 || ft->joinOrder[0] >= MAX_CLIENTS) { G_Error("G_ApplyToFireTeam: fireteam leader is invalid\n"); } leader = &g_entities[(int)ft->joinOrder[0]]; if (!leader->client) { G_Error("G_ApplyToFireTeam: fireteam leader client is NULL\n"); } if (G_CountFireteamMembers(ft) >= MAX_FIRETEAM_MEMBERS) { G_ClientPrint(entityNum, "Too many players already on this fireteam"); return; } // DEBUG //G_AddClientToFireteam( entityNum, ft->joinOrder[0] ); trap_SendServerCommand(entityNum, va("application -1")); trap_SendServerCommand(leader - g_entities, va("application %i", entityNum)); leader->client->pers.applicationClient = entityNum; leader->client->pers.applicationEndTime = level.time + 20000; }
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); }
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\n"); } if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) { G_Error("G_KickFireTeamPlayer: invalid client\n"); } if (!G_IsFireteamLeader(entityNum, &ft)) { G_ClientPrint(entityNum, "You are not the leader of a fireteam"); return; } if ((!G_IsOnFireteam(otherEntityNum, &ft2)) || ft != ft2) { G_ClientPrint(entityNum, "You are not on the same fireteam as the other player"); return; } #ifdef FEATURE_OMNIBOT Bot_Event_LeftFireTeam(otherEntityNum); #endif G_RemoveClientFromFireteams(otherEntityNum, qtrue, qfalse); G_ClientPrint(otherEntityNum, "You have been kicked from the fireteam"); }
void G_WarnFireTeamPlayer(int entityNum, int otherEntityNum) { fireteamData_t *ft, *ft2; if (entityNum == otherEntityNum) { return; // stop being silly } if ((entityNum < 0 || entityNum >= MAX_CLIENTS) || !g_entities[entityNum].client) { G_Error("G_WarnFireTeamPlayer: invalid client\n"); } if ((otherEntityNum < 0 || otherEntityNum >= MAX_CLIENTS) || !g_entities[otherEntityNum].client) { G_Error("G_WarnFireTeamPlayer: invalid client\n"); } if (!G_IsFireteamLeader(entityNum, &ft)) { G_ClientPrint(entityNum, "You are not the leader of a fireteam"); return; } if ((!G_IsOnFireteam(otherEntityNum, &ft2)) || ft != ft2) { G_ClientPrint(entityNum, "You are not on the same fireteam as the other player"); return; } trap_SendServerCommand(otherEntityNum, "cpm \"You have been warned by your fireteam leader\""); #ifdef FEATURE_OMNIBOT Bot_Event_FireTeam_Warn(entityNum, otherEntityNum); #endif }
// Command handler void Cmd_FireTeam_MP_f(gentity_t *ent) { char command[32]; int i; if (trap_Argc() < 2) { G_ClientPrint(ent - g_entities, "usage: fireteam <create|leave|apply|invite>"); return; } 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_ClientPrint(ent - g_entities, "usage: fireteam apply <fireteamname|fireteamnumber>"); return; } trap_Argv(2, namebuffer, 32); fireteam = G_FireteamNumberForString(namebuffer, ent->client->sess.sessionTeam); if (fireteam <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam apply <fireteamname|fireteamnumber>"); return; } G_ApplyToFireTeam(ent - g_entities, fireteam - 1); } else if (!Q_stricmp(command, "invite")) { char namebuffer[32]; int clientnum = 0; if (trap_Argc() < 3) { G_ClientPrint(ent - g_entities, "usage: fireteam invite <clientname|clientnumber>"); return; } 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_ClientPrint(ent - g_entities, "Invalid client selected"); return; } } if (clientnum <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam invite <clientname|clientnumber>"); return; } G_InviteToFireTeam(ent - g_entities, clientnum - 1); } else if (!Q_stricmp(command, "warn")) { char namebuffer[32]; int clientnum = 0; if (trap_Argc() < 3) { G_ClientPrint(ent - g_entities, "usage: fireteam warn <clientname|clientnumber>"); return; } 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_ClientPrint(ent - g_entities, "Invalid client selected"); return; } } if (clientnum <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam warn <clientname|clientnumber>"); return; } G_WarnFireTeamPlayer(ent - g_entities, clientnum - 1); } else if (!Q_stricmp(command, "kick")) { char namebuffer[32]; int clientnum = 0; if (trap_Argc() < 3) { G_ClientPrint(ent - g_entities, "usage: fireteam kick <clientname|clientnumber>"); return; } 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_ClientPrint(ent - g_entities, "Invalid client selected"); return; } } if (clientnum <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam kick <clientname|clientnumber>"); return; } G_KickFireTeamPlayer(ent - g_entities, clientnum - 1); } else if (!Q_stricmp(command, "propose")) { char namebuffer[32]; int clientnum = 0; if (trap_Argc() < 3) { G_ClientPrint(ent - g_entities, "usage: fireteam propose <clientname|clientnumber>"); return; } 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_ClientPrint(ent - g_entities, "Invalid client selected"); return; } } if (clientnum <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam propose <clientname|clientnumber>"); return; } G_ProposeFireTeamPlayer(ent - g_entities, clientnum - 1); } else if (!Q_stricmp(command, "privacy")) { fireteamData_t *ft; if (G_IsFireteamLeader(ent - g_entities, &ft)) { if (ft->priv) { ft->priv = qfalse; G_UpdateFireteamConfigString(ft); G_ClientPrint(ent - g_entities, "Your fireteam is now public"); return; } else { ft->priv = qtrue; G_UpdateFireteamConfigString(ft); G_ClientPrint(ent - g_entities, "Your fireteam is now private"); return; } } else { G_ClientPrint(ent - g_entities, "You are not a fireteam admin"); return; } } else if (!Q_stricmp(command, "admin")) { char namebuffer[32]; int clientnum = 0; if (trap_Argc() < 3) { G_ClientPrint(ent - g_entities, "usage: fireteam admin <clientname|clientnumber>"); return; } 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_ClientPrint(ent - g_entities, "Invalid client selected"); return; } } if (clientnum <= 0) { G_ClientPrint(ent - g_entities, "usage: fireteam admin <clientname|clientnumber>"); return; } G_GiveAdminOfFireTeam(ent - g_entities, clientnum - 1); } }
// Should be the only function that ever creates a fireteam void G_RegisterFireteam(int entityNum) { fireteamData_t *ft; gentity_t *leader; int count, ident; if (entityNum < 0 || entityNum >= MAX_CLIENTS) { G_Error("G_RegisterFireteam: invalid client\n"); } leader = &g_entities[entityNum]; if (!leader->client) { G_Error("G_RegisterFireteam: attempting to register a fireteam to an entity with no client\n"); } if (G_IsOnFireteam(entityNum, NULL)) { G_ClientPrint(entityNum, "You are already on a fireteam, leave it first"); return; } if ((ft = G_FindFreeFireteam()) == NULL) { G_ClientPrint(entityNum, "No free fireteams available"); return; } if (leader->client->sess.sessionTeam != TEAM_AXIS && leader->client->sess.sessionTeam != TEAM_ALLIES) { G_ClientPrint(entityNum, "Only players on a team can create a fireteam"); return; } count = G_CountTeamFireteams(leader->client->sess.sessionTeam); if (count >= MAX_FIRETEAMS / 2) { G_ClientPrint(entityNum, "Your team already has the maximum number of fireteams allowed"); return; } ident = G_FindFreeFireteamIdent(leader->client->sess.sessionTeam) + 1; if (ident == 0) { G_Error("G_RegisterFireteam: free fireteam is invalid\n"); return; } // good to go now ft->inuse = qtrue; memset(ft->joinOrder, -1, sizeof(level.fireTeams[0].joinOrder)); ft->joinOrder[0] = leader - g_entities; ft->ident = ident; if (g_autoFireteams.integer) { ft->priv = qfalse; trap_SendServerCommand(entityNum, "aft -1"); leader->client->pers.autofireteamEndTime = level.time + 20500; } else { ft->priv = qfalse; } #ifdef FEATURE_OMNIBOT Bot_Event_FireTeamCreated(entityNum, ft->ident); Bot_Event_JoinedFireTeam(leader - g_entities, leader); #endif G_UpdateFireteamConfigString(ft); }