mirror of
https://github.com/Q3Rally-Team/q3rally.git
synced 2024-11-22 03:51:23 +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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1991,4 +1991,3 @@ int BotMatchMessage(bot_state_t *bs, char *message) {
|
|||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
|
|
|
@ -96,13 +96,15 @@ void BotDumpNodeSwitches(bot_state_t *bs) {
|
|||
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];
|
||||
|
||||
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
|
||||
BotAI_Print(PRT_MESSAGE, "%s", nodeswitch[numnodeswitches]);
|
||||
if (0) {
|
||||
BotAI_Print(PRT_MESSAGE, "%s", nodeswitch[numnodeswitches]);
|
||||
}
|
||||
#endif //DEBUG
|
||||
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));
|
||||
BotAI_Print(PRT_MESSAGE, "%1.1f: new nearby goal %s\n", FloatTime(), buf);
|
||||
}
|
||||
//*/
|
||||
*/
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -306,7 +308,7 @@ int BotGetItemLongTermGoal(bot_state_t *bs, int tfl, bot_goal_t *goal) {
|
|||
trap_BotGetTopGoal(bs->gs, goal);
|
||||
trap_BotGoalName(goal->number, buf, sizeof(buf));
|
||||
BotAI_Print(PRT_MESSAGE, "%1.1f: new long term goal %s\n", FloatTime(), buf);
|
||||
//*/
|
||||
*/
|
||||
bs->ltg_time = FloatTime() + 20;
|
||||
}
|
||||
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);
|
||||
//time the bot gets to pick up the nearby goal item
|
||||
bs->nbg_time = FloatTime() + 8;
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "BotLongTermGoal: go for air");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -768,7 +770,7 @@ int BotGetLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal)
|
|||
if( isRallyRace() )
|
||||
{
|
||||
if (bs->ltgtype == LTG_WINRACE) {
|
||||
AIEnter_MoveToNextCheckpoint( bs );
|
||||
AIEnter_MoveToNextCheckpoint( bs, "BotGetLongTermGoal" );
|
||||
/*
|
||||
gentity_t *checkpoint = NULL;
|
||||
int num;
|
||||
|
@ -1230,8 +1232,8 @@ int BotLongTermGoal(bot_state_t *bs, int tfl, int retreat, bot_goal_t *goal) {
|
|||
AIEnter_Intermission
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Intermission(bot_state_t *bs) {
|
||||
BotRecordNodeSwitch(bs, "intermission", "");
|
||||
void AIEnter_Intermission(bot_state_t *bs, char *s) {
|
||||
BotRecordNodeSwitch(bs, "intermission", "", s);
|
||||
//reset the bot state
|
||||
BotResetState(bs);
|
||||
//check for end level chat
|
||||
|
@ -1259,7 +1261,7 @@ int AINode_Intermission(bot_state_t *bs) {
|
|||
else {
|
||||
bs->stand_time = FloatTime() + 2;
|
||||
}
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "intermission: chat");
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -1269,8 +1271,8 @@ int AINode_Intermission(bot_state_t *bs) {
|
|||
AIEnter_Observer
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Observer(bot_state_t *bs) {
|
||||
BotRecordNodeSwitch(bs, "observer", "");
|
||||
void AIEnter_Observer(bot_state_t *bs, char *s) {
|
||||
BotRecordNodeSwitch(bs, "observer", "", s);
|
||||
//reset the bot state
|
||||
BotResetState(bs);
|
||||
bs->ainode = AINode_Observer;
|
||||
|
@ -1288,7 +1290,7 @@ int AINode_Observer(bot_state_t *bs) {
|
|||
|
||||
//if the bot left observer mode
|
||||
if (!BotIsObserver(bs)) {
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "observer: left observer");
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -1298,8 +1300,8 @@ int AINode_Observer(bot_state_t *bs) {
|
|||
AIEnter_Stand
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Stand(bot_state_t *bs) {
|
||||
BotRecordNodeSwitch(bs, "stand", "");
|
||||
void AIEnter_Stand(bot_state_t *bs, char *s) {
|
||||
BotRecordNodeSwitch(bs, "stand", "", s);
|
||||
bs->standfindenemy_time = FloatTime() + 1;
|
||||
bs->ainode = AINode_Stand;
|
||||
}
|
||||
|
@ -1324,7 +1326,7 @@ int AINode_Stand(bot_state_t *bs) {
|
|||
}
|
||||
if (bs->standfindenemy_time < FloatTime()) {
|
||||
if (BotFindEnemy(bs, -1)) {
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "stand: found enemy");
|
||||
return qfalse;
|
||||
}
|
||||
bs->standfindenemy_time = FloatTime() + 1;
|
||||
|
@ -1334,7 +1336,7 @@ int AINode_Stand(bot_state_t *bs) {
|
|||
// when done standing
|
||||
if (bs->stand_time < FloatTime()) {
|
||||
trap_BotEnterChat(bs->cs, 0, bs->chatto);
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "stand: time out");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -1346,8 +1348,8 @@ int AINode_Stand(bot_state_t *bs) {
|
|||
AIEnter_Respawn
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Respawn(bot_state_t *bs) {
|
||||
BotRecordNodeSwitch(bs, "respawn", "");
|
||||
void AIEnter_Respawn(bot_state_t *bs, char *s) {
|
||||
BotRecordNodeSwitch(bs, "respawn", "", s);
|
||||
//reset some states
|
||||
trap_BotResetMoveState(bs->ms);
|
||||
trap_BotResetGoalState(bs->gs);
|
||||
|
@ -1381,7 +1383,7 @@ int AINode_Respawn(bot_state_t *bs) {
|
|||
// if waiting for the actual respawn
|
||||
if (bs->respawn_wait) {
|
||||
if (!BotIsDead(bs)) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "respawn: respawned");
|
||||
}
|
||||
else {
|
||||
trap_EA_Respawn(bs->client);
|
||||
|
@ -1560,8 +1562,8 @@ void BotClearPath(bot_state_t *bs, bot_moveresult_t *moveresult) {
|
|||
AIEnter_Seek_ActivateEntity
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs) {
|
||||
BotRecordNodeSwitch(bs, "activate entity", "");
|
||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s) {
|
||||
BotRecordNodeSwitch(bs, "activate entity", "", s);
|
||||
bs->ainode = AINode_Seek_ActivateEntity;
|
||||
}
|
||||
|
||||
|
@ -1584,19 +1586,19 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
|
||||
if (BotIsObserver(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "active entity: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "activate entity: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "activate entity: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -1611,7 +1613,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
// if the bot has no activate goal
|
||||
if (!bs->activatestack) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "activate entity: no goal");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -1658,7 +1660,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
bs->activatestack->time = FloatTime() + 10;
|
||||
return qfalse;
|
||||
}
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "activate entity: time out");
|
||||
return qfalse;
|
||||
}
|
||||
memset(&moveresult, 0, sizeof(bot_moveresult_t));
|
||||
|
@ -1686,7 +1688,7 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
bs->activatestack->time = FloatTime() + 10;
|
||||
return qfalse;
|
||||
}
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "activate entity: activated");
|
||||
return qfalse;
|
||||
}
|
||||
//predict obstacles
|
||||
|
@ -1761,14 +1763,14 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
if (BotFindEnemy(bs, -1)) {
|
||||
if (BotWantsToRetreat(bs)) {
|
||||
//keep the current long term goal and retreat
|
||||
AIEnter_Battle_NBG(bs);
|
||||
AIEnter_Battle_NBG(bs, "activate entity: found enemy");
|
||||
}
|
||||
else {
|
||||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
//empty the goal stack
|
||||
trap_BotEmptyGoalStack(bs->gs);
|
||||
//go fight
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "activate entity: found enemy");
|
||||
}
|
||||
BotClearActivateGoalStack(bs);
|
||||
}
|
||||
|
@ -1780,16 +1782,16 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) {
|
|||
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;
|
||||
char buf[144];
|
||||
|
||||
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
||||
trap_BotGoalName(goal.number, buf, 144);
|
||||
BotRecordNodeSwitch(bs, "seek NBG", buf);
|
||||
BotRecordNodeSwitch(bs, "seek NBG", buf, s);
|
||||
}
|
||||
else {
|
||||
BotRecordNodeSwitch(bs, "seek NBG", "no goal");
|
||||
BotRecordNodeSwitch(bs, "seek NBG", "no goal", s);
|
||||
}
|
||||
bs->ainode = AINode_Seek_NBG;
|
||||
}
|
||||
|
@ -1809,17 +1811,17 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "seek nbg: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "seek nbg: intermision");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "seek nbg: bot dead");
|
||||
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
|
||||
bs->check_time = FloatTime() + 0.05;
|
||||
//go back to seek ltg
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "seek nbg: time out");
|
||||
return qfalse;
|
||||
}
|
||||
//predict obstacles
|
||||
|
@ -1903,14 +1905,14 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
|||
if (BotFindEnemy(bs, -1)) {
|
||||
if (BotWantsToRetreat(bs)) {
|
||||
//keep the current long term goal and retreat
|
||||
AIEnter_Battle_NBG(bs);
|
||||
AIEnter_Battle_NBG(bs, "seek nbg: found enemy");
|
||||
}
|
||||
else {
|
||||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
//empty the goal stack
|
||||
trap_BotEmptyGoalStack(bs->gs);
|
||||
//go fight
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "seek nbg: found enemy");
|
||||
}
|
||||
}
|
||||
return qtrue;
|
||||
|
@ -1921,16 +1923,16 @@ int AINode_Seek_NBG(bot_state_t *bs) {
|
|||
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;
|
||||
char buf[144];
|
||||
|
||||
if (trap_BotGetTopGoal(bs->gs, &goal)) {
|
||||
trap_BotGoalName(goal.number, buf, 144);
|
||||
BotRecordNodeSwitch(bs, "seek LTG", buf);
|
||||
BotRecordNodeSwitch(bs, "seek LTG", buf, s);
|
||||
}
|
||||
else {
|
||||
BotRecordNodeSwitch(bs, "seek LTG", "no goal");
|
||||
BotRecordNodeSwitch(bs, "seek LTG", "no goal", s);
|
||||
}
|
||||
bs->ainode = AINode_Seek_LTG;
|
||||
}
|
||||
|
@ -1954,23 +1956,23 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "seek ltg: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "seek ltg: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "seek ltg: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
if (BotChat_Random(bs)) {
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "seek ltg: random chat");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -1999,7 +2001,7 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
// END
|
||||
if (BotWantsToRetreat(bs)) {
|
||||
//keep the current long term goal and retreat
|
||||
AIEnter_Battle_Retreat(bs);
|
||||
AIEnter_Battle_Retreat(bs, "seek ltg: found enemy");
|
||||
return qfalse;
|
||||
}
|
||||
else {
|
||||
|
@ -2007,7 +2009,7 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
//empty the goal stack
|
||||
trap_BotEmptyGoalStack(bs->gs);
|
||||
//go fight
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "seek ltg: found enemy");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2052,17 +2054,15 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
//BotAI_Print(PRT_MESSAGE, "new nearby goal %s\n", buf);
|
||||
//time the bot gets to pick up the nearby goal item
|
||||
bs->nbg_time = FloatTime() + 4 + range * 0.01;
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "ltg seek: nbg");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
//predict obstacles
|
||||
if (BotAIPredictObstacles(bs, &goal))
|
||||
return qfalse;
|
||||
|
||||
//initialize the movement state
|
||||
BotSetupForMovement(bs);
|
||||
|
||||
//move towards the goal
|
||||
// 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);
|
||||
bs->ltg_time = 0;
|
||||
}
|
||||
|
||||
//
|
||||
BotAIBlocked(bs, &moveresult, qtrue);
|
||||
|
||||
//
|
||||
BotClearPath(bs, &moveresult);
|
||||
|
||||
//if the viewangles are used for the movement
|
||||
if (moveresult.flags & (MOVERESULT_MOVEMENTVIEWSET|MOVERESULT_MOVEMENTVIEW|MOVERESULT_SWIMVIEW)) {
|
||||
VectorCopy(moveresult.ideal_viewangles, bs->ideal_viewangles);
|
||||
}
|
||||
|
||||
//if waiting for something
|
||||
else if (moveresult.flags & MOVERESULT_WAITING) {
|
||||
if (random() < bs->thinktime * 0.8) {
|
||||
|
@ -2131,10 +2127,8 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
}
|
||||
bs->ideal_viewangles[2] *= 0.5;
|
||||
}
|
||||
|
||||
//if the weapon is used for the bot movement
|
||||
if (moveresult.flags & MOVERESULT_MOVEMENTWEAPON) bs->weaponnum = moveresult.weapon;
|
||||
|
||||
//
|
||||
return qtrue;
|
||||
}
|
||||
|
@ -2144,13 +2138,13 @@ int AINode_Seek_LTG(bot_state_t *bs)
|
|||
AIEnter_Battle_Fight
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Battle_Fight(bot_state_t *bs) {
|
||||
void AIEnter_Battle_Fight(bot_state_t *bs, char *s) {
|
||||
// Q3Rally Code Start
|
||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||
return;
|
||||
// END
|
||||
|
||||
BotRecordNodeSwitch(bs, "battle fight", "");
|
||||
BotRecordNodeSwitch(bs, "battle fight", "", s);
|
||||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
bs->ainode = AINode_Battle_Fight;
|
||||
bs->flags &= ~BFL_FIGHTSUICIDAL;
|
||||
|
@ -2161,13 +2155,13 @@ void AIEnter_Battle_Fight(bot_state_t *bs) {
|
|||
AIEnter_Battle_SuicidalFight
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Battle_SuicidalFight(bot_state_t *bs) {
|
||||
void AIEnter_Battle_SuicidalFight(bot_state_t *bs, char *s) {
|
||||
// Q3Rally Code Start
|
||||
// if ( gametype == GT_RACING )
|
||||
// return;
|
||||
// END
|
||||
|
||||
BotRecordNodeSwitch(bs, "battle fight", "");
|
||||
BotRecordNodeSwitch(bs, "battle fight", "", s);
|
||||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
bs->ainode = AINode_Battle_Fight;
|
||||
bs->flags |= BFL_FIGHTSUICIDAL;
|
||||
|
@ -2189,18 +2183,18 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "battle fight: observer");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "battle fight: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "battle fight: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//if there is another better enemy
|
||||
|
@ -2211,7 +2205,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
}
|
||||
//if no enemy
|
||||
if (bs->enemy < 0) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle fight: no enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -2225,11 +2219,11 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
}
|
||||
if (bs->lastkilledplayer == bs->enemy && BotChat_Kill(bs)) {
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "battle fight: enemy dead");
|
||||
}
|
||||
else {
|
||||
bs->ltg_time = 0;
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle fight: enemy dead");
|
||||
}
|
||||
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 (EntityIsInvisible(&entinfo) && !EntityIsShooting(&entinfo)) {
|
||||
if (random() < 0.2) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle fight: invisible");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2270,7 +2264,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
if (bs->lastframe_health > bs->inventory[INVENTORY_HEALTH]) {
|
||||
if (BotChat_HitNoDeath(bs)) {
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "battle fight: chat health decreased");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2278,7 +2272,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
if (bs->cur_ps.persistant[PERS_HITS] > bs->lasthitcount) {
|
||||
if (BotChat_HitNoKill(bs)) {
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "battle fight: chat hit someone");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2294,11 +2288,11 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
}
|
||||
#endif
|
||||
if (BotWantsToChase(bs)) {
|
||||
AIEnter_Battle_Chase(bs);
|
||||
AIEnter_Battle_Chase(bs, "battle fight: enemy out of sight");
|
||||
return qfalse;
|
||||
}
|
||||
else {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle fight: enemy out of sight");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2333,7 +2327,7 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
//if the bot wants to retreat
|
||||
if (!(bs->flags & BFL_FIGHTSUICIDAL)) {
|
||||
if (BotWantsToRetreat(bs)) {
|
||||
AIEnter_Battle_Retreat(bs);
|
||||
AIEnter_Battle_Retreat(bs, "battle fight: wants to retreat");
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
@ -2345,13 +2339,13 @@ int AINode_Battle_Fight(bot_state_t *bs) {
|
|||
AIEnter_Battle_Chase
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Battle_Chase(bot_state_t *bs) {
|
||||
void AIEnter_Battle_Chase(bot_state_t *bs, char *s) {
|
||||
// Q3Rally Code Start
|
||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||
return;
|
||||
// END
|
||||
|
||||
BotRecordNodeSwitch(bs, "battle chase", "");
|
||||
BotRecordNodeSwitch(bs, "battle chase", "", s);
|
||||
bs->chase_time = FloatTime();
|
||||
bs->ainode = AINode_Battle_Chase;
|
||||
}
|
||||
|
@ -2373,22 +2367,22 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "battle chase: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "battle chase: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "battle chase: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//if no enemy
|
||||
if (bs->enemy < 0) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle chase: no enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//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->cur_ps.viewangles, 360, bs->enemy)) {
|
||||
// END
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "battle chase");
|
||||
return qfalse;
|
||||
}
|
||||
//if there is another enemy
|
||||
if (BotFindEnemy(bs, -1)) {
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "battle chase: better enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//there is no last enemy area
|
||||
if (!bs->lastenemyareanum) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle chase: no enemy area");
|
||||
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 there's no chase time left
|
||||
if (!bs->chase_time || bs->chase_time < FloatTime() - 10) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle chase: time out");
|
||||
return qfalse;
|
||||
}
|
||||
//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
|
||||
bs->nbg_time = FloatTime() + 0.1 * range + 1;
|
||||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
AIEnter_Battle_NBG(bs);
|
||||
AIEnter_Battle_NBG(bs, "battle chase: nbg");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2489,7 +2483,7 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
|||
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 (BotWantsToRetreat(bs)) {
|
||||
AIEnter_Battle_Retreat(bs);
|
||||
AIEnter_Battle_Retreat(bs, "battle chase: wants to retreat");
|
||||
return qtrue;
|
||||
}
|
||||
return qtrue;
|
||||
|
@ -2500,13 +2494,13 @@ int AINode_Battle_Chase(bot_state_t *bs)
|
|||
AIEnter_Battle_Retreat
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Battle_Retreat(bot_state_t *bs) {
|
||||
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s) {
|
||||
// STONELANCE
|
||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||
return;
|
||||
// END
|
||||
|
||||
BotRecordNodeSwitch(bs, "battle retreat", "");
|
||||
BotRecordNodeSwitch(bs, "battle retreat", "", s);
|
||||
bs->ainode = AINode_Battle_Retreat;
|
||||
}
|
||||
|
||||
|
@ -2528,28 +2522,28 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "battle retreat: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "battle retreat: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "battle retreat: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//if no enemy
|
||||
if (bs->enemy < 0) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle retreat: no enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
BotEntityInfo(bs->enemy, &entinfo);
|
||||
if (EntityIsDead(&entinfo)) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle retreat: enemy dead");
|
||||
return qfalse;
|
||||
}
|
||||
//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
|
||||
trap_BotEmptyGoalStack(bs->gs);
|
||||
//go chase the enemy
|
||||
AIEnter_Battle_Chase(bs);
|
||||
AIEnter_Battle_Chase(bs, "battle retreat: wants to chase");
|
||||
return qfalse;
|
||||
}
|
||||
//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 (bs->enemyvisible_time < FloatTime() - 4) {
|
||||
AIEnter_Seek_LTG(bs);
|
||||
AIEnter_Seek_LTG(bs, "battle retreat: lost enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//else if the enemy is NOT visible
|
||||
else if (bs->enemyvisible_time < FloatTime()) {
|
||||
//if there is another enemy
|
||||
if (BotFindEnemy(bs, -1)) {
|
||||
AIEnter_Battle_Fight(bs);
|
||||
AIEnter_Battle_Fight(bs, "battle retreat: another enemy");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2618,7 +2612,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
|||
BotBattleUseItems(bs);
|
||||
//get the current long term goal while retreating
|
||||
if (!BotLongTermGoal(bs, bs->tfl, qtrue, &goal)) {
|
||||
AIEnter_Battle_SuicidalFight(bs);
|
||||
AIEnter_Battle_SuicidalFight(bs, "battle retreat: no way out");
|
||||
return qfalse;
|
||||
}
|
||||
//check for nearby goals periodicly
|
||||
|
@ -2647,7 +2641,7 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
|||
trap_BotResetLastAvoidReach(bs->ms);
|
||||
//time the bot gets to pick up the nearby goal item
|
||||
bs->nbg_time = FloatTime() + range / 100 + 1;
|
||||
AIEnter_Battle_NBG(bs);
|
||||
AIEnter_Battle_NBG(bs, "battle retreat: nbg");
|
||||
return qfalse;
|
||||
}
|
||||
}
|
||||
|
@ -2704,13 +2698,13 @@ int AINode_Battle_Retreat(bot_state_t *bs) {
|
|||
AIEnter_Battle_NBG
|
||||
==================
|
||||
*/
|
||||
void AIEnter_Battle_NBG(bot_state_t *bs) {
|
||||
void AIEnter_Battle_NBG(bot_state_t *bs, char *s) {
|
||||
// STONELANCE
|
||||
if ( gametype == GT_RACING || gametype == GT_TEAM_RACING )
|
||||
return;
|
||||
// END
|
||||
|
||||
BotRecordNodeSwitch(bs, "battle NBG", "");
|
||||
BotRecordNodeSwitch(bs, "battle NBG", "", s);
|
||||
bs->ainode = AINode_Battle_NBG;
|
||||
}
|
||||
|
||||
|
@ -2732,28 +2726,28 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
|||
// END
|
||||
|
||||
if (BotIsObserver(bs)) {
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "battle nbg: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "battle nbg: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "battle nbg: bot dead");
|
||||
return qfalse;
|
||||
}
|
||||
//if no enemy
|
||||
if (bs->enemy < 0) {
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "battle nbg: no enemy");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
BotEntityInfo(bs->enemy, &entinfo);
|
||||
if (EntityIsDead(&entinfo)) {
|
||||
AIEnter_Seek_NBG(bs);
|
||||
AIEnter_Seek_NBG(bs, "battle nbg: enemy dead");
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
|
@ -2803,8 +2797,10 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
|||
//pop the current goal from the stack
|
||||
trap_BotPopGoal(bs->gs);
|
||||
//if the bot still has a goal
|
||||
if (trap_BotGetTopGoal(bs->gs, &goal)) AIEnter_Battle_Retreat(bs);
|
||||
else AIEnter_Battle_Fight(bs);
|
||||
if (trap_BotGetTopGoal(bs->gs, &goal))
|
||||
AIEnter_Battle_Retreat(bs, "battle nbg: time out");
|
||||
else
|
||||
AIEnter_Battle_Fight(bs, "battle nbg: time out");
|
||||
//
|
||||
return qfalse;
|
||||
}
|
||||
|
@ -2866,12 +2862,12 @@ int AINode_Battle_NBG(bot_state_t *bs) {
|
|||
AIEnter_MoveToNextCheckpoint
|
||||
==================
|
||||
*/
|
||||
void AIEnter_MoveToNextCheckpoint( bot_state_t *bs )
|
||||
void AIEnter_MoveToNextCheckpoint( bot_state_t *bs, char *s )
|
||||
{
|
||||
if ( !isRallyRace() )
|
||||
return;
|
||||
|
||||
BotRecordNodeSwitch(bs, "move to next checkpoint", "");
|
||||
BotRecordNodeSwitch(bs, "move to next checkpoint", "", s);
|
||||
bs->ainode = AINode_MoveToNextCheckpoint;
|
||||
}
|
||||
|
||||
|
@ -3033,19 +3029,19 @@ int AINode_MoveToNextCheckpoint( bot_state_t *bs )
|
|||
|
||||
if (BotIsObserver(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Observer(bs);
|
||||
AIEnter_Observer(bs, "moveToNextCheckpoint: observer");
|
||||
return qfalse;
|
||||
}
|
||||
//if in the intermission
|
||||
if (BotIntermission(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Intermission(bs);
|
||||
AIEnter_Intermission(bs, "moveToNextCheckpoint: intermission");
|
||||
return qfalse;
|
||||
}
|
||||
//respawn if dead
|
||||
if (BotIsDead(bs)) {
|
||||
BotClearActivateGoalStack(bs);
|
||||
AIEnter_Respawn(bs);
|
||||
AIEnter_Respawn(bs, "moveToNextCheckpoint: dead");
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,18 +33,18 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
|
||||
#define MAX_NODESWITCHES 50
|
||||
|
||||
void AIEnter_Intermission(bot_state_t *bs);
|
||||
void AIEnter_Observer(bot_state_t *bs);
|
||||
void AIEnter_Respawn(bot_state_t *bs);
|
||||
void AIEnter_Stand(bot_state_t *bs);
|
||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs);
|
||||
void AIEnter_Seek_NBG(bot_state_t *bs);
|
||||
void AIEnter_Seek_LTG(bot_state_t *bs);
|
||||
void AIEnter_Seek_Camp(bot_state_t *bs);
|
||||
void AIEnter_Battle_Fight(bot_state_t *bs);
|
||||
void AIEnter_Battle_Chase(bot_state_t *bs);
|
||||
void AIEnter_Battle_Retreat(bot_state_t *bs);
|
||||
void AIEnter_Battle_NBG(bot_state_t *bs);
|
||||
void AIEnter_Intermission(bot_state_t *bs, char *s);
|
||||
void AIEnter_Observer(bot_state_t *bs, char *s);
|
||||
void AIEnter_Respawn(bot_state_t *bs, char *s);
|
||||
void AIEnter_Stand(bot_state_t *bs, char *s);
|
||||
void AIEnter_Seek_ActivateEntity(bot_state_t *bs, char *s);
|
||||
void AIEnter_Seek_NBG(bot_state_t *bs, char *s);
|
||||
void AIEnter_Seek_LTG(bot_state_t *bs, char *s);
|
||||
void AIEnter_Seek_Camp(bot_state_t *bs, char *s);
|
||||
void AIEnter_Battle_Fight(bot_state_t *bs, char *s);
|
||||
void AIEnter_Battle_Chase(bot_state_t *bs, char *s);
|
||||
void AIEnter_Battle_Retreat(bot_state_t *bs, char *s);
|
||||
void AIEnter_Battle_NBG(bot_state_t *bs, char *s);
|
||||
int AINode_Intermission(bot_state_t *bs);
|
||||
int AINode_Observer(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);
|
||||
|
||||
// STONELANCE
|
||||
void AIEnter_MoveToNextCheckpoint(bot_state_t *bs);
|
||||
void AIEnter_MoveToNextCheckpoint(bot_state_t *bs, char *s);
|
||||
int AINode_MoveToNextCheckpoint(bot_state_t *bs);
|
||||
// END
|
||||
|
||||
|
|
|
@ -217,18 +217,6 @@ qboolean EntityIsDead(aas_entityinfo_t *entinfo) {
|
|||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
EntityIsInvisible
|
||||
==================
|
||||
*/
|
||||
qboolean EntityIsInvisible(aas_entityinfo_t *entinfo) {
|
||||
if (entinfo->powerups & (1 << PW_INVIS)) {
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
EntityCarriesFlag
|
||||
|
@ -246,6 +234,22 @@ qboolean EntityCarriesFlag(aas_entityinfo_t *entinfo) {
|
|||
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
|
||||
|
@ -1607,7 +1611,7 @@ void BotSetupForMovement(bot_state_t *bs) {
|
|||
memset(&initmove, 0, sizeof(bot_initmove_t));
|
||||
VectorCopy(bs->cur_ps.origin, initmove.origin);
|
||||
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.entitynum = bs->entitynum;
|
||||
initmove.client = bs->client;
|
||||
|
@ -2257,7 +2261,6 @@ float BotAggression(bot_state_t *bs) {
|
|||
//if the bot can use the shotgun
|
||||
if (bs->inventory[INVENTORY_SHOTGUN] > 0 &&
|
||||
bs->inventory[INVENTORY_SHELLS] > 10) return 50;
|
||||
|
||||
//otherwise the bot is not feeling too good
|
||||
return 0;
|
||||
}
|
||||
|
@ -2539,7 +2542,7 @@ int BotWantsToCamp(bot_state_t *bs) {
|
|||
//if the bot isn't healthy enough
|
||||
if (BotAggression(bs) < 50) return qfalse;
|
||||
//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_BFG10K] <= 0 || bs->inventory[INVENTORY_BFGAMMO] < 10)) {
|
||||
return qfalse;
|
||||
|
@ -3019,6 +3022,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) {
|
|||
bs->enemysight_time = FloatTime();
|
||||
bs->enemysuicide = qfalse;
|
||||
bs->enemydeath_time = 0;
|
||||
bs->enemyvisible_time = FloatTime();
|
||||
return qtrue;
|
||||
}
|
||||
}
|
||||
|
@ -3090,6 +3094,7 @@ int BotFindEnemy(bot_state_t *bs, int curenemy) {
|
|||
else bs->enemysight_time = FloatTime();
|
||||
bs->enemysuicide = qfalse;
|
||||
bs->enemydeath_time = 0;
|
||||
bs->enemyvisible_time = FloatTime();
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
|
@ -3667,19 +3672,14 @@ void BotCheckAttack(bot_state_t *bs) {
|
|||
}
|
||||
}
|
||||
//
|
||||
// STONELANCE - 1.27 bugfix
|
||||
//
|
||||
VectorSubtract(bs->aimtarget, bs->eye, dir);
|
||||
// END
|
||||
//
|
||||
if (bs->weaponnum == WP_GAUNTLET) {
|
||||
if (VectorLengthSquared(dir) > Square(60)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
//
|
||||
// STONELANCE - 1.27 bugfix - line moved up
|
||||
// VectorSubtract(bs->aimtarget, bs->eye, dir);
|
||||
// END
|
||||
//
|
||||
if (VectorLengthSquared(dir) < Square(100))
|
||||
fov = 120;
|
||||
else
|
||||
|
@ -3832,10 +3832,10 @@ void BotMapScripts(bot_state_t *bs) {
|
|||
BotSetMovedir
|
||||
==================
|
||||
*/
|
||||
vec3_t VEC_UP = {0, -1, 0};
|
||||
vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
vec3_t VEC_DOWN = {0, -2, 0};
|
||||
vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
static vec3_t VEC_UP = {0, -1, 0};
|
||||
static vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
static vec3_t VEC_DOWN = {0, -2, 0};
|
||||
static vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void BotSetMovedir(vec3_t angles, vec3_t movedir) {
|
||||
if (VectorCompare(angles, VEC_UP)) {
|
||||
|
@ -4235,7 +4235,7 @@ BotGetActivateGoal
|
|||
//#define OBSTACLEDEBUG
|
||||
|
||||
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 target[128], classname[128];
|
||||
float health;
|
||||
|
@ -4293,13 +4293,29 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ
|
|||
VectorClear(angles);
|
||||
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++) {
|
||||
if (activategoal->numareas >= MAX_ACTIVATEAREAS)
|
||||
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];
|
||||
}
|
||||
}
|
||||
// store any remaining areas
|
||||
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);
|
||||
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)) {
|
||||
// enter the activate entity AI node
|
||||
AIEnter_Seek_ActivateEntity(bs);
|
||||
AIEnter_Seek_ActivateEntity(bs, "BotGoForActivateGoal");
|
||||
return qtrue;
|
||||
}
|
||||
else {
|
||||
|
@ -4765,7 +4781,7 @@ void BotCheckConsoleMessages(bot_state_t *bs) {
|
|||
//remove the console message
|
||||
trap_BotRemoveConsoleMessage(bs->cs, handle);
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "BotCheckConsoleMessages: reply chat");
|
||||
//EA_Say(bs->client, bs->cs.chatmessage);
|
||||
break;
|
||||
}
|
||||
|
@ -5346,13 +5362,13 @@ void BotDeathmatchAI(bot_state_t *bs, float thinktime) {
|
|||
}
|
||||
//if the bot has no ai node
|
||||
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 (!bs->entergamechat && bs->entergame_time > FloatTime() - 8) {
|
||||
if (BotChat_EnterGame(bs)) {
|
||||
bs->stand_time = FloatTime() + BotChatTime(bs);
|
||||
AIEnter_Stand(bs);
|
||||
AIEnter_Stand(bs, "BotDeathmatchAI: chat enter game");
|
||||
}
|
||||
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
|
||||
BotInputToUserCommand(&bi, &bs->lastucmd, bs->cur_ps.delta_angles, time);
|
||||
|
||||
//subtract the delta angles
|
||||
for (j = 0; j < 3; 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
|
||||
BotInterbreeding();
|
||||
|
||||
//cap the bot think time
|
||||
if (bot_thinktime.integer > 200) {
|
||||
trap_Cvar_Set("bot_thinktime", "200");
|
||||
|
@ -1596,6 +1594,7 @@ int BotAIStartFrame(int time) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// execute bot user commands every frame
|
||||
for( i = 0; i < MAX_CLIENTS; i++ ) {
|
||||
if( !botstates[i] || !botstates[i]->inuse ) {
|
||||
|
@ -1641,10 +1640,11 @@ int BotInitLibrary(void) {
|
|||
trap_BotLibVarSet("g_gametype", buf);
|
||||
//bot developer mode and log file
|
||||
trap_BotLibVarSet("bot_developer", bot_developer.string);
|
||||
trap_Cvar_VariableStringBuffer("logfile", buf, sizeof(buf));
|
||||
trap_BotLibVarSet("log", buf);
|
||||
//no chatting
|
||||
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
|
||||
trap_Cvar_VariableStringBuffer("bot_visualizejumppads", buf, sizeof(buf));
|
||||
if (strlen(buf)) trap_BotLibVarSet("bot_visualizejumppads", buf);
|
||||
|
@ -1673,9 +1673,9 @@ int BotInitLibrary(void) {
|
|||
//game directory
|
||||
trap_Cvar_VariableStringBuffer("fs_game", buf, sizeof(buf));
|
||||
if (strlen(buf)) trap_BotLibVarSet("gamedir", buf);
|
||||
//cd directory
|
||||
trap_Cvar_VariableStringBuffer("fs_cdpath", buf, sizeof(buf));
|
||||
if (strlen(buf)) trap_BotLibVarSet("cddir", buf);
|
||||
//home directory
|
||||
trap_Cvar_VariableStringBuffer("fs_homepath", buf, sizeof(buf));
|
||||
if (strlen(buf)) trap_BotLibVarSet("homedir", buf);
|
||||
//
|
||||
#ifdef MISSIONPACK
|
||||
trap_BotLibDefine("MISSIONPACK");
|
||||
|
@ -1748,4 +1748,3 @@ int BotAIShutdown( int restart ) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue