From df1414b99bf3692d9c55d10d8fb2841f5fa50c32 Mon Sep 17 00:00:00 2001 From: Andrei Drexler Date: Wed, 1 May 2002 05:32:46 +0000 Subject: [PATCH] Bots reload akimbos/handcannons. Also, they can decide whether or not an item in the ground is better than theirs --- reaction/game/ai_dmnet.c | 162 ++++++++++++++++++++++++++++++++++++--- reaction/game/ai_dmq3.c | 39 ++++++++-- reaction/game/game.plg | 105 +++++++++++++++++++------ 3 files changed, 266 insertions(+), 40 deletions(-) diff --git a/reaction/game/ai_dmnet.c b/reaction/game/ai_dmnet.c index 1092dd72..cc854bc9 100644 --- a/reaction/game/ai_dmnet.c +++ b/reaction/game/ai_dmnet.c @@ -5,6 +5,10 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.17 2002/05/01 05:32:45 makro +// Bots reload akimbos/handcannons. Also, they can decide whether +// or not an item in the ground is better than theirs +// // Revision 1.16 2002/04/30 11:54:37 makro // Bots rule ! Also, added clips to give all. Maybe some other things // @@ -88,7 +92,12 @@ //Makro - to get rid of the warnings void Cmd_Bandage (gentity_t *ent); +void Cmd_DropItem_f(gentity_t *ent); gentity_t *SelectRandomDeathmatchSpawnPoint( void ); + +int FindHumanTeamLeader(bot_state_t *bs); +void BotVoiceChat_FollowMe(bot_state_t *bs, int client, int mode); + //From ai_dmq3.c void VectorTargetDist(vec3_t src, vec3_t dest, int dist, vec3_t final); void BotAttack(bot_state_t *bs); @@ -104,6 +113,15 @@ char nodeswitch[MAX_NODESWITCHES+1][144]; #define LOOKAHEAD_DISTANCE 300 +/* +================== +BotRespawn + +Added by Makro +Replaces trap_EA_respawn +================== +*/ + /* ================== BotResetNodeSwitches @@ -257,6 +275,130 @@ int BotNearbyGoal(bot_state_t *bs, int tfl, bot_goal_t *ltg, float range) { return ret; } +/* +================== +RQ3_Bot_SpecialWeapon + +Added by Makro +================== +*/ +int RQ3_Bot_SpecialWeapon(bot_state_t *bs) { + return WP_NONE; +} + +/* +==================================== +RQ3_Bot_ComboScore + +Added by Makro +Note - lots of factors should be +considered here; they aren't :/ +==================================== +*/ +int RQ3_Bot_ComboScore(int weapon, holdable_t item) +{ + if (item != HI_KEVLAR || item != HI_LASER || item != HI_BANDOLIER || + item != HI_SLIPPERS || item != HI_SILENCER) + return 0; + switch (weapon) { + //Shotgun + case WP_M3: + switch (item) { + case HI_KEVLAR: return 100; + case HI_LASER: return 30; + case HI_BANDOLIER: return 80; + case HI_SILENCER: return 30; + case HI_SLIPPERS: return 80; + } + break; + //MP5 + case WP_MP5: + switch (item) { + case HI_KEVLAR: return 90; + case HI_LASER: return 100; + case HI_BANDOLIER: return 70; + case HI_SILENCER: return 80; + case HI_SLIPPERS: return 40; + } + break; + //HANDCANNON + case WP_HANDCANNON: + switch (item) { + case HI_KEVLAR: return 90; + case HI_LASER: return 30; + case HI_BANDOLIER: return 90; + case HI_SILENCER: return 30; + case HI_SLIPPERS: return 90; + } + break; + //SSG3000 + case WP_SSG3000: + switch (item) { + case HI_KEVLAR: return 100; + case HI_LASER: return 40; + case HI_BANDOLIER: return 80; + case HI_SILENCER: return 90; + case HI_SLIPPERS: return 40; + } + break; + //M4 + case WP_M4: + switch (item) { + case HI_KEVLAR: return 100; + case HI_LASER: return 90; + case HI_BANDOLIER: return 80; + case HI_SILENCER: return 30; + case HI_SLIPPERS: return 40; + } + break; + } + return 0; +} + +/* +================== +RQ3_Bot_NeedToDropStuff + +Added by Makro +================== +*/ +qboolean RQ3_Bot_NeedToDropStuff(bot_state_t *bs, bot_goal_t *goal) { + //if the bot doesn't have an item or it didn't reach one + if (!g_entities[goal->entitynum].item) + return qfalse; + if ( bs->cur_ps.stats[STAT_HOLDABLE_ITEM] < 1 || bs->cur_ps.stats[STAT_HOLDABLE_ITEM] >= bg_numItems || g_entities[goal->entitynum].item->giType != IT_HOLDABLE) + return qfalse; + else + { + holdable_t oldItem = bg_itemlist[bs->cur_ps.stats[STAT_HOLDABLE_ITEM]].giTag; + holdable_t newItem = g_entities[goal->entitynum].item->giTag; + int i, oldScore, newScore; + //if the two items are identical + if (oldItem == newItem) return qfalse; + + newScore = oldScore = 0; + //check all the weapons + for (i = 0; i < MAX_WEAPONS; i++) { + //if the bot has the weapon + if ( bs->cur_ps.stats[STAT_WEAPONS] & (1 << i) ) { + //get the score for it + oldScore += RQ3_Bot_ComboScore(i, oldItem); + newScore += RQ3_Bot_ComboScore(i, newItem); + } + } + + //FIXME - special code is needed for the bandolier, since throwing it away + //will also throw one of the weapons + if (newScore > oldScore) { + Cmd_DropItem_f( &g_entities[bs->entitynum] ); + return qtrue; + } + + + } + + return qfalse; +} /* ================== BotReachedGoal @@ -267,7 +409,9 @@ int BotReachedGoal(bot_state_t *bs, bot_goal_t *goal) { //if touching the goal if (trap_BotTouchingGoal(bs->origin, goal)) { if (!(goal->flags & GFL_DROPPED)) { + //Makro - check if the bot picked up a better weapon or item trap_BotSetAvoidGoalTime(bs->gs, goal->number, -1); + RQ3_Bot_NeedToDropStuff( bs , goal ); } /* if (g_entities[goal->entitynum].classname) { @@ -1322,8 +1466,13 @@ void AIEnter_Respawn(bot_state_t *bs, char *s) { bs->radioresponse_count = 0; //set respawn state - bs->standfindenemy_time = FloatTime() + 5; - bs->stand_time = FloatTime() + 10; + if (gametype != GT_TEAMPLAY) { + bs->standfindenemy_time = FloatTime() + 5; + bs->stand_time = FloatTime() + 10; + } else { + bs->standfindenemy_time = FloatTime() + 1; + bs->check_time = bs->stand_time = FloatTime() + 2; + } bs->respawn_wait = qfalse; bs->ainode = AINode_Respawn; } @@ -1341,15 +1490,6 @@ int AINode_Respawn(bot_state_t *bs) { } else { trap_EA_Respawn(bs->client); - //Makro - maybe this will help in teamplay - if (gametype == GT_TEAMPLAY) { - gentity_t *spot = SelectRandomDeathmatchSpawnPoint(); - aas_entityinfo_t entinfo; - - BotEntityInfo(spot-g_entities, &entinfo); - BotMoveTo(bs, entinfo.origin); - //BotRoamGoal(bs, entinfo.origin); - } } } else if (bs->respawn_time < FloatTime()) { diff --git a/reaction/game/ai_dmq3.c b/reaction/game/ai_dmq3.c index 22d778d5..1f95994e 100644 --- a/reaction/game/ai_dmq3.c +++ b/reaction/game/ai_dmq3.c @@ -5,6 +5,10 @@ //----------------------------------------------------------------------------- // // $Log$ +// Revision 1.21 2002/05/01 05:32:45 makro +// Bots reload akimbos/handcannons. Also, they can decide whether +// or not an item in the ground is better than theirs +// // Revision 1.20 2002/04/30 12:14:53 makro // Fixed a small warning // @@ -165,22 +169,26 @@ void VectorTargetDist(vec3_t src, vec3_t dest, int dist, vec3_t final) { /* ================== -RQ3_Bot_ClipForWeapon +RQ3_Bot_ClipsForWeapon Added by Makro ================== */ -int RQ3_Bot_ClipForWeapon( bot_state_t *bs, int weapon ) +int RQ3_Bot_ClipsForWeapon( bot_state_t *bs, int weapon ) { switch (weapon) { case WP_PISTOL: - case WP_AKIMBO: return bs->inventory[INVENTORY_PISTOLCLIP]; break; + case WP_AKIMBO: + return bs->inventory[INVENTORY_AKIMBOCLIP]; + break; case WP_M3: - case WP_HANDCANNON: return bs->inventory[INVENTORY_M3CLIP]; break; + case WP_HANDCANNON: + return bs->inventory[INVENTORY_HANDCANNONCLIP]; + break; case WP_MP5: return bs->inventory[INVENTORY_MP5CLIP]; break; @@ -197,6 +205,25 @@ int RQ3_Bot_ClipForWeapon( bot_state_t *bs, int weapon ) } +/* +================== +RQ3_Bot_CanReload + +Added by Makro +================== +*/ +qboolean RQ3_Bot_CanReload( bot_state_t *bs, int weapon ) { + int clips = RQ3_Bot_ClipsForWeapon(bs, weapon); + + //If no clips or not a valid weapon + if ( !clips || !(bs->cur_ps.stats[STAT_WEAPONS] & (1 << weapon)) ) return qfalse; + + if (weapon == WP_AKIMBO || weapon == WP_HANDCANNON) + return (clips >= 2); + else + return qtrue; +} + /* ================== BotAttack @@ -212,8 +239,8 @@ void BotAttack(bot_state_t *bs) { //If the gun is empty if ( (bs->cur_ps.ammo[bs->cur_ps.weapon]) == 0 ) { - //If bot has extra clips, reload - if ( RQ3_Bot_ClipForWeapon(bs, bs->cur_ps.weapon) >= 1 ) { + //If the bot has extra ammo + if ( RQ3_Bot_CanReload(bs, bs->cur_ps.weapon) >= 1 ) { //Cmd_Reload( &g_entities[bs->entitynum] ); trap_EA_Action(bs->client, ACTION_AFFIRMATIVE); } diff --git a/reaction/game/game.plg b/reaction/game/game.plg index 17f46083..a36a8c88 100644 --- a/reaction/game/game.plg +++ b/reaction/game/game.plg @@ -3,25 +3,54 @@
 

