/* =============== Svcmd_AddBot_f =============== */ void Svcmd_AddBot_f(void) { float skill; int delay; char name[MAX_TOKEN_CHARS]; char altname[MAX_TOKEN_CHARS]; char string[MAX_TOKEN_CHARS]; char team[MAX_TOKEN_CHARS]; // are bots enabled? if(!trap_Cvar_VariableIntegerValue("bot_enable")) { return; } // name trap_Argv(1, name, sizeof(name)); if(!name[0]) { trap_Printf("Usage: Addbot <botname> [skill 1-5] [team] [msec delay] [altname]\n"); return; } // skill trap_Argv(2, string, sizeof(string)); if(!string[0]) { skill = 4; } else { skill = atof(string); } // team trap_Argv(3, team, sizeof(team)); // delay trap_Argv(4, string, sizeof(string)); if(!string[0]) { delay = 0; } else { delay = atoi(string); } // alternative name trap_Argv(5, altname, sizeof(altname)); G_AddBot(name, skill, team, delay, altname); // if this was issued during gameplay and we are playing locally, // go ahead and load the bot's media immediately if(level.time - level.startTime > 1000 && trap_Cvar_VariableIntegerValue("cl_running")) { trap_SendServerCommand(-1, "loaddefered\n"); // FIXME: spelled wrong, but not changing for demo } }
/* =============== Svcmd_AddBot_f =============== */ void Svcmd_AddBot_f( void ) { int skill; int delay; char name[MAX_TOKEN_CHARS]; char string[MAX_TOKEN_CHARS]; char team[MAX_TOKEN_CHARS]; // are bots enabled? if ( !bot_enable.integer ) { return; } // name trap_Argv( 1, name, sizeof( name ) ); /// read it just so we can check if it's a name (old method) if ( name[0] && !Q_stricmp( name, "?" ) ) { trap_Printf( "Usage: Addbot [skill 1-4] [team (RED/BLUE)] [msec delay]\n" ); return; } // CHRUKER: b070 - Was 'wolfbot' but this must match in case Q_strncpyz( name, "Wolfbot", sizeof( name ) ); // RF, hard code the bots for wolf if ( !name[0] ) { trap_Printf( "Usage: Addbot [skill 1-4] [team (RED/BLUE)] [msec delay]\n" ); return; } // skill trap_Argv( 1, string, sizeof( string ) ); if ( !string[0] ) { trap_Cvar_Update( &bot_defaultskill ); skill = bot_defaultskill.integer; } else { skill = atoi( string ); } // team trap_Argv( 2, team, sizeof( team ) ); // delay trap_Argv( 3, string, sizeof( string ) ); if ( !string[0] ) { delay = 0; } else { delay = atoi( string ); } G_AddBot( name, skill, team, NULL, 0, 0, -1, NULL, NULL, -1, NULL, qfalse); // if this was issued during gameplay and we are playing locally, // go ahead and load the bot's media immediately if ( level.time - level.startTime > 1000 && trap_Cvar_VariableIntegerValue( "cl_running" ) ) { } }
/* * Svcmd_AddBot_f */ void Svcmd_AddBot_f(void) { float skill; int delay; char name[MAX_TOKEN_CHARS]; char altname[MAX_TOKEN_CHARS]; char string[MAX_TOKEN_CHARS]; char team[MAX_TOKEN_CHARS]; /* are bots enabled? */ if(!trap_cvargeti("bot_enable")) return; /* name */ trap_Argv(1, name, sizeof(name)); if(!name[0]){ trap_Print( "Usage: Addbot <botname> [skill 1-5] [team] [msec delay] [altname]\n"); return; } /* skill */ trap_Argv(2, string, sizeof(string)); if(!string[0]) skill = 4; else skill = atof(string); /* team */ trap_Argv(3, team, sizeof(team)); /* delay */ trap_Argv(4, string, sizeof(string)); if(!string[0]) delay = 0; else delay = atoi(string); /* alternative name */ trap_Argv(5, altname, sizeof(altname)); G_AddBot(name, skill, team, delay, altname); /* if this was issued during gameplay and we are playing locally, * go ahead and load the bot's media immediately */ if(level.time - level.startTime > 1000 && trap_cvargeti("cl_running")) trap_SendServerCommand(-1, "loaddeferred\n"); }
/* =================== G_Q3P_AddPlannerBot =================== */ gentity_t* G_Q3P_AddPlannerBot(void) { gentity_t *pBot; // add the bot G_AddBot("Sarge", 1.0, "free", 0, "PlannerBot"); // load bot's media if(level.time - level.startTime > 1000 && trap_Cvar_VariableIntegerValue("cl_running")) { trap_SendServerCommand(-1, "loaddefered\n"); } // the bot is the last connected client pBot = g_entities + level.numConnectedClients - 1; //pBot->client->pers.pmoveFixed = qtrue; pBot->client->ps.commandTime = level.time - 50; pBot->client->pers.cmd.serverTime = level.time; pBot->q3p_isPlannerBot = qtrue; return pBot; }
/* ================== G_SpawnBot ================== */ void G_SpawnBot( const char *text ) { // bot parameters char name[MAX_TOKEN_CHARS] = "wolfBot"; //GS prevent bot health from counting down to 70 (i.e. don't set STAT_MAX_HEALTH = 70) char skill[MAX_TOKEN_CHARS] = "4"; char team[MAX_TOKEN_CHARS] = ""; char pClass[MAX_TOKEN_CHARS] = ""; char pWeapon[MAX_TOKEN_CHARS] = "0"; char spawnPoint[MAX_TOKEN_CHARS] = ""; char respawn[MAX_TOKEN_CHARS] = ""; char scriptName[MAX_TOKEN_CHARS] = "wolfBot"; char characterFile[MAX_TOKEN_CHARS] = ""; // START - Mad Doc - TDF char rank[MAX_TOKEN_CHARS] = ""; char botSkills[MAX_TOKEN_CHARS] = ""; // END Mad Doc - TDF char pow[MAX_TOKEN_CHARS] = "no"; // This is the selection meny index used in SetWolfSpawnWeapons int weaponSpawnNumber = -1; // parsing vars char *token, *pStr, *old_pStr; char cmd[MAX_TOKEN_CHARS], last_cmd[MAX_TOKEN_CHARS]; char cmd_var[MAX_TOKEN_CHARS]; char string[MAX_TOKEN_CHARS]; int j, pClassInt; int characterInt, rankNum; int skills[SK_NUM_SKILLS]; qboolean prisonerOfWar; int teamNum; // parameters spawnBotCommand_t params[] = { {"/name", name, qfalse, "[name]"}, {"/skill", skill, qfalse, "[0-4]"}, {"/team", team, qfalse, "[AXIS/ALLIES]"}, {"/class", pClass, qfalse, "[SOLDIER/MEDIC/LIEUTENANT/ENGINEER/COVERTOPS/FIELDOPS]"}, // FIXME: remove LIEUTENANT from missionpack {"/weapon", pWeapon, qfalse, "[weaponValue]"}, {"/spawnpoint", spawnPoint, qtrue, "[targetname]"}, {"/respawn", respawn, qfalse, "[ON/OFF]"}, {"/scriptName", scriptName, qfalse, "[scriptName]"}, {"/character", characterFile, qfalse, "[character]"}, // START Mad Doc - TDF {"/rank", rank, qfalse, "[rank]"}, {"/skills", botSkills, qfalse, "[botskills]"}, // not really to be exposed to script // END Mad Doc - TDF {"/pow", pow, qfalse, "[yes/no]"}, {NULL} }; // special tables typedef struct { char *weapon; int index; } spawnBotWeapons_t; // TAT 1/16/2003 - uninit'ed data here - getting crazy data for the skills memset(&skills, 0, sizeof(skills)); // // parse the vars pStr = (char *)text; token = COM_Parse( &pStr ); Q_strncpyz( cmd, token, sizeof(cmd) ); // if this is a question mark, show help info if (!Q_stricmp( cmd, "?" ) || !Q_stricmp( cmd, "/?" )) { G_Printf( "Spawns a bot into the game, with the given parameters.\n\nSPAWNBOT [/param [value]] [/param [value]] ...\n\n where [/param [value]] may consist of:\n\n" ); for (j=0; params[j].cmd; j++) { G_Printf( " %s %s\n", params[j].cmd, params[j].help ); } return; } // // intitializations for (j=0; params[j].cmd; j++) { params[j].count = 0; } memset( last_cmd, 0, sizeof(last_cmd) ); pStr = (char *)text; // // parse each command while (cmd[0]) { // // build the string up to the next parameter change token = COM_Parse( &pStr ); Q_strncpyz( cmd, token, sizeof(cmd) ); if (!cmd[0]) break; // if we find an "or", then use the last command if (!Q_stricmp( cmd, "or" )) { // use the last command Q_strncpyz( cmd, last_cmd, sizeof(cmd) ); } // // read the parameters memset( string, 0, sizeof(string) ); token = COM_Parse( &pStr ); Q_strncpyz( cmd_var, token, sizeof(cmd_var) ); if (!cmd_var[0]) break; while (qtrue) { Q_strcat( string, sizeof(string), cmd_var ); old_pStr = pStr; token = COM_Parse( &pStr ); Q_strncpyz( cmd_var, token, sizeof(cmd_var) ); if (cmd_var[0] && (cmd_var[0] == '/' || !Q_stricmp( cmd_var, "or" ))) { pStr = old_pStr; break; } if (!cmd_var[0]) break; Q_strcat( string, sizeof(string), " " ); } // // see if this command exists in the parameters table for (j=0; params[j].cmd; j++) { if (!Q_stricmp( params[j].cmd, cmd )) { // found a match, if this field already has an entry, then randomly override it if (!params[j].count || (!params[j].appendParams && ((rand()%(++params[j].count)) == 0))) { Q_strncpyz( params[j].string, string, sizeof(string) ); } else if (params[j].appendParams) { // append this token Q_strcat( params[j].string, sizeof(string), va(" %s", string) ); } params[j].count++; break; } } if (!params[j].cmd) { G_Printf( "G_SpawnBot: unknown parameter: %s\nFor usage info, use \"spawnbot /?\"\n", cmd ); return; } // Q_strncpyz( last_cmd, cmd, sizeof(last_cmd) ); Q_strncpyz( cmd, cmd_var, sizeof(cmd) ); } // if (strlen( pClass )) { pClassInt = 1 + G_ClassForString( pClass ); } else { pClassInt = 0; } if ( !Q_stricmp( team, "red" ) || !Q_stricmp( team, "r" ) || !Q_stricmp( team, "axis" ) ) { teamNum = TEAM_AXIS; } else if ( !Q_stricmp( team, "blue" ) || !Q_stricmp( team, "b" ) || !Q_stricmp( team, "allies" ) ) { teamNum = TEAM_ALLIES; } else { // pick the team with the least number of players teamNum = PickTeam( -1 ); } G_BotParseCharacterParms( characterFile, &characterInt ); // Gordon: 27/11/02 if( *pow && !Q_stricmp(pow, "yes") ) { prisonerOfWar = qtrue; } else { prisonerOfWar = qfalse; } // START Mad Doc - TDF // special case: if "NONE" is specified, treat this differently if (!Q_stricmp(pWeapon, "NONE")) { weaponSpawnNumber = -1; } // END Mad Doc - TDF // START Mad Doctor I changes, 8/17/2002. // If we have a weapon specified, and we have a class specified else if (isdigit(pWeapon[0])) { // Just convert the string to a number weaponSpawnNumber = atoi(pWeapon); } // if (isdigit(pWeapon[0]))... // If we have a weapon specified as a string, and we have a class specified else if (pClassInt > 0) { // Translate the weapon name into a proper weapon index // Get the index for the weapon weaponSpawnNumber = Bot_GetWeaponForClassAndTeam( pClassInt - 1, teamNum, pWeapon ); // Get default weapon if (weaponSpawnNumber == -1) weaponSpawnNumber = BG_GetPlayerClassInfo( teamNum, pClassInt - 1 )->classWeapons[0]; } // if (Q_stricmp(pWeapon[MAX_TOKEN_CHARS], "0")... // Otherwise, no weapon is selected else { // Just use the default weaponSpawnNumber = BG_GetPlayerClassInfo( teamNum, pClassInt - 1 )->classWeapons[0]; } // else... // START Mad Doc - TDF rankNum = atoi(rank); if( rankNum ) { rankNum--; // people like to start with 1 // Gordon: coders are people too :( } if (botSkills[0]) { // parse the skills out int i; char *pString, *token; pString = botSkills; for (i = 0; i < SK_NUM_SKILLS; i++) { token = COM_ParseExt( &pString, qfalse ); skills[i] = atoi(token); } } // {"/botskills", botSkills, qfalse, "[botskills]"}, // not really to be exposed to script // END Mad Doc - TDF G_AddBot( name, atoi(skill), team, spawnPoint, pClassInt, weaponSpawnNumber, characterInt, respawn, scriptName, rankNum, skills, prisonerOfWar ); // END Mad Doctor I changes, 8/17/2002. }