View Single Post
Author Message
Benoist3012
Veteran Member
Join Date: Mar 2014
Location: CWave::ForceFinish()
Old 11-11-2021 , 12:44   [ANY?/TF2] SourceTools - NPC Framework & SDK Tools
Reply With Quote #1

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_IntegerInputSayNumber)
    .
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_OnStartOnStart);
    
ActionFactory.SetCallback(NextBotActionCallbackType_UpdateUpdate);
    
ActionFactory.SetCallback(NextBotActionCallbackType_OnEndOnEnd);
    
ActionFactory.SetCallback(NextBotActionCallbackType_OnSuspendOnSuspend);
    
ActionFactory.SetEventCallback(EventResponderType_OnInjuredOnInjured);
}

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 actionint actorfloat 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.
__________________

Last edited by Benoist3012; 08-01-2023 at 03:45.
Benoist3012 is offline