Skip to content

Commit

Permalink
v1.40beta3, lots of fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jkivilin committed Dec 3, 2011
1 parent bae365b commit 7fb39fd
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 150 deletions.
5 changes: 5 additions & 0 deletions addons/jk_botti/jk_botti_readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ CPU intensive operation this can only be done on map change.
--------------------
1.40:
* Add support for Opposing Force Deathmatch.
* Bugfixes to goal selection and weapon selection.
* Bot now understands that it can get more ammo by picking up same weapon
again.
* Bot avoids combat if it doesn't have good weapon or doesn't have enough
health.
* Changed optimization flags from '-O3 -funroll-loops' to '-O2'.
* Output warning message when model given for bot creation is replaced by
team-balance code.
Expand Down
106 changes: 86 additions & 20 deletions bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ qboolean b_observer_mode = FALSE;
qboolean b_botdontshoot = FALSE;


//
qboolean BotLowHealth( bot_t &pBot )
{
return(pBot.pEdict->v.health + 0.8f * pBot.pEdict->v.armorvalue < VALVE_MAX_NORMAL_HEALTH * 0.5f);
}


//
void BotKick(bot_t &pBot)
{
Expand Down Expand Up @@ -133,6 +140,11 @@ void BotSpawnInit( bot_t &pBot )
pBot.b_on_ladder = 0;
pBot.b_in_water = 0;
pBot.b_ducking = 0;
pBot.b_has_enough_ammo_for_good_weapon = 0;

pBot.f_last_time_attacked = 0;

pBot.secondary_state = 0;

pBot.blinded_time = 0.0;
pBot.f_max_speed = CVAR_GET_FLOAT("sv_maxspeed");
Expand Down Expand Up @@ -2151,44 +2163,98 @@ void BotThink( bot_t &pBot )
BotLookForDrop( pBot );
}

// reset pause time if being attacked
if((gpGlobals->time - pBot.f_last_time_attacked) < 1.0f)
pBot.f_pause_time = 0;

// turn towards ideal_pitch by pitch_speed degrees
pitch_degrees = BotChangePitch( pBot, pEdict->v.pitch_speed );

// turn towards ideal_yaw by yaw_speed degrees
yaw_degrees = BotChangeYaw( pBot, pEdict->v.yaw_speed );

// get enemy
pBot.pBotEnemy = (b_botdontshoot == 0) ? BotFindEnemy( pBot ) : NULL; // clear enemy pointer (no ememy for you!)

if(pBot.pBotEnemy == NULL)
// Only need to check ammo, since ammo check for weapons includes weapons ;)
pBot.b_has_enough_ammo_for_good_weapon = !BotAllWeaponsRunningOutOfAmmo(pBot, TRUE);
if((pBot.b_has_enough_ammo_for_good_weapon && !BotLowHealth(pBot)) || pBot.f_last_time_attacked < gpGlobals->time + 3.0f)
{
// try find sound enemy (something that bot will track)
BotFindSoundEnemy(pBot);

// if has zoom weapon and zooming click off zoom
if(pBot.current_weapon_index != -1 &&
weapon_select[pBot.current_weapon_index].type == WEAPON_FIRE_ZOOM &&
pEdict->v.fov != 0 &&
!(pEdict->v.button & (IN_ATTACK|IN_ATTACK2)))
// get enemy
pBot.pBotEnemy = (b_botdontshoot == 0) ? BotFindEnemy( pBot ) : NULL; // clear enemy pointer (no ememy for you!)

if(pBot.pBotEnemy == NULL)
{
pEdict->v.button |= IN_ATTACK2;
// try find sound enemy (something that bot will track)
BotFindSoundEnemy(pBot);

// if has zoom weapon and zooming, click off zoom
if(pBot.current_weapon_index != -1 &&
(weapon_select[pBot.current_weapon_index].type & WEAPON_FIRE_ZOOM) == WEAPON_FIRE_ZOOM &&
pEdict->v.fov != 0 &&
!(pEdict->v.button & (IN_ATTACK|IN_ATTACK2)))
{
pEdict->v.button |= IN_ATTACK2;
}

// if has aim spot weapon and have spot on, click spot off
if(pBot.current_weapon_index != -1 &&
(weapon_select[pBot.current_weapon_index].type & WEAPON_AIMSPOT) == WEAPON_AIMSPOT &&
pBot.secondary_state != 0 &&
!(pEdict->v.button & (IN_ATTACK|IN_ATTACK2)))
{
pEdict->v.button |= IN_ATTACK2;
pBot.secondary_state = 0;
}
}
}

// does an enemy exist?
qboolean DidShootAtEnemy = FALSE;

// does have an enemy?
if (pBot.pBotEnemy != NULL)
{
BotShootAtEnemy( pBot ); // shoot at the enemy
if(BotWeaponCanAttack(pBot, FALSE) && (!BotLowHealth(pBot) || pBot.f_last_time_attacked < gpGlobals->time + 3.0f))
{
BotShootAtEnemy( pBot ); // shoot at the enemy
DidShootAtEnemy = (pBot.pBotEnemy != NULL);

pBot.f_pause_time = 0; // dont't pause if enemy exists
pBot.f_pause_time = 0; // dont't pause if enemy exists

// check if bot is on a ladder
if (pBot.b_on_ladder)
// check if bot is on a ladder
if (pBot.b_on_ladder)
{
// bot is stuck on a ladder... jump off ladder
pEdict->v.button |= IN_JUMP;
}
}
else
{
// bot is stuck on a ladder... jump off ladder
pEdict->v.button |= IN_JUMP;
//
pBot.f_pause_time = 0;

// need waypoint away from enemy?
edict_t *pAvoidEnemy = pBot.pBotEnemy;

// don't have an enemy anymore so null out the pointer...
pBot.pBotEnemy = NULL;

int enemy_waypoint = WaypointFindNearest(pAvoidEnemy, REACHABLE_RANGE);
int self_waypoint = WaypointFindNearest(pEdict, REACHABLE_RANGE);

if(enemy_waypoint != -1 && self_waypoint != -1)
{
int runaway_waypoint = WaypointFindRunawayPath(self_waypoint, enemy_waypoint);

pBot.curr_waypoint_index = -1; // forget about this waypoint
pBot.waypoint_goal = runaway_waypoint;
pBot.f_waypoint_goal_time = gpGlobals->time + 5.0f;
}
}
}

