bot: switch look/body angles updates to thread worker
build: msvc projects now again targets msvc by default
This commit is contained in:
parent
52bfac2b09
commit
5ce2032acd
8 changed files with 59 additions and 35 deletions
|
|
@ -416,23 +416,23 @@ CR_DECLARE_SCOPED_ENUM (FrustumSide,
|
|||
)
|
||||
|
||||
// some hard-coded desire defines used to override calculated ones
|
||||
struct TaskPri {
|
||||
static constexpr auto Normal { 35.0f };
|
||||
static constexpr auto Pause { 36.0f };
|
||||
static constexpr auto Camp { 37.0f };
|
||||
static constexpr auto Spraypaint { 38.0f };
|
||||
static constexpr auto FollowUser { 39.0f };
|
||||
static constexpr auto MoveToPosition { 50.0f };
|
||||
static constexpr auto DefuseBomb { 89.0f };
|
||||
static constexpr auto PlantBomb { 89.0f };
|
||||
static constexpr auto Attack { 90.0f };
|
||||
static constexpr auto SeekCover { 91.0f };
|
||||
static constexpr auto Hide { 92.0f };
|
||||
static constexpr auto Throw { 99.0f };
|
||||
static constexpr auto DoubleJump { 99.0f };
|
||||
static constexpr auto Blind { 100.0f };
|
||||
static constexpr auto ShootBreakable { 100.0f };
|
||||
static constexpr auto EscapeFromBomb { 100.0f };
|
||||
namespace TaskPri {
|
||||
constexpr auto Normal { 35.0f };
|
||||
constexpr auto Pause { 36.0f };
|
||||
constexpr auto Camp { 37.0f };
|
||||
constexpr auto Spraypaint { 38.0f };
|
||||
constexpr auto FollowUser { 39.0f };
|
||||
constexpr auto MoveToPosition { 50.0f };
|
||||
constexpr auto DefuseBomb { 89.0f };
|
||||
constexpr auto PlantBomb { 89.0f };
|
||||
constexpr auto Attack { 90.0f };
|
||||
constexpr auto SeekCover { 91.0f };
|
||||
constexpr auto Hide { 92.0f };
|
||||
constexpr auto Throw { 99.0f };
|
||||
constexpr auto DoubleJump { 99.0f };
|
||||
constexpr auto Blind { 100.0f };
|
||||
constexpr auto ShootBreakable { 100.0f };
|
||||
constexpr auto EscapeFromBomb { 100.0f };
|
||||
};
|
||||
|
||||
constexpr auto kInfiniteDistance = 9999999.0f;
|
||||
|
|
@ -441,6 +441,7 @@ constexpr auto kGrenadeCheckTime = 0.6f;
|
|||
constexpr auto kSprayDistance = 260.0f;
|
||||
constexpr auto kDoubleSprayDistance = kSprayDistance * 2;
|
||||
constexpr auto kMaxChatterRepeatInterval = 99.0f;
|
||||
constexpr auto kViewFrameUpdate = 1.0f / 30.0f;
|
||||
|
||||
constexpr auto kInfiniteDistanceLong = static_cast <int> (kInfiniteDistance);
|
||||
constexpr auto kMaxWeapons = 32;
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ public:
|
|||
private:
|
||||
mutable Mutex m_pathFindLock {};
|
||||
mutable Mutex m_predictLock {};
|
||||
mutable Mutex m_lookAnglesLock {};
|
||||
|
||||
private:
|
||||
uint32_t m_states {}; // sensing bitstates
|
||||
|
|
@ -471,6 +472,7 @@ private:
|
|||
void checkBurstMode (float distance);
|
||||
void checkSilencer ();
|
||||
void updateAimDir ();
|
||||
void syncUpdateLookAngles ();
|
||||
void updateLookAngles ();
|
||||
void updateBodyAngles ();
|
||||
void updateLookAnglesNewbie (const Vector &direction, float delta);
|
||||
|
|
@ -701,7 +703,8 @@ public:
|
|||
|
||||
// need to wait until all threads will finish it's work before terminating bot object
|
||||
~Bot () {
|
||||
MutexScopedLock lock (m_pathFindLock);
|
||||
MutexScopedLock lock1 (m_pathFindLock);
|
||||
MutexScopedLock lock2 (m_lookAnglesLock);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void Bot::avoidGrenades () {
|
|||
if (!bots.hasActiveGrenades ()) {
|
||||
return;
|
||||
}
|
||||
auto &activeGrenades = bots.getActiveGrenades ();
|
||||
const auto &activeGrenades = bots.getActiveGrenades ();
|
||||
|
||||
// find all grenades on the map
|
||||
for (auto pent : activeGrenades) {
|
||||
|
|
@ -524,7 +524,7 @@ void Bot::updatePickups () {
|
|||
allowPickup = false;
|
||||
|
||||
if (!m_defendHostage && m_personality != Personality::Rusher && m_difficulty >= Difficulty::Normal && rg.chance (15) && m_timeCamping + 15.0f < game.time ()) {
|
||||
int index = findDefendNode (origin);
|
||||
const int index = findDefendNode (origin);
|
||||
|
||||
startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (30.0f, 60.0f), true); // push camp task on to stack
|
||||
startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (3.0f, 6.0f), true); // push move command
|
||||
|
|
@ -543,11 +543,11 @@ void Bot::updatePickups () {
|
|||
if (!m_defendedBomb) {
|
||||
m_defendedBomb = true;
|
||||
|
||||
int index = findDefendNode (origin);
|
||||
const int index = findDefendNode (origin);
|
||||
const Path &path = graph[index];
|
||||
|
||||
float bombTimer = mp_c4timer.float_ ();
|
||||
float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
|
||||
const float bombTimer = mp_c4timer.float_ ();
|
||||
const float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
|
||||
|
||||
if (timeMidBlowup > game.time ()) {
|
||||
clearTask (Task::MoveToPosition); // remove any move tasks
|
||||
|
|
@ -618,10 +618,10 @@ void Bot::updatePickups () {
|
|||
if (!m_defendedBomb && !allowPickup) {
|
||||
m_defendedBomb = true;
|
||||
|
||||
int index = findDefendNode (origin);
|
||||
const int index = findDefendNode (origin);
|
||||
const auto &path = graph[index];
|
||||
|
||||
float timeToExplode = bots.getTimeBombPlanted () + mp_c4timer.float_ () - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
|
||||
const float timeToExplode = bots.getTimeBombPlanted () + mp_c4timer.float_ () - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
|
||||
|
||||
clearTask (Task::MoveToPosition); // remove any move tasks
|
||||
|
||||
|
|
@ -648,7 +648,7 @@ void Bot::updatePickups () {
|
|||
allowPickup = false;
|
||||
|
||||
if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && m_healthValue < 60) {
|
||||
int index = findDefendNode (origin);
|
||||
const int index = findDefendNode (origin);
|
||||
|
||||
startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (30.0f, 70.0f), true); // push camp task on to stack
|
||||
startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (10.0f, 30.0f), true); // push move command
|
||||
|
|
@ -778,7 +778,7 @@ Vector Bot::getCampDirection (const Vector &dest) {
|
|||
return graph[lookAtNode].origin;
|
||||
}
|
||||
}
|
||||
auto dangerIndex = practice.getIndex (m_team, m_currentNodeIndex, m_currentNodeIndex);
|
||||
const auto dangerIndex = practice.getIndex (m_team, m_currentNodeIndex, m_currentNodeIndex);
|
||||
|
||||
if (graph.exists (dangerIndex)) {
|
||||
return graph[dangerIndex].origin;
|
||||
|
|
|
|||
|
|
@ -2300,7 +2300,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) {
|
|||
}
|
||||
|
||||
// perform DFS instead of floyd-warshall, this shit speedup this process in a bit
|
||||
auto length = cr::min (static_cast <size_t> (kMaxNodes), m_paths.length ());
|
||||
const auto length = cr::min (static_cast <size_t> (kMaxNodes), m_paths.length ());
|
||||
|
||||
// ensure valid capacity
|
||||
assert (length > 8 && length < static_cast <size_t> (kMaxNodes));
|
||||
|
|
|
|||
|
|
@ -2153,9 +2153,6 @@ bool Bot::selectBestNextNode () {
|
|||
// this function does a realtime post processing of nodes return from the
|
||||
// pathfinder, to vary paths and find the best node on our way
|
||||
|
||||
assert (!m_pathWalk.empty ());
|
||||
assert (m_pathWalk.hasNext ());
|
||||
|
||||
const auto nextNodeIndex = m_pathWalk.next ();
|
||||
const auto currentNodeIndex = m_pathWalk.first ();
|
||||
const auto prevNodeIndex = m_currentNodeIndex;
|
||||
|
|
|
|||
|
|
@ -412,7 +412,9 @@ void BotSupport::updateClients () {
|
|||
}
|
||||
|
||||
int BotSupport::getPingBitmask (edict_t *ent, int loss, int ping) {
|
||||
// this function generats bitmask for SVC_PINGS engine message. See SV_EmitPings from engine for details
|
||||
// this function generates bitmask for SVC_PINGS engine message
|
||||
// see:
|
||||
// https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/sv_main.cpp#L4590
|
||||
|
||||
const auto emit = [] (int s0, int s1, int s2) {
|
||||
return (s0 & (cr::bit (s1) - 1)) << s2;
|
||||
|
|
@ -443,6 +445,16 @@ void BotSupport::syncCalculatePings () {
|
|||
int ping, loss;
|
||||
engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss);
|
||||
|
||||
// @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread
|
||||
// since the function doesn't modify anything inside engine, so race-condition and crash isn't viable situation
|
||||
// it's just fills ping and loss from engine structures, the only way to cause crash in separate thread
|
||||
// is to call it with a invalid ``client`` pointer (on goldsrc), thus causing Con_Printf which is not compatible with
|
||||
// multi-threaded environment
|
||||
//
|
||||
// see:
|
||||
// https://github.com/dreamstalker/rehlds/blob/a680f18ee1e7eb8c39fbdc45682163ca9477d783/rehlds/engine/pr_cmds.cpp#L2735C15-L2735C32
|
||||
// https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443
|
||||
|
||||
// store normal client ping
|
||||
client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails
|
||||
++numHumans;
|
||||
|
|
|
|||
|
|
@ -337,7 +337,18 @@ void Bot::updateBodyAngles () {
|
|||
}
|
||||
|
||||
void Bot::updateLookAngles () {
|
||||
const float delta = cr::clamp (game.time () - m_lookUpdateTime, cr::kFloatEqualEpsilon, 1.0f / 30.0f);
|
||||
worker.enqueue ([this] () {
|
||||
syncUpdateLookAngles ();
|
||||
});
|
||||
}
|
||||
|
||||
void Bot::syncUpdateLookAngles () {
|
||||
if (!m_lookAnglesLock.tryLock ()) {
|
||||
return; // allow only single instance of syncUpdateLookAngles per-bot
|
||||
}
|
||||
ScopedUnlock <Mutex> unlock (m_lookAnglesLock);
|
||||
|
||||
const float delta = cr::clamp (game.time () - m_lookUpdateTime, cr::kFloatEqualEpsilon, kViewFrameUpdate);
|
||||
m_lookUpdateTime = game.time ();
|
||||
|
||||
// adjust all body and view angles to face an absolute vector
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<EnableASAN>false</EnableASAN>
|
||||
|
|
@ -137,7 +137,7 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>ClangCL</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<EnableASAN>false</EnableASAN>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue