void BotMatch_WrongWall(bot_state_t* bs, bot_match_t *match){
	char netname[MAX_MESSAGE_SIZE];
	char buf[MAX_INFO_STRING];
	int client;

	if(gametype != GT_SPRAY)
		return;

	// talking about me ? (avoid clientfromname, its ambiguous)
	trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	trap_GetConfigstring(CS_PLAYERS + bs->client, buf, sizeof(buf));
	Q_CleanStr( buf );
	if (!Q_stricmp(Info_ValueForKey(buf, "n"), netname)){
		// could be someone with same name, so make (more) sure
		if( ClientInSprayroom(bs->client) ){
			bs->which_wall = BotChooseCorrectWall(bs);
			bs->enemy = -1;
			// chat
			BotAI_BotInitialChat(bs, "wall_missed", NULL);
			trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
			return;
		}
	}
	// check if opposite team
	client = ClientFromName(netname);
	if(!BotSameTeam(bs, client)){
		float rnd;
		// flame
		rnd = trap_Characteristic_BFloat(bs->character, CHARACTERISTIC_CHAT_INSULT, 0, 1);
		if(random() > rnd) return;	
		BotAI_BotInitialChat(bs, "wall_insult", netname, NULL);
		trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
	}
}
예제 #2
0
/*
=======================================================================================================================================
BotMatch_CheckPoint
=======================================================================================================================================
*/
void BotMatch_CheckPoint(bot_state_t *bs, bot_match_t *match) {
	int areanum;
	char buf[MAX_MESSAGE_SIZE];
	vec3_t position;
	bot_waypoint_t *cp;

	if (!TeamPlayIsOn()) {
		return;
	}

	trap_BotMatchVariable(match, POSITION, buf, MAX_MESSAGE_SIZE);
	VectorClear(position);
	// 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, bs->client, CHAT_TEAM);
		}

		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, bs->client, CHAT_TEAM);
	}
}
예제 #3
0
/*
==================
BotMatch_WhereAreYou
==================
*/
void BotMatch_WhereAreYou( bot_state_t *bs, bot_match_t *match ) {
	float dist, bestdist;
	int i, bestitem, redflagtt, blueflagtt, redtobluett;
	bot_goal_t goal;
	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",
		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 ) {
			redflagtt = trap_AAS_AreaTravelTimeToGoalArea( bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT );
			blueflagtt = trap_AAS_AreaTravelTimeToGoalArea( bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT );
			redtobluett = trap_AAS_AreaTravelTimeToGoalArea( ctf_redflag.areanum, ctf_redflag.origin, ctf_blueflag.areanum, TFL_DEFAULT );
			if ( redflagtt < ( redflagtt + blueflagtt ) * 0.4 ) {
				BotAI_BotInitialChat( bs, "ctflocation", nearbyitems[bestitem], "red", NULL );
			} else if ( blueflagtt < ( redflagtt + blueflagtt ) * 0.4 )       {
				BotAI_BotInitialChat( bs, "ctflocation", nearbyitems[bestitem], "blue", NULL );
			} else {
				BotAI_BotInitialChat( bs, "location", nearbyitems[bestitem], NULL );
			}
		} else {
			BotAI_BotInitialChat( bs, "location", nearbyitems[bestitem], NULL );
		}
		trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
	}
}
예제 #4
0
/*
=======================================================================================================================================
BotMatch_Kill
=======================================================================================================================================
*/
void BotMatch_Kill(bot_state_t *bs, bot_match_t *match) {
	char enemy[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_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return;
	}

	bs->teamgoal.entitynum = client;
	// set the time to send a message to the team mates
	bs->teammessage_time = trap_AAS_Time() + 2 * random();
	// set the ltg type
	bs->ltgtype = LTG_KILL;
	// set the team goal time
	bs->teamgoal_time = trap_AAS_Time() + TEAM_KILL_SOMEONE;
#ifdef DEBUG
	BotPrintTeamGoal(bs);
#endif // DEBUG
}
/*
==================
BotMatch_GetItem
==================
*/
void BotMatch_GetItem(bot_state_t *bs, bot_match_t *match) {
	char itemname[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 match variable
	trap_BotMatchVariable(match, ITEM, itemname, sizeof(itemname));
	//
	if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
		BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
		trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return;
	}
	trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	client = ClientOnSameTeamFromName(bs, 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() + 1 * random();
	//set the ltg type
	bs->ltgtype = LTG_GETITEM;
	//set the team goal time
	bs->teamgoal_time = FloatTime() + TEAM_GETITEM_TIME;

#ifdef DEBUG
//	BotPrintTeamGoal(bs);
#endif //DEBUG
}
예제 #6
0
/*
==================
BotVoiceChat_Camp
==================
*/
void
BotVoiceChat_Camp(bot_state_t * bs, int client, int mode)
{
  int areanum;
  aas_entityinfo_t entinfo;
  char netname[MAX_NETNAME];

  //
  bs->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)) {
      //NOTE: just assume the bot knows where the person is
      //if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) {
      bs->teamgoal.entitynum = client;
      bs->teamgoal.areanum = areanum;
      VectorCopy(entinfo.origin, bs->teamgoal.origin);
      VectorSet(bs->teamgoal.mins, -8, -8, -8);
      VectorSet(bs->teamgoal.maxs, 8, 8, 8);
      //}
    }
  }
  //if the other is not visible
  if (bs->teamgoal.entitynum < 0)
  {
    BotAI_BotInitialChat(bs, "whereareyou",
			 EasyClientName(client, netname,
					sizeof(netname)), NULL);
    trap_BotEnterChat(bs->cs, client, CHAT_TELL);
    return;
  }
  //
  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_CAMPORDER;
  //get the team goal time
  bs->teamgoal_time = FloatTime() + TEAM_CAMP_TIME;
  //the teammate that requested the camping
  bs->teammate = client;
  //not arrived yet
  bs->arrive_time = 0;
  //
  BotSetTeamStatus(bs);
  // remember last ordered task
  BotRememberLastOrderedTask(bs);
