Bots reload akimbos/handcannons. Also, they can decide whether

or not an item in the ground is better than theirs
This commit is contained in:
Andrei Drexler 2002-05-01 05:32:46 +00:00
parent c79a22f81d
commit df1414b99b
3 changed files with 266 additions and 40 deletions

View file

@ -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()) {

View file

@ -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);
}

View file

@ -3,25 +3,54 @@
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: cgame - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
cgamex86.dll - 0 error(s), 0 warning(s)
<h3>
--------------------Configuration: game - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
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"
<h3>Output Window</h3>
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
<h3>Results</h3>
qagamex86.dll - 0 error(s), 0 warning(s)
<h3>
--------------------Configuration: ui - Win32 Release TA--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
uix86.dll - 0 error(s), 0 warning(s)
qagamex86.dll - 0 error(s), 1 warning(s)
</pre>
</body>
</html>