Skip to content

Commit

Permalink
Scripting: added eventCallbackEx() and SE_EVENTBOX_ENTER/EXIT events.
Browse files Browse the repository at this point in the history
`eventCallbackEx()` has precedence over `eventCallback()`. Normal `game.registerForEvent()` mechanic applies. Extended arguments are described in 'gameplay/ScriptEvents.h' `enum scriptEvents`.

TBD: The 'type' param of SE_EVENTBOX_ENTER/EXIT is the same as for `defaultEventCallback()`, which means "always 0". 

Per request by @AnotherFoxGuy on Discord: https://discord.com/channels/136544456244461568/189904947649708032/1074385401571184740
  • Loading branch information
ohlidalp committed Feb 15, 2023
1 parent 413fe54 commit 60dea9f
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 25 deletions.
9 changes: 8 additions & 1 deletion doc/angelscript/Game2Script/script_callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ void main();
*/
void frameStep(float dt);

/** Optional; Invoked if a registered event is triggered, see Script2Game::game::registerForEvent.
/** Optional; Invoked if a registered event is triggered, see `GameScriptClass::registerForEvent()`.
* @param event Event code.
* @param param Event-specific parameter, see docs for the event codes.
*/
void eventCallback(Script2Game::scriptEvents event, int param);

/** Optional; if present, will be used instead of `Game2Script::eventCallback()`.
* Invoked if a registered event is triggered, see `GameScriptClass::registerForEvent()`.
* The first argument is the same as `eventCallback()` gets, other are extras, see descriptions at `Script2Game::scriptEvents`.
* @param event Event code.
*/
void eventCallbackEx(Script2Game::scriptEvents event, int arg1, int arg2ex, int arg3ex, int arg4ex, string arg5ex, string arg6ex, string arg7ex, string arg8ex);

