Le VGUI
Voilà le tutorial surement le plus dur de l’adaptations de vos bots à votre mod.
Bon commençons par bot_client.ccp là on a ce code :
// Ce message est envoyé quand le vgui de tfc est affiché
void BotClient_TFC_VGUI(void *p, int bot_index)
{
static int state = 0; // le status du client
if (state == 0)
{
if ((*(int *)p) == 2) //est ce le menu de sélection de team?
bots[bot_index].start_action = MSG_TFC_TEAM_SELECT;
else if ((*(int *)p) == 3) // est ce le menu de sélection de classe?
bots[bot_index].start_action = MSG_TFC_CLASS_SELECT;
}
state++;
if (state == 1)
state = 0;
}
Ce code sert à détecter quel vgui est affiché (n’oublier pas de déclarer votre vgui dans bot_client.h).
"else if ((*(int *)p) == 3) " cette ligne test si l’id du vgui est 3 ; dans la plupart des mods cela correspond au menu de changement de classe (2 correspond lui à celui de sélection de team). Vos msg sont à déclarés dans "bot.h".
Ensuite tout se passe dans "bot_start.ccp"
Recherchez :
if (mod_id == TFC_DLL)
{
if ((pBot->start_action == MSG_TFC_IDLE) &&
(pBot->create_time + 3.0 <= gpGlobals->time))
{
pBot->start_action = MSG_TFC_TEAM_SELECT; // force la sélection de la team
}
// handle Team Fortress Classic stuff here...
if (pBot->start_action == MSG_TFC_TEAM_SELECT)
{
pBot->start_action = MSG_TFC_IDLE; // retourne à idle
pBot->create_time = gpGlobals->time; // reset
if ((pBot->bot_team != 1) && (pBot->bot_team != 2) &&
(pBot->bot_team != 3) && (pBot->bot_team != 4) &&
(pBot->bot_team != 5))
pBot->bot_team = -1;
if (pBot->bot_team == -1)
pBot->bot_team = RANDOM_LONG(1, max_teams);
retry_count = 0;
while ((retry_count < 4) &&
(max_team_players[pBot->bot_team-1] > 0)) // not unlimited?
{
count = 0;
// compte le nombre de joueur dans la team
for (index = 1; index <= gpGlobals->maxClients; index++)
{
pPlayer = INDEXENT(index);
if (pPlayer && !pPlayer->free)
{
if (UTIL_GetTeam(pPlayer) == (pBot->bot_team - 1))
count++;
}
}
if (count < max_team_players[pBot->bot_team-1])
break; // on a atteint la limite donc on casse la boucle
else
{
pBot->bot_team++;
if (pBot->bot_team > max_teams)
pBot->bot_team = 1;
retry_count++;
}
}
// selectionne l'équipe que le bot va rejoindre
if (pBot->bot_team == 1)
strcpy(c_team, "1");
else if (pBot->bot_team == 2)
strcpy(c_team, "2");
else if (pBot->bot_team == 3)
strcpy(c_team, "3");
else if (pBot->bot_team == 4)
strcpy(c_team, "4");
else
strcpy(c_team, "5");
FakeClientCommand(pEdict, "jointeam", c_team, NULL);
return;
}
if (pBot->start_action == MSG_TFC_CLASS_SELECT)
{
pBot->start_action = MSG_TFC_IDLE; // retourne à idle
pBot->create_time = gpGlobals->time; // reset
if ((pBot->bot_class < 0) || (pBot->bot_class > 10))
pBot->bot_class = -1;
if (pBot->bot_class == -1)
pBot->bot_class = RANDOM_LONG(1, 10);
team = UTIL_GetTeam(pEdict);
if (team_class_limits[team] == -1) // civile seulement?
{
pBot->bot_class = 0; // civile
}
else
{
if (pBot->bot_class == 10)
class_not_allowed = team_class_limits[team] & (1<<7);
else if (pBot->bot_class <= 7)
class_not_allowed = team_class_limits[team] & (1<<(pBot->bot_class-1));
else
class_not_allowed = team_class_limits[team] & (1<<(pBot->bot_class));
while (class_not_allowed)
{
pBot->bot_class = RANDOM_LONG(1, 10);
if (pBot->bot_class == 10)
class_not_allowed = team_class_limits[team] & (1<<7);
else if (pBot->bot_class <= 7)
class_not_allowed = team_class_limits[team] & (1<<(pBot->bot_class-1));
else
class_not_allowed = team_class_limits[team] & (1<<(pBot->bot_class));
}
}
// selectionne la classe que le bot doit choisir
if (pBot->bot_class == 0)
strcpy(c_class, "civilian");
else if (pBot->bot_class == 1)
strcpy(c_class, "scout");
else if (pBot->bot_class == 2)
strcpy(c_class, "sniper");
else if (pBot->bot_class == 3)
strcpy(c_class, "soldier");
else if (pBot->bot_class == 4)
strcpy(c_class, "demoman");
else if (pBot->bot_class == 5)
strcpy(c_class, "medic");
else if (pBot->bot_class == 6)
strcpy(c_class, "hwguy");
else if (pBot->bot_class == 7)
strcpy(c_class, "pyro");
else if (pBot->bot_class == 8)
strcpy(c_class, "spy");
else if (pBot->bot_class == 9)
strcpy(c_class, "engineer");
else
strcpy(c_class, "randompc");
FakeClientCommand(pEdict, c_class, NULL, NULL); // on envoie le choix du joueur
// le bot à rejoint la partie
pBot->not_started = 0;
return;
}
}
Ce code est très complet mais très facile à comprendre, bien sur vous n’aurez pas besoin de tout ça. Mais remarquez ceci : FakeClientCommand(pEdict, "jointeam", c_team, NULL) ; Cela simule une commande console envoyée par le bot. FakeClientCommand(cible, "commande", arg1, arg2) ; Mettez "NULL" lorsque vous n’utilisez pas un champ.