📄 ai_cmd.c
字号:
if (dist < bestdist) {
//trace from start to end
BotAI_Trace(&trace, bs->eye, NULL, NULL, tmpgoal.origin, bs->client, CONTENTS_SOLID|CONTENTS_PLAYERCLIP);
if (trace.fraction >= 1.0) {
bestdist = dist;
memcpy(goal, &tmpgoal, sizeof(bot_goal_t));
}
}
} while(i > 0);
return bestdist;
}
/*
==================
BotMatch_WhereAreYou
==================
*/
void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) {
float dist, bestdist;
int i, bestitem, redtt, bluett, client;
bot_goal_t goal;
char netname[MAX_MESSAGE_SIZE];
char *nearbyitems[] = {
"Shotgun",
"Grenade Launcher",
"Rocket Launcher",
"Plasmagun",
"Railgun",
"Lightning Gun",
"BFG10K",
"Quad Damage",
"Regeneration",
"Battle Suit",
"Speed",
"Invisibility",
"Flight",
"Armor",
"Heavy Armor",
"Red Flag",
"Blue Flag",
#ifdef MISSIONPACK
"Nailgun",
"Prox Launcher",
"Chaingun",
"Scout",
"Guard",
"Doubler",
"Ammo Regen",
"Neutral Flag",
"Red Obelisk",
"Blue Obelisk",
"Neutral Obelisk",
#endif
NULL
};
//
if (!TeamPlayIsOn())
return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match))
return;
bestitem = -1;
bestdist = 999999;
for (i = 0; nearbyitems[i]; i++) {
dist = BotNearestVisibleItem(bs, nearbyitems[i], &goal);
if (dist < bestdist) {
bestdist = dist;
bestitem = i;
}
}
if (bestitem != -1) {
if (gametype == GT_CTF
#ifdef MISSIONPACK
|| gametype == GT_1FCTF
#endif
) {
redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT);
bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT);
if (redtt < (redtt + bluett) * 0.4) {
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "red", NULL);
}
else if (bluett < (redtt + bluett) * 0.4) {
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "blue", NULL);
}
else {
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
}
}
#ifdef MISSIONPACK
else if (gametype == GT_OBELISK || gametype == GT_HARVESTER) {
redtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, redobelisk.areanum, TFL_DEFAULT);
bluett = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, blueobelisk.areanum, TFL_DEFAULT);
if (redtt < (redtt + bluett) * 0.4) {
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "red", NULL);
}
else if (bluett < (redtt + bluett) * 0.4) {
BotAI_BotInitialChat(bs, "teamlocation", nearbyitems[bestitem], "blue", NULL);
}
else {
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
}
}
#endif
else {
BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
}
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
}
}
/*
==================
BotMatch_LeadTheWay
==================
*/
void BotMatch_LeadTheWay(bot_state_t *bs, bot_match_t *match) {
aas_entityinfo_t entinfo;
char netname[MAX_MESSAGE_SIZE], teammate[MAX_MESSAGE_SIZE];
int client, areanum, other;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
//if someone asks for someone else
if (match->subtype & ST_SOMEONE) {
//get the team mate name
trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
client = FindClientByName(teammate);
//if this is the bot self
if (client == bs->client) {
other = qfalse;
}
else if (!BotSameTeam(bs, client)) {
//FIXME: say "I don't help the enemy"
return;
}
else {
other = qtrue;
}
}
else {
//get the netname
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
other = qfalse;
}
//if the bot doesn't know who to help (FindClientByName returned -1)
if (client < 0) {
BotAI_BotInitialChat(bs, "whois", netname, NULL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
return;
}
//
bs->lead_teamgoal.entitynum = -1;
BotEntityInfo(client, &entinfo);
//if info is valid (in PVS)
if (entinfo.valid) {
areanum = BotPointAreaNum(entinfo.origin);
if (areanum) { // && trap_AAS_AreaReachability(areanum)) {
bs->lead_teamgoal.entitynum = client;
bs->lead_teamgoal.areanum = areanum;
VectorCopy(entinfo.origin, bs->lead_teamgoal.origin);
VectorSet(bs->lead_teamgoal.mins, -8, -8, -8);
VectorSet(bs->lead_teamgoal.maxs, 8, 8, 8);
}
}
if (bs->teamgoal.entitynum < 0) {
if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL);
else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
return;
}
bs->lead_teammate = client;
bs->lead_time = FloatTime() + TEAM_LEAD_TIME;
bs->leadvisible_time = 0;
bs->leadmessage_time = -(FloatTime() + 2 * random());
}
/*
==================
BotMatch_Kill
==================
*/
void BotMatch_Kill(bot_state_t *bs, bot_match_t *match) {
char enemy[MAX_MESSAGE_SIZE];
char netname[MAX_MESSAGE_SIZE];
int client;
if (!TeamPlayIsOn()) return;
//if not addressed to this bot
if (!BotAddressedToBot(bs, match)) return;
trap_BotMatchVariable(match, ENEMY, enemy, sizeof(enemy));
//
client = FindEnemyByName(bs, enemy);
if (client < 0) {
BotAI_BotInitialChat(bs, "whois", enemy, NULL);
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = ClientFromName(netname);
trap_BotEnterChat(bs->cs, client, CHAT_TELL);
return;
}
bs->teamgoal.entitynum = client;
//set the time to send a message to the team mates
bs->teammessage_time = FloatTime() + 2 * random();
//set the ltg type
bs->ltgtype = LTG_KILL;
//set the team goal time
bs->teamgoal_time = FloatTime() + TEAM_KILL_SOMEONE;
//
BotSetTeamStatus(bs);
#ifdef DEBUG
BotPrintTeamGoal(bs);
#endif //DEBUG
}
/*
==================
BotMatch_CTF
==================
*/
void BotMatch_CTF(bot_state_t *bs, bot_match_t *match) {
char flag[128], netname[MAX_NETNAME];
if (gametype == GT_CTF) {
trap_BotMatchVariable(match, FLAG, flag, sizeof(flag));
if (match->subtype & ST_GOTFLAG) {
if (!Q_stricmp(flag, "red")) {
bs->redflagstatus = 1;
if (BotTeam(bs) == TEAM_BLUE) {
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
bs->flagcarrier = ClientFromName(netname);
}
}
else {
bs->blueflagstatus = 1;
if (BotTeam(bs) == TEAM_RED) {
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
bs->flagcarrier = ClientFromName(netname);
}
}
bs->flagstatuschanged = 1;
bs->lastflagcapture_time = FloatTime();
}
else if (match->subtype & ST_CAPTUREDFLAG) {
bs->redflagstatus = 0;
bs->blueflagstatus = 0;
bs->flagcarrier = 0;
bs->flagstatuschanged = 1;
}
else if (match->subtype & ST_RETURNEDFLAG) {
if (!Q_stricmp(flag, "red")) bs->redflagstatus = 0;
else bs->blueflagstatus = 0;
bs->flagstatuschanged = 1;
}
}
#ifdef MISSIONPACK
else if (gametype == GT_1FCTF) {
if (match->subtype & ST_1FCTFGOTFLAG) {
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
bs->flagcarrier = ClientFromName(netname);
}
}
#endif
}
void BotMatch_EnterGame(bot_state_t *bs, bot_match_t *match) {
int client;
char netname[MAX_NETNAME];
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = FindClientByName(netname);
if (client >= 0) {
notleader[client] = qfalse;
}
//NOTE: eliza chats will catch this
//Com_sprintf(buf, sizeof(buf), "heya %s", netname);
//EA_Say(bs->client, buf);
}
void BotMatch_NewLeader(bot_state_t *bs, bot_match_t *match) {
int client;
char netname[MAX_NETNAME];
trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
client = FindClientByName(netname);
if (!BotSameTeam(bs, client))
return;
Q_strncpyz(bs->teamleader, netname, sizeof(bs->teamleader));
}
/*
==================
BotMatchMessage
==================
*/
int BotMatchMessage(bot_state_t *bs, char *message) {
bot_match_t match;
match.type = 0;
//if it is an unknown message
if (!trap_BotFindMatch(message, &match, MTCONTEXT_MISC
|MTCONTEXT_INITIALTEAMCHAT
|MTCONTEXT_CTF)) {
return qfalse;
}
//react to the found message
switch(match.type)
{
case MSG_HELP: //someone calling for help
case MSG_ACCOMPANY: //someone calling for company
{
BotMatch_HelpAccompany(bs, &match);
break;
}
case MSG_DEFENDKEYAREA: //teamplay defend a key area
{
BotMatch_DefendKeyArea(bs, &match);
break;
}
case MSG_CAMP: //camp somewhere
{
BotMatch_Camp(bs, &match);
break;
}
case MSG_PATROL: //patrol between several key areas
{
BotMatch_Patrol(bs, &match);
break;
}
//CTF & 1FCTF
case MSG_GETFLAG: //ctf get the enemy flag
{
BotMatch_GetFlag(bs, &match);
break;
}
#ifdef MISSIONPACK
//CTF & 1FCTF & Obelisk & Harvester
case MSG_ATTACKENEMYBASE:
{
BotMatch_AttackEnemyBase(bs, &match);
break;
}
//Harvester
case MSG_HARVEST:
{
BotMatch_Harvest(bs, &match);
break;
}
#endif
//CTF & 1FCTF & Harvester
case MSG_RUSHBASE: //ctf rush to the base
{
BotMatch_RushBase(bs, &match);
break;
}
//CTF & 1FCTF
case MSG_RETURNFLAG:
{
BotMatch_ReturnFlag(bs, &match);
break;
}
//CTF & 1FCTF & Obelisk & Harvester
case MSG_TASKPREFERENCE:
{
BotMatch_TaskPreference(bs, &match);
break;
}
//CTF & 1FCTF
case MSG_CTF:
{
BotMatch_CTF(bs, &match);
break;
}
case MSG_GETITEM:
{
BotMatch_GetItem(bs, &match);
break;
}
case MSG_JOINSUBTEAM: //join a sub team
{
BotMatch_JoinSubteam(bs, &match);
break;
}
case MSG_LEAVESUBTEAM: //leave a sub team
{
BotMatch_LeaveSubteam(bs, &match);
break;
}
case MSG_WHICHTEAM:
{
BotMatch_WhichTeam(bs, &match);
break;
}
case MSG_CHECKPOINT: //remember a check point
{
BotMatch_CheckPoint(bs, &match);
break;
}
case MSG_CREATENEWFORMATION: //start the creation of a new formation
{
trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged");
break;
}
case MSG_FORMATIONPOSITION: //tell someone his/her position in the formation
{
trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged");
break;
}
case MSG_FORMATIONSPACE: //set the formation space
{
BotMatch_FormationSpace(bs, &match);
break;
}
case MSG_DOFORMATION: //form a certain formation
{
break;
}
case MSG_DISMISS: //dismiss someone
{
BotMatch_Dismiss(bs, &match);
break;
}
case MSG_STARTTEAMLEADERSHIP: //someone will become the team leader
{
BotMatch_StartTeamLeaderShip(bs, &match);
break;
}
case MSG_STOPTEAMLEADERSHIP: //someone will stop being the team leader
{
BotMatch_StopTeamLeaderShip(bs, &match);
break;
}
case MSG_WHOISTEAMLAEDER:
{
BotMatch_WhoIsTeamLeader(bs, &match);
break;
}
case MSG_WHATAREYOUDOING: //ask a bot what he/she is doing
{
BotMatch_WhatAreYouDoing(bs, &match);
break;
}
case MSG_WHATISMYCOMMAND:
{
BotMatch_WhatIsMyCommand(bs, &match);
break;
}
case MSG_WHEREAREYOU:
{
BotMatch_WhereAreYou(bs, &match);
break;
}
case MSG_LEADTHEWAY:
{
BotMatch_LeadTheWay(bs, &match);
break;
}
case MSG_KILL:
{
BotMatch_Kill(bs, &match);
break;
}
case MSG_ENTERGAME: //someone entered the game
{
BotMatch_EnterGame(bs, &match);
break;
}
case MSG_NEWLEADER:
{
BotMatch_NewLeader(bs, &match);
break;
}
case MSG_WAIT:
{
break;
}
case MSG_SUICIDE:
{
BotMatch_Suicide(bs, &match);
break;
}
default:
{
BotAI_Print(PRT_MESSAGE, "unknown match type\n");
break;
}
}
return qtrue;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -