A friendly extension for plugins makers to use in order to create custom NPCs or utilise some advanced functions from Source Engine.

All of that and more in the future, on the game Team Fortress 2, and other source games (although that last part will require some work on your side, but it's a long term goal).
General Overview :
It's hard to list everything this extension has to offer for plugin makers. A good idea would be to simply read the .inc files.
HTML Code:
- Custom NPC entity (base_npc) on which you can utilize Valve's Nextbot framework
- Custom entity factory & datamaps, yes you can register custom entities
- Most of navmesh functions
- CBaseEntity functions
- CBaseAnimating functions
- CBaseAnimatingOverlay functions
Custom Entity Factories :
With this extension you can create custom entity factories, with custom datamap fields, inputs and outputs. No more need to create giant enum structs or methodmaps to retain a bunch of properties regarding a given entity.
And if you're also a mapper, yes this allows you to add custom entities to your game.fdg file !
Example code
PHP Code:
CEntityFactory EntityFactory = new CEntityFactory("prop_dynamic_sourcemod");
EntityFactory.DeriveFromClass("prop_dynamic");
EntityFactory.BeginDataMapDesc()
.DefineIntField("m_screamCount")
.DefineIntField("m_shieldHealth")
.DefineEntityField("m_effectEntity")
.DefineFloatField("m_timeBeforeUniverseCollapse")
.DefineInputFunc("SayNumber", InputFuncValueType_Integer, InputSayNumber)
.DefineOutput("OnScreamed")
.EndDataMapDesc();
We also allow overriding of base game factories ! Yes you can add more datamaps, attach a nextbot interface, or even an intention interface go wild !
Example code
PHP Code:
CEntityFactory EntityFactory = new CEntityFactory("player");
EntityFactory.DeriveFromClass("player");
EntityFactory.AttachNextBot(ToolsNextBotPlayer_Factory);
EntityFactory.Install();
Custom NextBot Intention (Action) interface :
Do you wish to completely override a given NextBot's brain (like Meramus on TF2). Or instead create your own entity with a brain ? The extension allows that. All the Action callbacks are exposed for your plugins.
Example code
PHP Code:
CEntityFactory EntityFactory = new CEntityFactory("meramus");
EntityFactory.DeriveFromClass("meramus");
EntityFactory.SetInitialActionFactory(YourPlugin_ActionFactory);
EntityFactory.Install();
PHP Code:
CEntityFactory EntityFactory = new CEntityFactory("my_marvelous_custom_npc");
EntityFactory.DeriveFromNPC();
EntityFactory.SetInitialActionFactory(YourPlugin_ActionFactory);
EntityFactory.Install();
PHP Code:
static NextBotActionFactory ActionFactory;
void YourPlugin_ActionInitialize() // Call under OnPluginStart or wherever, just once
{
ActionFactory = new NextBotActionFactory("ScoutBaitAction");
ActionFactory.BeginDataMapDesc()
.DefineFloatField("m_flNextSoundTime")
.DefineFloatField("m_flFinishTime")
.EndDataMapDesc();
ActionFactory.SetCallback(NextBotActionCallbackType_OnStart, OnStart);
ActionFactory.SetCallback(NextBotActionCallbackType_Update, Update);
ActionFactory.SetCallback(NextBotActionCallbackType_OnEnd, OnEnd);
ActionFactory.SetCallback(NextBotActionCallbackType_OnSuspend, OnSuspend);
ActionFactory.SetEventCallback(EventResponderType_OnInjured, OnInjured);
}
NextBotActionFactory YourPlugin_ActionFactory()
{
return ActionFactory;
}
The Intention(Action) framework is built to work exactly the same way valve's would. And if you wish to switch to another action, just initialise another action factory and use it like so.
PHP Code:
static int Update(NextBotAction action, int actor, float interval)
{
if (action.GetDataFloat("m_flFinishTime") < GetGameTime())
{
return action.SuspendFor(anotherActionFactory.Create());
}
return action.Continue();
}
NextBot functions :
If you wish to interact with the various NextBot objects. The extension exposes natives for the following interfaces :
PHP Code:
IVision
ILocomotion
IIntention
INextBot
Path
And of course, the extension also allows for the instanciation of PathFollower & ChasePath objects.
NavMesh functions :
The extension offers a very large chunk of valve's nav framework.
For instance we expose TheNavMesh global pointer, as well as a lot of its associated functions. If you ever used our navmesh plugin before, these should be familiar to you. Otherwise just read the inc files to see what each function does.
HTML Code:
CNavMesh natives :
.Address
.IsLoaded
.IsAnalyzed
.IsOutOfDate
.GetNavAreaCount
.GetNavArea
.GetNavAreaEntity
.CollectSurroundingAreas
.GetNavAreaByID
.GetNearestNavArea
.BuildPath
And of course, the extension also exposes nav area natives.
HTML Code:
CNavArea natives :
.UpdateBlocked
.IsBlocked
.GetID
.GetCorner
.GetCenter
.GetAdjacentCount
.GetAdjacentArea
.GetAttributes
.HasAttributes
.SetParent
.GetParent
.GetParentHow
.SetCostSoFar
.GetCostSoFar
.SetTotalCost
.GetTotalCost
.SetPathLengthSoFar
.GetPathLengthSoFar
.ComputePortal
.ComputeClosestPointInPortal
.GetClosestPointOnArea
.GetDistanceSquaredToPoint
.ComputeAdjacentConnectionHeightChange
[... And way way more, too much to list in this forum post, check out the .inc files !]
We also expose nav area ladder natives, as well as navmesh hiding spots.
SDK functions :
On top of everything above, the extension also offers natives for very common entities in source.
HTML Code:
CBaseEntity natives :
.NetworkProp
.CollisionProp
.NetworkStateChanged
.NetworkStateChangedVar
.Set/GetAbsOrigin
.Set/GetAbsAngles
.Set/GetAbsVelocity
.Set/GetLocalOrigin
.Set/GetLocalAngles
.Spawn
.Teleport
.WorldSpaceCenter
.GetVectors
.MyNextBotPointer
.GetBaseAnimating
.MyCombatCharacterPointer
.IsNetworkable
[... And again way way more than we can list in a single forum post ]
HTML Code:
CBaseAnimating natives :
.StudioFrameAdvance
.DispatchAnimEvents
.LookupSequence
.SequenceDuration
.SelectWeightedSequence
.ResetSequence
.LookupAttachment
.GetAttachment
.GetAttachmentMatrix
.GetModelPtr
.LookupPoseParameter
.SetPoseParameter
.GetPoseParameter
HTML Code:
CBaseAnimatingOverlay natives :
.AddGestureSequence
.AddGesture
.IsPlayingGesture
.RestartGesture
.RemoveAllGestures
.AddLayeredSequence
.SetLayerPriority
.IsValidLayer
.Set/GetLayerDuration
.Set/GetLayerCycle
.SetLayerPlaybackRate
.Set/GetLayerWeight
[... And more layer related functions ]
HTML Code:
CBaseCombatCharacter natives :
.UpdateLastKnownArea
.GetLastKnownArea
Documentation :
Ultimately it's hard to condense everything the extension can do in a single forum post, our include files are very well documented, and you shouldn't have much troubles getting started. Should that still be a problem, we provide example plugins on our repository.
Credits :
-
KitRifty : Maintains the extension with me, and made the custom factory & datamap feature as well as being a formidable bug hunter.
-
Arthurdead : Original, deleted, extension "pluginbot" on which the framework was built.
-
Pelipoika : Figured CBaseAnimatingOverlay's overlay structure.
-
Drixevel : Excellent test subject.
- Light08 : Excellent test subject.
Links :
Source & Download
Warning if compiling the ext for tf2, we use a custom sdk make sure you compile against it, OR YOUR SERVER WILL CRASH!
Custom TF2 SDK
Changelog :
HTML Code:
23/07/2023 - 1.9.0
- Added `CTakeDamageInfo` natives
CTakeDamageInfo.CTakeDamageInfo
GetInflictor
SetInflictor
GetWeapon
SetWeapon
GetAttacker
SetAttacker
GetDamage
SetDamage
GetMaxDamage
SetMaxDamage
ScaleDamage
AddDamage
SubtractDamage
GetDamageBonus
SetDamageBonus
GetDamageBonusProvider
GetBaseDamage
BaseDamageIsValid
GetDamageForce
SetDamageForce
ScaleDamageForce
GetDamageForForceCalc
SetDamageForForceCalc
GetDamagePosition
SetDamagePosition
GetReportedPosition
SetReportedPosition
GetDamageType
SetDamageType
AddDamageType
GetDamageCustom
SetDamageCustom
GetDamageStats
SetDamageStats
SetForceFriendlyFire
IsForceFriendlyFire
GetAmmoType
SetAmmoType
GetAmmoName
GetPlayerPenetrationCount
SetPlayerPenetrationCount
GetDamagedOtherPlayers
SetDamagedOtherPlayers
SetCritType
GetCritType
- Refactored natives code
- Fixed a bug where `CBaseNPC` and `CExtNPC` natives would not throw an error when using `INVALID_NPC` index
05/06/2023 - 1.8.5
- Fixed a crash that would occur on SM 1.12.6998 or later
14/03/2023 - 1.8.4
- Fixed misaligned memory for entities allocated with a custom constructor (gamedata)
19/02/2023 - 1.8.3
- Fixes a case where the IsHindrance query callback fails to take into account a special CBaseEntity* value called IS_ANY_HINDRANCE_POSSIBLE.
- Fixes a case where using CBaseNPC_Locomotion.CallBaseFunction within IsEntityTraversable and ShouldCollideWith callbacks resulted in a crash.
- Reformated include guards to use #endinput and to use relative paths instead. This notably fix headers with the sourcepawn VSCode extension.
- Added examples to using CBaseNPC_Locomotion callbacks to the scout test bot.
03/12/2022 - 1.8.2
- Fixed a rare crash related to tf2 vscript update
02/12/2022 - 1.8.1
- Rebuilt the extension against our updated custom tf2 sdk
02/12/2022 - 1.8.0
- VScript gamedata update
20/11/2022 - 1.7.1
- Fix OnOtherKilled event callback not passing victim parameter
25/07/2022 - 1.7.0
- Added a new NextBot interface, intended to mimic NextBotPlayer
- The blank NextBot interface, and the NextBotPlayer interface can now be instanciated with the following stocks/natives :
ToolsNextBot_Factory
ToolsNextBotPlayer_Factory
- Added the ability to provide a NextBot factory to CBaseCombatCharacter based factories
20/07/2022 - 1.6.2
- Added CBaseEntity-based typedefs to typesets
07/07/2022 - 1.6.1
- Fixed GetDataDescMap returning an invalid pointer during entity delition
07/07/2022 - 1.6.0
- Added the following natives
NextBotAction.GetDataEnt
NextBotAction.SetDataEnt
NextBotActionFactory.DefineEntityField
06/07/2022 - 1.5.3
- Destroy NextBot interface before detaching datamap
04/07/2022 - 1.5.2
- Fixed a crash when uninstalling a CEntityFactory
03/07/2022 - 1.5.1
- Build against SM 1.11
03/07/2022 - 1.5.0
- Allow overriding of game entity factories
- Introduced blank NextBot interfaced
06/06/2022 - 1.4.0
- Fixed an error case with BuildPath returning false when it shouldn't under some conditions
- Added more NavMesh natives
CNavArea.IsOverlappingX
CNavArea.IsOverlappingY
CNavArea.GetExtent
CNavArea.ContainsPoint
CNavMesh.GetNavArea
CNavMesh.GetNavAreaEntity
- Added the following stocks
DirectionLeft
DirectionRight
DirectionToAngle
AngleToDirection
07/02/2022 - 1.3.1 # Note this should have been a version update, not a patch
- Fixed CNavArea.SetCostSoFar not registered as a native
- Fixed CNavArea.GetSizeX/Y not being defined in includes
- Added more NavMesh natives
TheNavMesh.BuildPath
CNavArea.Get/SetTotalCost
CNavArea.Get/SetPathLengthSoFar
CNavArea.ComputePortal
CNavArea.ComputeClosestPointInPortal
CNavArea.GetClosestPointOnArea
CNavArea.ComputeAdjacentConnectionHeightChange
CNavArea.IsOverlappingPoint
CNavArea.IsOverlappingArea
CNavArea.IsOverlappingExtent
CNavArea.GetDistanceSquaredToPoint
CNavArea.IsEntirelyVisible
CNavArea.IsPartiallyVisible
CNavArea.IsPotentiallyVisible
CNavArea.IsCompletelyVisible
14/01/2022 - 1.3.0
- Fixed the behaviour of RemoveEntity under action callbacks
- Fixed warnings for SM 1.11 compilation in example plugins
16/11/2021 - 1.2.1
- Gamedata update for TF2 update
15/11/2021 - 1.2.0
- Added a lot of NavMesh natives
OppositeDirection()
CNavMesh.Address
CNavMesh.IsLoaded()
CNavMesh.IsAnalyzed()
CNavMesh.IsOutOfDate()
CNavMesh.GetNavAreaCount()
CNavArea.GetAdjacentCount()
CNavArea.GetAdjacentArea()
CNavArea.GetAdjacentAreas()
CNavArea.GetIncomingConnectionCount()
CNavArea.GetIncomingConnection()
CNavArea.GetIncomingConnections()
CNavArea.GetLightIntensity()
CNavArea.GetPositionLightIntensity()
CNavArea.GetHidingSpotCount()
CNavArea.GetHidingSpot()
CNavArea.GetHidingSpots()
CNavArea.ClearSearchLists()
CNavArea.IsOpenListEmpty()
CNavArea.PopOpenList()
CNavArea.IsOpen()
CNavArea.AddToOpenList()
CNavArea.UpdateOnOpenList()
CNavArea.IsClosed()
CNavArea.AddToClosedList()
14/11/2021 - 1.1.0
- Allow plugin makers, to control CBaseNPC locomotion interface.
This will eventually be expanded to encompass all locomotion interfaces.
14/11/2021 - 1.0.0
- Extension can now be compiled with AMBuild 2.2
- Removed threaded nav
11/11/2021 - Public release
After 4 years, we're public. Scary.
__________________