Build Log

---------------------Configuration: cgame - Win32 Release-------------------- -

-

Command Lines

- - - -

Results

-cgamex86.dll - 0 error(s), 0 warning(s) -

--------------------Configuration: game - Win32 Release--------------------

Command Lines

-Creating temporary file "D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1D0F.tmp" with contents +Creating temporary file "D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1E1E.tmp" with contents [ /nologo /G6 /ML /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR"c:\reactionoutput/" /Fp"c:\reactionoutput/game.pch" /YX /Fo"c:\reactionoutput/" /Fd"c:\reactionoutput/" /FD /c +"C:\Games\Quake3\rq3source\reaction\game\ai_chat.c" +"C:\Games\Quake3\rq3source\reaction\game\ai_cmd.c" +"C:\Games\Quake3\rq3source\reaction\game\ai_dmnet.c" "C:\Games\Quake3\rq3source\reaction\game\ai_dmq3.c" +"C:\Games\Quake3\rq3source\reaction\game\ai_main.c" +"C:\Games\Quake3\rq3source\reaction\game\ai_team.c" +"C:\Games\Quake3\rq3source\reaction\game\ai_vcmd.c" +"C:\Games\Quake3\rq3source\reaction\game\bg_misc.c" +"C:\Games\Quake3\rq3source\reaction\game\bg_pmove.c" +"C:\Games\Quake3\rq3source\reaction\game\bg_slidemove.c" +"C:\Games\Quake3\rq3source\reaction\game\g_active.c" +"C:\Games\Quake3\rq3source\reaction\game\g_arenas.c" +"C:\Games\Quake3\rq3source\reaction\game\g_bot.c" +"C:\Games\Quake3\rq3source\reaction\game\g_client.c" +"C:\Games\Quake3\rq3source\reaction\game\g_cmds.c" +"C:\Games\Quake3\rq3source\reaction\game\g_combat.c" +"C:\Games\Quake3\rq3source\reaction\game\g_fileio.c" +"C:\Games\Quake3\rq3source\reaction\game\g_items.c" +"C:\Games\Quake3\rq3source\reaction\game\g_main.c" +"C:\Games\Quake3\rq3source\reaction\game\g_matchmode.c" +"C:\Games\Quake3\rq3source\reaction\game\g_mem.c" +"C:\Games\Quake3\rq3source\reaction\game\g_misc.c" +"C:\Games\Quake3\rq3source\reaction\game\g_missile.c" +"C:\Games\Quake3\rq3source\reaction\game\g_mover.c" +"C:\Games\Quake3\rq3source\reaction\game\g_session.c" +"C:\Games\Quake3\rq3source\reaction\game\g_spawn.c" +"C:\Games\Quake3\rq3source\reaction\game\g_svcmds.c" +"C:\Games\Quake3\rq3source\reaction\game\g_syscalls.c" +"C:\Games\Quake3\rq3source\reaction\game\g_target.c" +"C:\Games\Quake3\rq3source\reaction\game\g_team.c" +"C:\Games\Quake3\rq3source\reaction\game\g_teamplay.c" +"C:\Games\Quake3\rq3source\reaction\game\g_trigger.c" +"C:\Games\Quake3\rq3source\reaction\game\g_utils.c" +"C:\Games\Quake3\rq3source\reaction\game\g_weapon.c" +"C:\Games\Quake3\rq3source\reaction\game\q_math.c" +"C:\Games\Quake3\rq3source\reaction\game\q_shared.c" +"C:\Games\Quake3\rq3source\reaction\game\rxn_game.c" +"C:\Games\Quake3\rq3source\reaction\game\zcam.c" +"C:\Games\Quake3\rq3source\reaction\game\zcam_target.c" ] -Creating command line "cl.exe @D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1D0F.tmp" -Creating temporary file "D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1D10.tmp" with contents +Creating command line "cl.exe @D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1E1E.tmp" +Creating temporary file "D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1E1F.tmp" with contents [ kernel32.lib user32.lib winmm.lib /nologo /base:"0x20000000" /subsystem:windows /dll /incremental:no /pdb:"c:\reactionoutput/qagamex86.pdb" /map:"c:\reactionoutput/qagamex86.map" /machine:I386 /def:".\game.def" /out:"..\Release/qagamex86.dll" /implib:"c:\reactionoutput/qagamex86.lib" \reactionoutput\ai_chat.obj @@ -64,26 +93,56 @@ kernel32.lib user32.lib winmm.lib /nologo /base:"0x20000000" /subsystem:windows \reactionoutput\zcam.obj \reactionoutput\zcam_target.obj ] -Creating command line "link.exe @D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1D10.tmp" +Creating command line "link.exe @D:\DOCUME~1\Andrei\LOCALS~1\Temp\RSP1E1F.tmp"