#ifdef DEBUG
  BotPrintTeamGoal(bs);
#endif //DEBUG
}
예제 #7
0
/*
==================
BotMatch_WhichTeam
==================
*/
void BotMatch_WhichTeam(bot_state_t *bs, bot_match_t *match)
{
	// State which team the bot is in, if any
	if (strlen(bs->subteam))
		Bot_InitialChat(bs, "inteam", bs->subteam, NULL);
	else
		Bot_InitialChat(bs, "noteam", NULL);
	trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
}
예제 #8
0
/*
==================
BotVoiceChat_FollowMe
==================
*/
void
BotVoiceChat_FollowMe(bot_state_t * bs, int client, int mode)
{
  int areanum;
  aas_entityinfo_t entinfo;
  char netname[MAX_NETNAME];

  bs->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->teamgoal.entitynum = client;
      bs->teamgoal.areanum = areanum;
      VectorCopy(entinfo.origin, bs->teamgoal.origin);
      VectorSet(bs->teamgoal.mins, -8, -8, -8);
      VectorSet(bs->teamgoal.maxs, 8, 8, 8);
    }
  }
  //if the other is not visible
  if (bs->teamgoal.entitynum < 0)
  {
    BotAI_BotInitialChat(bs, "whereareyou",
			 EasyClientName(client, netname,
					sizeof(netname)), NULL);
    trap_BotEnterChat(bs->cs, client, CHAT_TELL);
    return;
  }
  //
  bs->decisionmaker = client;
  bs->ordered = qtrue;
  bs->order_time = FloatTime();
  //the team mate
  bs->teammate = client;
  //last time the team mate was assumed visible
  bs->teammatevisible_time = FloatTime();
  //set the time to send a message to the team mates
  bs->teammessage_time = FloatTime() + 2 * random();
  //get the team goal time
  bs->teamgoal_time = FloatTime() + TEAM_ACCOMPANY_TIME;
  //set the ltg type
  bs->ltgtype = LTG_TEAMACCOMPANY;
  bs->formation_dist = 3.5 * 32;	//3.5 meter
  bs->arrive_time = 0;
  //
  BotSetTeamStatus(bs);
  // remember last ordered task
  BotRememberLastOrderedTask(bs);
#ifdef DEBUG
  BotPrintTeamGoal(bs);
