ff_i_events
Event functions.
Event types:
NWNX internal event - is a string - sent to a file that registered the event => Dispatched via NWNX:EE or manual NWNX_Events_SignalEvent
NWNX Console - is a string - uses local variables - uses a script chunk => Registers in ff_i_events::RegisterConsoleCommand => Runs on_console.nss => Dispatches via NWNX_Events_SignalEvent
NWNX SignalEvent
NWN Scripts (int, EVENT_SCRIPT_* / user defined)
Item Tag events (string, itm_*)
-
CURRENT_EVENT
-
int GetUserDefinedEventScript(object oObject)
- Parameters:
oObject – An object. Returns 0 for types that have no user-defined event (item, store, waypoint).
Return oObject’s EVENT_SCRIPT_*_USER_DEFINED_EVENT.
-
void MoveEventScript(object oObject, int nHandler, string sFile = "")
- Parameters:
oObject – An object.
nHandler – An EVENT_SCRIPT_* constant identifying the event slot.
sFile – Script to append to the dispatch list. Skipped when empty, SCRIPT_ON_EVENT, or SCRIPT_NULL. Defaults to “”.
Move script in nHandler’s place to a local variable for unicast dispatch.
-
int GetCurrentEventScript()
Returns the currently executing event script (EVENT_SCRIPT_*) or 0 if not determinable.
-
string GetCurrentEvent()
Return NWNX_Events_GetCurrentEvent first if it exists.
-
void SubscribeToEvent(string sEvent, string sFile, object oObject = OBJECT_INVALID)
- Parameters:
sEvent – The event name.
sFile – Script to call when the event fires. Use
Subscribe to an event, whatever the object.
-
int SendEvent(string sEvent, object oTarget = OBJECT_SELF)
- Parameters:
sEvent – Event name to signal.
oTarget – Object to signal. Defaults to OBJECT_SELF.
Send one event to all files for a single object.
-
string GetConsoleEventName(string sEvent)
- Parameters:
sEvent – Console command name.
Return the ON_CONSOLE_COMMAND__<sEvent> event name (uppercased).
-
void RegisterConsoleCommand(string sCommand, string sFile)
- Parameters:
sCommand – Command string (without “/” prefix)
sFile – File to call on command
Register a command that can be used from nwn-server console.
-
string GetItemTagEventName(string sEvent, string sFileOrTag)
- Parameters:
sEvent – Base event name.
sFileOrTag – Item tag or filename; extension is stripped.
Return the tag-based event name for sEvent and sFileOrTag.
-
void SendItemTagEvent(string sEvent, object oObject, object oTarget = OBJECT_SELF)
- Parameters:
sEvent – Unused; kept for API symmetry.
oObject – Object whose tag is used as the script name.
oTarget – Object the script executes on. Defaults to OBJECT_SELF.
Execute the script named by oObject’s tag on oTarget.
Source code
// @code
#include "ff_i_console"
#include "ff_i_events_c"
#include "ff_i_filesystem"
#include "ff_i_stringify"
#include "nwnx_object"
#include "nwnx_events"
// -----------------------------------------------------------------------------
const string CURRENT_EVENT = "CURRENT_EVENT";
// =============================================================================
// EVENT SCRIPT FUNCTIONS
// =============================================================================
//! @brief Return oObject's EVENT_SCRIPT_*_USER_DEFINED_EVENT
//! @param oObject An object. Returns 0 for types that have no user-defined event (item, store, waypoint).
int GetUserDefinedEventScript(object oObject);
int GetUserDefinedEventScript(object oObject)
{
int nType = NWNX_Object_GetInternalObjectType(oObject);
switch (nType)
{
case NWNX_OBJECT_TYPE_INTERNAL_AREA: return EVENT_SCRIPT_AREA_ON_USER_DEFINED_EVENT;
case NWNX_OBJECT_TYPE_INTERNAL_CREATURE: return EVENT_SCRIPT_CREATURE_ON_USER_DEFINED_EVENT;
case NWNX_OBJECT_TYPE_INTERNAL_DOOR: return EVENT_SCRIPT_DOOR_ON_USERDEFINED;
case NWNX_OBJECT_TYPE_INTERNAL_ITEM: return 0;
case NWNX_OBJECT_TYPE_INTERNAL_MODULE: return EVENT_SCRIPT_MODULE_ON_USER_DEFINED_EVENT;
case NWNX_OBJECT_TYPE_INTERNAL_PLACEABLE: return EVENT_SCRIPT_PLACEABLE_ON_USER_DEFINED_EVENT;
case NWNX_OBJECT_TYPE_INTERNAL_STORE: return 0;
case NWNX_OBJECT_TYPE_INTERNAL_TRIGGER: return EVENT_SCRIPT_TRIGGER_ON_USER_DEFINED_EVENT;
case NWNX_OBJECT_TYPE_INTERNAL_WAYPOINT: return 0;
default:
LogError(__FILE__ + "::" + __FUNCTION__ + ":" + IntToString(__LINE__) + ", object type " + IntToString(nType) + " not mapped to script");
LogStackTrace(__FILE__, __FUNCTION__, __LINE__);
return 0;
}
return 0;
}
// -----------------------------------------------------------------------------
// Fixup the string by removing duplicates, double commas, etc.
string _TrimScripts(string sScripts)
{
sScripts = GetStringTrim(sScripts) + ",";
sScripts = GetStringReplace(sScripts, " ", "");
sScripts = GetStringReplace(sScripts, ",,", ",");
sScripts = GetStringReplace(sScripts, SCRIPT_NULL + ",", ",");
if (GetStringLeft(sScripts, 1) == ",")
sScripts = GetSubStringEx(sScripts, 1);
return sScripts;
}
// -----------------------------------------------------------------------------
void _AppendScriptToUserDefinedVariable(object oObject, string sEvent, string sFile)
{
string sScripts = GetLocalString(oObject, sEvent);
string sNewFile = RemoveExtension(sFile) + ",";
// Clean up the string, and only add once.
sScripts = _TrimScripts(sScripts);
sScripts = GetStringReplace(sScripts, sNewFile, "");
sScripts += RemoveExtension(sFile) + ",";
if (GetStringLeft(sScripts, 1) == ",")
sScripts = GetSubStringEx(sScripts, 1);
SetLocalString(oObject, sEvent, sScripts);
}
// -----------------------------------------------------------------------------
//! @brief Move script in nHandler's place to a local variable for unicast dispatch
//! @param oObject An object.
//! @param nHandler An EVENT_SCRIPT_* constant identifying the event slot.
//! @param sFile Script to append to the dispatch list. Skipped when empty, SCRIPT_ON_EVENT, or SCRIPT_NULL. Defaults to "".
void MoveEventScript(object oObject, int nHandler, string sFile = "");
void MoveEventScript(object oObject, int nHandler, string sFile = "")
{
// If a file is present, move it to a variable, and that variable will
// be just a list of files to execute when event happens
if (sFile != "" && sFile != SCRIPT_ON_EVENT && sFile != SCRIPT_NULL)
{
string sEvent = EventScriptToEvent(nHandler);
_AppendScriptToUserDefinedVariable(oObject, sEvent, sFile);
}
// Set the script to SCRIPT_ON_EVENT, unless it's "null" which
// we promised not to change.
string sCurrentFile = GetEventScript(oObject, nHandler);
if (sCurrentFile == SCRIPT_NULL)
{ /* do nothing */}
else
SetEventScript(oObject, nHandler, SCRIPT_ON_EVENT);
}
// -----------------------------------------------------------------------------
//! @brief Returns the currently executing event script (EVENT_SCRIPT_*) or 0 if not determinable.
int GetCurrentEventScript();
int GetCurrentEventScript()
{
int nHandler = GetCurrentlyRunningEvent(FALSE);
if (nHandler == 0)
nHandler = GetCurrentlyRunningEvent(TRUE);
return nHandler;
}
// =============================================================================
// EVENT FUNCTIONS
// =============================================================================
//! @brief Return NWNX_Events_GetCurrentEvent first if it exists.
string GetCurrentEvent();
string GetCurrentEvent()
{
// If the event name is forced, then return it
string sEvent = GetLocalString(GetModule(), CURRENT_EVENT);
if (sEvent != "")
return sEvent;
// Otherwise, we might be in a NWNX event
sEvent = NWNX_Events_GetCurrentEvent();
if (sEvent != "")
return sEvent;
// Last, send the corresponding Event from EventScript
int nHandler = GetCurrentEventScript();
if (nHandler != 0)
return EventScriptToEvent(nHandler);
return "";
}
// -----------------------------------------------------------------------------
//! @brief Subscribe to an event, whatever the object.
//! @param sEvent The event name.
//! @param sFile Script to call when the event fires. Use __FILE__. Scoped to oObject via dispatch list if oObject is valid.
void SubscribeToEvent(string sEvent, string sFile, object oObject = OBJECT_INVALID);
void SubscribeToEvent(string sEvent, string sFile, object oObject = OBJECT_INVALID)
{
sFile = RemoveExtension(sFile);
if (GetIsObjectValid(oObject))
{
int nHandler = EventToEventScript(oObject, sEvent);
if (nHandler <= 0)
{
NWNX_Events_SubscribeEvent(sEvent, sFile);
NWNX_Events_ToggleDispatchListMode(sEvent, sFile, TRUE);
NWNX_Events_AddObjectToDispatchList(sEvent, sFile, oObject);
}
else
MoveEventScript(oObject, nHandler, sFile);
}
else
NWNX_Events_SubscribeEvent(sEvent, sFile);
}
// =============================================================================
// BROADCAST FUNCTIONS
// =============================================================================
//! @brief Send one event to all files for a single object.
//! @param sEvent Event name to signal.
//! @param oTarget Object to signal. Defaults to OBJECT_SELF.
int SendEvent(string sEvent, object oTarget = OBJECT_SELF);
int SendEvent(string sEvent, object oTarget = OBJECT_SELF)
{
if (sEvent == "")
return FALSE;
if (!GetIsObjectValid(oTarget))
return FALSE;
return (NWNX_Events_SignalEvent(sEvent, oTarget));
}
// =============================================================================
// CONSOLE
// =============================================================================
//! @brief Return the ON_CONSOLE_COMMAND__<sEvent> event name (uppercased).
//! @param sEvent Console command name.
string GetConsoleEventName(string sEvent);
string GetConsoleEventName(string sEvent)
{
return GetStringUpperCase(ON_CONSOLE_COMMAND + "__" + sEvent);
}
// -----------------------------------------------------------------------------
//! @brief Register a command that can be used from nwn-server console.
//! @param sCommand Command string (without "/" prefix)
//! @param sFile File to call on command
void RegisterConsoleCommand(string sCommand, string sFile);
void RegisterConsoleCommand(string sCommand, string sFile)
{
// There's already a warning during module start if
// NWNX_CORE_ALLOW_NWNX_FUNCTIONS_IN_EXECUTE_SCRIPT_CHUNK is not set
// Commands are all in lowercase, but the event will be in uppercase
sCommand = GetStringLowerCase(sCommand);
string sScript = "";
sScript += "SetLocalString(GetModule(), \"" + CONSOLE_COMMAND + "\", \"" + sCommand + "\");";
sScript += "SetLocalString(GetModule(), \"" + CONSOLE_ARGS + "\", \"$args\");";
sScript += "ExecuteScript(\"" + SCRIPT_ON_CONSOLE + "\");";
NWNX_Util_RegisterServerConsoleCommand(sCommand, sScript);
sFile = RemoveExtension(sFile);
NWNX_Events_SubscribeEvent(GetConsoleEventName(sCommand), sFile);
}
// =============================================================================
// TAG BASED EXECUTION
// =============================================================================
//! @brief Return the tag-based event name for sEvent and sFileOrTag.
//! @param sEvent Base event name.
//! @param sFileOrTag Item tag or filename; extension is stripped.
string GetItemTagEventName(string sEvent, string sFileOrTag);
string GetItemTagEventName(string sEvent, string sFileOrTag)
{
// We abuse the fact that item tag == filename
return GetStringUpperCase(sEvent + "__" + RemoveExtension(sFileOrTag));
}
// -----------------------------------------------------------------------------
//! @brief Execute the script named by oObject's tag on oTarget.
//! @param sEvent Unused; kept for API symmetry.
//! @param oObject Object whose tag is used as the script name.
//! @param oTarget Object the script executes on. Defaults to OBJECT_SELF.
void SendItemTagEvent(string sEvent, object oObject, object oTarget = OBJECT_SELF);
void SendItemTagEvent(string sEvent, object oObject, object oTarget = OBJECT_SELF)
{
ExecuteScript(GetTag(oObject), oTarget);
}