Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@ ActionResult<CNEOBot> CNEOBotRetreatFromHazardArea::Update(CNEOBot *me, float in
CNEOBotPathCompute(me, m_path, m_safeArea->GetCenter(), RETREAT_ROUTE);
}

// Possibly don't want to cloak with grenade/smoke hazards yet
// because in such situations either the threat noticed you already
// or because they didn't notice you yet, you shouldn't announce your position
if (CNEOBotPathReservations()->IsAreaNpcTurretHazard(myArea->GetID(), me))
{
me->EnableCloak(3.0f);
}

m_path.Update(me);
return Continue();
}
Expand Down
45 changes: 45 additions & 0 deletions src/game/server/neo/bot/neo_bot_path_reservation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,7 @@ void CNEOBotPathReservationSystem::AddDeadlyHazard(int navAreaID, float expireTi
HazardInfo blank;
blank.hazardExpireTime = expireTime;
blank.smokeExpireTime = 0.0f;
blank.npcTurretExpireTime = 0.0f;
index = m_HazardAreas[teamID].Insert(navAreaID, blank);
}
else
Expand Down Expand Up @@ -466,6 +467,7 @@ void CNEOBotPathReservationSystem::AddSmokeHazard(int navAreaID, float expireTim
HazardInfo blank;
blank.hazardExpireTime = 0.0f;
blank.smokeExpireTime = expireTime;
blank.npcTurretExpireTime = 0.0f;
index = m_HazardAreas[teamID].Insert(navAreaID, blank);
}
else
Expand All @@ -490,6 +492,49 @@ void CNEOBotPathReservationSystem::AddSmokeHazard(int navAreaID, float expireTim
}
}

//-------------------------------------------------------------------------------------------------
// Area tagged by neo_npc_targetsystem turret, whose motion vision
// cannot see slow cloaked players, so bots escaping it should cloak
void CNEOBotPathReservationSystem::AddNpcTurretHazard(int navAreaID, float expireTime, int teamID, bool propagatePVS)
{
AddDeadlyHazard(navAreaID, expireTime, teamID, propagatePVS);

if ( (teamID < 0) || (teamID >= TEAM__TOTAL) )
{
return;
}

int index = m_HazardAreas[teamID].Find(navAreaID);
if ( m_HazardAreas[teamID].IsValidIndex(index) )
{
// Inform the bots in the specific target area to turn on cloak
m_HazardAreas[teamID][index].npcTurretExpireTime = expireTime;
}
}

//-------------------------------------------------------------------------------------------------
bool CNEOBotPathReservationSystem::IsAreaNpcTurretHazard(int navAreaID, const CNEOBot *me) const
{
if ( !neo_bot_path_reservation_avoid_penalty_enable.GetBool() || !me )
{
return false;
}

int teamID = me->GetTeamNumber();
if ( (teamID < 0) || (teamID >= TEAM__TOTAL) )
{
return false;
}

int index = m_HazardAreas[teamID].Find(navAreaID);
if ( !m_HazardAreas[teamID].IsValidIndex(index) )
{
return false;
}

return m_HazardAreas[teamID][index].npcTurretExpireTime > gpGlobals->curtime;
}

//-------------------------------------------------------------------------------------------------
float CNEOBotPathReservationSystem::GetAreaHazardousTime(int navAreaID, const CNEOBot *me) const
{
Expand Down
3 changes: 3 additions & 0 deletions src/game/server/neo/bot/neo_bot_path_reservation.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct HazardInfo
{
float smokeExpireTime; // when the smoke hazard risk expires
float hazardExpireTime; // when a general deadly hazard risk expires
float npcTurretExpireTime; // when a neo_npc_targetsystem hazard expires
};

struct BotReservedAreas_t
Expand Down Expand Up @@ -75,6 +76,8 @@ class CNEOBotPathReservationSystem
void AddDeadlyHazard(int navAreaID, float expireTime, int teamID, bool propagatePVS = false);
void AddFragHazard(int navAreaID, float expireTime, int teamID);
void AddSmokeHazard(int navAreaID, float expireTime, int teamID, bool propagatePVS = true);
void AddNpcTurretHazard(int navAreaID, float expireTime, int teamID, bool propagatePVS = true);
bool IsAreaNpcTurretHazard(int navAreaID, const CNEOBot *me) const;
float GetAreaHazardousTime(int navAreaID, const CNEOBot *me) const;
bool IsAreaHazardous(int navAreaID, const CNEOBot *me) const;

Expand Down
93 changes: 93 additions & 0 deletions src/game/server/neo/neo_npc_targetsystem.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
#include "neo_npc_targetsystem.h"
#include "neo_player.h"
#include "ammodef.h"
#include "nav_mesh.h"
#include "NextBotManager.h"
#include "bot/neo_bot_path_reservation.h"

#include "tier0/memdbgon.h"

#define CLOAKED_VELOCITY_THRESHOLD 32400 // 180 horizontal velocity. Slightly under sprint/wigglerun speed

// Bot hazard timing
static constexpr float BOT_HAZARD_REACTION_TIME = 0.25f;
static constexpr float BOT_HAZARD_INTERVAL = BOT_HAZARD_REACTION_TIME;
static constexpr float BOT_HAZARD_DURATION = 2.0f;

LINK_ENTITY_TO_CLASS(neo_npc_targetsystem, CNEO_NPCTargetSystem);

BEGIN_DATADESC(CNEO_NPCTargetSystem)
Expand Down Expand Up @@ -185,6 +193,7 @@ void CNEO_NPCTargetSystem::Think()
{
m_OnSpotted.FireOutput(pBestTarget, this);
m_bTargetAcquired = true;
m_flNextHazardTime = gpGlobals->curtime + BOT_HAZARD_REACTION_TIME;
}

if (bMiddleIgnore && !m_bMiddleIgnoreActive)
Expand Down Expand Up @@ -234,6 +243,8 @@ void CNEO_NPCTargetSystem::Think()
m_bMiddleIgnoreActive = false;
}

PublishBotHazards(pBestTarget);

// Optional - damage the target
if (m_hDamageSource && pBestTarget && (iNewZone == ZONE_MIDDLE))
{
Expand All @@ -260,6 +271,88 @@ void CNEO_NPCTargetSystem::Think()
SetNextThink(gpGlobals->curtime + 0.05f);
}

//-----------------------------------------------------------------------------
// Bot hazard publishing - Bots cannot fight this entity.
// Hazards: its own area and all adjacent areas for every team (run-over),
// and its targeted player's area once acquired.
//-----------------------------------------------------------------------------

void CNEO_NPCTargetSystem::PublishBotHazards(CBasePlayer *pTarget)
{
if (!TheNavMesh->IsLoaded() || TheNextBots().GetNextBotCount() == 0)
{
return;
}

if (gpGlobals->curtime < m_flNextHazardTime)
{
return;
}

m_flNextHazardTime = gpGlobals->curtime + BOT_HAZARD_INTERVAL;
const float flExpireTime = gpGlobals->curtime + BOT_HAZARD_DURATION;

// A team is targeted if a living member passes the filter; on ntre_rogue_ctg
// the filter swaps on ghost pickup so the carrier's team is left out
bool bTeamTargeted[TEAM__TOTAL] = {};
for (int i = 1; i <= gpGlobals->maxClients; i++)
{
CBasePlayer *pPlayer = UTIL_PlayerByIndex(i);
if (!pPlayer || !pPlayer->IsAlive() || pPlayer->GetTeamNumber() < FIRST_GAME_TEAM)
{
continue;
}

if (!m_pFilter || m_pFilter->PassesFilter(this, pPlayer))
{
bTeamTargeted[pPlayer->GetTeamNumber()] = true;
}
}

// Mark areas PVS to the tank as do not hang out in my view
CNavArea *pOwnArea = TheNavMesh->GetNearestNavArea(GetAbsOrigin());
if (pOwnArea)
{
for (int iTeam = FIRST_GAME_TEAM; iTeam < TEAM__TOTAL; ++iTeam)
{
CNEOBotPathReservations()->AddDeadlyHazard(pOwnArea->GetID(), flExpireTime, iTeam);

if (bTeamTargeted[iTeam])
{
AddVisibleHazard(pOwnArea, iTeam, flExpireTime);
}
}
}

if (pTarget)
{
CNavArea *pTargetArea = TheNavMesh->GetNearestNavArea(pTarget->GetAbsOrigin());
if (pTargetArea)
{
// Don't propagate the PVS for the targeted bot location to avoid marking the areas around the corner
AddVisibleHazard(pTargetArea, pTarget->GetTeamNumber(), flExpireTime, false);
}
}
}

void CNEO_NPCTargetSystem::AddVisibleHazard(CNavArea *pArea, int iTeam, float flExpireTime, bool bPropagatePVS)
{
const bool bMotionVision = m_bMotionVision;
auto addHazard = [flExpireTime, iTeam, bMotionVision, bPropagatePVS](CNavArea *pVisible)
{
if (bMotionVision)
{
CNEOBotPathReservations()->AddNpcTurretHazard(pVisible->GetID(), flExpireTime, iTeam, bPropagatePVS);
}
else
{
CNEOBotPathReservations()->AddDeadlyHazard(pVisible->GetID(), flExpireTime, iTeam, bPropagatePVS);
}
return true;
};
addHazard(pArea);
}

bool CNEO_NPCTargetSystem::CanSee(CBaseEntity *pEntity)
{
if (m_pFilter && m_pFilter->PassesFilter(this, pEntity))
Expand Down
6 changes: 6 additions & 0 deletions src/game/server/neo/neo_npc_targetsystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include "cbase.h"
#include "filters.h"

class CNavArea;

class CNEO_NPCTargetSystem : public CBaseEntity
{
public:
Expand Down Expand Up @@ -45,6 +47,9 @@ class CNEO_NPCTargetSystem : public CBaseEntity
bool CanSee(CBaseEntity *pEntity);

private:
void PublishBotHazards(CBasePlayer *pTarget);
void AddVisibleHazard(CNavArea *pArea, int iTeam, float flExpireTime, bool bPropagatePVS = true);

enum TargetZone_e
{
ZONE_NONE = 0,
Expand All @@ -58,4 +63,5 @@ class CNEO_NPCTargetSystem : public CBaseEntity
bool m_bMiddleIgnoreActive = false;
float m_flNextFireTime = 0;
CBasePlayer *m_pLastBestTarget = nullptr;
float m_flNextHazardTime = 0;
};