if(DidShootAtEnemy)
{
// do nothing
}
else if (pBot.f_pause_time > gpGlobals->time) // is bot "paused"?
{
// you could make the bot look left then right, or look up
Expand Down
5 changes: 5 additions & 0 deletions bot.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ typedef struct
qboolean b_on_ladder;
qboolean b_in_water;
qboolean b_ducking;
qboolean b_has_enough_ammo_for_good_weapon;

int secondary_state;

// things from pev in CBasePlayer...
float idle_angle;
Expand Down Expand Up @@ -226,6 +229,8 @@ typedef struct
float f_bot_see_enemy_time;
float f_bot_find_enemy_time;
edict_t *pFindSoundEnt;

float f_last_time_attacked;

edict_t *killer_edict;
qboolean b_bot_say;
Expand Down
21 changes: 12 additions & 9 deletions bot_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,19 @@ void BotClient_Valve_CurrentWeapon(void *p, int bot_index)
{
if (iState == 1)
{
bots[bot_index].current_weapon.iId = iId;
bots[bot_index].current_weapon.iClip = iClip;

// update the ammo counts for this weapon...
bots[bot_index].current_weapon.iAmmo1 =
bots[bot_index].m_rgAmmo[weapon_defs[iId].iAmmo1];
bots[bot_index].current_weapon.iAmmo2 =
bots[bot_index].m_rgAmmo[weapon_defs[iId].iAmmo2];

bot_weapon_select_t *pSelect = NULL;
bot_fire_delay_t *pDelay = NULL;
int found = 0;

bots[bot_index].current_weapon.iId = iId;
bots[bot_index].current_weapon.iClip = iClip;

bots[bot_index].secondary_state = 0;

// update the ammo counts for this weapon...
bots[bot_index].current_weapon.iAmmo1 = bots[bot_index].m_rgAmmo[weapon_defs[iId].iAmmo1];
bots[bot_index].current_weapon.iAmmo2 = bots[bot_index].m_rgAmmo[weapon_defs[iId].iAmmo2];

pSelect = &weapon_select[0];
pDelay = &fire_delay[0];

Expand All @@ -145,6 +145,7 @@ void BotClient_Valve_CurrentWeapon(void *p, int bot_index)
if(iId == pSelect[i].iId)
{
bots[bot_index].current_opt_distance = pSelect[i].opt_distance;
bots[bot_index].current_weapon_index = i;
found = 1;
break;
}
Expand Down Expand Up @@ -340,6 +341,8 @@ void BotClient_Valve_Damage(void *p, int bot_index)
if (damage_bits & IGNORE_DAMAGE)
return;

bots[bot_index].f_last_time_attacked = gpGlobals->time;

// if the bot doesn't have an enemy and someone is shooting at it then
// turn in the attacker's direction...
if (bots[bot_index].pBotEnemy == NULL || !FPredictedVisible(bots[bot_index]))
Expand Down
55 changes: 42 additions & 13 deletions bot_combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,22 @@ void BotAimPost( bot_t &pBot )
pBot.f_special_shoot_angle = 0.0;
}

// special case for m249
if(pBot.current_weapon.iId == GEARBOX_WEAPON_M249)
{
if((pBot.pEdict->v.flags & FL_DUCKING) == FL_DUCKING)
pBot.f_recoil /= 4;
}
// special case for eagle
else if(pBot.current_weapon.iId == GEARBOX_WEAPON_EAGLE)
{
if(pBot.secondary_state != 0)
pBot.f_recoil /= 15;
}

// add any recoil left to punch angle now
pBot.pEdict->v.punchangle.x += pBot.f_recoil;

pBot.f_recoil = 0;
}

Expand Down Expand Up @@ -1111,14 +1125,14 @@ qboolean CheckWeaponFireConditions(bot_t & pBot, const bot_weapon_select_t &sele
edict_t *pEdict = pBot.pEdict;

//
if (select.type == WEAPON_MELEE)
if ((select.type & WEAPON_MELEE) == WEAPON_MELEE)
{
// check if bot needs to duck down to hit enemy...
if (fabs(pBot.pBotEnemy->v.origin.z - pEdict->v.origin.z) > 16 &&
(pBot.pBotEnemy->v.origin - pEdict->v.origin).Length() < 64)
pBot.f_duck_time = gpGlobals->time + 1.0;
}
else if(select.type == WEAPON_THROW && !HaveRoomForThrow(pBot))
else if((select.type & WEAPON_THROW) == WEAPON_THROW && !HaveRoomForThrow(pBot))
{
return FALSE;
}
Expand All @@ -1143,10 +1157,6 @@ qboolean CheckWeaponFireConditions(bot_t & pBot, const bot_weapon_select_t &sele
if(!ok)
use_primary = !(use_secondary = FALSE);
}

// use secondary once to enable zoom
if(use_primary && (select.type & WEAPON_FIRE_ZOOM) == WEAPON_FIRE_ZOOM && pEdict->v.fov == 0)
use_primary = !(use_secondary = TRUE);

return TRUE;
}
Expand All @@ -1167,7 +1177,24 @@ qboolean BotFireSelectedWeapon(bot_t & pBot, const bot_weapon_select_t &select,
// Check if weapon can be fired and setup bot for firing this weapon
if(!CheckWeaponFireConditions(pBot, select, use_primary, use_secondary))
return FALSE;

// use secondary once to enable zoom
if(use_primary && (select.type & WEAPON_FIRE_ZOOM) == WEAPON_FIRE_ZOOM && pEdict->v.fov == 0)
use_primary = !(use_secondary = TRUE);

// use secondary once to enable aimspot
if(use_primary && (select.type & WEAPON_AIMSPOT) == WEAPON_AIMSPOT && pBot.secondary_state == 0)
{
use_primary = !(use_secondary = TRUE);
pBot.secondary_state = 1;
}

//duck for better aim
if((select.type & WEAPON_AIMDUCK) == WEAPON_AIMDUCK)
{
pBot.f_duck_time = gpGlobals->time + 0.25f;
}

if (use_primary)
{
pEdict->v.button |= IN_ATTACK; // use primary attack
Expand Down Expand Up @@ -1444,6 +1471,8 @@ qboolean BotFireWeapon(const Vector & v_enemy, bot_t &pBot, int weapon_choice)
if(pBot.f_weaponchange_time >= gpGlobals->time && pBot.current_weapon_index >= 0 && weapon_choice == 0)
return FALSE;

pBot.current_weapon_index = -1; // forget current weapon

//
// 1. check which weapons are available and with which percents
//
Expand All @@ -1454,16 +1483,12 @@ qboolean BotFireWeapon(const Vector & v_enemy, bot_t &pBot, int weapon_choice)
select_index = -1;
while (pSelect[++select_index].iId)
{
// skip currently selected weapon.. it wasn't good enough earlier so it isn't now either
if(pBot.current_weapon_index >= 0 && pBot.current_weapon_index == select_index)
{
pBot.current_weapon_index = -1; // forget current weapon
continue;
}

// Check if we can use this weapon
if(!(weapon_choice == pSelect[select_index].iId || weapon_choice == 0))
continue;

if(pSelect[select_index].avoid_this_gun)
continue;

if(!IsValidWeaponChoose(pBot, pSelect[select_index]) ||
!BotCanUseWeapon(pBot, pSelect[select_index]) ||
Expand Down Expand Up @@ -1494,6 +1519,8 @@ qboolean BotFireWeapon(const Vector & v_enemy, bot_t &pBot, int weapon_choice)
next->percent_end = total_percent + pSelect[select_index].use_percent;
next->select_index = select_index;

//UTIL_ConsolePrintf("add: %d .. %d [%s]", total_percent, total_percent + pSelect[select_index].use_percent, pSelect[select_index].weapon_name);

total_percent += pSelect[select_index].use_percent;

// add to end of linked list
Expand Down Expand Up @@ -1535,6 +1562,8 @@ qboolean BotFireWeapon(const Vector & v_enemy, bot_t &pBot, int weapon_choice)
use_secondary = next->use_secondary;
select_index = next->select_index;

//UTIL_ConsolePrintf("choose: %d [%s]", choose, pSelect[select_index].weapon_name);

if(!TrySelectWeapon(pBot, select_index, pSelect[select_index], pDelay[select_index]))
return FALSE; //error

Expand Down
2 changes: 2 additions & 0 deletions bot_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ qboolean BotEdgeForward( bot_t &pBot, const Vector &v_move_dir );
qboolean BotEdgeRight( bot_t &pBot, const Vector &v_move_dir );
qboolean BotEdgeLeft( bot_t &pBot, const Vector &v_move_dir );

qboolean BotLowHealth( bot_t &pBot );
void BotResetReactionTime(bot_t &pBot);
void BotKick(bot_t &pBot);
void BotCheckTeamplay(void);
edict_t *BotFindEnemy( bot_t &pBot );
Expand Down
Loading

0 comments on commit 7fb39fd

Please sign in to comment.