Server: add AI task debug code

Reimplement CAI_BaseNPC::TaskFail.
This commit is contained in:
Kawe Mazidjatari 2024-07-28 22:36:05 +02:00
parent 47aee3125d
commit 5c4a66f5b5
6 changed files with 115 additions and 1 deletions

View File

@ -138,6 +138,7 @@
#include "game/server/movehelper_server.h"
#include "game/server/player.h"
#include "game/server/player_command.h"
#include "game/server/ai_basenpc.h"
#include "game/server/physics_main.h"
#include "game/server/vscript_server.h"
#endif // !CLIENT_DLL
@ -668,6 +669,7 @@ void DetourRegister() // Register detour classes to be searched and hooked.
REGISTER(VBaseEntity);
REGISTER(VBaseAnimating);
REGISTER(VPlayer);
REGISTER(VAI_BaseNPC);
REGISTER(VPlayerMove);
#endif // !CLIENT_DLL

View File

@ -82,6 +82,7 @@ add_sources( SOURCE_GROUP "AI"
"server/ai_node.h"
"server/ai_utility.cpp"
"server/ai_utility.h"
"server/ai_task.cpp"
"server/ai_task.h"
"server/ai_schedule.cpp"
"server/ai_schedule.h"

View File

@ -4,4 +4,25 @@
//
//=============================================================================//
#include "ai_basenpc.h"
#include "game/shared/util_shared.h"
static ConVar ai_debug_tasks("ai_debug_tasks", "0", FCVAR_DEVELOPMENTONLY, "Debug the attempted tasks");
void CAI_BaseNPC::_TaskFail(CAI_BaseNPC* thisptr, const AI_TaskFailureCode_t code)
{
if (ai_debug_tasks.GetBool())
{
thisptr->m_failText = TaskFailureToString(code);
thisptr->m_failedSchedule = thisptr->GetCurSchedule();
Msg(eDLL_T::SERVER, "TaskFail -> %s (%s)\n", thisptr->m_failText, UTIL_GetEntityScriptInfo(thisptr));
}
CAI_BaseNPC__TaskFail(thisptr, code);
}
void VAI_BaseNPC::Detour(const bool bAttach) const
{
DetourSetup(&CAI_BaseNPC__TaskFail, &CAI_BaseNPC::_TaskFail, bAttach);
}

View File

@ -91,6 +91,17 @@ class CAI_BaseNPC : public CBaseCombatCharacter,
public IAI_BehaviorBridge
{
public:
// Hook statics
static void _TaskFail(CAI_BaseNPC* thisptr, const AI_TaskFailureCode_t code);
public:
//-----------------------------------------------------
//
// Schedules & tasks
//
//-----------------------------------------------------
inline CAI_Schedule* GetCurSchedule() const { return m_pSchedule; }
float GetTimeScheduleStarted() const { return m_ScheduleState.timeStarted; }
private:
int m_threadedPostProcessJob;
@ -431,4 +442,24 @@ private:
static_assert(sizeof(CAI_BaseNPC) == 0x6648);
inline void(*CAI_BaseNPC__TaskFail)(CAI_BaseNPC* thisptr, const AI_TaskFailureCode_t code);
///////////////////////////////////////////////////////////////////////////////
class VAI_BaseNPC : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("CAI_BaseNPC::TaskFail", CAI_BaseNPC__TaskFail);
}
virtual void GetFun(void) const
{
g_GameDll.FindPatternSIMD("48 89 5C 24 ?? 57 48 83 EC ?? 48 8B D9 48 8B FA 48 81 C1 ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 83 FF").GetPtr(CAI_BaseNPC__TaskFail);
}
virtual void GetVar(void) const { }
virtual void GetCon(void) const { }
virtual void Detour(const bool bAttach) const;
};
///////////////////////////////////////////////////////////////////////////////
#endif // AI_BASENPC_H

View File

@ -0,0 +1,59 @@
//====== Copyright © 1996-2005, Valve Corporation, All rights reserved. =======//
//
// Purpose: Sets up the tasks for default AI.
//
// $NoKeywords: $
//=============================================================================//
//#include "ai_basenpc.h"
#include "ai_task.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
static const char* const s_ppszTaskFailureText[NUM_FAIL_CODES] =
{
"No failure", // NO_TASK_FAILURE
"No target", // FAIL_NO_TARGET
"Weapon owned by someone else", // FAIL_WEAPON_OWNED
"Item doesn't exist", // FAIL_ITEM_NO_FIND
"No hint node", // FAIL_NO_HINT_NODE
"Schedule not found", // FAIL_SCHEDULE_NOT_FOUND
"Don't have an enemy", // FAIL_NO_ENEMY
"Found no near node", // FAIL_NO_NEAR_NODE
"Found no back away node", // FAIL_NO_BACKAWAY_NODE
"Couldn't find cover", // FAIL_NO_COVER
"Couldn't find flank", // FAIL_NO_FLANK
"Couldn't find shoot position", // FAIL_NO_SHOOT
"Don't have a route", // FAIL_NO_ROUTE
"Don't have a route: no goal", // FAIL_NO_ROUTE_GOAL
"Don't have a route: blocked", // FAIL_NO_ROUTE_BLOCKED
"Don't have a route: illegal move", // FAIL_NO_ROUTE_ILLEGAL
"Couldn't walk to target", // FAIL_NO_WALK
"Don't have LOS", // FAIL_NO_LOS
"Node already locked", // FAIL_ALREADY_LOCKED
"No sound present", // FAIL_NO_SOUND
"Bad activity", // FAIL_BAD_ACTIVITY
"No goal entity", // FAIL_NO_GOAL
"No player", // FAIL_NO_PLAYER
"Can't reach any nodes", // FAIL_NO_REACHABLE_NODE
"No AI Network to use", // FAIL_NO_AI_NETWORK
"No start position", // FAIL_NO_START_POSITION
"Bad position to target", // FAIL_BAD_POSITION
"Route destination no longer valid", // FAIL_BAD_PATH_GOAL
"Stuck on top of something", // FAIL_STUCK_ONTOP
"Item has been taken", // FAIL_ITEM_TAKEN
"Too frozen", // FAIL_FROZEN
"Animation blocked", // FAIL_ANIMATION_BLOCKED
"Timeout", // FAIL_TIMEOUT
"Detour specific", // FAIL_DETOUR_SPECIFIC
};
const char* TaskFailureToString(const AI_TaskFailureCode_t code)
{
const char* pszResult;
if (code < 0 || code >= NUM_FAIL_CODES)
pszResult = (const char*)code;
else
pszResult = s_ppszTaskFailureText[code];
return pszResult;
}

View File

@ -14,7 +14,7 @@
typedef intp AI_TaskFailureCode_t;
//=========================================================
// These are th efailure codes
// These are the failure codes
//=========================================================
enum AI_BaseTaskFailureCodes_t
{