get rid of goto statements

This commit is contained in:
jeefo 2016-04-04 10:51:52 +03:00
commit de1e9b68e2
4 changed files with 152 additions and 122 deletions

View file

@ -122,7 +122,8 @@ enum ClientFlags
{ {
CF_USED = (1 << 0), CF_USED = (1 << 0),
CF_ALIVE = (1 << 1), CF_ALIVE = (1 << 1),
CF_ADMIN = (1 << 2) CF_ADMIN = (1 << 2),
CF_CHATTER = (1 << 3)
}; };
// radio messages // radio messages
@ -870,6 +871,7 @@ private:
bool CanDuckUnder (const Vector &normal); bool CanDuckUnder (const Vector &normal);
bool CanJumpUp (const Vector &normal); bool CanJumpUp (const Vector &normal);
bool FinishCanJumpUp (const Vector &normal);
bool CantMoveForward (const Vector &normal, TraceResult *tr); bool CantMoveForward (const Vector &normal, TraceResult *tr);
// split RunTask into RunTask_* functions // split RunTask into RunTask_* functions
@ -937,6 +939,7 @@ private:
int FindCoverWaypoint (float maxDistance); int FindCoverWaypoint (float maxDistance);
int FindDefendWaypoint (const Vector &origin); int FindDefendWaypoint (const Vector &origin);
int FindGoal (void); int FindGoal (void);
int FinishFindGoal (int tactic, Array <int> *defensive, Array <int> *offsensive);
void FilterGoals (const Array <int> &goals, int *result); void FilterGoals (const Array <int> &goals, int *result);
void FindItem (void); void FindItem (void);
void CheckTerrain (float movedDistance, const Vector &dirNormal); void CheckTerrain (float movedDistance, const Vector &dirNormal);
@ -1003,6 +1006,7 @@ private:
bool LookupEnemy (void); bool LookupEnemy (void);
bool IsEnemyHiddenByRendering (edict_t *enemy); bool IsEnemyHiddenByRendering (edict_t *enemy);
void FireWeapon (void); void FireWeapon (void);
void FinishWeaponSelection (float distance, int index, int id, int choosen);
void FocusEnemy (void); void FocusEnemy (void);
void SelectBestWeapon (void); void SelectBestWeapon (void);

View file

@ -968,9 +968,19 @@ void Bot::SwitchChatterIcon (bool show)
for (int i = 0; i < engine.MaxClients (); i++) for (int i = 0; i < engine.MaxClients (); i++)
{ {
if (!(g_clients[i].flags & CF_USED) || (g_clients[i].ent->v.flags & FL_FAKECLIENT) || g_clients[i].team != m_team) Client &client = g_clients[i];
if ((show && !(client.flags & CF_CHATTER)) || (!show && (client.flags & CF_CHATTER)))
continue; continue;
if (!(client.flags & CF_USED) || (client.ent->v.flags & FL_FAKECLIENT) || client.team != m_team)
continue;
if (show)
client.flags |= CF_CHATTER;
else
client.flags &= ~CF_CHATTER;
MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_BOTVOICE), NULL, g_clients[i].ent); // begin message MESSAGE_BEGIN (MSG_ONE, engine.FindMessageId (NETMSG_BOTVOICE), NULL, g_clients[i].ent); // begin message
WRITE_BYTE (show); // switch on/off WRITE_BYTE (show); // switch on/off
WRITE_BYTE (GetIndex ()); WRITE_BYTE (GetIndex ());

View file

@ -48,7 +48,7 @@ int Bot::GetNearbyEnemiesNearPosition(const Vector &origin, float radius)
bool Bot::IsEnemyHiddenByRendering (edict_t *enemy) bool Bot::IsEnemyHiddenByRendering (edict_t *enemy)
{ {
if (engine.IsNullEntity (enemy) || !yb_check_enemy_rendering.GetBool ()) if (!yb_check_enemy_rendering.GetBool () || engine.IsNullEntity (enemy))
return false; return false;
entvars_t &v = enemy->v; entvars_t &v = enemy->v;
@ -718,92 +718,10 @@ bool Bot::DoFirePause (float distance)
return false; return false;
} }
void Bot::FireWeapon (void) void Bot::FinishWeaponSelection (float distance, int index, int id, int choosen)
{ {
// this function will return true if weapon was fired, false otherwise
float distance = (m_lookAt - EyePosition ()).GetLength (); // how far away is the enemy?
// if using grenade stop this
if (m_isUsingGrenade)
{
m_shootTime = engine.Time () + 0.1f;
return;
}
// or if friend in line of fire, stop this too but do not update shoot time
if (!engine.IsNullEntity (m_enemy))
{
if (IsFriendInLineOfFire (distance))
{
m_fightStyle = FIGHT_STRAFE;
m_lastFightStyleCheck = engine.Time ();
return;
}
}
WeaponSelect *tab = &g_weaponSelect[0]; WeaponSelect *tab = &g_weaponSelect[0];
edict_t *enemy = m_enemy;
int selectId = WEAPON_KNIFE, selectIndex = 0, chosenWeaponIndex = 0;
int weapons = pev->weapons;
// if jason mode use knife only
if (yb_jasonmode.GetBool ())
goto WeaponSelectEnd;
// use knife if near and good difficulty (l33t dude!)
if (m_difficulty >= 3 && pev->health > 80.0f && !engine.IsNullEntity (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsOnLadder () && !IsGroupOfEnemies (pev->origin))
goto WeaponSelectEnd;
// loop through all the weapons until terminator is found...
while (tab[selectIndex].id)
{
// is the bot carrying this weapon?
if (weapons & (1 << tab[selectIndex].id))
{
// is enough ammo available to fire AND check is better to use pistol in our current situation...
if (m_ammoInClip[tab[selectIndex].id] > 0 && !IsWeaponBadInDistance (selectIndex, distance))
chosenWeaponIndex = selectIndex;
}
selectIndex++;
}
selectId = tab[chosenWeaponIndex].id;
// if no available weapon...
if (chosenWeaponIndex == 0)
{
selectIndex = 0;
// loop through all the weapons until terminator is found...
while (tab[selectIndex].id)
{
int id = tab[selectIndex].id;
// is the bot carrying this weapon?
if (weapons & (1 << id))
{
if ( g_weaponDefs[id].ammo1 != -1 && g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= tab[selectIndex].minPrimaryAmmo)
{
// available ammo found, reload weapon
if (m_reloadState == RELOAD_NONE || m_reloadCheckTime > engine.Time ())
{
m_isReloading = true;
m_reloadState = RELOAD_PRIMARY;
m_reloadCheckTime = engine.Time ();
RadioMessage (Radio_NeedBackup);
}
return;
}
}
selectIndex++;
}
selectId = WEAPON_KNIFE; // no available ammo, use knife!
}
WeaponSelectEnd:
// we want to fire weapon, don't reload now // we want to fire weapon, don't reload now
if (!m_isReloading) if (!m_isReloading)
{ {
@ -812,9 +730,9 @@ WeaponSelectEnd:
} }
// select this weapon if it isn't already selected // select this weapon if it isn't already selected
if (m_currentWeapon != selectId) if (m_currentWeapon != id)
{ {
SelectWeaponByName (g_weaponDefs[selectId].className); SelectWeaponByName (g_weaponDefs[id].className);
// reset burst fire variables // reset burst fire variables
m_firePause = 0.0f; m_firePause = 0.0f;
@ -823,17 +741,17 @@ WeaponSelectEnd:
return; return;
} }
if (tab[chosenWeaponIndex].id != selectId) if (tab[choosen].id != id)
{ {
chosenWeaponIndex = 0; choosen = 0;
// loop through all the weapons until terminator is found... // loop through all the weapons until terminator is found...
while (tab[chosenWeaponIndex].id) while (tab[choosen].id)
{ {
if (tab[chosenWeaponIndex].id == selectId) if (tab[choosen].id == id)
break; break;
chosenWeaponIndex++; choosen++;
} }
} }
@ -844,7 +762,7 @@ WeaponSelectEnd:
{ {
if (distance >= 750.0f && !IsShieldDrawn ()) if (distance >= 750.0f && !IsShieldDrawn ())
pev->button |= IN_ATTACK2; // draw the shield pev->button |= IN_ATTACK2; // draw the shield
else if (IsShieldDrawn () || (!engine.IsNullEntity (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable(m_enemy)))) else if (IsShieldDrawn () || (!engine.IsNullEntity (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !IsEnemyViewable (m_enemy))))
pev->button |= IN_ATTACK2; // draw out the shield pev->button |= IN_ATTACK2; // draw out the shield
m_shieldCheckTime = engine.Time () + 1.0f; m_shieldCheckTime = engine.Time () + 1.0f;
@ -884,7 +802,7 @@ WeaponSelectEnd:
// need to care for burst fire? // need to care for burst fire?
if (distance < 256.0f || m_blindTime > engine.Time ()) if (distance < 256.0f || m_blindTime > engine.Time ())
{ {
if (selectId == WEAPON_KNIFE) if (id == WEAPON_KNIFE)
{ {
if (distance < 64.0f) if (distance < 64.0f)
{ {
@ -896,7 +814,7 @@ WeaponSelectEnd:
} }
else else
{ {
if (tab[chosenWeaponIndex].primaryFireHold && m_ammo[g_weaponDefs[tab[selectIndex].id].ammo1] > tab[selectIndex].minPrimaryAmmo) // if automatic weapon, just press attack if (tab[choosen].primaryFireHold && m_ammo[g_weaponDefs[tab[index].id].ammo1] > tab[index].minPrimaryAmmo) // if automatic weapon, just press attack
pev->button |= IN_ATTACK; pev->button |= IN_ATTACK;
else // if not, toggle buttons else // if not, toggle buttons
{ {
@ -912,13 +830,13 @@ WeaponSelectEnd:
return; return;
// don't attack with knife over long distance // don't attack with knife over long distance
if (selectId == WEAPON_KNIFE) if (id == WEAPON_KNIFE)
{ {
m_shootTime = engine.Time (); m_shootTime = engine.Time ();
return; return;
} }
if (tab[chosenWeaponIndex].primaryFireHold) if (tab[choosen].primaryFireHold)
{ {
m_shootTime = engine.Time (); m_shootTime = engine.Time ();
m_zoomCheckTime = engine.Time (); m_zoomCheckTime = engine.Time ();
@ -935,6 +853,98 @@ WeaponSelectEnd:
} }
} }
void Bot::FireWeapon (void)
{
// this function will return true if weapon was fired, false otherwise
float distance = (m_lookAt - EyePosition ()).GetLength (); // how far away is the enemy?
// if using grenade stop this
if (m_isUsingGrenade)
{
m_shootTime = engine.Time () + 0.1f;
return;
}
// or if friend in line of fire, stop this too but do not update shoot time
if (!engine.IsNullEntity (m_enemy))
{
if (IsFriendInLineOfFire (distance))
{
m_fightStyle = FIGHT_STRAFE;
m_lastFightStyleCheck = engine.Time ();
return;
}
}
WeaponSelect *tab = &g_weaponSelect[0];
edict_t *enemy = m_enemy;
int selectId = WEAPON_KNIFE, selectIndex = 0, choosenWeapon = 0;
int weapons = pev->weapons;
// if jason mode use knife only
if (yb_jasonmode.GetBool ())
{
FinishWeaponSelection (distance, selectIndex, selectId, choosenWeapon);
return;
}
// use knife if near and good difficulty (l33t dude!)
if (m_difficulty >= 3 && pev->health > 80.0f && !engine.IsNullEntity (enemy) && pev->health >= enemy->v.health && distance < 100.0f && !IsOnLadder () && !IsGroupOfEnemies (pev->origin))
{
FinishWeaponSelection (distance, selectIndex, selectId, choosenWeapon);
return;
}
// loop through all the weapons until terminator is found...
while (tab[selectIndex].id)
{
// is the bot carrying this weapon?
if (weapons & (1 << tab[selectIndex].id))
{
// is enough ammo available to fire AND check is better to use pistol in our current situation...
if (m_ammoInClip[tab[selectIndex].id] > 0 && !IsWeaponBadInDistance (selectIndex, distance))
choosenWeapon = selectIndex;
}
selectIndex++;
}
selectId = tab[choosenWeapon].id;
// if no available weapon...
if (choosenWeapon == 0)
{
selectIndex = 0;
// loop through all the weapons until terminator is found...
while (tab[selectIndex].id)
{
int id = tab[selectIndex].id;
// is the bot carrying this weapon?
if (weapons & (1 << id))
{
if ( g_weaponDefs[id].ammo1 != -1 && g_weaponDefs[id].ammo1 < 32 && m_ammo[g_weaponDefs[id].ammo1] >= tab[selectIndex].minPrimaryAmmo)
{
// available ammo found, reload weapon
if (m_reloadState == RELOAD_NONE || m_reloadCheckTime > engine.Time ())
{
m_isReloading = true;
m_reloadState = RELOAD_PRIMARY;
m_reloadCheckTime = engine.Time ();
RadioMessage (Radio_NeedBackup);
}
return;
}
}
selectIndex++;
}
selectId = WEAPON_KNIFE; // no available ammo, use knife!
}
FinishWeaponSelection (distance, selectIndex, selectId, choosenWeapon);
}
bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance) bool Bot::IsWeaponBadInDistance (int weaponIndex, float distance)
{ {
// this function checks, is it better to use pistol instead of current primary weapon // this function checks, is it better to use pistol instead of current primary weapon

View file

@ -31,13 +31,13 @@ int Bot::FindGoal (void)
} }
} }
// forcing terrorist bot to not move to another bombspot // forcing terrorist bot to not move to another bomb spot
if (m_inBombZone && !m_hasProgressBar && m_hasC4) if (m_inBombZone && !m_hasProgressBar && m_hasC4)
return waypoints.FindNearest (pev->origin, 400.0f, FLAG_GOAL); return waypoints.FindNearest (pev->origin, 400.0f, FLAG_GOAL);
} }
int tactic = 0; int tactic = 0;
// path finding behaviour depending on map type // path finding behavior depending on map type
float offensive = 0.0f; float offensive = 0.0f;
float defensive = 0.0f; float defensive = 0.0f;
@ -68,14 +68,14 @@ int Bot::FindGoal (void)
if (m_hasC4 || m_isVIP) if (m_hasC4 || m_isVIP)
{ {
tactic = 3; tactic = 3;
goto TacticChoosen; return FinishFindGoal (tactic, defensiveWpts, offensiveWpts);
} }
else if (m_team == CT && HasHostage ()) else if (m_team == CT && HasHostage ())
{ {
tactic = 2; tactic = 2;
offensiveWpts = &waypoints.m_rescuePoints; offensiveWpts = &waypoints.m_rescuePoints;
goto TacticChoosen; return FinishFindGoal (tactic, defensiveWpts, offensiveWpts);
} }
offensive = m_agressionLevel * 100.0f; offensive = m_agressionLevel * 100.0f;
@ -153,11 +153,15 @@ int Bot::FindGoal (void)
if (goalDesire > tacticChoice) if (goalDesire > tacticChoice)
tactic = 3; tactic = 3;
TacticChoosen: return FinishFindGoal (tactic, defensiveWpts, offensiveWpts);
int goalChoices[4] = {-1, -1, -1, -1}; }
if (tactic == 0 && !(*defensiveWpts).IsEmpty ()) // careful goal int Bot::FinishFindGoal (int tactic, Array <int> *defensive, Array <int> *offsensive)
FilterGoals (*defensiveWpts, goalChoices); {
int goalChoices[4] = { -1, -1, -1, -1 };
if (tactic == 0 && !(*defensive).IsEmpty ()) // careful goal
FilterGoals (*defensive, goalChoices);
else if (tactic == 1 && !waypoints.m_campPoints.IsEmpty ()) // camp waypoint goal else if (tactic == 1 && !waypoints.m_campPoints.IsEmpty ()) // camp waypoint goal
{ {
// pickup sniper points if possible for sniping bots // pickup sniper points if possible for sniping bots
@ -166,8 +170,8 @@ TacticChoosen:
else else
FilterGoals (waypoints.m_campPoints, goalChoices); FilterGoals (waypoints.m_campPoints, goalChoices);
} }
else if (tactic == 2 && !(*offensiveWpts).IsEmpty ()) // offensive goal else if (tactic == 2 && !(*offsensive).IsEmpty ()) // offensive goal
FilterGoals (*offensiveWpts, goalChoices); FilterGoals (*offsensive, goalChoices);
else if (tactic == 3 && !waypoints.m_goalPoints.IsEmpty ()) // map goal waypoint else if (tactic == 3 && !waypoints.m_goalPoints.IsEmpty ()) // map goal waypoint
{ {
// force bomber to select closest goal, if round-start goal was reset by something // force bomber to select closest goal, if round-start goal was reset by something
@ -213,7 +217,7 @@ TacticChoosen:
m_currentWaypointIndex = ChangeWptIndex (waypoints.FindNearest (pev->origin)); m_currentWaypointIndex = ChangeWptIndex (waypoints.FindNearest (pev->origin));
if (goalChoices[0] == -1) if (goalChoices[0] == -1)
return m_chosenGoalIndex = Random.Long (0, g_numWaypoints - 1); return m_chosenGoalIndex = Random.Long (0, g_numWaypoints - 1);
bool isSorting = false; bool isSorting = false;
@ -2712,7 +2716,7 @@ bool Bot::CanJumpUp (const Vector &normal)
engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr);
if (tr.flFraction < 1.0f) if (tr.flFraction < 1.0f)
goto CheckDuckJump; return FinishCanJumpUp (normal);
else else
{ {
// now trace from jump height upward to check for obstructions... // now trace from jump height upward to check for obstructions...
@ -2734,7 +2738,7 @@ bool Bot::CanJumpUp (const Vector &normal)
// if trace hit something, return false // if trace hit something, return false
if (tr.flFraction < 1.0f) if (tr.flFraction < 1.0f)
goto CheckDuckJump; return FinishCanJumpUp (normal);
// now trace from jump height upward to check for obstructions... // now trace from jump height upward to check for obstructions...
src = dest; src = dest;
@ -2755,7 +2759,7 @@ bool Bot::CanJumpUp (const Vector &normal)
// if trace hit something, return false // if trace hit something, return false
if (tr.flFraction < 1.0f) if (tr.flFraction < 1.0f)
goto CheckDuckJump; return FinishCanJumpUp (normal);
// now trace from jump height upward to check for obstructions... // now trace from jump height upward to check for obstructions...
src = dest; src = dest;
@ -2765,13 +2769,15 @@ bool Bot::CanJumpUp (const Vector &normal)
// if trace hit something, return false // if trace hit something, return false
return tr.flFraction > 1.0f; return tr.flFraction > 1.0f;
}
// here we check if a duck jump would work... bool Bot::FinishCanJumpUp (const Vector &normal)
CheckDuckJump: {
// use center of the body first... maximum duck jump height is 62, so check one unit above that (63) // use center of the body first... maximum duck jump height is 62, so check one unit above that (63)
src = pev->origin + Vector (0.0f, 0.0f, -36.0f + 63.0f); Vector src = pev->origin + Vector (0.0f, 0.0f, -36.0f + 63.0f);
dest = src + normal * 32.0f; Vector dest = src + normal * 32.0f;
TraceResult tr;
// trace a line forward at maximum jump height... // trace a line forward at maximum jump height...
engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr); engine.TestLine (src, dest, TRACE_IGNORE_MONSTERS, GetEntity (), &tr);