Skip to content

Commit

Permalink
Small Changes
Browse files Browse the repository at this point in the history
- Warn when trying to add bots on maps without a navigation mesh.
- Expose more natives to SourceMod plugins.
- Add bot command now accepts an optional bot name.
  • Loading branch information
caxanga334 committed Oct 12, 2024
1 parent 725e8f1 commit 94e5262
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 14 deletions.
15 changes: 14 additions & 1 deletion extension/concommands_bots.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,20 @@

CON_COMMAND(sm_navbot_add, "Adds a Nav Bot to the game.")
{
extmanager->AddBot();
if (!TheNavMesh->IsLoaded())
{
Warning("Nav Mesh not loaded, bots will not be able to move!");
}

if (args.ArgC() < 2)
{
extmanager->AddBot(nullptr, nullptr);
}
else
{
std::string botname(args[1]);
extmanager->AddBot(&botname, nullptr);
}
}

CON_COMMAND(sm_navbot_kick, "Removes a Nav Bot from the game.")
Expand Down
42 changes: 30 additions & 12 deletions extension/manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,27 +280,34 @@ bool CExtManager::IsNavBot(const int client) const
return false;
}

void CExtManager::AddBot()
void CExtManager::AddBot(std::string* newbotname, edict_t** newbotedict)
{
const char* name = nullptr;

if (m_botnames.size() == 0)
if (newbotname != nullptr)
{
char botname[30]{};
std::sprintf(botname, "SMNav Bot #%04d", librandom::generate_random_int(0, 9999));
name = botname;
name = newbotname->c_str();
}
else
{
auto& botname = m_botnames[m_nextbotname];
m_nextbotname++;

if (m_nextbotname >= m_botnames.size())
if (m_botnames.empty())
{
m_nextbotname = 0; // go back to start
char botname[30]{};
std::sprintf(botname, "NavBot #%04d", librandom::generate_random_int(0, 9999));
name = botname;
}
else
{
auto& botname = m_botnames[m_nextbotname];
m_nextbotname++;

name = botname.c_str();
if (m_nextbotname >= m_botnames.size())
{
m_nextbotname = 0; // go back to start
}

name = botname.c_str();
}
}

// Tell the bot manager to create a new bot. Now that we are using SourceHooks, we need to catch the bot on 'OnClientPutInServer'.
Expand All @@ -311,6 +318,12 @@ void CExtManager::AddBot()
if (edict == nullptr)
{
smutils->LogError(myself, "Failed to create a new bot with the Bot Manager interface!");

if (newbotedict != nullptr)
{
newbotedict = nullptr;
}

return;
}

Expand All @@ -329,6 +342,11 @@ void CExtManager::AddBot()
bot->GetInventoryInterface();
#endif // EXT_DEBUG

if (newbotedict != nullptr)
{
newbotedict = &edict;
}

smutils->LogMessage(myself, "NavBot added to the game.");
}

Expand Down Expand Up @@ -407,7 +425,7 @@ void CExtManager::LoadBotNames()
}
#endif // EXT_DEBUG

rootconsole->ConsolePrint("[SMNav] Bot name list loaded with %i names.", m_botnames.size());
rootconsole->ConsolePrint("[NavBot] Bot name list loaded with %i names.", m_botnames.size());
}

void CExtManager::UpdateBotQuota()
Expand Down
2 changes: 1 addition & 1 deletion extension/manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CExtManager
CBaseBot* GetBotByIndex(int index);
bool IsNavBot(const int client) const;

void AddBot();
void AddBot(std::string* newbotname = nullptr, edict_t** newbotedict = nullptr);
void RemoveRandomBot(const char* message);
void RemoveAllBots(const char* message);

Expand Down
46 changes: 46 additions & 0 deletions extension/natives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace natives
{
sp_nativeinfo_t list[] = {
{"IsNavBot", IsNavBot},
{"AddNavBot", AddNavBot},
{"IsNavMeshLoaded", IsNavMeshLoaded},
};

nv.insert(nv.end(), std::begin(list), std::end(list));
Expand All @@ -32,4 +34,48 @@ namespace natives

return isbot ? 1 : 0;
}

cell_t AddNavBot(IPluginContext* context, const cell_t* params)
{
if (!TheNavMesh->IsLoaded())
{
context->ReportError("Cannot add bot. Navigation Mesh is not loaded!");
return 0;
}

cell_t* client = nullptr;
edict_t* edict = nullptr;

context->LocalToPhysAddr(params[1], &client);

char* szName = nullptr;

context->LocalToStringNULL(params[2], &szName);

if (szName != nullptr)
{
std::string name(szName);

extmanager->AddBot(&name, &edict);
}
else
{
extmanager->AddBot(nullptr, &edict);
}

if (edict == nullptr)
{
*client = 0;
return 0;
}

*client = static_cast<cell_t>(gamehelpers->IndexOfEdict(edict));

return 1;
}

cell_t IsNavMeshLoaded(IPluginContext* context, const cell_t* params)
{
return TheNavMesh->IsLoaded() ? 1 : 0;
}
}
2 changes: 2 additions & 0 deletions extension/natives.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace natives
{
void setup(std::vector<sp_nativeinfo_t>& nv);
cell_t IsNavBot(IPluginContext* context, const cell_t* params);
cell_t AddNavBot(IPluginContext* context, const cell_t* params);
cell_t IsNavMeshLoaded(IPluginContext* context, const cell_t* params);
}


Expand Down
19 changes: 19 additions & 0 deletions scripting/include/navbot.inc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,29 @@
* Checks if the given client is a NavBot managed fake client.
*
* @param client Client index.
* @return True if the given client is a NavBot, false otherwise.
* @error Invalid client index
*/
native bool IsNavBot(int client);

/**
* Adds a NavBot.
*
* @param client The index of the bot just added.
* @param botName Optional bot name. NULL_STRING to use a random name.
* @return True if the bot was added, false otherwise.
* @error AddBot unavailable.
*/
native bool AddNavBot(int& client, const char[] botName = NULL_STRING);


/**
* Checks if NavBot's Navigation Mesh for the current map is loaded.
*
* @return True if loaded, false otherwise.
*/
native bool IsNavMeshLoaded();

/**
* Do not edit below this line!
*/
Expand Down

0 comments on commit 94e5262

Please sign in to comment.