📄 ai_cmd.c
字号:
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_RUSHBASE;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_RUSHBASE_TIME;
bs->rushbaseaway_time = 0;
//
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotMatch_TaskPreference
==================
*/
void BotMatch_TaskPreference(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_NETNAME];
char teammatename[MAX_MESSAGE_SIZE];
int teammate, preference;
ClientName(bs->client, netname, sizeof(netname));
if (Q_stricmp(netname, bs->teamleader) != 0) return;
trap_BotMatchVariable(match, NETNAME, teammatename, sizeof(teammatename));
teammate = ClientFromName(teammatename);
if (teammate < 0) return;
preference = BotGetTeamMateTaskPreference(bs, teammate);
switch(match->subtype)
{
case ST_DEFENDER:
{
preference &= ~TEAMTP_ATTACKER;
preference |= TEAMTP_DEFENDER;
break;
}
case ST_ATTACKER:
{
preference &= ~TEAMTP_DEFENDER;
preference |= TEAMTP_ATTACKER;
break;
}
case ST_ROAMER:
{
preference &= ~(TEAMTP_ATTACKER|TEAMTP_DEFENDER);
break;
}
}
BotSetTeamMateTaskPreference(bs, teammate, preference);
//
EasyClientName(teammate, teammatename, sizeof(teammatename));
BotAI_BotInitialChat(bs, "keepinmind", teammatename, NULL);
trap_BotEnterChat(bs->cs, teammate, CHAT_TELL);
BotVoiceChatOnly(bs, teammate, VOICECHAT_YES);
trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
/*
==================
BotMatch_ReturnFlag
==================
*/
void BotMatch_ReturnFlag(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
int client;
//if not in CTF mode
if (
gametype != GT_CTF
#ifdef MISSIONPACK
&& gametype != GT_1FCTF
#endif
)
return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match))
return;
//
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
//
client = FindClientByName(netname);
//
bs->decisionmaker = client;
bs->ordered = qtrue;
bs->order_time = FloatTime();
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_RETURNFLAG;
//set the team goal time
bs->teamgoal_time = FloatTime() + CTF_RETURNFLAG_TIME;
bs->rushbaseaway_time = 0;
//
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotMatch_JoinSubteam
==================
*/
void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match) {
char teammate[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
int client;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//get the sub team name
trap_BotMatchVariable(match, TEAMNAME, teammate, sizeof(teammate));
//set the sub team name
strncpy(bs->subteam, teammate, 32);
bs->subteam[31] = '\0';
//
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "joinedteam", teammate, NULL);
client = ClientFromName(netname);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
/*
==================
BotMatch_LeaveSubteam
==================
*/
void BotMatch_LeaveSubteam(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
int client;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//
if (strlen(bs->subteam))
{
BotAI_BotInitialChat(bs, "leftteam", bs->subteam, NULL);
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
} //end if
strcpy(bs->subteam, "");
}
/*
==================
BotMatch_LeaveSubteam
==================
*/
void BotMatch_WhichTeam(bot_state_t *bs, bot_match_t *match) {
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//
if (strlen(bs->subteam)) {
BotAI_BotInitialChat(bs, "inteam", bs->subteam, NULL);
}
else {
BotAI_BotInitialChat(bs, "noteam", NULL);
}
trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
}
/*
==================
BotMatch_CheckPoint
==================
*/
void BotMatch_CheckPoint(bot_state_t *bs, bot_match_t *match) {
int areanum, client;
char buf[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
vec3_t position;
bot_waypoint_t *cp;
if (!TeamPlayIsOn()) return;
//
trap_BotMatchVariable(match, POSITION, buf, MAX_MESSAGE_SIZE);
VectorClear(position);
//
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
//BotGPSToPosition(buf, position);
sscanf(buf, "%f %f %f", &position[0], &position[1], &position[2]);
position[2] += 0.5;
areanum = BotPointAreaNum(position);
if (!areanum) {
if (BotAddressedToBot(bs, match)) {
BotAI_BotInitialChat(bs, "checkpoint_invalid", NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
return;
}
//
trap_BotMatchVariable(match, NAME, buf, MAX_MESSAGE_SIZE);
//check if there already exists a checkpoint with this name
cp = BotFindWayPoint(bs->checkpoints, buf);
if (cp) {
if (cp->next) cp->next->prev = cp->prev;
if (cp->prev) cp->prev->next = cp->next;
else bs->checkpoints = cp->next;
cp->inuse = qfalse;
}
//create a new check point
cp = BotCreateWayPoint(buf, position, areanum);
//add the check point to the bot's known chech points
cp->next = bs->checkpoints;
if (bs->checkpoints) bs->checkpoints->prev = cp;
bs->checkpoints = cp;
//
if (BotAddressedToBot(bs, match)) {
Com_sprintf(buf, sizeof(buf), "%1.0f %1.0f %1.0f", cp->goal.origin[0],
cp->goal.origin[1],
cp->goal.origin[2]);
BotAI_BotInitialChat(bs, "checkpoint_confirm", cp->name, buf, NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
}
/*
==================
BotMatch_FormationSpace
==================
*/
void BotMatch_FormationSpace(bot_state_t *bs, bot_match_t *match) {
char buf[MAX_MESSAGE_SIZE];
float space;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//
trap_BotMatchVariable(match, NUMBER, buf, MAX_MESSAGE_SIZE);
//if it's the distance in feet
if (match->subtype & ST_FEET) space = 0.3048 * 32 * atof(buf);
//else it's in meters
else space = 32 * atof(buf);
//check if the formation intervening space is valid
if (space < 48 || space > 500) space = 100;
bs->formation_dist = space;
}
/*
==================
BotMatch_Dismiss
==================
*/
void BotMatch_Dismiss(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
int client;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
//
bs->decisionmaker = client;
//
bs->ltgtype = 0;
bs->lead_time = 0;
bs->lastgoal_ltgtype = 0;
//
BotAI_BotInitialChat(bs, "dismissed", NULL);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
/*
==================
BotMatch_Suicide
==================
*/
void BotMatch_Suicide(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
int client;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//
trap_EA_Command(bs->client, "kill");
//
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
//
BotVoiceChat(bs, client, VOICECHAT_TAUNT);
trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
/*
==================
BotMatch_StartTeamLeaderShip
==================
*/
void BotMatch_StartTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
int client;
char teammate[MAX_MESSAGE_SIZE];
if (!TeamPlayIsOn()) return;
//if chats for him or herself
if (match->subtype & ST_I) {
//get the team mate that will be the team leader
trap_BotMatchVariable(match, NETNAME, teammate, sizeof(teammate));
strncpy(bs->teamleader, teammate, sizeof(bs->teamleader));
bs->teamleader[sizeof(bs->teamleader)] = '\0';
}
//chats for someone else
else {
//get the team mate that will be the team leader
trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
client = FindClientByName(teammate);
if (client >= 0) ClientName(client, bs->teamleader, sizeof(bs->teamleader));
}
}
/*
==================
BotMatch_StopTeamLeaderShip
==================
*/
void BotMatch_StopTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
int client;
char teammate[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
if (!TeamPlayIsOn()) return;
//get the team mate that stops being the team leader
trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
//if chats for him or herself
if (match->subtype & ST_I) {
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = FindClientByName(netname);
}
//chats for someone else
else {
client = FindClientByName(teammate);
} //end else
if (client >= 0) {
if (!Q_stricmp(bs->teamleader, ClientName(client, netname, sizeof(netname)))) {
bs->teamleader[0] = '\0';
notleader[client] = qtrue;
}
}
}
/*
==================
BotMatch_WhoIsTeamLeader
==================
*/
void BotMatch_WhoIsTeamLeader(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
if (!TeamPlayIsOn()) return;
ClientName(bs->client, netname, sizeof(netname));
//if this bot IS the team leader
if (!Q_stricmp(netname, bs->teamleader)) {
trap_EA_SayTeam(bs->client, "I'm the team leader\n");
}
}
/*
==================
BotMatch_WhatAreYouDoing
==================
*/
void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_MESSAGE_SIZE];
char goalname[MAX_MESSAGE_SIZE];
int client;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//
switch(bs->ltgtype) {
case LTG_TEAMHELP:
{
EasyClientName(bs->teammate, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "helping", netname, NULL);
break;
}
case LTG_TEAMACCOMPANY:
{
EasyClientName(bs->teammate, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "accompanying", netname, NULL);
break;
}
case LTG_DEFENDKEYAREA:
{
trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
BotAI_BotInitialChat(bs, "defending", goalname, NULL);
break;
}
case LTG_GETITEM:
{
trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
BotAI_BotInitialChat(bs, "gettingitem", goalname, NULL);
break;
}
case LTG_KILL:
{
ClientName(bs->teamgoal.entitynum, netname, sizeof(netname));
BotAI_BotInitialChat(bs, "killing", netname, NULL);
break;
}
case LTG_CAMP:
case LTG_CAMPORDER:
{
BotAI_BotInitialChat(bs, "camping", NULL);
break;
}
case LTG_PATROL:
{
BotAI_BotInitialChat(bs, "patrolling", NULL);
break;
}
case LTG_GETFLAG:
{
BotAI_BotInitialChat(bs, "capturingflag", NULL);
break;
}
case LTG_RUSHBASE:
{
BotAI_BotInitialChat(bs, "rushingbase", NULL);
break;
}
case LTG_RETURNFLAG:
{
BotAI_BotInitialChat(bs, "returningflag", NULL);
break;
}
#ifdef MISSIONPACK
case LTG_ATTACKENEMYBASE:
{
BotAI_BotInitialChat(bs, "attackingenemybase", NULL);
break;
}
case LTG_HARVEST:
{
BotAI_BotInitialChat(bs, "harvesting", NULL);
break;
}
#endif
default:
{
BotAI_BotInitialChat(bs, "roaming", NULL);
break;
}
}
//chat what the bot is doing
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
/*
==================
BotMatch_WhatIsMyCommand
==================
*/
void BotMatch_WhatIsMyCommand(bot_state_t *bs, bot_match_t *match) {
char netname[MAX_NETNAME];
ClientName(bs->client, netname, sizeof(netname));
if (Q_stricmp(netname, bs->teamleader) != 0) return;
bs->forceorders = qtrue;
}
/*
==================
BotNearestVisibleItem
==================
*/
float BotNearestVisibleItem(bot_state_t *bs, char *itemname, bot_goal_t *goal) {
int i;
char name[64];
bot_goal_t tmpgoal;
float dist, bestdist;
vec3_t dir;
bsp_trace_t trace;
bestdist = 999999;
i = -1;
do {
i = trap_BotGetLevelItemGoal(i, itemname, &tmpgoal);
trap_BotGoalName(tmpgoal.number, name, sizeof(name));
if (Q_stricmp(itemname, name) != 0)
continue;
VectorSubtract(tmpgoal.origin, bs->origin, dir);
dist = VectorLength(dir);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -