// Logs every action/behavior/component allocation or deallocation
// Used to track memory leaks
// 1 - Enable memory debug, 0 - Disable memory debug
ext_actions_debug_memory "0"
Commands
PHP Code:
ext_actions_dump - Dumps every nextbot actions to console.
Guide Samples
Action Handlers
You can hook action handler by setting it's callback function (or unhook with INVALID_FUNCTION)
PHP Code:
action.OnUpdate = OnUpdate;
Simple example, if you need to hook "Update" handler of every "whatever" action
PHP Code:
/*
* OnActionCreated notifies whenever entity got a new action but without actual transition yet.
* That means action is constructed by the corresponding constructor and still hasn't been updated or * started yet.
*/
public void OnActionCreated(BehaviorAction action, int actor, const char[] name)
{
if (strcmp(name, "whatever") = 0)
{
action.Update = OnWhateverUpdate;
}
}
public Action OnWhateverUpdate(BehaviorAction action, int actor, float interval, ActionResult)
{
// unhook it
action.Update = INVALID_FUNCTION;
return Plugin_Continue;
}
You can store any data in action with and without identity
Data stored without identity is shared between plugins and persists until action is deleted
Data stored with identity is NOT shared between plugins (multiple plugins can use same keys) and persists until plugin who owns the data is unloaded
Usually you want to store data without identity, the latter is for specific use cases where you want to store handles or something important that has to be accessible even if action is destroyed
Example:
PHP Code:
public void OnActionCreated(BehaviorAction action, int actor, const char[] name)
{
// to store with identity add "Identity" after Data
// action.SetUserDataIdentity("my_int", 2);
// action.SetUserDataIdentityVector("my_vector", { -89.0, 125.0, -5324.0 });
action.SetUserData("my_int", 2);
action.SetUserData("my_float", 2.25);
action.SetUserDataVector("my_vector", { -89.0, 125.0, -5324.0 });
action.SetUserDataString("my_string", "Test test test test");
}
public void OnActionDestroyed(BehaviorAction action, int actor, const char[] name)
{
int ivalue, fvalue;
float vector[3];
char buffer[64];
If you want to create internal game actions then you need to create SDKCall then call it on allocated memory.
Even if this approach works, I still think there should be a way to hide SDKCall and memory allocation into gamedata.
So there is ActionConstructor
PHP Code:
ActionConstructor g_SampleActionConstructor;
public void OnPluginStart()
{
GameData data = new GameData("");
"params"
{
"target"
{
/*
* basic - plain generic data
* float - floating point data
* object - raw struct/class/array?
*/
"type" "basic"
/*
* byval - pass by val
* byref - pass by ref
* dtor - object has destructor
* ctor - object has constructor
* assignop - object has assignment operator
* unalign - object contains unaligned fields
*/
"flags" "byval"
// You can specify encoder to transform arbitary data to valve params (eg. entity index -> CBaseEntity)
/*
* entity - entity index to CBaseEntity
* vector - raw array to Vector struct
*/
"encoder" "entity"
}
}
}
}
}
}
Action Component
All actions are eventually stored in the behavior and behavior is stored in IIntention component.
You can create your own IIntention component called "ActionComponent"
The created component works exactly the same as the other components but you can also delete it at any time
If the plugin is unloaded all its components will be deleted automatically
PHP Code:
#include <actions>
public void OnPluginStart()
{
HookEvent("player_spawn", player_spawn);
}
public Action Suspendable_Update(BehaviorAction action, int actor, float interval, ActionResult result)
{
action.Update = INVALID_FUNCTION;
int approach_target;
if (ActionsManager.GetActionUserData(action, "approach_target", approach_target))
{
if ((approach_target = EntRefToEntIndex(approach_target)) <= 0)
return Plugin_Continue;
public Action SurvivorApproach_Update(BehaviorAction action, int actor, float interval, ActionResult result)
{
float origin[3], goal[3];
GetClientAbsOrigin(actor, origin);
if (!ActionsManager.GetActionUserDataVector(action, "survivor_approach_goal", goal))
{
int target = EntRefToEntIndex(action.GetUserData("survivor_approach_target"));
- Fixed InitialContainedAction handler for custom actions
I understand that with the help of your extension, can force a tank to attack a certain player or make him just stand still or run away from players or even make zombie friends for a survivors, I understand that the extension gives full control over the intelligence of entities that is embedded in the game engine?)
__________________
-
PHP Code:
public OnClientConnect(int Client) {
KickClient(Client, "sorry");
}
Using nb_move_to_cursor and nb_move_to_position seems to crash when a bot is spawned in when using this amazing extension.
And I for the life of me can not figure out how to use or what this is even supposed to do, Am somewhat new to messing with plugins at times. Any help on what it is supposed to do and how to use would be amazing!
PHP Code:
/* Used to iterate through all entity actions */
public static native void Actions( int entity, ActionsIteratorCallback callback );
And GetName() doesn't seem to work when getting the name of a result action like
Using nb_move_to_cursor and nb_move_to_position seems to crash when a bot is spawned in when using this amazing extension.
Thanks for report. Fixed
Quote:
Originally Posted by NightlyRaine
And I for the life of me can not figure out how to use or what this is even supposed to do, Am somewhat new to messing with plugins at times. Any help on what it is supposed to do and how to use would be amazing!
It will give every action that passed entity contains. There is no way to legally create ArrayList via extension so that's the only way how can you pass multiple objects without creating your own handle type.
How to use
PHP Code:
#pragma semicolon 1
#pragma newdecls required
#include <sdktools>
#include <actions>
public void OnPluginStart()
{
RegConsoleCmd("sm_actions", sm_actions);
}
public Action sm_actions( int client, int args )
{
int target = GetClientAimTarget(client, false);