Skip to content

Commit

Permalink
Better retreat from danger
Browse files Browse the repository at this point in the history
  • Loading branch information
FreeSlave committed Jun 20, 2022
1 parent 66fb780 commit 82c9462
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 7 deletions.
1 change: 1 addition & 0 deletions dlls/basemonster.h
Expand Up @@ -238,6 +238,7 @@ class CBaseMonster : public CBaseToggle

bool FindLateralCover(const Vector& vecThreat, const Vector& vecViewOffset);
virtual bool FindCover(Vector vecThreat, Vector vecViewOffset, float flMinDist, float flMaxDist);
bool FindRetreat(Vector vecThreat, float flMinDist, float flMaxDist);
virtual bool FValidateCover(const Vector& vecCoverLocation) { return true; }
virtual float CoverRadius() { return 784; } // Default cover radius

Expand Down
70 changes: 70 additions & 0 deletions dlls/monsters.cpp
Expand Up @@ -2317,6 +2317,76 @@ bool CBaseMonster::FindCover(Vector vecThreat, Vector vecViewOffset, float flMin
return false;
}

bool CBaseMonster::FindRetreat(Vector vecThreat, float flMinDist, float flMaxDist)
{
int i;
int iMyHullIndex;
int iMyNode;
int iThreatNode;
float flDist;

if (0 == flMaxDist)
{
// user didn't supply a MaxDist, so work up a crazy one.
flMaxDist = 784;
}

if (flMinDist > 0.5 * flMaxDist)
{
#if _DEBUG
ALERT(at_console, "FindRetreat MinDist (%.0f) too close to MaxDist (%.0f)\n", flMinDist, flMaxDist);
#endif
flMinDist = 0.5 * flMaxDist;
}

if (0 == WorldGraph.m_fGraphPresent || 0 == WorldGraph.m_fGraphPointersSet)
{
ALERT(at_aiconsole, "Graph not ready for findretreat!\n");
return false;
}

iMyNode = WorldGraph.FindNearestNode(pev->origin, this);
iThreatNode = WorldGraph.FindNearestNode(vecThreat, this);
iMyHullIndex = WorldGraph.HullIndex(this);

if (iMyNode == NO_NODE)
{
ALERT(at_aiconsole, "FindRetreat() - %s has no nearest node!\n", STRING(pev->classname));
return false;
}
if (iThreatNode == NO_NODE)
{
// ALERT ( at_aiconsole, "FindRetreat() - Threat has no nearest node!\n" );
iThreatNode = iMyNode;
// return false;
}

// we'll do a rough sample to find nodes that are relatively nearby
for (i = 0; i < WorldGraph.m_cNodes; i++)
{
int nodeNumber = (i + WorldGraph.m_iLastCoverSearch) % WorldGraph.m_cNodes;

CNode& node = WorldGraph.Node(nodeNumber);

// could use an optimization here!!
flDist = (pev->origin - node.m_vecOrigin).Length();

if (flDist >= flMinDist && flDist < flMaxDist)
{
// node is also closer to me than the threat, or the same distance from myself and the threat the node is good.
if ((iMyNode == iThreatNode) || WorldGraph.PathLength(iMyNode, nodeNumber, iMyHullIndex, m_afCapability) <= WorldGraph.PathLength(iThreatNode, nodeNumber, iMyHullIndex, m_afCapability))
{
if (FValidateCover(node.m_vecOrigin) && MoveToLocation(ACT_RUN, 0, node.m_vecOrigin))
{
WorldGraph.m_iLastCoverSearch = nodeNumber + 1; // next monster that searches for cover node will start where we left off here.
return true;
}
}
}
}
return false;
}


//=========================================================
// BuildNearestRoute - tries to build a route as close to the target
Expand Down
21 changes: 14 additions & 7 deletions dlls/schedule.cpp
Expand Up @@ -797,15 +797,22 @@ void CBaseMonster::StartTask(Task_t* pTask)
}
*/

if (pBestSound && FindCover(pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius()))
if (pBestSound)
{
// then try for plain ole cover
m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
TaskComplete();
if (FindCover(pBestSound->m_vecOrigin, g_vecZero, pBestSound->m_iVolume, CoverRadius()))
{
// then try for plain ole cover
m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
TaskComplete();
}
else if (FindRetreat(pBestSound->m_vecOrigin, pBestSound->m_iVolume, CoverRadius()))
{
m_flMoveWaitFinished = gpGlobals->time + pTask->flData;
TaskComplete();
}
}
else
{
// no coverwhatsoever. or no sound in list
// no coverwhatsoever. or no sound in list
if (!TaskIsComplete()) {
TaskFail();
}
break;
Expand Down

0 comments on commit 82c9462

Please sign in to comment.