View Full Version : New SDK Bot for Source
Source SDK Updated
According to the Steampowered news, a new update for the Source SDK has been released tonight.
Source SDK
>> Added XSI addon for importing and exporting SMDs
>> Added simple SDK bot sample code for adding bots to your mod
>> Added source files for six Half-Life 2 single player maps
>> Added interface plugin to add bots to mods
>> Fixed resource leak in the SDK launcher and vconfig utiity
>> Added bspzip tool — allows you to compile custom content directly into a .bsp
If you're interested in grabbing this update, simply restart your Steam client.
stefanhendriks
20-01-2005, 09:53
I told ya! :D w00t w00t w00t w00t
Running steam! :D
Pierre-Marie Baty
20-01-2005, 10:11
don't jump through the roof yet, they said: "for adding bots to your mod".
See what I mean ?
Whistler
20-01-2005, 10:14
it seems to be something like botman's old HL bot or CZero bot...
Pierre-Marie Baty
20-01-2005, 10:39
my SDK is updated.
http://www.valve-erc.com/srcsdk/Code/bots.html
I'm on it.
C:\bleh\src\dlls\sdk\sdk_bot_temp.cpp
I was right with the CUserCmd : that's all you need for everything.
...and just to be clear, the server plugin bot example is...
C:\MyMod\src\utils\serverplugin_sample\serverplugi n_bot.cpp
botman
it`s good that we have acess to CGlobalVars too now.
stefanhendriks
20-01-2005, 17:40
as far as i can tell , the bot sample plugin should work with the current mod you create. But i don't know if its working for CSS for example, but i did not test this either! (cant!)
If it works for CSS; its definatly NOT creating the turtlerock version, because the command in the plugin is different afaik.
Looks nice so far, can't wait to do something with it...
I tried the plugin bot example in HL2DM.
It can't load some interfaces:
Unable to load playerinfomanager, ignoring
Unable to load botcontroller, ignoring
:(
I guess we still can't create bots for HL2DM.
Edit: The pluginbot works in CSS! So I guess it's CSS only (for now).
how the hell do you get the source for the sample bot plugin? I've refreshed sdk content about twenty times already, still no joy
never mind forget that. just made a new mod :|
anyway gotta update my bot now with all this new non hacky stuff. Still one thing though, I don't know how to get a players edict's flags without CBasePlayer (im removing all cbaseplayer stuff) (im looking for gettign these from normal players or even other entites, not bots)
great well Im trying some new non hacky code and now half of my bots run around in circles, I'm sure valve changed how the angles work from 360 to 180 ranges, and I don't know what else to do, most of the bots still run around in circles, but at least they no look in the right direction :/
cheeseh i think they have check
void Bot_UpdateDirection (CPluginBot *pBot);
it wraps the angles between +/- 180 ranges.
Pierre-Marie Baty
21-01-2005, 09:14
Just for information, I've been dissecating the thing for the night. I'm starting to understand pretty well how the plugin API works. Exactly like metamod, except that they don't seem to hook the network. Anyway, it looks like that unlike in HL1, here we won't even need to catch any network message at all, the game event hooks will certainly provide all that we need. Kudos to Valve. I'm also testing the bot facilities, how they move, how their angle stuff works and what they can do. Everything seems to be quite integrated. I've had a quick look to the trace facilities too, they're impressive. It seems you can define your own hull size for the trace, among other stuff. Wahey, the sun's rising but I certainly ain't going to bed yet!
Pierre-Marie Baty
22-01-2005, 03:16
If some of you want to understand EXACTLY (hopefully, with enough comments) how the plugin interface works, here's a minimalistic bot plugin that fits in 1 file :)
I'll from now use that as a template to port some of my plugins (like PMTools) to Source
///////////////////////////////////////////////////////////////
// Minimalistic Source plugin suitable for bots and most addons
// Wrapped together by Pierre-Marie Baty from Bots-United
// http://forums.bots-united.com
#include <stdio.h>
#define PLUGIN_DESCRIPTION "Bot plugin Source template"
#define WrapAngle(a) ((a) == 180 ? -180 : ((a) >= 180 ? (a) - 360 * abs (((int) (a) + 180) / 360) : ((a) < -180 ? (a) + 360 * abs (((int) (a) - 180) / 360) : (a))))
///////////////////////////////////////////////////////////////////////////////////////
// START of plugin interface
#include "interface.h"
#include "filesystem.h"
#undef VECTOR_NO_SLOW_OPERATIONS
#include "vector.h"
#include "edict.h"
#include "engine/iserverplugin.h"
#include "dlls/iplayerinfo.h"
#include "eiface.h"
#include "igameevents.h"
#include "convar.h"
#include "icvar.h"
#include "engine/IEngineTrace.h"
#include "../../game_shared/in_buttons.h"
#include "../../game_shared/shareddefs.h"
#include "tier0/memdbgon.h"// memdbgon must be the last include file in a .cpp file!!!
// plugin interface virtual function table pointers
IVEngineServer *engine = NULL; // helper engine functions
IFileSystem *filesystem = NULL; // file I/O
IGameEventManager *gameeventmanager = NULL; // game events interface
IPlayerInfoManager *playerinfomanager = NULL; // game dll interface to interact with players
IBotManager *botmanager = NULL; // game dll interface to interact with bots
IServerPluginHelpers *helpers = NULL; // special 3rd party plugin helpers from the engine
IEngineTrace *enginetrace = NULL; // engine trace facilities (lines and hulls)
ICvar *serverconsole = NULL; // plugin's own console access
CGlobalVars *gpGlobals = NULL; // server globals
// plugin interface classes
class CConCommandAccessor: public IConCommandBaseAccessor
{
public:
virtual bool RegisterConCommandBase (ConCommandBase *pCommand)
{
pCommand->AddFlags (FCVAR_PLUGIN);
pCommand->SetNext (0); // Unlink from plugin only list
serverconsole->RegisterConCommandBase (pCommand); // Link to engine's list instead
return (true);
}
};
CConCommandAccessor g_ConVarAccessor; // server console commands AND cvars accessor
class CPlugin: public IServerPluginCallbacks, public IGameEventListener
{
public:
// IServerPluginCallbacks interface
virtual bool Load (CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
{
// get the interfaces we want to use
if (!(playerinfomanager = (IPlayerInfoManager *) gameServerFactory (INTERFACEVERSION_PLAYERINFOMANAGER,NULL))
|| !(botmanager = (IBotManager *) gameServerFactory (INTERFACEVERSION_PLAYERBOTMANAGER, NULL))
|| !(engine = (IVEngineServer *) interfaceFactory (INTERFACEVERSION_VENGINESERVER, NULL))
|| !(gameeventmanager = (IGameEventManager *) interfaceFactory (INTERFACEVERSION_GAMEEVENTSMANAGER,NULL))
|| !(filesystem = (IFileSystem *) interfaceFactory (FILESYSTEM_INTERFACE_VERSION, NULL)) // FIXME: not needed for bots perhaps ?
|| !(helpers = (IServerPluginHelpers *) interfaceFactory (INTERFACEVERSION_ISERVERPLUGINHELPERS, NULL))
|| !(enginetrace = (IEngineTrace *) interfaceFactory (INTERFACEVERSION_ENGINETRACE_SERVER,NULL))
|| !(serverconsole = (ICvar *) interfaceFactory (VENGINE_CVAR_INTERFACE_VERSION, NULL)))
return (false); // we require all these interface to function
gpGlobals = playerinfomanager->GetGlobalVars (); // get a pointer to the engine's globalvars
ConCommandBaseMgr::OneTimeInit (&g_ConVarAccessor); // register any cvars and server commands
return (true); // return true so as to enable the engine to load this plugin
}
virtual void Unload (void) { gameeventmanager->RemoveListener (this); }
virtual void Pause (void) { }
virtual void UnPause (void) { }
virtual const char *GetPluginDescription (void) { return (PLUGIN_DESCRIPTION); }
virtual void LevelInit (char const *pMapName) { gameeventmanager->AddListener (this, true); }
virtual void ServerActivate (edict_t *pEdictList, int edictCount, int clientMax) { }
virtual void GameFrame (bool simulating); // <-- define this one
virtual void LevelShutdown (void) { gameeventmanager->RemoveListener (this); }
virtual void ClientActive (edict_t *pEntity) { }
virtual void ClientDisconnect (edict_t *pEntity) { }
virtual void ClientPutInServer (edict_t *pEntity, char const *playername) { }
virtual void SetCommandClient (int index) { }
virtual void ClientSettingsChanged (edict_t *pEdict) { };
virtual PLUGIN_RESULT ClientConnect (bool *bAllowConnect, edict_t *pEntity, const char *pszName, const char *pszAddress, char *reject, int maxrejectlen) { return (PLUGIN_CONTINUE); }
virtual PLUGIN_RESULT ClientCommand (edict_t *pEntity) { return (PLUGIN_CONTINUE); }
virtual PLUGIN_RESULT NetworkIDValidated (const char *pszUserName, const char *pszNetworkID) { return (PLUGIN_CONTINUE); }
// IGameEventListener interface
virtual void FireGameEvent (KeyValues * event); // <-- define this one
};
// tell the engine to create a plugin interface instance for us
EXPOSE_SINGLE_INTERFACE (CPlugin, IServerPluginCallbacks, INTERFACEVERSION_ISERVERPLUGINCALLBACKS);
// END of plugin interface
///////////////////////////////////////////////////////////////////////////////////////
typedef struct
{
edict_t *pEdict;
bool is_started;
float f_crouch_time;
float f_jump_time;
float f_forward_time;
float f_backwards_time;
float f_strafeleft_time;
float f_straferight_time;
Vector v_angles;
IBotController *m_BotInterface;
IPlayerInfo *m_PlayerInfo;
CBotCmd cmd;
} bot_t;
// global variables
bot_t bots[64];
int bot_count;
// prototypes
void Bot_RunAll (void);
void BotThink (bot_t *pBot);
void BotSelectTeamAndClass (bot_t *pBot);
// plugin server command handler
CON_COMMAND (bot, "bot server command handler")
{
char cmd[128];
char arg1[128];
char arg2[128];
char arg3[128];
if (botmanager == NULL)
return; // reliability check
sprintf (cmd, engine->Cmd_Argv (0));
sprintf (arg1, engine->Cmd_Argv (1));
sprintf (arg2, engine->Cmd_Argv (2));
sprintf (arg3, engine->Cmd_Argv (3));
// have we been requested to add a bot ?
if (strcmp (arg1, "add") == 0)
{
bots[bot_count].pEdict = botmanager->CreateBot ("w00t w00t");
if (bots[bot_count].pEdict != NULL)
{
bots[bot_count].m_BotInterface = botmanager->GetBotController (bots[bot_count].pEdict);
bots[bot_count].m_PlayerInfo = playerinfomanager->GetPlayerInfo (bots[bot_count].pEdict);
bots[bot_count].is_started = false; // need to select team and class
}
bot_count++;
}
// else have we been asked to kick a bot ?
else if (strcmp (arg1, "kick") == 0)
{
; // bleh
}
// etc...
}
void CPlugin::GameFrame (bool simulating)
{
if (simulating)
Bot_RunAll ();
}
void CPlugin::FireGameEvent (KeyValues *event)
{
// do what you want here to catch any game event (check the keyvalue data)
//Msg ("FireGameEvent: Got event \"%s\"\n", event->GetName ());
}
void Bot_RunAll (void)
{
if (!botmanager)
return;
for (int i = 0; i < bot_count; i++)
BotThink (&bots[i]);
}
void BotSelectTeamAndClass (bot_t *pBot)
{
// this is of course game-specific
helpers->ClientCommand (pBot->pEdict, "joingame");
helpers->ClientCommand (pBot->pEdict, "jointeam 3");
helpers->ClientCommand (pBot->pEdict, "joinclass 0");
}
void BotThink (bot_t *pBot)
{
// Run this Bot's AI for one frame.
memset (&pBot->cmd, 0, sizeof (pBot->cmd));
// is the bot not started yet ?
if (!pBot->is_started)
BotSelectTeamAndClass (pBot); // if so, select team and class
// is the bot dead ?
if (pBot->m_PlayerInfo->IsDead ())
return; // don't do anything, wait for new round (note: on other mods, press attack)
// bot AI here
// finally, ask the engine to perform the bot client movement
pBot->m_BotInterface->RunPlayerMove (&pBot->cmd);
}
dead bwoy
22-01-2005, 20:03
PMB, does PMTools allow you to edit map entities? Quite a few people have been asking about that.
Pierre-Marie Baty
22-01-2005, 22:14
Not PMTools. PMTools is a test/diagnosis/monitoring tool. But my MapEdit can. Also look for Austin's MapHack, which is a different version optimized for Counter-Strike; it enables you to add and remove spawn points, weapons, ammo and items in no time. It can convert a CS map into a DE map and reciprocally.
By the way, I'm working on (and WITH) PMTools:Source right now :P
dead bwoy
22-01-2005, 22:28
yea, I was wondering if there was a "maphack" out for CS:Source. I thought your plugin you're porting to Source may have this capability. Sorry for steering off-topic :\
Pierre-Marie how`s the current progress on the PMTools plugin (how long till a public release)?
Pierre-Marie Baty
23-01-2005, 17:18
Not all the functionalities are implemented. Currently it can dump the global vars (including what's in the base class), get the entity list, log to file, hook events and display stuff, but all the rest is still undone (trace stuff, etc.) Currently I'm working on the "printent" command, that displays the internal state of an entity (including its EngineEntity and pUnknown parts). I suppose by the end of the week most of the stuff should be working.
vBulletin® v3.7.1, Copyright ©2000-2009, Jelsoft Enterprises Ltd.