mirror of
https://github.com/Q3Rally-Team/q3rally.git
synced 2025-02-16 17:21:04 +00:00
Made parts of game bot AI more like ioq3.
This commit is contained in:
parent
a26985d0a6
commit
c42db21b59
8 changed files with 174 additions and 167 deletions
|
@ -1261,4 +1261,3 @@ void BotChatTest(bot_state_t *bs) {
|
||||||
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
|
trap_BotEnterChat(bs->cs, 0, CHAT_ALL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1991,4 +1991,3 @@ int BotMatchMessage(bot_state_t *bs, char *message) {
|
||||||
}
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,13 +96,15 @@ void BotDumpNodeSwitches(bot_state_t *bs) {
|
||||||
BotRecordNodeSwitch
|
BotRecordNodeSwitch
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void BotRecordNodeSwitch(bot_state_t *bs, char *node, char *str) {
|
void BotRecordNodeSwitch(bot_state_t *bs, char *node, char *str, char *s) {
|
||||||
char netname[MAX_NETNAME];
|
char netname[MAX_NETNAME];
|
||||||
|
|
||||||
ClientName(bs->client, netname, sizeof(netname));
|
ClientName(bs->client, netname, sizeof(netname));
|
||||||
Com_sprintf(nodeswitch[numnodeswitches], 144, "%s at %2.1f entered %s: %s\n", netname, FloatTime(), node, str);
|
Com_sprintf(nodeswitch[numnodeswitches], 144, "%s at %2.1f entered %s: %s from %s\n", netname, FloatTime(), node, str, s);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
BotAI_Print(PRT_MESSAGE, "%s", nodeswitch[numnodeswitches]);
|
if (0) {
|
||||||
|
BotAI_Print(PRT_MESSAGE, "%s", nodeswitch[numnodeswitches]);
|
||||||
|
}
|
||||||
#endif //DEBUG
|
#endif //DEBUG
|
||||||
numnodeswitches++;
|
numnodeswitches++;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +218,7 @@ int BotNearbyGoal(bot_state_t *bs, int tfl, bot_goal_t *ltg, float range) {
|
||||||
trap_BotGoalName(goal.number, buf, sizeof(buf));
|
trap_BotGoalName(goal.number, buf, sizeof(buf));
|
||||||
BotAI_Print(PRT_MESSAGE, "%1.1f: new nearby goal %s\n", FloatTime(), buf);
|
BotAI_Print(PRT_MESSAGE, "%1.1f: new nearby goal %s\n", FloatTime(), buf);
|
||||||
}
|
}
|
||||||
//*/
|
*/
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,7 +308,7 @@ int BotGetItemLongTermGoal(bot_state_t *bs, int tfl, bot_goal_t *goal) {
|
||||||
trap_BotGetTopGoal(bs->gs, goal);
|
trap_BotGetTopGoal(bs->gs, goal);
|
||||||
trap_BotGoalName(goal->number, buf, sizeof(buf));
|
trap_BotGoalName(goal->number, buf, sizeof(buf));
|
||||||
BotAI_Print(PRT_MESSAGE, "%1.1f: new long term goal %s\n", FloatTime(), buf);
|
BotAI_Print(PRT_MESSAGE, "%1.1f: new long term goal %s\n", FloatTime(), buf);
|
||||||
//*/
|
*/
|
||||||
bs->ltg_time = FloatTime() + 20;
|
bs->ltg_time = FloatTime() + 20;
|
||||||
}
|
}
|
||||||
else {//the bot gets sorta stuck with all the avoid timings, shouldn't happen though
|
else {//the bot gets sorta stuck with all the avoid timings, shouldn't happen though
|
||||||
|
@ -502,7 +504,7 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal)
|
||||||
//BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf);
|
//BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf);
|
||||||
//time the bot gets to pick up the nearby goal item
|
//time the bot gets to pick up the nearby goal item
|
||||||
bs->nbg_time = FloatTime() + 8;
|
bs->nbg_time = FloatTime() + 8;
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "BotLongTermGoal: go for air");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -768,7 +770,7 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal)
|
||||||
if( isRallyRace() )
|
if( isRallyRace() )
|
||||||
{
|
{
|
||||||
if (bs->ltgtype == LTG_WINRACE) {
|
if (bs->ltgtype == LTG_WINRACE) {
|
||||||
AIEnter_MoveToNextCheckpoint( bs );
|
AIEnter_MoveToNextCheckpoint( bs, "BotGetLongTermGoal" );
|
||||||
/*
|
/*
|
||||||
gentity_t *checkpoint = NULL;
|
gentity_t *checkpoint = NULL;
|
||||||
int num;
|
int num;
|
||||||
|
@ -1230,8 +1232,8 @@ int BotLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal) {
|
||||||
AIEnter_Intermission
|
AIEnter_Intermission
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Intermission(bot_state_t *bs) {
|
void AIEnter_Intermission(bot_state_t *bs, char *s) {
|
||||||
BotRecordNodeSwitch(bs, "intermission", "");
|
BotRecordNodeSwitch(bs, "intermission", "", s);
|
||||||
//reset the bot state
|
//reset the bot state
|
||||||
BotResetState(bs);
|
BotResetState(bs);
|
||||||
//check for end level chat
|
//check for end level chat
|
||||||
|
@ -1259,7 +1261,7 @@ int AINode_Intermission(bot_state_t *bs) {
|
||||||
else {
|
else {
|
||||||
bs->stand_time = FloatTime() + 2;
|
bs->stand_time = FloatTime() + 2;
|
||||||
}
|
}
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "intermission: chat");
|
||||||
}
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
@ -1269,8 +1271,8 @@ int AINode_Intermission(bot_state_t *bs) {
|
||||||
AIEnter_Observer
|
AIEnter_Observer
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Observer(bot_state_t *bs) {
|
void AIEnter_Observer(bot_state_t *bs, char *s) {
|
||||||
BotRecordNodeSwitch(bs, "observer", "");
|
BotRecordNodeSwitch(bs, "observer", "", s);
|
||||||
//reset the bot state
|
//reset the bot state
|
||||||
BotResetState(bs);
|
BotResetState(bs);
|
||||||
bs->ainode = AINode_Observer;
|
bs->ainode = AINode_Observer;
|
||||||
|
@ -1288,7 +1290,7 @@ int AINode_Observer(bot_state_t *bs) {
|
||||||
|
|
||||||
//if the bot left observer mode
|
//if the bot left observer mode
|
||||||
if (!BotIsObserver(bs)) {
|
if (!BotIsObserver(bs)) {
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "observer: left observer");
|
||||||
}
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
@ -1298,8 +1300,8 @@ int AINode_Observer(bot_state_t *bs) {
|
||||||
AIEnter_Stand
|
AIEnter_Stand
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Stand(bot_state_t *bs) {
|
void AIEnter_Stand(bot_state_t *bs, char *s) {
|
||||||
BotRecordNodeSwitch(bs, "stand", "");
|
BotRecordNodeSwitch(bs, "stand", "", s);
|
||||||
bs->standfindenemy_time = FloatTime() + 1;
|
bs->standfindenemy_time = FloatTime() + 1;
|
||||||
bs->ainode = AINode_Stand;
|
bs->ainode = AINode_Stand;
|
||||||
}
|
}
|
||||||
|
@ -1324,7 +1326,7 @@ int AINode_Stand(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
if (bs->standfindenemy_time < FloatTime()) {
|
if (bs->standfindenemy_time < FloatTime()) {
|
||||||
if (BotFindEnemy(bs, -1)) {
|
if (BotFindEnemy(bs, -1)) {
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "stand: found enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
bs->standfindenemy_time = FloatTime() + 1;
|
bs->standfindenemy_time = FloatTime() + 1;
|
||||||
|
@ -1334,7 +1336,7 @@ int AINode_Stand(bot_state_t *bs) {
|
||||||
// when done standing
|
// when done standing
|
||||||
if (bs->stand_time < FloatTime()) {
|
if (bs->stand_time < FloatTime()) {
|
||||||
trap_BotEnterChat(bs->cs, 0, bs->chatto);
|
trap_BotEnterChat(bs->cs, 0, bs->chatto);
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "stand: time out");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1346,8 +1348,8 @@ int AINode_Stand(bot_state_t *bs) {
|
||||||
AIEnter_Respawn
|
AIEnter_Respawn
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Respawn(bot_state_t *bs) {
|
void AIEnter_Respawn(bot_state_t *bs, char *s) {
|
||||||
BotRecordNodeSwitch(bs, "respawn", "");
|
BotRecordNodeSwitch(bs, "respawn", "", s);
|
||||||
//reset some states
|
//reset some states
|
||||||
trap_BotResetMoveState(bs->ms);
|
trap_BotResetMoveState(bs->ms);
|
||||||
trap_BotResetGoalState(bs->gs);
|
trap_BotResetGoalState(bs->gs);
|
||||||
|
@ -1381,7 +1383,7 @@ int AINode_Respawn(bot_state_t *bs) {
|
||||||
// if waiting for the actual respawn
|
// if waiting for the actual respawn
|
||||||
if (bs->respawn_wait) {
|
if (bs->respawn_wait) {
|
||||||
if (!BotIsDead(bs)) {
|
if (!BotIsDead(bs)) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "respawn: respawned");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trap_EA_Respawn(bs->client);
|
trap_EA_Respawn(bs->client);
|
||||||
|
@ -1560,8 +1562,8 @@ void BotClearPath(bot_state_t *bs, bot_moveresult_t *moveresult) {
|
||||||
AIEnter_Seek_ActivateEntity
|
AIEnter_Seek_ActivateEntity
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs) {
|
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s) {
|
||||||
BotRecordNodeSwitch(bs, "activate entity", "");
|
BotRecordNodeSwitch(bs, "activate entity", "", s);
|
||||||
bs->ainode = AINode_Seek_ActivateEntity;
|
bs->ainode = AINode_Seek_ActivateEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1584,19 +1586,19 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "active entity: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "activate entity: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "activate entity: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1611,7 +1613,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
// if the bot has no activate goal
|
// if the bot has no activate goal
|
||||||
if (!bs->activatestack) {
|
if (!bs->activatestack) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "activate entity: no goal");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1658,7 +1660,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
bs->activatestack->time = FloatTime() + 10;
|
bs->activatestack->time = FloatTime() + 10;
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "activate entity: time out");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
memset(&moveresult, 0, sizeof(bot_moveresult_t));
|
memset(&moveresult, 0, sizeof(bot_moveresult_t));
|
||||||
|
@ -1686,7 +1688,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
bs->activatestack->time = FloatTime() + 10;
|
bs->activatestack->time = FloatTime() + 10;
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "activate entity: activated");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//predict obstacles
|
//predict obstacles
|
||||||
|
@ -1761,14 +1763,14 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
if (BotFindEnemy(bs, -1)) {
|
if (BotFindEnemy(bs, -1)) {
|
||||||
if (BotWantsToRetreat(bs)) {
|
if (BotWantsToRetreat(bs)) {
|
||||||
//keep the current long term goal and retreat
|
//keep the current long term goal and retreat
|
||||||
AIEnter_Battle_NBG(bs);
|
AIEnter_Battle_NBG(bs, "activate entity: found enemy");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
//empty the goal stack
|
//empty the goal stack
|
||||||
trap_BotEmptyGoalStack(bs->gs);
|
trap_BotEmptyGoalStack(bs->gs);
|
||||||
//go fight
|
//go fight
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "activate entity: found enemy");
|
||||||
}
|
}
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
}
|
}
|
||||||
|
@ -1780,16 +1782,16 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
||||||
AIEnter_Seek_NBG
|
AIEnter_Seek_NBG
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Seek_NBG(bot_state_t *bs) {
|
void AIEnter_Seek_NBG(bot_state_t *bs, char *s) {
|
||||||
bot_goal_t goal;
|
bot_goal_t goal;
|
||||||
char buf[144];
|
char buf[144];
|
||||||
|
|
||||||
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
||||||
trap_BotGoalName(goal.number, buf, 144);
|
trap_BotGoalName(goal.number, buf, 144);
|
||||||
BotRecordNodeSwitch(bs, "seek NBG", buf);
|
BotRecordNodeSwitch(bs, "seek NBG", buf, s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BotRecordNodeSwitch(bs, "seek NBG", "no goal");
|
BotRecordNodeSwitch(bs, "seek NBG", "no goal", s);
|
||||||
}
|
}
|
||||||
bs->ainode = AINode_Seek_NBG;
|
bs->ainode = AINode_Seek_NBG;
|
||||||
}
|
}
|
||||||
|
@ -1809,17 +1811,17 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "seek nbg: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "seek nbg: intermision");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "seek nbg: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1850,7 +1852,7 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
||||||
//NOTE: we canNOT reset the check_time to zero because it would create an endless loop of node switches
|
//NOTE: we canNOT reset the check_time to zero because it would create an endless loop of node switches
|
||||||
bs->check_time = FloatTime() + 0.05;
|
bs->check_time = FloatTime() + 0.05;
|
||||||
//go back to seek ltg
|
//go back to seek ltg
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "seek nbg: time out");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//predict obstacles
|
//predict obstacles
|
||||||
|
@ -1903,14 +1905,14 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
||||||
if (BotFindEnemy(bs, -1)) {
|
if (BotFindEnemy(bs, -1)) {
|
||||||
if (BotWantsToRetreat(bs)) {
|
if (BotWantsToRetreat(bs)) {
|
||||||
//keep the current long term goal and retreat
|
//keep the current long term goal and retreat
|
||||||
AIEnter_Battle_NBG(bs);
|
AIEnter_Battle_NBG(bs, "seek nbg: found enemy");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
//empty the goal stack
|
//empty the goal stack
|
||||||
trap_BotEmptyGoalStack(bs->gs);
|
trap_BotEmptyGoalStack(bs->gs);
|
||||||
//go fight
|
//go fight
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "seek nbg: found enemy");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
|
@ -1921,16 +1923,16 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
||||||
AIEnter_Seek_LTG
|
AIEnter_Seek_LTG
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Seek_LTG(bot_state_t *bs) {
|
void AIEnter_Seek_LTG(bot_state_t *bs, char *s) {
|
||||||
bot_goal_t goal;
|
bot_goal_t goal;
|
||||||
char buf[144];
|
char buf[144];
|
||||||
|
|
||||||
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
||||||
trap_BotGoalName(goal.number, buf, 144);
|
trap_BotGoalName(goal.number, buf, 144);
|
||||||
BotRecordNodeSwitch(bs, "seek LTG", buf);
|
BotRecordNodeSwitch(bs, "seek LTG", buf, s);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BotRecordNodeSwitch(bs, "seek LTG", "no goal");
|
BotRecordNodeSwitch(bs, "seek LTG", "no goal", s);
|
||||||
}
|
}
|
||||||
bs->ainode = AINode_Seek_LTG;
|
bs->ainode = AINode_Seek_LTG;
|
||||||
}
|
}
|
||||||
|
@ -1954,23 +1956,23 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "seek ltg: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "seek ltg: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "seek ltg: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
if (BotChat_Random(bs)) {
|
if (BotChat_Random(bs)) {
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "seek ltg: random chat");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -1999,7 +2001,7 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
// END
|
// END
|
||||||
if (BotWantsToRetreat(bs)) {
|
if (BotWantsToRetreat(bs)) {
|
||||||
//keep the current long term goal and retreat
|
//keep the current long term goal and retreat
|
||||||
AIEnter_Battle_Retreat(bs);
|
AIEnter_Battle_Retreat(bs, "seek ltg: found enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2007,7 +2009,7 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
//empty the goal stack
|
//empty the goal stack
|
||||||
trap_BotEmptyGoalStack(bs->gs);
|
trap_BotEmptyGoalStack(bs->gs);
|
||||||
//go fight
|
//go fight
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "seek ltg: found enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2052,17 +2054,15 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
//BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf);
|
//BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf);
|
||||||
//time the bot gets to pick up the nearby goal item
|
//time the bot gets to pick up the nearby goal item
|
||||||
bs->nbg_time = FloatTime() + 4 + range * 0.01;
|
bs->nbg_time = FloatTime() + 4 + range * 0.01;
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "ltg seek: nbg");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//predict obstacles
|
//predict obstacles
|
||||||
if (BotAIPredictObstacles(bs, &goal))
|
if (BotAIPredictObstacles(bs, &goal))
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
|
||||||
//initialize the movement state
|
//initialize the movement state
|
||||||
BotSetupForMovement(bs);
|
BotSetupForMovement(bs);
|
||||||
|
|
||||||
//move towards the goal
|
//move towards the goal
|
||||||
// Q3Rally Code Start
|
// Q3Rally Code Start
|
||||||
/*
|
/*
|
||||||
|
@ -2093,18 +2093,14 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
//BotAI_Print(PRT_MESSAGE, "movement failure %d\n", moveresult.traveltype);
|
//BotAI_Print(PRT_MESSAGE, "movement failure %d\n", moveresult.traveltype);
|
||||||
bs->ltg_time = 0;
|
bs->ltg_time = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
BotAIBlocked(bs, &moveresult, qtrue);
|
BotAIBlocked(bs, &moveresult, qtrue);
|
||||||
|
|
||||||
//
|
//
|
||||||
BotClearPath(bs, &moveresult);
|
BotClearPath(bs, &moveresult);
|
||||||
|
|
||||||
//if the viewangles are used for the movement
|
//if the viewangles are used for the movement
|
||||||
if (moveresult.flags & (MOVERESULT_MOVEMENTVIEWSET|MOVERESULT_MOVEMENTVIEW|MOVERESULT_SWIMVIEW)) {
|
if (moveresult.flags & (MOVERESULT_MOVEMENTVIEWSET|MOVERESULT_MOVEMENTVIEW|MOVERESULT_SWIMVIEW)) {
|
||||||
VectorCopy(moveresult.ideal_viewangles, bs->ideal_viewangles);
|
VectorCopy(moveresult.ideal_viewangles, bs->ideal_viewangles);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if waiting for something
|
//if waiting for something
|
||||||
else if (moveresult.flags & MOVERESULT_WAITING) {
|
else if (moveresult.flags & MOVERESULT_WAITING) {
|
||||||
if (random() < bs->thinktime * 0.8) {
|
if (random() < bs->thinktime * 0.8) {
|
||||||
|
@ -2131,10 +2127,8 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
}
|
}
|
||||||
bs->ideal_viewangles[2] *= 0.5;
|
bs->ideal_viewangles[2] *= 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if the weapon is used for the bot movement
|
//if the weapon is used for the bot movement
|
||||||
if (moveresult.flags & MOVERESULT_MOVEMENTWEAPON) bs->weaponnum = moveresult.weapon;
|
if (moveresult.flags & MOVERESULT_MOVEMENTWEAPON) bs->weaponnum = moveresult.weapon;
|
||||||
|
|
||||||
//
|
//
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
@ -2144,13 +2138,13 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
||||||
AIEnter_Battle_Fight
|
AIEnter_Battle_Fight
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Battle_Fight(bot_state_t *bs) {
|
void AIEnter_Battle_Fight(bot_state_t *bs, char *s) {
|
||||||
// Q3Rally Code Start
|
// Q3Rally Code Start
|
||||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||||
return;
|
return;
|
||||||
// END
|
// END
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "battle fight", "");
|
BotRecordNodeSwitch(bs, "battle fight", "", s);
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
bs->ainode = AINode_Battle_Fight;
|
bs->ainode = AINode_Battle_Fight;
|
||||||
bs->flags &= ~BFL_FIGHTSUICIDAL;
|
bs->flags &= ~BFL_FIGHTSUICIDAL;
|
||||||
|
@ -2161,13 +2155,13 @@ void AIEnter_Battle_Fight(bot_state_t *bs) {
|
||||||
AIEnter_Battle_SuicidalFight
|
AIEnter_Battle_SuicidalFight
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Battle_SuicidalFight(bot_state_t *bs) {
|
void AIEnter_Battle_SuicidalFight(bot_state_t *bs, char *s) {
|
||||||
// Q3Rally Code Start
|
// Q3Rally Code Start
|
||||||
// if ( gametype == GT_RACING )
|
// if ( gametype == GT_RACING )
|
||||||
// return;
|
// return;
|
||||||
// END
|
// END
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "battle fight", "");
|
BotRecordNodeSwitch(bs, "battle fight", "", s);
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
bs->ainode = AINode_Battle_Fight;
|
bs->ainode = AINode_Battle_Fight;
|
||||||
bs->flags |= BFL_FIGHTSUICIDAL;
|
bs->flags |= BFL_FIGHTSUICIDAL;
|
||||||
|
@ -2189,18 +2183,18 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "battle fight: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "battle fight: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "battle fight: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if there is another better enemy
|
//if there is another better enemy
|
||||||
|
@ -2211,7 +2205,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
//if no enemy
|
//if no enemy
|
||||||
if (bs->enemy < 0) {
|
if (bs->enemy < 0) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle fight: no enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -2225,11 +2219,11 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
if (bs->lastkilledplayer == bs->enemy && BotChat_Kill(bs)) {
|
if (bs->lastkilledplayer == bs->enemy && BotChat_Kill(bs)) {
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "battle fight: enemy dead");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
bs->ltg_time = 0;
|
bs->ltg_time = 0;
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle fight: enemy dead");
|
||||||
}
|
}
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
@ -2242,7 +2236,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
//if the enemy is invisible and not shooting the bot looses track easily
|
//if the enemy is invisible and not shooting the bot looses track easily
|
||||||
if (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) {
|
if (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) {
|
||||||
if (random() < 0.2) {
|
if (random() < 0.2) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle fight: invisible");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2270,7 +2264,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
if (bs->lastframe_health > bs->inventory[INVENTORY_HEALTH]) {
|
if (bs->lastframe_health > bs->inventory[INVENTORY_HEALTH]) {
|
||||||
if (BotChat_HitNoDeath(bs)) {
|
if (BotChat_HitNoDeath(bs)) {
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "battle fight: chat health decreased");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2278,7 +2272,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
if (bs->cur_ps.persistant[PERS_HITS] > bs->lasthitcount) {
|
if (bs->cur_ps.persistant[PERS_HITS] > bs->lasthitcount) {
|
||||||
if (BotChat_HitNoKill(bs)) {
|
if (BotChat_HitNoKill(bs)) {
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "battle fight: chat hit someone");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2294,11 +2288,11 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (BotWantsToChase(bs)) {
|
if (BotWantsToChase(bs)) {
|
||||||
AIEnter_Battle_Chase(bs);
|
AIEnter_Battle_Chase(bs, "battle fight: enemy out of sight");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle fight: enemy out of sight");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2333,7 +2327,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
//if the bot wants to retreat
|
//if the bot wants to retreat
|
||||||
if (!(bs->flags & BFL_FIGHTSUICIDAL)) {
|
if (!(bs->flags & BFL_FIGHTSUICIDAL)) {
|
||||||
if (BotWantsToRetreat(bs)) {
|
if (BotWantsToRetreat(bs)) {
|
||||||
AIEnter_Battle_Retreat(bs);
|
AIEnter_Battle_Retreat(bs, "battle fight: wants to retreat");
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2345,13 +2339,13 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
||||||
AIEnter_Battle_Chase
|
AIEnter_Battle_Chase
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Battle_Chase(bot_state_t *bs) {
|
void AIEnter_Battle_Chase(bot_state_t *bs, char *s) {
|
||||||
// Q3Rally Code Start
|
// Q3Rally Code Start
|
||||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||||
return;
|
return;
|
||||||
// END
|
// END
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "battle chase", "");
|
BotRecordNodeSwitch(bs, "battle chase", "", s);
|
||||||
bs->chase_time = FloatTime();
|
bs->chase_time = FloatTime();
|
||||||
bs->ainode = AINode_Battle_Chase;
|
bs->ainode = AINode_Battle_Chase;
|
||||||
}
|
}
|
||||||
|
@ -2373,22 +2367,22 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "battle chase: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "battle chase: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "battle chase: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if no enemy
|
//if no enemy
|
||||||
if (bs->enemy < 0) {
|
if (bs->enemy < 0) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle chase: no enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if the enemy is visible
|
//if the enemy is visible
|
||||||
|
@ -2396,17 +2390,17 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
// if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, bs->enemy)) {
|
// if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, bs->enemy)) {
|
||||||
if (BotEntityVisible(bs->entitynum, bs->eye, bs->cur_ps.viewangles, 360, bs->enemy)) {
|
if (BotEntityVisible(bs->entitynum, bs->eye, bs->cur_ps.viewangles, 360, bs->enemy)) {
|
||||||
// END
|
// END
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "battle chase");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if there is another enemy
|
//if there is another enemy
|
||||||
if (BotFindEnemy(bs, -1)) {
|
if (BotFindEnemy(bs, -1)) {
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "battle chase: better enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//there is no last enemy area
|
//there is no last enemy area
|
||||||
if (!bs->lastenemyareanum) {
|
if (!bs->lastenemyareanum) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle chase: no enemy area");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -2430,7 +2424,7 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
if (trap_BotTouchingGoal(bs->origin, &goal)) bs->chase_time = 0;
|
if (trap_BotTouchingGoal(bs->origin, &goal)) bs->chase_time = 0;
|
||||||
//if there's no chase time left
|
//if there's no chase time left
|
||||||
if (!bs->chase_time || bs->chase_time < FloatTime() - 10) {
|
if (!bs->chase_time || bs->chase_time < FloatTime() - 10) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle chase: time out");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//check for nearby goals periodicly
|
//check for nearby goals periodicly
|
||||||
|
@ -2442,7 +2436,7 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
//the bot gets 5 seconds to pick up the nearby goal item
|
//the bot gets 5 seconds to pick up the nearby goal item
|
||||||
bs->nbg_time = FloatTime() + 0.1 * range + 1;
|
bs->nbg_time = FloatTime() + 0.1 * range + 1;
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
AIEnter_Battle_NBG(bs);
|
AIEnter_Battle_NBG(bs, "battle chase: nbg");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2489,7 +2483,7 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
if (bs->areanum == bs->lastenemyareanum) bs->chase_time = 0;
|
if (bs->areanum == bs->lastenemyareanum) bs->chase_time = 0;
|
||||||
//if the bot wants to retreat (the bot could have been damage during the chase)
|
//if the bot wants to retreat (the bot could have been damage during the chase)
|
||||||
if (BotWantsToRetreat(bs)) {
|
if (BotWantsToRetreat(bs)) {
|
||||||
AIEnter_Battle_Retreat(bs);
|
AIEnter_Battle_Retreat(bs, "battle chase: wants to retreat");
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
return qtrue;
|
return qtrue;
|
||||||
|
@ -2500,13 +2494,13 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
||||||
AIEnter_Battle_Retreat
|
AIEnter_Battle_Retreat
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Battle_Retreat(bot_state_t *bs) {
|
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s) {
|
||||||
// STONELANCE
|
// STONELANCE
|
||||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||||
return;
|
return;
|
||||||
// END
|
// END
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "battle retreat", "");
|
BotRecordNodeSwitch(bs, "battle retreat", "", s);
|
||||||
bs->ainode = AINode_Battle_Retreat;
|
bs->ainode = AINode_Battle_Retreat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2528,28 +2522,28 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "battle retreat: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "battle retreat: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "battle retreat: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if no enemy
|
//if no enemy
|
||||||
if (bs->enemy < 0) {
|
if (bs->enemy < 0) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle retreat: no enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
BotEntityInfo(bs->enemy, &entinfo);
|
BotEntityInfo(bs->enemy, &entinfo);
|
||||||
if (EntityIsDead(&entinfo)) {
|
if (EntityIsDead(&entinfo)) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle retreat: enemy dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if there is another better enemy
|
//if there is another better enemy
|
||||||
|
@ -2572,7 +2566,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
//empty the goal stack, when chasing, only the enemy is the goal
|
//empty the goal stack, when chasing, only the enemy is the goal
|
||||||
trap_BotEmptyGoalStack(bs->gs);
|
trap_BotEmptyGoalStack(bs->gs);
|
||||||
//go chase the enemy
|
//go chase the enemy
|
||||||
AIEnter_Battle_Chase(bs);
|
AIEnter_Battle_Chase(bs, "battle retreat: wants to chase");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//update the last time the enemy was visible
|
//update the last time the enemy was visible
|
||||||
|
@ -2601,14 +2595,14 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
//if the enemy is NOT visible for 4 seconds
|
//if the enemy is NOT visible for 4 seconds
|
||||||
if (bs->enemyvisible_time < FloatTime() - 4) {
|
if (bs->enemyvisible_time < FloatTime() - 4) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "battle retreat: lost enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//else if the enemy is NOT visible
|
//else if the enemy is NOT visible
|
||||||
else if (bs->enemyvisible_time < FloatTime()) {
|
else if (bs->enemyvisible_time < FloatTime()) {
|
||||||
//if there is another enemy
|
//if there is another enemy
|
||||||
if (BotFindEnemy(bs, -1)) {
|
if (BotFindEnemy(bs, -1)) {
|
||||||
AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Fight(bs, "battle retreat: another enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2618,7 +2612,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
BotBattleUseItems(bs);
|
BotBattleUseItems(bs);
|
||||||
//get the current long term goal while retreating
|
//get the current long term goal while retreating
|
||||||
if (!BotLongTermGoal(bs, bs->tfl, qtrue, &goal)) {
|
if (!BotLongTermGoal(bs, bs->tfl, qtrue, &goal)) {
|
||||||
AIEnter_Battle_SuicidalFight(bs);
|
AIEnter_Battle_SuicidalFight(bs, "battle retreat: no way out");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//check for nearby goals periodicly
|
//check for nearby goals periodicly
|
||||||
|
@ -2647,7 +2641,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
trap_BotResetLastAvoidReach(bs->ms);
|
trap_BotResetLastAvoidReach(bs->ms);
|
||||||
//time the bot gets to pick up the nearby goal item
|
//time the bot gets to pick up the nearby goal item
|
||||||
bs->nbg_time = FloatTime() + range / 100 + 1;
|
bs->nbg_time = FloatTime() + range / 100 + 1;
|
||||||
AIEnter_Battle_NBG(bs);
|
AIEnter_Battle_NBG(bs, "battle retreat: nbg");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2704,13 +2698,13 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
||||||
AIEnter_Battle_NBG
|
AIEnter_Battle_NBG
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_Battle_NBG(bot_state_t *bs) {
|
void AIEnter_Battle_NBG(bot_state_t *bs, char *s) {
|
||||||
// STONELANCE
|
// STONELANCE
|
||||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||||
return;
|
return;
|
||||||
// END
|
// END
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "battle NBG", "");
|
BotRecordNodeSwitch(bs, "battle NBG", "", s);
|
||||||
bs->ainode = AINode_Battle_NBG;
|
bs->ainode = AINode_Battle_NBG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2732,28 +2726,28 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
||||||
// END
|
// END
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "battle nbg: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "battle nbg: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "battle nbg: bot dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if no enemy
|
//if no enemy
|
||||||
if (bs->enemy < 0) {
|
if (bs->enemy < 0) {
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "battle nbg: no enemy");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
BotEntityInfo(bs->enemy, &entinfo);
|
BotEntityInfo(bs->enemy, &entinfo);
|
||||||
if (EntityIsDead(&entinfo)) {
|
if (EntityIsDead(&entinfo)) {
|
||||||
AIEnter_Seek_NBG(bs);
|
AIEnter_Seek_NBG(bs, "battle nbg: enemy dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -2803,8 +2797,10 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
||||||
//pop the current goal from the stack
|
//pop the current goal from the stack
|
||||||
trap_BotPopGoal(bs->gs);
|
trap_BotPopGoal(bs->gs);
|
||||||
//if the bot still has a goal
|
//if the bot still has a goal
|
||||||
if (trap_BotGetTopGoal(bs->gs, &goal)) AIEnter_Battle_Retreat(bs);
|
if (trap_BotGetTopGoal(bs->gs, &goal))
|
||||||
else AIEnter_Battle_Fight(bs);
|
AIEnter_Battle_Retreat(bs, "battle nbg: time out");
|
||||||
|
else
|
||||||
|
AIEnter_Battle_Fight(bs, "battle nbg: time out");
|
||||||
//
|
//
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
@ -2866,12 +2862,12 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
||||||
AIEnter_MoveToNextCheckpoint
|
AIEnter_MoveToNextCheckpoint
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void AIEnter_MoveToNextCheckpoint( bot_state_t *bs )
|
void AIEnter_MoveToNextCheckpoint( bot_state_t *bs, char *s )
|
||||||
{
|
{
|
||||||
if ( !isRallyRace() )
|
if ( !isRallyRace() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BotRecordNodeSwitch(bs, "move to next checkpoint", "");
|
BotRecordNodeSwitch(bs, "move to next checkpoint", "", s);
|
||||||
bs->ainode = AINode_MoveToNextCheckpoint;
|
bs->ainode = AINode_MoveToNextCheckpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3033,19 +3029,19 @@ int AINode_MoveToNextCheckpoint( bot_state_t *bs )
|
||||||
|
|
||||||
if (BotIsObserver(bs)) {
|
if (BotIsObserver(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Observer(bs);
|
AIEnter_Observer(bs, "moveToNextCheckpoint: observer");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//if in the intermission
|
//if in the intermission
|
||||||
if (BotIntermission(bs)) {
|
if (BotIntermission(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Intermission(bs);
|
AIEnter_Intermission(bs, "moveToNextCheckpoint: intermission");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
//respawn if dead
|
//respawn if dead
|
||||||
if (BotIsDead(bs)) {
|
if (BotIsDead(bs)) {
|
||||||
BotClearActivateGoalStack(bs);
|
BotClearActivateGoalStack(bs);
|
||||||
AIEnter_Respawn(bs);
|
AIEnter_Respawn(bs, "moveToNextCheckpoint: dead");
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,18 +33,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
#define MAX_NODESWITCHES 50
|
#define MAX_NODESWITCHES 50
|
||||||
|
|
||||||
void AIEnter_Intermission(bot_state_t *bs);
|
void AIEnter_Intermission(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Observer(bot_state_t *bs);
|
void AIEnter_Observer(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Respawn(bot_state_t *bs);
|
void AIEnter_Respawn(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Stand(bot_state_t *bs);
|
void AIEnter_Stand(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs);
|
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Seek_NBG(bot_state_t *bs);
|
void AIEnter_Seek_NBG(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Seek_LTG(bot_state_t *bs);
|
void AIEnter_Seek_LTG(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Seek_Camp(bot_state_t *bs);
|
void AIEnter_Seek_Camp(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Battle_Fight(bot_state_t *bs);
|
void AIEnter_Battle_Fight(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Battle_Chase(bot_state_t *bs);
|
void AIEnter_Battle_Chase(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Battle_Retreat(bot_state_t *bs);
|
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s);
|
||||||
void AIEnter_Battle_NBG(bot_state_t *bs);
|
void AIEnter_Battle_NBG(bot_state_t *bs, char *s);
|
||||||
int AINode_Intermission(bot_state_t *bs);
|
int AINode_Intermission(bot_state_t *bs);
|
||||||
int AINode_Observer(bot_state_t *bs);
|
int AINode_Observer(bot_state_t *bs);
|
||||||
int AINode_Respawn(bot_state_t *bs);
|
int AINode_Respawn(bot_state_t *bs);
|
||||||
|
@ -58,7 +58,7 @@ int AINode_Battle_Retreat(bot_state_t *bs);
|
||||||
int AINode_Battle_NBG(bot_state_t *bs);
|
int AINode_Battle_NBG(bot_state_t *bs);
|
||||||
|
|
||||||
// STONELANCE
|
// STONELANCE
|
||||||
void AIEnter_MoveToNextCheckpoint(bot_state_t *bs);
|
void AIEnter_MoveToNextCheckpoint(bot_state_t *bs, char *s);
|
||||||
int AINode_MoveToNextCheckpoint(bot_state_t *bs);
|
int AINode_MoveToNextCheckpoint(bot_state_t *bs);
|
||||||
// END
|
// END
|
||||||
|
|
||||||
|
|
|
@ -217,18 +217,6 @@ qboolean EntityIsDead(aas_entityinfo_t *entinfo) {
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
==================
|
|
||||||
EntityIsInvisible
|
|
||||||
==================
|
|
||||||
*/
|
|
||||||
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo) {
|
|
||||||
if (entinfo->powerups & (1 << PW_INVIS)) {
|
|
||||||
return qtrue;
|
|
||||||
}
|
|
||||||
return qfalse;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
EntityCarriesFlag
|
EntityCarriesFlag
|
||||||
|
@ -246,6 +234,22 @@ qboolean EntityCarriesFlag(aas_entityinfo_t *entinfo) {
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
==================
|
||||||
|
EntityIsInvisible
|
||||||
|
==================
|
||||||
|
*/
|
||||||
|
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo) {
|
||||||
|
// the flag is always visible
|
||||||
|
if (EntityCarriesFlag(entinfo)) {
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
if (entinfo->powerups & (1 << PW_INVIS)) {
|
||||||
|
return qtrue;
|
||||||
|
}
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
==================
|
==================
|
||||||
EntityIsShooting
|
EntityIsShooting
|
||||||
|
@ -1607,7 +1611,7 @@ void BotSetupForMovement(bot_state_t *bs) {
|
||||||
memset(&initmove, 0, sizeof(bot_initmove_t));
|
memset(&initmove, 0, sizeof(bot_initmove_t));
|
||||||
VectorCopy(bs->cur_ps.origin, initmove.origin);
|
VectorCopy(bs->cur_ps.origin, initmove.origin);
|
||||||
VectorCopy(bs->cur_ps.velocity, initmove.velocity);
|
VectorCopy(bs->cur_ps.velocity, initmove.velocity);
|
||||||
VectorCopy(bs->cur_ps.origin, initmove.viewoffset);
|
VectorClear(initmove.viewoffset);
|
||||||
initmove.viewoffset[2] += bs->cur_ps.viewheight;
|
initmove.viewoffset[2] += bs->cur_ps.viewheight;
|
||||||
initmove.entitynum = bs->entitynum;
|
initmove.entitynum = bs->entitynum;
|
||||||
initmove.client = bs->client;
|
initmove.client = bs->client;
|
||||||
|
@ -2257,7 +2261,6 @@ float BotAggression(bot_state_t *bs) {
|
||||||
//if the bot can use the shotgun
|
//if the bot can use the shotgun
|
||||||
if (bs->inventory[INVENTORY_SHOTGUN] > 0 &&
|
if (bs->inventory[INVENTORY_SHOTGUN] > 0 &&
|
||||||
bs->inventory[INVENTORY_SHELLS] > 10) return 50;
|
bs->inventory[INVENTORY_SHELLS] > 10) return 50;
|
||||||
|
|
||||||
//otherwise the bot is not feeling too good
|
//otherwise the bot is not feeling too good
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2539,7 +2542,7 @@ int BotWantsToCamp(bot_state_t *bs) {
|
||||||
//if the bot isn't healthy enough
|
//if the bot isn't healthy enough
|
||||||
if (BotAggression(bs) < 50) return qfalse;
|
if (BotAggression(bs) < 50) return qfalse;
|
||||||
//the bot should have at least have the rocket launcher, the railgun or the bfg10k with some ammo
|
//the bot should have at least have the rocket launcher, the railgun or the bfg10k with some ammo
|
||||||
if ((bs->inventory[INVENTORY_ROCKETLAUNCHER] <= 0 || bs->inventory[INVENTORY_ROCKETS < 10]) &&
|
if ((bs->inventory[INVENTORY_ROCKETLAUNCHER] <= 0 || bs->inventory[INVENTORY_ROCKETS] < 10) &&
|
||||||
(bs->inventory[INVENTORY_RAILGUN] <= 0 || bs->inventory[INVENTORY_SLUGS] < 10) &&
|
(bs->inventory[INVENTORY_RAILGUN] <= 0 || bs->inventory[INVENTORY_SLUGS] < 10) &&
|
||||||
(bs->inventory[INVENTORY_BFG10K] <= 0 || bs->inventory[INVENTORY_BFGAMMO] < 10)) {
|
(bs->inventory[INVENTORY_BFG10K] <= 0 || bs->inventory[INVENTORY_BFGAMMO] < 10)) {
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
@ -3019,6 +3022,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) {
|
||||||
bs->enemysight_time = FloatTime();
|
bs->enemysight_time = FloatTime();
|
||||||
bs->enemysuicide = qfalse;
|
bs->enemysuicide = qfalse;
|
||||||
bs->enemydeath_time = 0;
|
bs->enemydeath_time = 0;
|
||||||
|
bs->enemyvisible_time = FloatTime();
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3090,6 +3094,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) {
|
||||||
else bs->enemysight_time = FloatTime();
|
else bs->enemysight_time = FloatTime();
|
||||||
bs->enemysuicide = qfalse;
|
bs->enemysuicide = qfalse;
|
||||||
bs->enemydeath_time = 0;
|
bs->enemydeath_time = 0;
|
||||||
|
bs->enemyvisible_time = FloatTime();
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
return qfalse;
|
return qfalse;
|
||||||
|
@ -3667,19 +3672,14 @@ void BotCheckAttack(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// STONELANCE - 1.27 bugfix
|
//
|
||||||
VectorSubtract(bs->aimtarget, bs->eye, dir);
|
VectorSubtract(bs->aimtarget, bs->eye, dir);
|
||||||
// END
|
//
|
||||||
if (bs->weaponnum == WP_GAUNTLET) {
|
if (bs->weaponnum == WP_GAUNTLET) {
|
||||||
if (VectorLengthSquared(dir) > Square(60)) {
|
if (VectorLengthSquared(dir) > Square(60)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// STONELANCE - 1.27 bugfix - line moved up
|
|
||||||
// VectorSubtract(bs->aimtarget, bs->eye, dir);
|
|
||||||
// END
|
|
||||||
//
|
|
||||||
if (VectorLengthSquared(dir) < Square(100))
|
if (VectorLengthSquared(dir) < Square(100))
|
||||||
fov = 120;
|
fov = 120;
|
||||||
else
|
else
|
||||||
|
@ -3832,10 +3832,10 @@ void BotMapScripts(bot_state_t *bs) {
|
||||||
BotSetMovedir
|
BotSetMovedir
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
vec3_t VEC_UP = {0, -1, 0};
|
static vec3_t VEC_UP = {0, -1, 0};
|
||||||
vec3_t MOVEDIR_UP = {0, 0, 1};
|
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||||
vec3_t VEC_DOWN = {0, -2, 0};
|
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||||
vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||||
|
|
||||||
void BotSetMovedir(vec3_t angles, vec3_t movedir) {
|
void BotSetMovedir(vec3_t angles, vec3_t movedir) {
|
||||||
if (VectorCompare(angles, VEC_UP)) {
|
if (VectorCompare(angles, VEC_UP)) {
|
||||||
|
@ -4235,7 +4235,7 @@ BotGetActivateGoal
|
||||||
//#define OBSTACLEDEBUG
|
//#define OBSTACLEDEBUG
|
||||||
|
|
||||||
int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activategoal) {
|
int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activategoal) {
|
||||||
int i, ent, cur_entities[10], spawnflags, modelindex, areas[10], numareas, t;
|
int i, ent, cur_entities[10], spawnflags, modelindex, areas[MAX_ACTIVATEAREAS*2], numareas, t;
|
||||||
char model[MAX_INFO_STRING], tmpmodel[128];
|
char model[MAX_INFO_STRING], tmpmodel[128];
|
||||||
char target[128], classname[128];
|
char target[128], classname[128];
|
||||||
float health;
|
float health;
|
||||||
|
@ -4293,13 +4293,29 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ
|
||||||
VectorClear(angles);
|
VectorClear(angles);
|
||||||
BotModelMinsMaxs(modelindex, ET_MOVER, 0, absmins, absmaxs);
|
BotModelMinsMaxs(modelindex, ET_MOVER, 0, absmins, absmaxs);
|
||||||
//
|
//
|
||||||
numareas = trap_AAS_BBoxAreas(absmins, absmaxs, areas, 10);
|
numareas = trap_AAS_BBoxAreas(absmins, absmaxs, areas, MAX_ACTIVATEAREAS*2);
|
||||||
|
// store the areas with reachabilities first
|
||||||
for (i = 0; i < numareas; i++) {
|
for (i = 0; i < numareas; i++) {
|
||||||
|
if (activategoal->numareas >= MAX_ACTIVATEAREAS)
|
||||||
|
break;
|
||||||
|
if ( !trap_AAS_AreaReachability(areas[i]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
trap_AAS_AreaInfo(areas[i], &areainfo);
|
trap_AAS_AreaInfo(areas[i], &areainfo);
|
||||||
if (areainfo.contents & AREACONTENTS_MOVER) {
|
if (areainfo.contents & AREACONTENTS_MOVER) {
|
||||||
activategoal->areas[activategoal->numareas++] = areas[i];
|
activategoal->areas[activategoal->numareas++] = areas[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// store any remaining areas
|
||||||
|
for (i = 0; i < numareas; i++) {
|
||||||
if (activategoal->numareas >= MAX_ACTIVATEAREAS)
|
if (activategoal->numareas >= MAX_ACTIVATEAREAS)
|
||||||
break;
|
break;
|
||||||
|
if ( trap_AAS_AreaReachability(areas[i]) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
trap_AAS_AreaInfo(areas[i], &areainfo);
|
||||||
|
if (areainfo.contents & AREACONTENTS_MOVER) {
|
||||||
|
activategoal->areas[activategoal->numareas++] = areas[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4424,7 +4440,7 @@ int BotGoForActivateGoal(bot_state_t *bs, bot_activategoal_t *activategoal) {
|
||||||
//
|
//
|
||||||
if (BotPushOntoActivateGoalStack(bs, activategoal)) {
|
if (BotPushOntoActivateGoalStack(bs, activategoal)) {
|
||||||
// enter the activate entity AI node
|
// enter the activate entity AI node
|
||||||
AIEnter_Seek_ActivateEntity(bs);
|
AIEnter_Seek_ActivateEntity(bs, "BotGoForActivateGoal");
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -4765,7 +4781,7 @@ void BotCheckConsoleMessages(bot_state_t *bs) {
|
||||||
//remove the console message
|
//remove the console message
|
||||||
trap_BotRemoveConsoleMessage(bs->cs, handle);
|
trap_BotRemoveConsoleMessage(bs->cs, handle);
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "BotCheckConsoleMessages: reply chat");
|
||||||
//EA_Say(bs->client, bs->cs.chatmessage);
|
//EA_Say(bs->client, bs->cs.chatmessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -5346,13 +5362,13 @@ void BotDeathmatchAI(bot_state_t *bs, float thinktime) {
|
||||||
}
|
}
|
||||||
//if the bot has no ai node
|
//if the bot has no ai node
|
||||||
if (!bs->ainode) {
|
if (!bs->ainode) {
|
||||||
AIEnter_Seek_LTG(bs);
|
AIEnter_Seek_LTG(bs, "BotDeathmatchAI: no ai node");
|
||||||
}
|
}
|
||||||
//if the bot entered the game less than 8 seconds ago
|
//if the bot entered the game less than 8 seconds ago
|
||||||
if (!bs->entergamechat && bs->entergame_time > FloatTime() - 8) {
|
if (!bs->entergamechat && bs->entergame_time > FloatTime() - 8) {
|
||||||
if (BotChat_EnterGame(bs)) {
|
if (BotChat_EnterGame(bs)) {
|
||||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||||
AIEnter_Stand(bs);
|
AIEnter_Stand(bs, "BotDeathmatchAI: chat enter game");
|
||||||
}
|
}
|
||||||
bs->entergamechat = qtrue;
|
bs->entergamechat = qtrue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -963,7 +963,6 @@ void BotUpdateInput(bot_state_t *bs, int time, int elapsed_time) {
|
||||||
}
|
}
|
||||||
//convert the bot input to a usercmd
|
//convert the bot input to a usercmd
|
||||||
BotInputToUserCommand(&bi, &bs->lastucmd, bs->cur_ps.delta_angles, time);
|
BotInputToUserCommand(&bi, &bs->lastucmd, bs->cur_ps.delta_angles, time);
|
||||||
|
|
||||||
//subtract the delta angles
|
//subtract the delta angles
|
||||||
for (j = 0; j < 3; j++) {
|
for (j = 0; j < 3; j++) {
|
||||||
bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
|
bs->viewangles[j] = AngleMod(bs->viewangles[j] - SHORT2ANGLE(bs->cur_ps.delta_angles[j]));
|
||||||
|
@ -1481,7 +1480,6 @@ int BotAIStartFrame(int time) {
|
||||||
}
|
}
|
||||||
//check if bot interbreeding is activated
|
//check if bot interbreeding is activated
|
||||||
BotInterbreeding();
|
BotInterbreeding();
|
||||||
|
|
||||||
//cap the bot think time
|
//cap the bot think time
|
||||||
if (bot_thinktime.integer > 200) {
|
if (bot_thinktime.integer > 200) {
|
||||||
trap_Cvar_Set("bot_thinktime", "200");
|
trap_Cvar_Set("bot_thinktime", "200");
|
||||||
|
@ -1596,6 +1594,7 @@ int BotAIStartFrame(int time) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// execute bot user commands every frame
|
// execute bot user commands every frame
|
||||||
for( i = 0; i < MAX_CLIENTS; i++ ) {
|
for( i = 0; i < MAX_CLIENTS; i++ ) {
|
||||||
if( !botstates[i] || !botstates[i]->inuse ) {
|
if( !botstates[i] || !botstates[i]->inuse ) {
|
||||||
|
@ -1641,10 +1640,11 @@ int BotInitLibrary(void) {
|
||||||
trap_BotLibVarSet("g_gametype", buf);
|
trap_BotLibVarSet("g_gametype", buf);
|
||||||
//bot developer mode and log file
|
//bot developer mode and log file
|
||||||
trap_BotLibVarSet("bot_developer", bot_developer.string);
|
trap_BotLibVarSet("bot_developer", bot_developer.string);
|
||||||
|
trap_Cvar_VariableStringBuffer("logfile", buf, sizeof(buf));
|
||||||
trap_BotLibVarSet("log", buf);
|
trap_BotLibVarSet("log", buf);
|
||||||
//no chatting
|
//no chatting
|
||||||
trap_Cvar_VariableStringBuffer("bot_nochat", buf, sizeof(buf));
|
trap_Cvar_VariableStringBuffer("bot_nochat", buf, sizeof(buf));
|
||||||
if (strlen(buf)) trap_BotLibVarSet("nochat", "0");
|
if (strlen(buf)) trap_BotLibVarSet("nochat", buf);
|
||||||
//visualize jump pads
|
//visualize jump pads
|
||||||
trap_Cvar_VariableStringBuffer("bot_visualizejumppads", buf, sizeof(buf));
|
trap_Cvar_VariableStringBuffer("bot_visualizejumppads", buf, sizeof(buf));
|
||||||
if (strlen(buf)) trap_BotLibVarSet("bot_visualizejumppads", buf);
|
if (strlen(buf)) trap_BotLibVarSet("bot_visualizejumppads", buf);
|
||||||
|
@ -1673,9 +1673,9 @@ int BotInitLibrary(void) {
|
||||||
//game directory
|
//game directory
|
||||||
trap_Cvar_VariableStringBuffer("fs_game", buf, sizeof(buf));
|
trap_Cvar_VariableStringBuffer("fs_game", buf, sizeof(buf));
|
||||||
if (strlen(buf)) trap_BotLibVarSet("gamedir", buf);
|
if (strlen(buf)) trap_BotLibVarSet("gamedir", buf);
|
||||||
//cd directory
|
//home directory
|
||||||
trap_Cvar_VariableStringBuffer("fs_cdpath", buf, sizeof(buf));
|
trap_Cvar_VariableStringBuffer("fs_homepath", buf, sizeof(buf));
|
||||||
if (strlen(buf)) trap_BotLibVarSet("cddir", buf);
|
if (strlen(buf)) trap_BotLibVarSet("homedir", buf);
|
||||||
//
|
//
|
||||||
#ifdef MISSIONPACK
|
#ifdef MISSIONPACK
|
||||||
trap_BotLibDefine("MISSIONPACK");
|
trap_BotLibDefine("MISSIONPACK");
|
||||||
|
@ -1748,4 +1748,3 @@ int BotAIShutdown( int restart ) {
|
||||||
return qtrue;
|
return qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2084,4 +2084,3 @@ void BotTeamAI(bot_state_t *bs) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -550,4 +550,3 @@ int BotVoiceChatCommand(bot_state_t *bs, int mode, char *voiceChat) {
|
||||||
}
|
}
|
||||||
return qfalse;
|
return qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue