some optimizations to goal finding
This commit is contained in:
parent
9ec495d0de
commit
73f21591f9
6 changed files with 130 additions and 144 deletions
|
|
@ -704,9 +704,11 @@ struct Client
|
||||||
edict_t *ent; // pointer to actual edict
|
edict_t *ent; // pointer to actual edict
|
||||||
Vector origin; // position in the world
|
Vector origin; // position in the world
|
||||||
Vector soundPosition; // position sound was played
|
Vector soundPosition; // position sound was played
|
||||||
|
|
||||||
int team; // bot team
|
int team; // bot team
|
||||||
int realTeam; // real bot team in free for all mode (csdm)
|
int realTeam; // real bot team in free for all mode (csdm)
|
||||||
int flags; // client flags
|
int flags; // client flags
|
||||||
|
|
||||||
float hearingDistance; // distance this sound is heared
|
float hearingDistance; // distance this sound is heared
|
||||||
float timeSoundLasting; // time sound is played/heared
|
float timeSoundLasting; // time sound is played/heared
|
||||||
float maxTimeSoundLasting; // max time sound is played/heared (to divide the difference between that above one and the current one)
|
float maxTimeSoundLasting; // max time sound is played/heared (to divide the difference between that above one and the current one)
|
||||||
|
|
@ -1000,6 +1002,7 @@ private:
|
||||||
int FindCoverWaypoint (float maxDistance);
|
int FindCoverWaypoint (float maxDistance);
|
||||||
int FindDefendWaypoint (Vector origin);
|
int FindDefendWaypoint (Vector origin);
|
||||||
int FindGoal (void);
|
int FindGoal (void);
|
||||||
|
void FilterGoals (const Array <int> &goals, int *result);
|
||||||
void FindItem (void);
|
void FindItem (void);
|
||||||
void CheckTerrain (float movedDistance, const Vector &dir, const Vector &dirNormal);
|
void CheckTerrain (float movedDistance, const Vector &dir, const Vector &dirNormal);
|
||||||
|
|
||||||
|
|
@ -1153,6 +1156,7 @@ public:
|
||||||
int m_actMessageIndex; // current processed message
|
int m_actMessageIndex; // current processed message
|
||||||
int m_pushMessageIndex; // offset for next pushed message
|
int m_pushMessageIndex; // offset for next pushed message
|
||||||
|
|
||||||
|
int m_goalFailed; // if bot can't reach several times in a row
|
||||||
int m_prevGoalIndex; // holds destination goal waypoint
|
int m_prevGoalIndex; // holds destination goal waypoint
|
||||||
int m_chosenGoalIndex; // used for experience, same as above
|
int m_chosenGoalIndex; // used for experience, same as above
|
||||||
float m_goalValue; // ranking value for this waypoint
|
float m_goalValue; // ranking value for this waypoint
|
||||||
|
|
|
||||||
|
|
@ -1204,7 +1204,7 @@ public:
|
||||||
// Returns:
|
// Returns:
|
||||||
// Number of allocated items.
|
// Number of allocated items.
|
||||||
//
|
//
|
||||||
int GetSize (void)
|
int GetSize (void) const
|
||||||
{
|
{
|
||||||
return m_itemSize;
|
return m_itemSize;
|
||||||
}
|
}
|
||||||
|
|
@ -1216,7 +1216,7 @@ public:
|
||||||
// Returns:
|
// Returns:
|
||||||
// Number of elements.
|
// Number of elements.
|
||||||
//
|
//
|
||||||
int GetElementNumber (void)
|
int GetElementNumber (void) const
|
||||||
{
|
{
|
||||||
return m_itemCount;
|
return m_itemCount;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2678,7 +2678,7 @@ void Bot::CheckRadioCommands (void)
|
||||||
{
|
{
|
||||||
if (g_timeNextBombUpdate < GetWorldTime ())
|
if (g_timeNextBombUpdate < GetWorldTime ())
|
||||||
{
|
{
|
||||||
float minDistance = FLT_MAX;
|
float minDistance = 4096.0f;
|
||||||
|
|
||||||
// find nearest bomb waypoint to player
|
// find nearest bomb waypoint to player
|
||||||
IterateArray (g_waypoint->m_goalPoints, i)
|
IterateArray (g_waypoint->m_goalPoints, i)
|
||||||
|
|
@ -3202,25 +3202,10 @@ void Bot::RunTask (void)
|
||||||
m_aimFlags |= AIM_NAVPOINT;
|
m_aimFlags |= AIM_NAVPOINT;
|
||||||
|
|
||||||
// user forced a waypoint as a goal?
|
// user forced a waypoint as a goal?
|
||||||
if (yb_debug_goal.GetInt () != -1)
|
if (yb_debug_goal.GetInt () != -1 && GetTask ()->data != yb_debug_goal.GetInt ())
|
||||||
{
|
{
|
||||||
// check if we reached it
|
DeleteSearchNodes ();
|
||||||
if (((m_currentPath->origin - pev->origin).SkipZ ()).GetLengthSquared () < 16 && GetTask ()->data == yb_debug_goal.GetInt ())
|
GetTask ()->data = yb_debug_goal.GetInt ();
|
||||||
{
|
|
||||||
m_moveSpeed = 0.0;
|
|
||||||
m_strafeSpeed = 0.0;
|
|
||||||
|
|
||||||
m_checkTerrain = false;
|
|
||||||
m_moveToGoal = false;
|
|
||||||
|
|
||||||
return; // we can safely return here
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GetTask ()->data != yb_debug_goal.GetInt ())
|
|
||||||
{
|
|
||||||
DeleteSearchNodes ();
|
|
||||||
GetTask ()->data = yb_debug_goal.GetInt ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// bots rushing with knife, when have no enemy (thanks for idea to nicebot project)
|
// bots rushing with knife, when have no enemy (thanks for idea to nicebot project)
|
||||||
|
|
@ -3300,15 +3285,14 @@ void Bot::RunTask (void)
|
||||||
|
|
||||||
MakeVectors (pev->v_angle);
|
MakeVectors (pev->v_angle);
|
||||||
|
|
||||||
m_timeCamping = GetWorldTime () + Random.Float (10.0f, 30.0f);
|
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (20.0f, 40.0f), true);
|
||||||
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, m_timeCamping, true);
|
|
||||||
|
|
||||||
m_camp = Vector (m_currentPath->campStartX, m_currentPath->campStartY, 0.0f);
|
m_camp = Vector (m_currentPath->campStartX, m_currentPath->campStartY, 0.0f);
|
||||||
m_aimFlags |= AIM_CAMP;
|
m_aimFlags |= AIM_CAMP;
|
||||||
m_campDirection = 0;
|
m_campDirection = 0;
|
||||||
|
|
||||||
// tell the world we're camping
|
// tell the world we're camping
|
||||||
if (Random.Long (0, 100) < 95)
|
if (Random.Long (0, 100) < 80)
|
||||||
RadioMessage (Radio_InPosition);
|
RadioMessage (Radio_InPosition);
|
||||||
|
|
||||||
m_moveToGoal = false;
|
m_moveToGoal = false;
|
||||||
|
|
@ -3349,8 +3333,7 @@ void Bot::RunTask (void)
|
||||||
ChatterMessage (Chatter_GoingToGuardVIPSafety); // play info about that
|
ChatterMessage (Chatter_GoingToGuardVIPSafety); // play info about that
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ((g_mapType & MAP_DE) && ((m_currentPath->flags & FLAG_GOAL) || m_inBombZone) && m_seeEnemyTime + 1.5f < GetWorldTime ())
|
||||||
if ((g_mapType & MAP_DE) && ((m_currentPath->flags & FLAG_GOAL) || m_inBombZone) && m_seeEnemyTime + 3.0 < GetWorldTime ())
|
|
||||||
{
|
{
|
||||||
// is it a terrorist carrying the bomb?
|
// is it a terrorist carrying the bomb?
|
||||||
if (m_hasC4)
|
if (m_hasC4)
|
||||||
|
|
@ -3368,12 +3351,12 @@ void Bot::RunTask (void)
|
||||||
}
|
}
|
||||||
else if (m_team == TEAM_CF)
|
else if (m_team == TEAM_CF)
|
||||||
{
|
{
|
||||||
if (!g_bombPlanted && GetNearbyFriendsNearPosition (pev->origin, 360) < 3 && Random.Long (0, 100) < 85 && GetTaskId () == TASK_NORMAL && m_fearLevel > m_agressionLevel / 2)
|
if (!g_bombPlanted && GetNearbyFriendsNearPosition (pev->origin, 360.0f) < 3 && Random.Long (0, 100) < 85 && m_personality != PERSONALITY_RUSHER)
|
||||||
{
|
{
|
||||||
int index = FindDefendWaypoint (m_currentPath->origin);
|
int index = FindDefendWaypoint (m_currentPath->origin);
|
||||||
|
|
||||||
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (45.0, 60.0), true); // push camp task on to stack
|
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (25.0, 40.0), true); // push camp task on to stack
|
||||||
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (10.0, 15.0), true); // push move command
|
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, index, GetWorldTime () + Random.Float (5.0f, 11.0f), true); // push move command
|
||||||
|
|
||||||
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
|
if (g_waypoint->GetPath (index)->vis.crouch <= g_waypoint->GetPath (index)->vis.stand)
|
||||||
m_campButtons |= IN_DUCK;
|
m_campButtons |= IN_DUCK;
|
||||||
|
|
@ -3715,7 +3698,7 @@ void Bot::RunTask (void)
|
||||||
m_idealReactionTime /= 2;
|
m_idealReactionTime /= 2;
|
||||||
|
|
||||||
m_navTimeset = GetWorldTime ();
|
m_navTimeset = GetWorldTime ();
|
||||||
m_timeCamping = GetWorldTime();
|
m_timeCamping = GetWorldTime();
|
||||||
|
|
||||||
m_moveSpeed = 0;
|
m_moveSpeed = 0;
|
||||||
m_strafeSpeed = 0.0;
|
m_strafeSpeed = 0.0;
|
||||||
|
|
@ -5180,7 +5163,7 @@ void Bot::BotAI (void)
|
||||||
sprintf (aimFlags, "%s%s%s%s%s%s%s%s",
|
sprintf (aimFlags, "%s%s%s%s%s%s%s%s",
|
||||||
m_aimFlags & AIM_NAVPOINT ? " NavPoint" : "",
|
m_aimFlags & AIM_NAVPOINT ? " NavPoint" : "",
|
||||||
m_aimFlags & AIM_CAMP ? " CampPoint" : "",
|
m_aimFlags & AIM_CAMP ? " CampPoint" : "",
|
||||||
m_aimFlags & AIM_PREDICT_PATH ? " predictPath" : "",
|
m_aimFlags & AIM_PREDICT_PATH ? " PredictPath" : "",
|
||||||
m_aimFlags & AIM_LAST_ENEMY ? " LastEnemy" : "",
|
m_aimFlags & AIM_LAST_ENEMY ? " LastEnemy" : "",
|
||||||
m_aimFlags & AIM_ENTITY ? " Entity" : "",
|
m_aimFlags & AIM_ENTITY ? " Entity" : "",
|
||||||
m_aimFlags & AIM_ENEMY ? " Enemy" : "",
|
m_aimFlags & AIM_ENEMY ? " Enemy" : "",
|
||||||
|
|
@ -5443,7 +5426,7 @@ void Bot::CollectGoalExperience (int damage, int team)
|
||||||
// gets called each time a bot gets damaged by some enemy. tries to achieve a statistic about most/less dangerous
|
// gets called each time a bot gets damaged by some enemy. tries to achieve a statistic about most/less dangerous
|
||||||
// waypoints for a destination goal used for pathfinding
|
// waypoints for a destination goal used for pathfinding
|
||||||
|
|
||||||
if ((g_numWaypoints < 1) || g_waypointsChanged || (m_chosenGoalIndex < 0) || (m_prevGoalIndex < 0))
|
if (g_numWaypoints < 1 || g_waypointsChanged || m_chosenGoalIndex < 0 || m_prevGoalIndex < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// only rate goal waypoint if bot died because of the damage
|
// only rate goal waypoint if bot died because of the damage
|
||||||
|
|
|
||||||
|
|
@ -997,11 +997,13 @@ void Touch (edict_t *pentTouched, edict_t *pentOther)
|
||||||
// the two entities both have velocities, for example two players colliding, this function
|
// the two entities both have velocities, for example two players colliding, this function
|
||||||
// is called twice, once for each entity moving.
|
// is called twice, once for each entity moving.
|
||||||
|
|
||||||
Bot *touched = g_botManager->GetBot (pentTouched);
|
if (!IsEntityNull (pentTouched) && (pentTouched->v.flags & FL_FAKECLIENT))
|
||||||
|
{
|
||||||
if (touched != NULL)
|
Bot *touched = g_botManager->GetBot (pentTouched);
|
||||||
touched->VerifyBreakable (pentOther);
|
|
||||||
|
|
||||||
|
if (touched != NULL)
|
||||||
|
touched->VerifyBreakable (pentOther);
|
||||||
|
}
|
||||||
if (g_isMetamod)
|
if (g_isMetamod)
|
||||||
RETURN_META (MRES_IGNORED);
|
RETURN_META (MRES_IGNORED);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -931,6 +931,7 @@ void Bot::NewRound (void)
|
||||||
m_currentWaypointIndex = -1;
|
m_currentWaypointIndex = -1;
|
||||||
m_currentPath = NULL;
|
m_currentPath = NULL;
|
||||||
m_currentTravelFlags = 0;
|
m_currentTravelFlags = 0;
|
||||||
|
m_goalFailed = 0;
|
||||||
m_desiredVelocity = nullvec;
|
m_desiredVelocity = nullvec;
|
||||||
m_prevGoalIndex = -1;
|
m_prevGoalIndex = -1;
|
||||||
m_chosenGoalIndex = -1;
|
m_chosenGoalIndex = -1;
|
||||||
|
|
@ -940,11 +941,8 @@ void Bot::NewRound (void)
|
||||||
m_duckDefuse = false;
|
m_duckDefuse = false;
|
||||||
m_duckDefuseCheckTime = 0.0;
|
m_duckDefuseCheckTime = 0.0;
|
||||||
|
|
||||||
m_prevWptIndex[0] = -1;
|
for (int i = 0; i < 5; i++)
|
||||||
m_prevWptIndex[1] = -1;
|
m_prevWptIndex[i] = -1;
|
||||||
m_prevWptIndex[2] = -1;
|
|
||||||
m_prevWptIndex[3] = -1;
|
|
||||||
m_prevWptIndex[4] = -1;
|
|
||||||
|
|
||||||
m_navTimeset = GetWorldTime ();
|
m_navTimeset = GetWorldTime ();
|
||||||
m_team = GetTeam (GetEntity ());
|
m_team = GetTeam (GetEntity ());
|
||||||
|
|
|
||||||
|
|
@ -50,16 +50,15 @@ int Bot::FindGoal (void)
|
||||||
}
|
}
|
||||||
int tactic;
|
int tactic;
|
||||||
|
|
||||||
|
|
||||||
// path finding behaviour depending on map type
|
// path finding behaviour depending on map type
|
||||||
int offensive;
|
float offensive;
|
||||||
int defensive;
|
float defensive;
|
||||||
int goalDesire;
|
|
||||||
|
|
||||||
int forwardDesire;
|
float goalDesire;
|
||||||
int campDesire;
|
float forwardDesire;
|
||||||
int backoffDesire;
|
float campDesire;
|
||||||
int tacticChoice;
|
float backoffDesire;
|
||||||
|
float tacticChoice;
|
||||||
|
|
||||||
Array <int> offensiveWpts;
|
Array <int> offensiveWpts;
|
||||||
Array <int> defensiveWpts;
|
Array <int> defensiveWpts;
|
||||||
|
|
@ -91,8 +90,8 @@ int Bot::FindGoal (void)
|
||||||
goto TacticChoosen;
|
goto TacticChoosen;
|
||||||
}
|
}
|
||||||
|
|
||||||
offensive = static_cast <int> (m_agressionLevel * 100);
|
offensive = m_agressionLevel * 100;
|
||||||
defensive = static_cast <int> (m_fearLevel * 100);
|
defensive = m_fearLevel * 100;
|
||||||
|
|
||||||
if (g_mapType & (MAP_AS | MAP_CS))
|
if (g_mapType & (MAP_AS | MAP_CS))
|
||||||
{
|
{
|
||||||
|
|
@ -103,8 +102,17 @@ int Bot::FindGoal (void)
|
||||||
}
|
}
|
||||||
else if (m_team == TEAM_CF)
|
else if (m_team == TEAM_CF)
|
||||||
{
|
{
|
||||||
defensive -= 25.0f;
|
// on hostage maps force more bots to save hostages
|
||||||
offensive += 25.0f;
|
if (g_mapType & MAP_CS)
|
||||||
|
{
|
||||||
|
defensive -= 25.0f - m_difficulty * 0.5f;
|
||||||
|
offensive += 25.0f + m_difficulty * 5.0f;
|
||||||
|
}
|
||||||
|
else // on AS leave as is
|
||||||
|
{
|
||||||
|
defensive -= 25.0f;
|
||||||
|
offensive += 25.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((g_mapType & MAP_DE) && m_team == TEAM_CF)
|
else if ((g_mapType & MAP_DE) && m_team == TEAM_CF)
|
||||||
|
|
@ -128,10 +136,10 @@ int Bot::FindGoal (void)
|
||||||
return m_chosenGoalIndex = FindDefendWaypoint (g_waypoint->GetBombPosition ());
|
return m_chosenGoalIndex = FindDefendWaypoint (g_waypoint->GetBombPosition ());
|
||||||
}
|
}
|
||||||
|
|
||||||
goalDesire = Random.Long (0, 100 + (offensive * 0.5)) + offensive;
|
goalDesire = Random.Float (0.0f, 100.0f) + offensive;
|
||||||
forwardDesire = Random.Long (0, 100) + offensive;
|
forwardDesire = Random.Float (0.0f, 100.0f) + offensive;
|
||||||
campDesire = Random.Long (0, 100) + defensive;
|
campDesire = Random.Float (0.0f, 100.0f) + defensive;
|
||||||
backoffDesire = Random.Long (0, 100) + defensive;
|
backoffDesire = Random.Float (0.0f, 100.0f) + defensive;
|
||||||
|
|
||||||
if (!UsesCampGun ())
|
if (!UsesCampGun ())
|
||||||
campDesire = 0;
|
campDesire = 0;
|
||||||
|
|
@ -158,41 +166,17 @@ TacticChoosen:
|
||||||
int goalChoices[4] = {-1, -1, -1, -1};
|
int goalChoices[4] = {-1, -1, -1, -1};
|
||||||
|
|
||||||
if (tactic == 0 && !defensiveWpts.IsEmpty ()) // careful goal
|
if (tactic == 0 && !defensiveWpts.IsEmpty ()) // careful goal
|
||||||
{
|
FilterGoals (defensiveWpts, goalChoices);
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
goalChoices[i] = defensiveWpts.GetRandomElement ();
|
|
||||||
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (tactic == 1 && !g_waypoint->m_campPoints.IsEmpty ()) // camp waypoint goal
|
else if (tactic == 1 && !g_waypoint->m_campPoints.IsEmpty ()) // camp waypoint goal
|
||||||
{
|
{
|
||||||
// pickup sniper points if possible for sniping bots
|
// pickup sniper points if possible for sniping bots
|
||||||
if (!g_waypoint->m_sniperPoints.IsEmpty () && ((pev->weapons & (1 << WEAPON_AWP)) || (pev->weapons & (1 << WEAPON_SCOUT)) || (pev->weapons & (1 << WEAPON_G3SG1)) || (pev->weapons & (1 << WEAPON_SG550))))
|
if (!g_waypoint->m_sniperPoints.IsEmpty () && UsesSniper ())
|
||||||
{
|
FilterGoals (g_waypoint->m_sniperPoints, goalChoices);
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
goalChoices[i] = g_waypoint->m_sniperPoints.GetRandomElement ();
|
|
||||||
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
FilterGoals (g_waypoint->m_campPoints, goalChoices);
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
goalChoices[i] = g_waypoint->m_campPoints.GetRandomElement ();
|
|
||||||
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (tactic == 2 && !offensiveWpts.IsEmpty ()) // offensive goal
|
else if (tactic == 2 && !offensiveWpts.IsEmpty ()) // offensive goal
|
||||||
{
|
FilterGoals (offensiveWpts, goalChoices);
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
goalChoices[i] = offensiveWpts.GetRandomElement ();
|
|
||||||
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (tactic == 3 && !g_waypoint->m_goalPoints.IsEmpty ()) // map goal waypoint
|
else if (tactic == 3 && !g_waypoint->m_goalPoints.IsEmpty ()) // map goal waypoint
|
||||||
{
|
{
|
||||||
// forcee bomber to select closest goal, if round-start goal was reset by something
|
// forcee bomber to select closest goal, if round-start goal was reset by something
|
||||||
|
|
@ -231,13 +215,7 @@ TacticChoosen:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
FilterGoals (g_waypoint->m_goalPoints, goalChoices);
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
goalChoices[i] = g_waypoint->m_goalPoints.GetRandomElement ();
|
|
||||||
InternalAssert (goalChoices[i] >= 0 && goalChoices[i] < g_numWaypoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentWaypointIndex == -1 || m_currentWaypointIndex >= g_numWaypoints)
|
if (m_currentWaypointIndex == -1 || m_currentWaypointIndex >= g_numWaypoints)
|
||||||
|
|
@ -259,31 +237,42 @@ TacticChoosen:
|
||||||
if (testIndex < 0)
|
if (testIndex < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (m_team == TEAM_TF)
|
int goal1 = m_team == TEAM_TF ? (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i])->team0Value : (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i])->team1Value;
|
||||||
{
|
int goal2 = m_team == TEAM_TF ? (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i + 1])->team0Value : (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i + 1])->team1Value;
|
||||||
if ((g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i])->team0Value < (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i + 1])->team0Value)
|
|
||||||
{
|
|
||||||
goalChoices[i + 1] = goalChoices[i];
|
|
||||||
goalChoices[i] = testIndex;
|
|
||||||
|
|
||||||
isSorting = true;
|
if (goal1 < goal2)
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if ((g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i])->team1Value < (g_experienceData + (m_currentWaypointIndex * g_numWaypoints) + goalChoices[i + 1])->team1Value)
|
goalChoices[i + 1] = goalChoices[i];
|
||||||
{
|
goalChoices[i] = testIndex;
|
||||||
goalChoices[i + 1] = goalChoices[i];
|
|
||||||
goalChoices[i] = testIndex;
|
|
||||||
|
|
||||||
isSorting = true;
|
isSorting = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (isSorting);
|
} while (isSorting);
|
||||||
|
|
||||||
// return and store goal
|
return m_chosenGoalIndex = goalChoices[0]; // return and store goal
|
||||||
return m_chosenGoalIndex = goalChoices[0];
|
}
|
||||||
|
|
||||||
|
void Bot::FilterGoals (const Array <int> &goals, int *result)
|
||||||
|
{
|
||||||
|
// this function filters the goals, so new goal is not bot's old goal, and array of goals doesn't contains duplicate goals
|
||||||
|
|
||||||
|
int totalGoals = goals.GetElementNumber ();
|
||||||
|
int searchCount = 0;
|
||||||
|
|
||||||
|
for (int index = 0; index < 4; index++)
|
||||||
|
{
|
||||||
|
int rand = goals.GetRandomElement ();
|
||||||
|
|
||||||
|
if (searchCount <= 8 && (m_prevGoalIndex == rand || ((result[0] == rand || result[1] == rand || result[2] == rand || result[3] == rand) && totalGoals > 4)) && !IsPointOccupied (rand))
|
||||||
|
{
|
||||||
|
if (index > 0)
|
||||||
|
index--;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
result[index] = rand;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::GoalIsValid (void)
|
bool Bot::GoalIsValid (void)
|
||||||
|
|
@ -665,8 +654,8 @@ bool Bot::DoWaypointNav (void)
|
||||||
// pressing the jump button gives the illusion of the bot actual jmping.
|
// pressing the jump button gives the illusion of the bot actual jmping.
|
||||||
if (IsOnFloor () || IsOnLadder ())
|
if (IsOnFloor () || IsOnLadder ())
|
||||||
{
|
{
|
||||||
if (m_desiredVelocity != nullvec)
|
if (m_desiredVelocity.x != 0.0f && m_desiredVelocity.y != 0.0f)
|
||||||
pev->velocity = m_desiredVelocity + m_desiredVelocity * 0.15; // cheating i know, but something changed in recent cs updates...
|
pev->velocity = m_desiredVelocity + m_desiredVelocity * 0.11f;
|
||||||
|
|
||||||
pev->button |= IN_JUMP;
|
pev->button |= IN_JUMP;
|
||||||
|
|
||||||
|
|
@ -1126,13 +1115,8 @@ bool Bot::DoWaypointNav (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// needs precise placement - check if we get past the point
|
// needs precise placement - check if we get past the point
|
||||||
if (desiredDistance < 16.0 && waypointDistance < 30)
|
if (desiredDistance < 16.0 && waypointDistance < 30 && (pev->origin + (pev->velocity * m_frameInterval) - m_waypointOrigin).GetLength () > waypointDistance)
|
||||||
{
|
desiredDistance = waypointDistance + 1.0;
|
||||||
Vector nextFrameOrigin = pev->origin + (pev->velocity * m_frameInterval);
|
|
||||||
|
|
||||||
if ((nextFrameOrigin - m_waypointOrigin).GetLength () > waypointDistance)
|
|
||||||
desiredDistance = waypointDistance + 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (waypointDistance < desiredDistance)
|
if (waypointDistance < desiredDistance)
|
||||||
{
|
{
|
||||||
|
|
@ -1279,9 +1263,7 @@ public:
|
||||||
if (m_size >= m_heapSize)
|
if (m_size >= m_heapSize)
|
||||||
{
|
{
|
||||||
m_heapSize += 100;
|
m_heapSize += 100;
|
||||||
m_heap = (Node *) realloc (m_heap, sizeof (Node) * m_heapSize);
|
m_heap = (Node *)realloc (m_heap, sizeof (Node) * m_heapSize);
|
||||||
|
|
||||||
ServerPrint ("REALLOCATING");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_heap[m_size].pri = pri;
|
m_heap[m_size].pri = pri;
|
||||||
|
|
@ -1954,7 +1936,29 @@ void Bot::GetValidWaypoint (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DeleteSearchNodes ();
|
DeleteSearchNodes ();
|
||||||
FindWaypoint ();
|
|
||||||
|
if (m_goalFailed > 1)
|
||||||
|
{
|
||||||
|
DebugMsg ("GOAL FAILED!");
|
||||||
|
int newGoal = FindGoal ();
|
||||||
|
|
||||||
|
m_prevGoalIndex = newGoal;
|
||||||
|
m_chosenGoalIndex = newGoal;
|
||||||
|
|
||||||
|
// remember index
|
||||||
|
GetTask ()->data = newGoal;
|
||||||
|
|
||||||
|
// do pathfinding if it's not the current waypoint
|
||||||
|
if (newGoal != m_currentWaypointIndex)
|
||||||
|
FindPath (m_currentWaypointIndex, newGoal, m_pathType);
|
||||||
|
|
||||||
|
m_goalFailed = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FindWaypoint ();
|
||||||
|
m_goalFailed++;
|
||||||
|
}
|
||||||
|
|
||||||
m_waypointOrigin = m_currentPath->origin;
|
m_waypointOrigin = m_currentPath->origin;
|
||||||
}
|
}
|
||||||
|
|
@ -1962,6 +1966,9 @@ void Bot::GetValidWaypoint (void)
|
||||||
|
|
||||||
void Bot::ChangeWptIndex (int waypointIndex)
|
void Bot::ChangeWptIndex (int waypointIndex)
|
||||||
{
|
{
|
||||||
|
if (waypointIndex == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
m_prevWptIndex[4] = m_prevWptIndex[3];
|
m_prevWptIndex[4] = m_prevWptIndex[3];
|
||||||
m_prevWptIndex[3] = m_prevWptIndex[2];
|
m_prevWptIndex[3] = m_prevWptIndex[2];
|
||||||
m_prevWptIndex[2] = m_prevWptIndex[1];
|
m_prevWptIndex[2] = m_prevWptIndex[1];
|
||||||
|
|
@ -1971,19 +1978,14 @@ void Bot::ChangeWptIndex (int waypointIndex)
|
||||||
m_navTimeset = GetWorldTime ();
|
m_navTimeset = GetWorldTime ();
|
||||||
|
|
||||||
m_currentPath = g_waypoint->GetPath (m_currentWaypointIndex);
|
m_currentPath = g_waypoint->GetPath (m_currentWaypointIndex);
|
||||||
|
m_waypointFlags = m_currentPath->flags;
|
||||||
// get the current waypoint flags
|
|
||||||
if (m_currentWaypointIndex != -1)
|
|
||||||
m_waypointFlags = m_currentPath->flags;
|
|
||||||
else
|
|
||||||
m_waypointFlags = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Bot::ChooseBombWaypoint (void)
|
int Bot::ChooseBombWaypoint (void)
|
||||||
{
|
{
|
||||||
// this function finds the best goal (bomb) waypoint for CTs when searching for a planted bomb.
|
// this function finds the best goal (bomb) waypoint for CTs when searching for a planted bomb.
|
||||||
|
|
||||||
Array <int> &goals = g_waypoint->m_goalPoints;
|
Array <int> goals = g_waypoint->m_goalPoints;
|
||||||
|
|
||||||
if (goals.IsEmpty ())
|
if (goals.IsEmpty ())
|
||||||
return Random.Long (0, g_numWaypoints - 1); // reliability check
|
return Random.Long (0, g_numWaypoints - 1); // reliability check
|
||||||
|
|
@ -2332,7 +2334,7 @@ bool Bot::HeadTowardWaypoint (void)
|
||||||
m_minSpeed = pev->maxspeed;
|
m_minSpeed = pev->maxspeed;
|
||||||
|
|
||||||
// only if we in normal task and bomb is not planted
|
// only if we in normal task and bomb is not planted
|
||||||
if (m_currentPath->flags & (FLAG_GOAL | FLAG_SNIPER | FLAG_CAMP) && GetTaskId () == TASK_NORMAL && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ())
|
if (GetTaskId () == TASK_NORMAL && m_timeCamping + 30.0f < GetWorldTime () && !g_bombPlanted && m_personality != PERSONALITY_RUSHER && !m_hasC4 && !m_isVIP && m_loosedBombWptIndex == -1 && !HasHostage ())
|
||||||
{
|
{
|
||||||
m_campButtons = 0;
|
m_campButtons = 0;
|
||||||
|
|
||||||
|
|
@ -2358,22 +2360,17 @@ bool Bot::HeadTowardWaypoint (void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_baseAgressionLevel < kills && GetTaskId () != TASK_MOVETOPOSITION && HasPrimaryWeapon ())
|
if (m_baseAgressionLevel < kills && HasPrimaryWeapon ())
|
||||||
{
|
{
|
||||||
DebugMsg ("pushing camp on to stack");
|
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + Random.Float (m_difficulty * 0.5, m_difficulty) * 5, true);
|
||||||
StartTask (TASK_CAMP, TASKPRI_CAMP, -1, GetWorldTime () + (m_fearLevel * (g_timeRoundMid - GetWorldTime ()) * 0.5), true); // push camp task on to stack
|
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (g_waypoint->GetPath (waypoint)->origin), GetWorldTime () + Random.Float (3.0f, 10.0f), true);
|
||||||
|
|
||||||
StartTask (TASK_MOVETOPOSITION, TASKPRI_MOVETOPOSITION, FindDefendWaypoint (g_waypoint->GetPath (waypoint)->origin), 0.0, true);
|
|
||||||
|
|
||||||
if (m_difficulty >= 3)
|
|
||||||
pev->button |= IN_DUCK;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (g_botsCanPause && !IsOnLadder () && !IsInWater () && !m_currentTravelFlags && IsOnFloor ())
|
else if (g_botsCanPause && !IsOnLadder () && !IsInWater () && !m_currentTravelFlags && IsOnFloor ())
|
||||||
{
|
{
|
||||||
if (static_cast <float> (kills) == m_baseAgressionLevel)
|
if (static_cast <float> (kills) == m_baseAgressionLevel)
|
||||||
m_campButtons |= IN_DUCK;
|
m_campButtons |= IN_DUCK;
|
||||||
else if (Random.Long (1, 100) > (m_difficulty * 25 + Random.Long (1, 20)))
|
else if (Random.Long (1, 100) > m_difficulty * 25)
|
||||||
m_minSpeed = GetWalkSpeed ();
|
m_minSpeed = GetWalkSpeed ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2430,7 +2427,6 @@ bool Bot::HeadTowardWaypoint (void)
|
||||||
if (willJump && m_currentWeapon != WEAPON_KNIFE && m_currentWeapon != WEAPON_SCOUT && !m_isReloading && !UsesPistol () && (jumpDistance > 210 || (destination.z + 32.0f > src.z && jumpDistance > 150.0f) || ((destination - src).GetLength2D () < 60 && jumpDistance > 60)) && IsEntityNull (m_enemy))
|
if (willJump && m_currentWeapon != WEAPON_KNIFE && m_currentWeapon != WEAPON_SCOUT && !m_isReloading && !UsesPistol () && (jumpDistance > 210 || (destination.z + 32.0f > src.z && jumpDistance > 150.0f) || ((destination - src).GetLength2D () < 60 && jumpDistance > 60)) && IsEntityNull (m_enemy))
|
||||||
SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed
|
SelectWeaponByName ("weapon_knife"); // draw out the knife if we needed
|
||||||
|
|
||||||
|
|
||||||
// bot not already on ladder but will be soon?
|
// bot not already on ladder but will be soon?
|
||||||
if ((g_waypoint->GetPath (destIndex)->flags & FLAG_LADDER) && !IsOnLadder ())
|
if ((g_waypoint->GetPath (destIndex)->flags & FLAG_LADDER) && !IsOnLadder ())
|
||||||
{
|
{
|
||||||
|
|
@ -3292,8 +3288,11 @@ bool Bot::IsPointOccupied (int index)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// check if this waypoint is already used
|
// check if this waypoint is already used
|
||||||
if (IsAlive (bot->GetEntity ()) && (bot->m_currentWaypointIndex == index || bot->GetTask ()->data == index || (g_waypoint->GetPath (index)->origin - bot->pev->origin).GetLength2D () < 120.0f))
|
if (IsAlive (bot->GetEntity ()))
|
||||||
return true;
|
{
|
||||||
|
if ((GetShootingConeDeviation (bot->GetEntity (), &pev->origin) >= 0.7 ? bot->m_prevWptIndex[0] : m_currentWaypointIndex) == index || bot->GetTask ()->data == index || (g_waypoint->GetPath (index)->origin - bot->pev->origin).GetLength2D () < 96.0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue