From 53dcd07b69f0644ba5d2409026bf411fe3525e34 Mon Sep 17 00:00:00 2001 From: Andrei Drexler Date: Sun, 31 Mar 2002 19:16:56 +0000 Subject: [PATCH] Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables --- reaction/game/ai_cmd.c | 20 ++++ reaction/game/ai_dmnet.c | 38 ++++++++ reaction/game/ai_dmq3.c | 204 ++++++++++++++++++++++++++++++++++++++- reaction/game/ai_main.c | 4 + reaction/game/ai_main.h | 4 + 5 files changed, 269 insertions(+), 1 deletion(-) diff --git a/reaction/game/ai_cmd.c b/reaction/game/ai_cmd.c index 43c75e6b..20b566ce 100644 --- a/reaction/game/ai_cmd.c +++ b/reaction/game/ai_cmd.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.5 2002/03/31 19:16:56 makro +// Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables +// // Revision 1.4 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // @@ -1519,6 +1522,8 @@ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) { bot_goal_t goal; char netname[MAX_MESSAGE_SIZE]; char *nearbyitems[] = { + //Makro - replacing with RQ3 names + /* "Shotgun", "Grenade Launcher", "Rocket Launcher", @@ -1534,6 +1539,21 @@ void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) { "Flight", "Armor", "Heavy Armor", + */ + RQ3_PISTOL_NAME, + RQ3_M3_NAME, + RQ3_M4_NAME, + RQ3_MP5_NAME, + RQ3_HANDCANNON_NAME, + RQ3_SSG3000_NAME, + RQ3_AKIMBO_NAME, + RQ3_KNIFE_NAME, + RQ3_GRENADE_NAME, + RQ3_KEVLAR_NAME, + RQ3_LASER_NAME, + RQ3_SILENCER_NAME, + RQ3_SLIPPERS_NAME, + RQ3_BANDOLIER_NAME, "Red Flag", "Blue Flag", #ifdef MISSIONPACK diff --git a/reaction/game/ai_dmnet.c b/reaction/game/ai_dmnet.c index 5409ebab..8cff1760 100644 --- a/reaction/game/ai_dmnet.c +++ b/reaction/game/ai_dmnet.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.7 2002/03/31 19:16:56 makro +// Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables +// // Revision 1.6 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // @@ -1489,6 +1492,31 @@ int AINode_Seek_ActivateEntity(bot_state_t *bs) { goal = &bs->activatestack->goal; // initialize target being visible to false targetvisible = qfalse; + + //Makro - if the bot has to open a door + if (bs->activatestack->openDoor) { + int dist; + + BotEntityInfo(goal->entitynum, &entinfo); + dist = Distance(bs->origin, entinfo.origin); + + if (dist < 64) { + /* + if (bot_developer.integer == 2) { + G_Printf(va("^5BOT CODE: ^7Reached door at (%i %i %i) from (%i %i %i)\n", + (int) (bs->origin[0]), (int) (bs->origin[1]), (int) (bs->origin[2]), + (int) (entinfo.origin[0]), (int) (entinfo.origin[1]), (int) (entinfo.origin[2]))); + } + */ + BotPopFromActivateGoalStack(bs); + //bs->activatestack->time = 0; + Cmd_OpenDoor( &g_entities[bs->entitynum] ); + BotMoveTowardsEnt(bs, entinfo.origin, -80); + return qtrue; + } + + } + // if the bot has to shoot at a target to activate something if (bs->activatestack->shoot) { // @@ -2372,6 +2400,16 @@ 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, "battle retreat: lost enemy"); + //Makro - bot retreating, enemy not in sight - a good time to bandage + if (bs->lastframe_health > bs->inventory[INVENTORY_HEALTH]) { + Cmd_Bandage( &g_entities[bs->entitynum] ); + /* + if (bot_developer.integer == 2) { + G_Printf("^5BOT CODE: ^7Bandaging\n"); + } + */ + + } return qfalse; } //else if the enemy is NOT visible diff --git a/reaction/game/ai_dmq3.c b/reaction/game/ai_dmq3.c index bfbef6d6..df2e23d8 100644 --- a/reaction/game/ai_dmq3.c +++ b/reaction/game/ai_dmq3.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.9 2002/03/31 19:16:56 makro +// Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables +// // Revision 1.8 2002/03/18 12:25:10 jbravo // Live players dont get fraglines, except their own. Cleanups and some // hacks to get bots to stop using knives only. @@ -116,6 +119,53 @@ aas_altroutegoal_t blue_altroutegoals[MAX_ALTROUTEGOALS]; int blue_numaltroutegoals; +/* +================== +BotMoveTowardsEnt + +Added by Makro +================== +*/ +void BotMoveTowardsEnt(bot_state_t *bs, vec3_t dest, int dist) { + vec3_t dir; + bot_goal_t goal; + bot_moveresult_t moveresult; + + VectorClear(dir); + VectorSubtract(bs->origin, dest, dir); + VectorNormalize(dir); + if (dist < 0 ) { + VectorScale(dir, -1, dir); + dist = -dist; + } + VectorScale(dir, dist, dir); + VectorAdd(dir, bs->origin, dir); + //trap_BotMoveInDirection(bs->ms, dir, dist, MOVE_RUN); + + //create goal + memset(&moveresult, 0, sizeof(moveresult)); + goal.entitynum = 0; + VectorCopy(dir, goal.origin); + VectorSet(goal.mins, -8, -8, -8); + VectorSet(goal.maxs, 8, 8, 8); + goal.areanum = trap_AAS_PointAreaNum(goal.origin); + /* + if (bot_developer.integer == 2) { + G_Printf(va("^5BOT CODE: ^7Moving from (%i %i %i) towards entity at (%i %i %i) up to (%i %i %i)\n", + (int) bs->origin[0], (int) bs->origin[1], (int) bs->origin[2], + (int) dest[0], (int) dest[1], (int) dest[2], + (int) dir[0], (int) dir[1], (int) dir[2])); + } + */ + //initialize the movement state + BotSetupForMovement(bs); + //move towards the goal + trap_BotMoveToGoal(&moveresult, bs->ms, &goal, TFL_DEFAULT); + + //moveresult->failure = qfalse; + //VectorCopy(dir, moveresult->movedir); +} + /* ================== BotSetUserInfo @@ -1587,6 +1637,21 @@ void BotChooseWeapon(bot_state_t *bs) { //BotAI_Print(PRT_MESSAGE, "bs->weaponnum = %d\n", bs->weaponnum); trap_EA_SelectWeapon(bs->client, bs->weaponnum); } + + //Makro - gun is empty; if bot has extra clips - reload, otherwise switch to knife + if ( (bs->cur_ps.ammo[bs->weaponnum]) == 0 ) { + if (g_entities[bs->entitynum].client->numClips[bs->weaponnum] >= 1 ) { + Cmd_Reload( &g_entities[bs->entitynum] ); + /* + if (bot_developer.integer == 2) { + G_Printf("^5BOT CODE: ^7Reloading\n"); + } + */ + } else { + bs->weaponnum = WP_KNIFE; + trap_EA_SelectWeapon(bs->client, bs->weaponnum); + } + } } /* @@ -2037,6 +2102,26 @@ BotBattleUseItems ================== */ void BotBattleUseItems(bot_state_t *bs) { + qboolean doBandage = qfalse; + //Makro - bot was hit; if very low on health, bandage immediately, otherwise, bandage randomly + if ( bs->lastframe_health > bs->inventory[INVENTORY_HEALTH] ) { + if (bs->inventory[INVENTORY_HEALTH] <= 20) { + doBandage = qtrue; + } else { + if ( (int) (random() * (float) (bs->inventory[INVENTORY_HEALTH])) == 0) { + doBandage = qtrue; + } + } + } + if (doBandage) { + Cmd_Bandage( &g_entities[bs->entitynum] ); + /* + if (bot_developer.integer == 2) { + G_Printf(va("^5BOT CODE: ^7Bandaging with %i health\n", bs->inventory[INVENTORY_HEALTH])); + } + */ + } + if (bs->inventory[INVENTORY_HEALTH] < 40) { if (bs->inventory[INVENTORY_TELEPORTER] > 0) { if (!BotCTFCarryingFlag(bs) @@ -2574,11 +2659,19 @@ BotGoForPowerups void BotGoForPowerups(bot_state_t *bs) { //don't avoid any of the powerups anymore + //Makro - replaced with Q3 items + /* BotDontAvoid(bs, "Quad Damage"); BotDontAvoid(bs, "Regeneration"); BotDontAvoid(bs, "Battle Suit"); BotDontAvoid(bs, "Speed"); BotDontAvoid(bs, "Invisibility"); + */ + BotDontAvoid(bs, RQ3_KEVLAR_NAME); + BotDontAvoid(bs, RQ3_LASER_NAME); + BotDontAvoid(bs, RQ3_BANDOLIER_NAME); + BotDontAvoid(bs, RQ3_SLIPPERS_NAME); + BotDontAvoid(bs, RQ3_SILENCER_NAME); //BotDontAvoid(bs, "Flight"); //reset the long term goal time so the bot will go for the powerup //NOTE: the long term goal type doesn't change @@ -4025,6 +4118,79 @@ int BotFuncDoorActivateGoal(bot_state_t *bs, int bspent, bot_activategoal_t *act return qtrue; } +/* +==================================== +BotFuncBreakableGoal + +Added by Makro +Basically a rip off of the previous +function +==================================== +*/ +int BotFuncBreakableGoal(bot_state_t *bs, int bspent, bot_activategoal_t *activategoal) { + int modelindex, entitynum; + char model[MAX_INFO_STRING]; + vec3_t mins, maxs, origin, angles; + + //shoot at the func_breakable + trap_AAS_ValueForBSPEpairKey(bspent, "model", model, sizeof(model)); + if (!*model) + return qfalse; + modelindex = atoi(model+1); + if (!modelindex) + return qfalse; + VectorClear(angles); + entitynum = BotModelMinsMaxs(modelindex, ET_BREAKABLE, 0, mins, maxs); + //breakable origin + VectorAdd(mins, maxs, origin); + VectorScale(origin, 0.5, origin); + VectorCopy(origin, activategoal->target); + activategoal->shoot = qtrue; + activategoal->goal.entitynum = entitynum; //NOTE: this is the entity number of the shootable door + activategoal->goal.number = 0; + activategoal->goal.flags = 0; + VectorCopy(bs->origin, activategoal->goal.origin); + activategoal->goal.areanum = bs->areanum; + VectorSet(activategoal->goal.mins, -8, -8, -8); + VectorSet(activategoal->goal.maxs, 8, 8, 8); + return qtrue; +} + +/* +==================================== +BotFuncDoorRotatingActivateGoal + +Added by Makro +==================================== +*/ +int BotFuncDoorRotatingActivateGoal(bot_state_t *bs, int bspent, bot_activategoal_t *activategoal) { + int modelindex, entitynum; + char model[MAX_INFO_STRING]; + vec3_t mins, maxs, origin, angles; + + trap_AAS_ValueForBSPEpairKey(bspent, "model", model, sizeof(model)); + if (!*model) + return qfalse; + modelindex = atoi(model+1); + if (!modelindex) + return qfalse; + VectorClear(angles); + entitynum = BotModelMinsMaxs(modelindex, ET_MOVER, 0, mins, maxs); + //door origin + VectorAdd(mins, maxs, origin); + VectorScale(origin, 0.5, origin); + activategoal->goal.entitynum = entitynum; + VectorCopy(origin, activategoal->target); + activategoal->openDoor = qtrue; + activategoal->goal.number = 0; + activategoal->goal.flags = 0; + VectorCopy(bs->origin, activategoal->goal.origin); + activategoal->goal.areanum = bs->areanum; + VectorSet(activategoal->goal.mins, -8, -8, -8); + VectorSet(activategoal->goal.maxs, 8, 8, 8); + return qtrue; +} + /* ================== BotTriggerMultipleGoal @@ -4238,6 +4404,13 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ modelindex = atoi(model+1); if (modelindex) { VectorClear(angles); + //Makro - this should help + Cmd_OpenDoor( &g_entities[bs->entitynum] ); + /* + if (bot_developer.integer == 2) { + G_Printf("^5BOT CODE: ^7Blocked by a sliding door\n"); + } + */ BotModelMinsMaxs(modelindex, ET_MOVER, 0, absmins, absmaxs); // numareas = trap_AAS_BBoxAreas(absmins, absmaxs, areas, MAX_ACTIVATEAREAS*2); @@ -4270,7 +4443,36 @@ int BotGetActivateGoal(bot_state_t *bs, int entitynum, bot_activategoal_t *activ } //if it is some glass if (!strcmp(classname, "func_breakable")) { - return ent; + BotFuncBreakableGoal(bs, ent, activategoal); + //disable all areas the blocking entity is in + BotEnableActivateGoalAreas( activategoal, qfalse ); + return ent; + } + //Makro - checking for rotating doors + if ( !strcmp(classname, "func_door_rotating") ) { + /* + if (bot_developer.integer == 2) { + G_Printf("^5BOT CODE: ^7Blocked by a rotating door\n"); + } + */ + /*if ( trap_AAS_AreaReachability(bs->areanum) ) { + // disable all areas the blocking entity is in + BotEnableActivateGoalAreas( activategoal, qfalse ); + } + */ + //if door is moving, wait till it stops + if ( g_entities[entitynum].moverState == ROTATOR_1TO2 || g_entities[entitynum].moverState == ROTATOR_2TO1 || (g_entities[entitynum].targetname) ) { + BotMoveTowardsEnt(bs, entinfo.origin, -80); + if ( g_entities[entitynum].targetname = NULL ) { + return 0; + } + } else { + //Cmd_OpenDoor( &g_entities[bs->entitynum] ); + BotFuncDoorRotatingActivateGoal(bs, ent, activategoal); + //disable all areas the blocking entity is in + BotEnableActivateGoalAreas( activategoal, qfalse ); + return ent; + } } // if the bot is blocked by or standing on top of a button if (!strcmp(classname, "func_button")) { diff --git a/reaction/game/ai_main.c b/reaction/game/ai_main.c index 259c7c0d..9477a2c4 100644 --- a/reaction/game/ai_main.c +++ b/reaction/game/ai_main.c @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.6 2002/03/31 19:16:55 makro +// Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables +// // Revision 1.5 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // @@ -1692,3 +1695,4 @@ int BotAIShutdown( int restart ) { return qtrue; } + diff --git a/reaction/game/ai_main.h b/reaction/game/ai_main.h index 9c04040e..6b15bc99 100644 --- a/reaction/game/ai_main.h +++ b/reaction/game/ai_main.h @@ -5,6 +5,9 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.5 2002/03/31 19:16:55 makro +// Bandaging, reloading, opening rotating doors (still needs a lot of), shooting breakables +// // Revision 1.4 2002/01/11 19:48:29 jbravo // Formatted the source in non DOS format. // @@ -108,6 +111,7 @@ typedef struct bot_activategoal_s float start_time; //time starting to activate something float justused_time; //time the goal was used int shoot; //true if bot has to shoot to activate + int openDoor; //Makro - true if bot has to open a door int weapon; //weapon to be used for activation vec3_t target; //target to shoot at to activate something vec3_t origin; //origin of the blocking entity to activate