Output Window

Compiling... +ai_chat.c +ai_cmd.c +ai_dmnet.c ai_dmq3.c +ai_main.c +ai_team.c +ai_vcmd.c +bg_misc.c +bg_pmove.c +bg_slidemove.c +g_active.c +g_arenas.c +g_bot.c +g_client.c +g_cmds.c +g_combat.c +g_fileio.c +g_items.c +g_main.c +g_matchmode.c +g_mem.c +g_misc.c +g_missile.c +g_mover.c +g_session.c +g_spawn.c +g_svcmds.c +g_syscalls.c +g_target.c +g_team.c +g_teamplay.c +g_trigger.c +g_utils.c +g_weapon.c +q_math.c +C:\Games\Quake3\rq3source\reaction\game\g_weapon.c(2576) : warning C4701: local variable 'tr' may be used without having been initialized +q_shared.c +rxn_game.c +zcam.c +zcam_target.c Linking... Creating library c:\reactionoutput/qagamex86.lib and object c:\reactionoutput/qagamex86.exp

Results

-qagamex86.dll - 0 error(s), 0 warning(s) -

---------------------Configuration: ui - Win32 Release TA-------------------- -

-

Command Lines

- - - -

Results

-uix86.dll - 0 error(s), 0 warning(s) +qagamex86.dll - 0 error(s), 1 warning(s)