/** Optional; Invoked when a vehicle touches an eventbox which has no custom handler function.
* @param trigger_type Unused, always 0.
* @param inst Unique ID of the terrain object instance which created the eventbox.
Expand Down
39 changes: 22 additions & 17 deletions source/main/gameplay/ScriptEvents.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,36 @@

#pragma once

#include "BitFlags.h"

/// This enum describes what events are existing. The script can register to receive events.
enum scriptEvents
{
SE_TRUCK_ENTER = 0x00000004, //!< triggered when switching from person mode to vehicle mode, the argument refers to the actor ID of the vehicle
SE_TRUCK_EXIT = 0x00000008, //!< triggered when switching from vehicle mode to person mode, the argument refers to the actor ID of the vehicle
SE_EVENTBOX_ENTER = BITMASK(1), //!< Actor or person entered an eventbox; arguments: #1 type, #2 actorID (actor only), #3 node ID (actor only), #4 unused, #5 object instance name #6 eventbox name, #7 unused #8 unused.
SE_EVENTBOX_EXIT = BITMASK(2), //!< Actor or person left an eventbox; arguments: #1 type, #2 actorID (actor only), #3 unused, #4 unused, #5 object instance name #6 eventbox name, #7 unused #8 unused.

SE_TRUCK_ENTER = BITMASK(3), //!< triggered when switching from person mode to vehicle mode, the argument refers to the actor ID of the vehicle
SE_TRUCK_EXIT = BITMASK(4), //!< triggered when switching from vehicle mode to person mode, the argument refers to the actor ID of the vehicle

SE_TRUCK_ENGINE_DIED = 0x00000010, //!< triggered when the vehicle's engine dies (from underrev, water, etc), the argument refers to the actor ID of the vehicle
SE_TRUCK_ENGINE_FIRE = 0x00000020, //!< triggered when the planes engines start to get on fire, the argument refers to the actor ID of the vehicle
SE_TRUCK_TOUCHED_WATER = 0x00000040, //!< triggered when any part of the actor touches water, the argument refers to the actor ID
SE_TRUCK_LIGHT_TOGGLE = 0x00000400, //!< triggered when the main light is toggled, the argument refers to the actor ID
SE_TRUCK_TIE_TOGGLE = 0x00001000, //!< triggered when the user toggles ties, the argument refers to the actor ID
SE_TRUCK_PARKINGBRAKE_TOGGLE = 0x00002000, //!< triggered when the user toggles the parking brake, the argument refers to the actor ID
SE_TRUCK_BEACONS_TOGGLE = 0x00004000, //!< triggered when the user toggles beacons, the argument refers to the actor ID
SE_TRUCK_CPARTICLES_TOGGLE = 0x00008000, //!< triggered when the user toggles custom particles, the argument refers to the actor ID
SE_TRUCK_ENGINE_DIED = BITMASK(5), //!< triggered when the vehicle's engine dies (from underrev, water, etc), the argument refers to the actor ID of the vehicle
SE_TRUCK_ENGINE_FIRE = BITMASK(6), //!< triggered when the planes engines start to get on fire, the argument refers to the actor ID of the vehicle
SE_TRUCK_TOUCHED_WATER = BITMASK(7), //!< triggered when any part of the actor touches water, the argument refers to the actor ID
SE_TRUCK_LIGHT_TOGGLE = BITMASK(8), //!< triggered when the main light is toggled, the argument refers to the actor ID
SE_TRUCK_TIE_TOGGLE = BITMASK(9), //!< triggered when the user toggles ties, the argument refers to the actor ID
SE_TRUCK_PARKINGBRAKE_TOGGLE = BITMASK(10), //!< triggered when the user toggles the parking brake, the argument refers to the actor ID
SE_TRUCK_BEACONS_TOGGLE = BITMASK(11), //!< triggered when the user toggles beacons, the argument refers to the actor ID
SE_TRUCK_CPARTICLES_TOGGLE = BITMASK(12), //!< triggered when the user toggles custom particles, the argument refers to the actor ID

SE_GENERIC_NEW_TRUCK = 0x00020000, //!< triggered when the user spawns a new actor, the argument refers to the actor ID
SE_GENERIC_DELETED_TRUCK = 0x00040000, //!< triggered when the user deletes an actor, the argument refers to the actor ID
SE_GENERIC_NEW_TRUCK = BITMASK(13), //!< triggered when the user spawns a new actor, the argument refers to the actor ID
SE_GENERIC_DELETED_TRUCK = BITMASK(14), //!< triggered when the user deletes an actor, the argument refers to the actor ID

SE_TRUCK_RESET = 0x00200000, //!< triggered when the user resets the truck, the argument refers to the actor ID of the vehicle
SE_TRUCK_TELEPORT = 0x00400000, //!< triggered when the user teleports the truck, the argument refers to the actor ID of the vehicle
SE_TRUCK_MOUSE_GRAB = 0x00100000, //!< triggered when the user uses the mouse to interact with the actor, the argument refers to the actor ID
SE_TRUCK_RESET = BITMASK(15), //!< triggered when the user resets the truck, the argument refers to the actor ID of the vehicle
SE_TRUCK_TELEPORT = BITMASK(16), //!< triggered when the user teleports the truck, the argument refers to the actor ID of the vehicle
SE_TRUCK_MOUSE_GRAB = BITMASK(17), //!< triggered when the user uses the mouse to interact with the actor, the argument refers to the actor ID

SE_ANGELSCRIPT_MANIPULATIONS = 0x00800000, //!< triggered when the user tries to dynamically use the scripting capabilities (prevent cheating)
SE_ANGELSCRIPT_MANIPULATIONS = BITMASK(18), //!< triggered when the user tries to dynamically use the scripting capabilities (prevent cheating)

SE_GENERIC_MESSAGEBOX_CLICK = 0x01000000, //!< triggered when the user clicks on a message box button, the argument refers to the button pressed
SE_GENERIC_MESSAGEBOX_CLICK = BITMASK(19), //!< triggered when the user clicks on a message box button, the argument refers to the button pressed

SE_ALL_EVENTS = 0xffffffff,

Expand Down
10 changes: 10 additions & 0 deletions source/main/physics/ActorForcesEuler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "GameContext.h"
#include "Replay.h"
#include "ScrewProp.h"
#include "ScriptEngine.h"
#include "SoundScriptManager.h"
#include "Terrain.h"
#include "Water.h"
Expand Down Expand Up @@ -1671,10 +1672,19 @@ void Actor::CalcEventBoxes()
if (do_callback)
{
App::GetGameContext()->GetTerrain()->GetCollisions()->envokeScriptCallback(cbox, &ar_nodes[i]);

const eventsource_t& eventsource = App::GetGameContext()->GetTerrain()->GetCollisions()->getEventSource(cbox->eventsourcenum);
TRIGGER_EVENT_EX(SE_EVENTBOX_ENTER, 0, ar_vector_index, ar_nodes[i].pos, 0, eventsource.es_instance_name, eventsource.es_box_name, "", "");
}
break;
}
}

if (!has_collision)
{
const eventsource_t & eventsource = App::GetGameContext()->GetTerrain()->GetCollisions()->getEventSource(cbox->eventsourcenum);
TRIGGER_EVENT_EX(SE_EVENTBOX_EXIT, 0, ar_vector_index, 0, 0, eventsource.es_instance_name, eventsource.es_box_name, "", "");
}
}
}
}
Expand Down
33 changes: 29 additions & 4 deletions source/main/scripting/ScriptEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

using namespace Ogre;
using namespace RoR;
using namespace AngelScript;

const char* RoR::ScriptCategoryToString(ScriptCategory c)
{
Expand Down Expand Up @@ -366,6 +367,11 @@ int ScriptEngine::addFunction(const String &arg)
if (m_script_units[unitID].eventCallbackFunctionPtr == nullptr)
m_script_units[unitID].eventCallbackFunctionPtr = func;
}
else if (func == mod->GetFunctionByDecl("void eventCallbackEx(scriptEvents, int, int, int, int, string, string, string, string)"))
{
if (m_script_units[unitID].eventCallbackExFunctionPtr == nullptr)
m_script_units[unitID].eventCallbackExFunctionPtr = func;
}
else if (func == mod->GetFunctionByDecl("void defaultEventCallback(int, string, string, int)"))
{
if (m_script_units[unitID].defaultEventCallbackFunctionPtr == nullptr)
Expand Down Expand Up @@ -442,6 +448,9 @@ int ScriptEngine::deleteFunction(const String &arg)
if ( m_script_units[m_terrain_script_unit].eventCallbackFunctionPtr == func )
m_script_units[m_terrain_script_unit].eventCallbackFunctionPtr = nullptr;

if (m_script_units[m_terrain_script_unit].eventCallbackExFunctionPtr == func)
m_script_units[m_terrain_script_unit].eventCallbackExFunctionPtr = nullptr;

if ( m_script_units[m_terrain_script_unit].defaultEventCallbackFunctionPtr == func )
m_script_units[m_terrain_script_unit].defaultEventCallbackFunctionPtr = nullptr;

Expand Down Expand Up @@ -507,23 +516,38 @@ int ScriptEngine::deleteVariable(const String &arg)
return index;
}

void ScriptEngine::triggerEvent(int eventnum, int value)
void ScriptEngine::triggerEvent(scriptEvents eventnum, int arg1, int arg2ex, int arg3ex, int arg4ex, std::string arg5ex, std::string arg6ex, std::string arg7ex, std::string arg8ex)
{
if (!engine || !context) return;

for (auto& pair: m_script_units)
{
ScriptUnitId_t id = pair.first;
if (m_script_units[id].eventCallbackFunctionPtr==nullptr)
asIScriptFunction* callback = m_script_units[id].eventCallbackExFunctionPtr;
if (!callback)
callback = m_script_units[id].eventCallbackFunctionPtr;
if (!callback)
continue;

if (m_script_units[id].eventMask & eventnum)
{
// script registered for that event, so sent it
context->Prepare(m_script_units[id].eventCallbackFunctionPtr);
context->Prepare(callback);

// Set the function arguments
context->SetArgDWord(0, eventnum);
context->SetArgDWord(1, value);
context->SetArgDWord(1, arg1);
if (callback == m_script_units[id].eventCallbackExFunctionPtr)
{
// Extended arguments
context->SetArgDWord(2, arg2ex);
context->SetArgDWord(3, arg3ex);
context->SetArgDWord(4, arg4ex);
context->SetArgObject(5, &arg5ex);
context->SetArgObject(6, &arg6ex);
context->SetArgObject(7, &arg7ex);
context->SetArgObject(8, &arg8ex);
}

m_currently_executing_script_unit = id;
int r = context->Execute();
Expand Down Expand Up @@ -641,6 +665,7 @@ int ScriptEngine::setupScriptUnit(int unit_id)
m_script_units[unit_id].frameStepFunctionPtr = m_script_units[unit_id].scriptModule->GetFunctionByDecl("void frameStep(float)");

m_script_units[unit_id].eventCallbackFunctionPtr = m_script_units[unit_id].scriptModule->GetFunctionByDecl("void eventCallback(int, int)");
m_script_units[unit_id].eventCallbackExFunctionPtr = m_script_units[unit_id].scriptModule->GetFunctionByDecl("void eventCallbackEx(scriptEvents, int, int, int, int, string, string, string, string)");

m_script_units[unit_id].defaultEventCallbackFunctionPtr = m_script_units[unit_id].scriptModule->GetFunctionByDecl("void defaultEventCallback(int, string, string, int)");

Expand Down
12 changes: 9 additions & 3 deletions source/main/scripting/ScriptEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@

#ifdef USE_ANGELSCRIPT

/// Invoke script function `eventCallbackEx()`, if registered, otherwise fall back to `eventCallback()`
#define TRIGGER_EVENT(x, y) App::GetScriptEngine()->triggerEvent((x), (y))

/// Invoke script function `eventCallbackEx()`, if registered, otherwise fall back to `eventCallback()`
#define TRIGGER_EVENT_EX(ev, a1, a2, a3, a4, a5, a6, a7, a8) App::GetScriptEngine()->triggerEvent((ev), (a1), (a2), (a3), (a4), (a5), (a6), (a7), (a8))

#define DEFAULT_TERRAIN_SCRIPT "terrain_default.as" // Used when map creator doesn't provide custom script.
#define DEFAULT_MISSION_SCRIPT "mission_default.as" // Used when mission creator doesn't provide custom script.

Expand Down Expand Up @@ -71,6 +75,7 @@ struct ScriptUnit
AngelScript::asIScriptModule* scriptModule = nullptr;
AngelScript::asIScriptFunction* frameStepFunctionPtr = nullptr; //!< script function pointer to the frameStep function
AngelScript::asIScriptFunction* eventCallbackFunctionPtr = nullptr; //!< script function pointer to the event callback function
AngelScript::asIScriptFunction* eventCallbackExFunctionPtr = nullptr; //!< script function pointer to the event callback function
AngelScript::asIScriptFunction* defaultEventCallbackFunctionPtr = nullptr; //!< script function pointer for spawner events
AngelScript::asIScriptFunction* loadMissionFunctionPtr = nullptr; //!< only `ScriptCategory::MISSION`, called to set up the mission.
AngelScript::asIScriptFunction* unloadMissionFunctionPtr = nullptr; //!< only `ScriptCategory::MISSION`, called to clean up the mission.
Expand Down Expand Up @@ -119,10 +124,10 @@ class ScriptEngine : public Ogre::LogListener, public ZeroedMemoryAllocator
void activateLogging();

/**
* triggers an event. Not to be used by the end-user
* @param eventValue \see enum scriptEvents
* triggers an event; Not to be used by the end-user.
* Runs either `eventCallbackEx()`, if registered, or `eventCallback()`, if registered, in this order.
*/
void triggerEvent(int scriptEvents, int value = 0);
void triggerEvent(scriptEvents eventnum, int arg1, int arg2ex=0, int arg3ex=0, int arg4ex=0, std::string arg5ex="", std::string arg6ex="", std::string arg7ex="", std::string arg8ex="");

/**
* executes a string (useful for the console)
Expand Down Expand Up @@ -227,4 +232,5 @@ class ScriptEngine : public Ogre::LogListener, public ZeroedMemoryAllocator

#else // USE_ANGELSCRIPT
# define TRIGGER_EVENT(x, y)
# define TRIGGER_EVENT_EX(ev, a1, a2, a3, a4, a5, a6, a7, a8)
#endif // USE_ANGELSCRIPT
4 changes: 4 additions & 0 deletions source/main/scripting/bindings/ScriptEventsAngelscript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ void RoR::RegisterScriptEvents(asIScriptEngine *engine)

// enum scriptEvents
result = engine->RegisterEnum("scriptEvents"); ROR_ASSERT(result>=0);

result = engine->RegisterEnumValue("scriptEvents", "SE_EVENTBOX_ENTER", SE_EVENTBOX_ENTER); ROR_ASSERT(result >= 0);
result = engine->RegisterEnumValue("scriptEvents", "SE_EVENTBOX_EXIT", SE_EVENTBOX_EXIT); ROR_ASSERT(result >= 0);

result = engine->RegisterEnumValue("scriptEvents", "SE_TRUCK_ENTER", SE_TRUCK_ENTER); ROR_ASSERT(result>=0);
result = engine->RegisterEnumValue("scriptEvents", "SE_TRUCK_EXIT", SE_TRUCK_EXIT); ROR_ASSERT(result>=0);

Expand Down

0 comments on commit 60dea9f

Please sign in to comment.