#endif //DEBUG
}
예제 #9
0
/*
====================
BotMatch_JoinSubteam
====================
*/
void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match, gentity_t *sender)
{
	// Set the bot's subteam name
	trap_BotMatchVariable(match, TEAMNAME, bs->subteam, sizeof(bs->subteam));

	// Make sure the string is properly terminated
	bs->subteam[ sizeof(bs->subteam)-1 ] = '\0';

	// Inform the sender that the bot has joined this subteam
	Bot_InitialChat(bs, "joinedteam", bs->subteam, NULL);
	trap_BotEnterChat(bs->cs, sender->s.number, CHAT_TELL);
}
예제 #10
0
/*
==================
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);
}
예제 #11
0
/*
==================
BotVoiceChat_WhoIsLeader
==================
*/
void BotVoiceChat_WhoIsLeader(bot_state_t *bs, int client, int mode) {
	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)) {
		BotAI_BotInitialChat(bs, "iamteamleader", NULL);
		trap_BotEnterChat(bs->cs, 0, CHAT_TEAM);
		BotVoiceChatOnly(bs, -1, VOICECHAT_STARTLEADER);
	}
}
예제 #12
0
/*
=====================
BotMatch_LeaveSubteam
=====================
*/
void BotMatch_LeaveSubteam(bot_state_t *bs, bot_match_t *match, gentity_t *sender)
{
	// Do nothing if the bot isn't on any subteam
	if (!strlen(bs->subteam))
		return;

	// Inform the sender that the bot has left this subteam
	Bot_InitialChat(bs, "leftteam", bs->subteam, NULL);
	trap_BotEnterChat(bs->cs, sender->s.number, CHAT_TELL);

	// Reset the subteam name
	strcpy(bs->subteam, "");
}
예제 #13
0
/*
==================
BotMatch_LeaveSubteam
==================
*/
void BotMatch_LeaveSubteam( 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, "leftteam", bs->subteam, NULL );
	} //end if
	trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
	strcpy( bs->subteam, "" );
}
예제 #14
0
/*
=======================================================================================================================================
BotMatch_Dismiss
=======================================================================================================================================
*/
void BotMatch_Dismiss(bot_state_t *bs, bot_match_t *match) {

	if (!TeamPlayIsOn()) {
		return;
	}
	// if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) {
		return;
	}

	bs->ltgtype = 0;
	bs->lead_time = 0;
	BotAI_BotInitialChat(bs, "dismissed", NULL);
	trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
}
예제 #15
0
/*
==================
BotVoiceChat_WantOnOffense
==================
*/
void BotVoiceChat_WantOnOffense(bot_state_t *bs, int client, int mode) {
	char netname[MAX_NETNAME];
	int preference;

	preference = BotGetTeamMateTaskPreference(bs, client);
	preference &= ~TEAMTP_DEFENDER;
	preference |= TEAMTP_ATTACKER;
	BotSetTeamMateTaskPreference(bs, client, preference);
	//
	EasyClientName(client, netname, sizeof(netname));
	BotAI_BotInitialChat(bs, "keepinmind", netname, NULL);
	trap_BotEnterChat(bs->cs, client, CHAT_TELL);
	BotVoiceChatOnly(bs, client, VOICECHAT_YES);
	trap_EA_Action(bs->client, ACTION_AFFIRMATIVE);
}
예제 #16
0
/*
==================
BotSayTeamOrders
==================
*/
void BotSayTeamOrder( bot_state_t *bs, int toclient ) {
	char teamchat[MAX_MESSAGE_SIZE];
	char buf[MAX_MESSAGE_SIZE];
	char name[MAX_NETNAME];

	//if the bot is talking to itself
	if ( bs->client == toclient ) {
		//don't show the message just put it in the console message queue
		trap_BotGetChatMessage( bs->cs, buf, sizeof( buf ) );
		ClientName( bs->client, name, sizeof( name ) );
		Com_sprintf( teamchat, sizeof( teamchat ), "(%s): %s", name, buf );
		trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, teamchat );
	} else {
		trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
	}
}
예제 #17
0
/*
===============
BotMatchMessage

This function returns if the message could be matched.  It does not
mean the bot actually processed the message.

NOTE: Death messages are sent as an EV_OBITUARY event, not actual console
messages.  As such, they are processed by BotCheckEvents() in ai_scan.c.
===============
*/
qboolean BotMatchMessage(bot_state_t *bs, char *message)
{
	bot_match_t match;
	char name[MAX_MESSAGE_SIZE];
	gentity_t *sender;

	// Try to match this message as a CTF teamchat message
	match.type = 0;
	if (!trap_BotFindMatch(message, &match,
						   MTCONTEXT_MISC | MTCONTEXT_INITIALTEAMCHAT | MTCONTEXT_CTF))
		return qfalse;

	// Ignore messages in deathmatch modes, but return true because it's a real message
	if ( !(game_style & GS_TEAM) )
		return qtrue;

	// Check if this message is a team management message
	trap_BotMatchVariable(&match, NETNAME, name, sizeof(name));
	sender = TeammateFromName(bs, name);
	if (BotMatch_Team(bs, &match, sender))
		return qtrue;

	// Ignore messages not from a teammate
	if (!sender)
	{
		Bot_InitialChat(bs, "whois", name, NULL);
		trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return qtrue;
	}

	// Ignore other messages if they aren't intended for this bot
	if (!BotAddresseeMatch(bs, &match))
		return qtrue;

	// Check if this message is an order
	if (BotMatch_Order(bs, &match, sender))
		return qtrue;

	// Check if this message is a subteam request
	if (BotMatch_Subteam(bs, &match, sender))
		return qtrue;

	// Still return true because the message matched-- our code just elected not to process it
	BotAI_Print(PRT_WARNING, "Unknown match type %i\n", match.type);
	return qtrue;
}
예제 #18
0
/*
==================
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, "");
}
예제 #19
0
/*
==================
BotVoiceChat_Patrol
==================
*/
void BotVoiceChat_Patrol(bot_state_t *bs, int client, int mode) {
	//
	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);
	BotVoiceChatOnly(bs, -1, VOICECHAT_ONPATROL);
	//
	BotSetTeamStatus(bs);
#ifdef DEBUG
	BotPrintTeamGoal(bs);
#endif //DEBUG
}
예제 #20
0
/*
=======================================================================================================================================
BotMatch_JoinSubteam
=======================================================================================================================================
*/
void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match) {
	char teammate[MAX_MESSAGE_SIZE];

	if (!TeamPlayIsOn()) {
		return;
	}
	// if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) {
		return;
	}
	// get the sub team name
	trap_BotMatchVariable(match, TEAMNAME, teammate, MAX_MESSAGE_SIZE);
	// set the sub team name
	strncpy(bs->subteam, teammate, 32);
	bs->subteam[31] = '\0';
	BotAI_BotInitialChat(bs, "joinedteam", teammate, NULL);
	trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
}
예제 #21
0
/*
==================
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);
}
예제 #22
0
/*
==================
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);
}
예제 #23
0
/*
==============
BotAIShutdownClient
==============
*/
int BotAIShutdownClient( int client ) {
	bot_state_t *bs;

	// Wolfenstein
	if ( g_entities[client].r.svFlags & SVF_CASTAI ) {
		AICast_ShutdownClient( client );
		return BLERR_NOERROR;
	}
	// done.

	bs = botstates[client];
	if ( !bs || !bs->inuse ) {
		// BotAI_Print(PRT_ERROR, "client %d already shutdown\n", client);
		return BLERR_AICLIENTALREADYSHUTDOWN;
	}

	if ( BotChat_ExitGame( bs ) ) {
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}

	trap_BotFreeMoveState( bs->ms );
	//free the goal state
	trap_BotFreeGoalState( bs->gs );
	//free the chat file
	trap_BotFreeChatState( bs->cs );
	//free the weapon weights
	trap_BotFreeWeaponState( bs->ws );
	//free the bot character
	trap_BotFreeCharacter( bs->character );
	//
	BotFreeWaypoints( bs->checkpoints );
	BotFreeWaypoints( bs->patrolpoints );
	//clear the bot state
	memset( bs, 0, sizeof( bot_state_t ) );
	//set the inuse flag to qfalse
	bs->inuse = qfalse;
	//there's one bot less
	numbots--;
	//everything went ok
	return BLERR_NOERROR;
}
예제 #24
0
/*
==============
BotAIShutdownClient
==============
*/
int BotAIShutdownClient(int client, qboolean restart)
{
    bot_state_t *bs;

    bs = botstates[client];
    if (!bs || !bs->inuse) {
        //BotAI_Print(PRT_ERROR, "BotAIShutdownClient: client %d already shutdown\n", client);
        return qfalse;
    }

    if (restart) {
        BotWriteSessionData(bs);
    }

    if (BotChat_ExitGame(bs)) {
        trap_BotEnterChat(bs->cs, bs->client, CHAT_ALL);
    }

    trap_BotFreeMoveState(bs->ms);
    //free the goal state
    trap_BotFreeGoalState(bs->gs);
    //free the chat file
    trap_BotFreeChatState(bs->cs);
    //free the weapon weights
    trap_BotFreeWeaponState(bs->ws);
    //free the bot character
    trap_BotFreeCharacter(bs->character);
    //
    BotFreeWaypoints(bs->checkpoints);
    BotFreeWaypoints(bs->patrolpoints);
    //clear activate goal stack
    BotClearActivateGoalStack(bs);
    //clear the bot state
    memset(bs, 0, sizeof(bot_state_t));
    //set the inuse flag to qfalse
    bs->inuse = qfalse;
    //there's one bot less
    numbots--;
    //everything went ok
    return qtrue;
}
예제 #25
0
/*
==================
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);
}
예제 #26
0
/*
==================
BotChatTest
==================
*/
void BotChatTest( bot_state_t *bs ) {

	char name[32];
	char *weap;
	int num, i;

	num = trap_BotNumInitialChats( bs->cs, "game_enter" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "game_enter",
							  EasyClientName( bs->client, name, 32 ), // 0
							  BotRandomOpponentName( bs ),  // 1
							  "[invalid var]",          // 2
							  "[invalid var]",          // 3
							  BotMapTitle(),                // 4
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "game_exit" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "game_exit",
							  EasyClientName( bs->client, name, 32 ), // 0
							  BotRandomOpponentName( bs ),  // 1
							  "[invalid var]",          // 2
							  "[invalid var]",          // 3
							  BotMapTitle(),                // 4
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "level_start" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "level_start",
							  EasyClientName( bs->client, name, 32 ), // 0
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "level_end_victory" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "level_end_victory",
							  EasyClientName( bs->client, name, 32 ), // 0
							  BotRandomOpponentName( bs ), // 1
							  BotFirstClientInRankings(), // 2
							  BotLastClientInRankings(), // 3
							  BotMapTitle(),            // 4
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "level_end_lose" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "level_end_lose",
							  EasyClientName( bs->client, name, 32 ), // 0
							  BotRandomOpponentName( bs ), // 1
							  BotFirstClientInRankings(), // 2
							  BotLastClientInRankings(), // 3
							  BotMapTitle(),            // 4
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "level_end" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "level_end",
							  EasyClientName( bs->client, name, 32 ), // 0
							  BotRandomOpponentName( bs ), // 1
							  BotFirstClientInRankings(), // 2
							  BotLastClientInRankings(), // 3
							  BotMapTitle(),            // 4
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	EasyClientName( bs->lastkilledby, name, sizeof( name ) );
	num = trap_BotNumInitialChats( bs->cs, "death_drown" );
	for ( i = 0; i < num; i++ )
	{
		//
		BotAI_BotInitialChat( bs, "death_drown", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_slime" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_slime", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_lava" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_lava", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_cratered" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_cratered", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_suicide" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_suicide", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_telefrag" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_telefrag", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_gauntlet" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_gauntlet",
							  name,                                 // 0
							  BotWeaponNameForMeansOfDeath( bs->botdeathtype ), // 1
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_rail" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_rail",
							  name,                                 // 0
							  BotWeaponNameForMeansOfDeath( bs->botdeathtype ), // 1
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_bfg" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_bfg",
							  name,                                 // 0
							  BotWeaponNameForMeansOfDeath( bs->botdeathtype ), // 1
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_insult" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_insult",
							  name,                                     // 0
							  BotWeaponNameForMeansOfDeath( bs->botdeathtype ), // 1
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "death_praise" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "death_praise",
							  name,                                     // 0
							  BotWeaponNameForMeansOfDeath( bs->botdeathtype ), // 1
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	//
	EasyClientName( bs->lastkilledplayer, name, 32 );
	//
	num = trap_BotNumInitialChats( bs->cs, "kill_gauntlet" );
	for ( i = 0; i < num; i++ )
	{
		//
		BotAI_BotInitialChat( bs, "kill_gauntlet", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "kill_rail" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "kill_rail", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "kill_telefrag" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "kill_telefrag", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "kill_insult" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "kill_insult", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "kill_praise" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "kill_praise", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "enemy_suicide" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "enemy_suicide", name, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	ClientName( g_entities[bs->client].client->lasthurt_client, name, sizeof( name ) );
	weap = BotWeaponNameForMeansOfDeath( g_entities[bs->client].client->lasthurt_client );
	num = trap_BotNumInitialChats( bs->cs, "hit_talking" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "hit_talking", name, weap, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "hit_nodeath" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "hit_nodeath", name, weap, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "hit_nokill" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "hit_nokill", name, weap, NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	//
	if ( bs->lastkilledplayer == bs->client ) {
		strcpy( name, BotRandomOpponentName( bs ) );
	} else {
		EasyClientName( bs->lastkilledplayer, name, sizeof( name ) );
	}
	//
	num = trap_BotNumInitialChats( bs->cs, "random_misc" );
	for ( i = 0; i < num; i++ )
	{
		//
		BotAI_BotInitialChat( bs, "random_misc",
							  BotRandomOpponentName( bs ), // 0
							  name,             // 1
							  "[invalid var]", // 2
							  "[invalid var]", // 3
							  BotMapTitle(),    // 4
							  BotRandomWeaponName(), // 5
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
	num = trap_BotNumInitialChats( bs->cs, "random_insult" );
	for ( i = 0; i < num; i++ )
	{
		BotAI_BotInitialChat( bs, "random_insult",
							  BotRandomOpponentName( bs ), // 0
							  name,             // 1
							  "[invalid var]", // 2
							  "[invalid var]", // 3
							  BotMapTitle(),    // 4
							  BotRandomWeaponName(), // 5
							  NULL );
		trap_BotEnterChat( bs->cs, bs->client, CHAT_ALL );
	}
}
예제 #27
0
/*
=======================================================================================================================================
BotMatch_Camp
=======================================================================================================================================
*/
void BotMatch_Camp(bot_state_t *bs, bot_match_t *match) {
	int client, areanum;
	char netname[MAX_MESSAGE_SIZE];
	char itemname[MAX_MESSAGE_SIZE];
	aas_entityinfo_t entinfo;

	if (!TeamPlayIsOn()) {
		return;
	}
	// if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) {
		return;
	}

	trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
	// asked for someone else
	client = FindClientByName(netname);
	// if there's no valid client with this name
	if (client < 0) {
		BotAI_BotInitialChat(bs, "whois", netname, NULL);
		trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return;
	}
	// get the match variable
	trap_BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname));
	// in CTF it could be the base
	if (match->subtype & ST_THERE) {
		// camp at the spot the bot is currently standing
		bs->teamgoal.entitynum = bs->entitynum;
		bs->teamgoal.areanum = bs->areanum;
		VectorCopy(bs->origin, bs->teamgoal.origin);
		VectorSet(bs->teamgoal.mins, -8, -8, -8);
		VectorSet(bs->teamgoal.maxs, 8, 8, 8);
	} else if (match->subtype & ST_HERE) {
		// if this is the bot self
		if (client == bs->client) {
			return;
		}

		bs->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)) {
				// NOTE: just cheat and assume the bot knows where the person is
				// if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) {
				bs->teamgoal.entitynum = client;
				bs->teamgoal.areanum = areanum;
				VectorCopy(entinfo.origin, bs->teamgoal.origin);
				VectorSet(bs->teamgoal.mins, -8, -8, -8);
				VectorSet(bs->teamgoal.maxs, 8, 8, 8);
				//}
			}
		}
		// if the other is not visible
		if (bs->teamgoal.entitynum < 0) {
			BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
			trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
			return;
		}
	} else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
		// BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
		// trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return;
	}
	// set the time to send a message to the team mates
	bs->teammessage_time = trap_AAS_Time() + 2 * random();
	// set the ltg type
	bs->ltgtype = LTG_CAMPORDER;
	// get the team goal time
	bs->teamgoal_time = BotGetTime(match);
	// set the team goal time
	if (!bs->teamgoal_time) {
		bs->teamgoal_time = trap_AAS_Time() + TEAM_CAMP_TIME;
	}
	// the teammate that requested the camping
	bs->teammate = client;
	// not arrived yet
	bs->arrive_time = 0;
#ifdef DEBUG
	BotPrintTeamGoal(bs);
#endif // DEBUG
}
예제 #28
0
/*
=======================================================================================================================================
BotMatch_HelpAccompany
=======================================================================================================================================
*/
void BotMatch_HelpAccompany(bot_state_t *bs, bot_match_t *match) {
	int client, other, areanum;
	char teammate[MAX_MESSAGE_SIZE], netname[MAX_MESSAGE_SIZE];
	char itemname[MAX_MESSAGE_SIZE];
	bot_match_t teammatematch;
	aas_entityinfo_t entinfo;

	if (!TeamPlayIsOn()) {
		return;
	}
	// if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) {
		return;
	}
	// get the team mate name
	trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
	// get the client to help
	if (trap_BotFindMatch(teammate, &teammatematch, MTCONTEXT_TEAMMATE) &&
		// if someone asks for him or herself
		 teammatematch.type == MSG_ME) {
		// get the netname
		trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		client = ClientFromName(netname);
		other = qfalse;
	} else {
		// asked for someone else
		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;
		}
	}
	// if the bot doesn't know who to help (FindClientByName returned -1)
	if (client < 0) {
		if (other) {
			BotAI_BotInitialChat(bs, "whois", teammate, NULL);
		} else {BotAI_BotInitialChat(bs, "whois", netname, NULL);}

		trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
		return;
	}
	// don't help or accompany yourself
	if (client == bs->client) {
		return;
	}

	bs->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->teamgoal.entitynum = client;
			bs->teamgoal.areanum = areanum;
			VectorCopy(entinfo.origin, bs->teamgoal.origin);
			VectorSet(bs->teamgoal.mins, -8, -8, -8);
			VectorSet(bs->teamgoal.maxs, 8, 8, 8);
		}
	}
	// if no teamgoal yet
	if (bs->teamgoal.entitynum < 0) {
		// if near an item
		if (match->subtype & ST_NEARITEM) {
			// get the match variable
			trap_BotMatchVariable(match, ITEM, itemname, sizeof(itemname));

			if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
				// BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
				// trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
				return;
			}
		}
	}

	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;
	}
	// the team mate
	bs->teammate = client;
	// last time the team mate was assumed visible
	bs->teammatevisible_time = trap_AAS_Time();
	// set the time to send a message to the team mates
	bs->teammessage_time = trap_AAS_Time() + 2 * random();
	// get the team goal time
	bs->teamgoal_time = BotGetTime(match);
	// set the ltg type
	if (match->type == MSG_HELP) {
		bs->ltgtype = LTG_TEAMHELP;

		if (!bs->teamgoal_time) {
			bs->teamgoal_time = trap_AAS_Time() + TEAM_HELP_TIME;
		}
	} else {
		bs->ltgtype = LTG_TEAMACCOMPANY;

		if (!bs->teamgoal_time) {
			bs->teamgoal_time = trap_AAS_Time() + TEAM_ACCOMPANY_TIME;
		}

		bs->formation_dist = 3.5 * 32;     // 3.5 meter
		bs->arrive_time = 0;
	}
#ifdef DEBUG
	BotPrintTeamGoal(bs);
#endif // DEBUG
}
예제 #29
0
/*
=======================================================================================================================================
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 = trap_AAS_Time() + TEAM_LEAD_TIME;
	bs->leadvisible_time = 0;
	bs->leadmessage_time = -(trap_AAS_Time() + 2 * random());
}
예제 #30
0
/*
=======================================================================================================================================
BotMatch_WhatAreYouDoing
=======================================================================================================================================
*/
void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) {
	char netname[MAX_MESSAGE_SIZE];
	char goalname[MAX_MESSAGE_SIZE];
	// if not addressed to this bot
	if (!BotAddressedToBot(bs, match)) {
		return;
	}

	switch (bs->ltgtype) {
	case LTG_TEAMHELP:
	{
		trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		EasyClientName(bs->teammate, netname, MAX_MESSAGE_SIZE);
		BotAI_BotInitialChat(bs, "helping", netname, NULL);
		break;
	}

	case LTG_TEAMACCOMPANY:
	{
		trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
		EasyClientName(bs->teammate, netname, MAX_MESSAGE_SIZE);
		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;
	}

	default:
	{
		BotAI_BotInitialChat(bs, "roaming", NULL);
		break;
	}
	}
	// chat what the bot is doing
	trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
}