From d1f933ba0a4044dee4ed2eb20b1ca70d6eede034 Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Wed, 13 Apr 2022 14:20:19 -0700 Subject: [PATCH 1/4] Adds an onUnitAction event --- docs/Lua API.rst | 4 +++ docs/changelog.txt | 1 + library/include/modules/EventManager.h | 7 ++++++ library/modules/EventManager.cpp | 35 ++++++++++++++++++++++++++ plugins/eventful.cpp | 8 ++++++ plugins/lua/eventful.lua | 1 + 6 files changed, 56 insertions(+) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index b785bee496..1bd435b88a 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4178,6 +4178,10 @@ These events are straight from EventManager module. Each of them first needs to Called when a unit uses an interaction on another. +14. ``onUnitAction(unit_id, action, action_id)`` + + Called when a unit does an action (movement, attacking, talking and so on). + Functions --------- diff --git a/docs/changelog.txt b/docs/changelog.txt index d7fcb96174..9492d84985 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -47,6 +47,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - `EventManager`: add new event type ``JOB_STARTED``, triggered when a job first gains a worker - `EventManager`: add new event type ``NEW_UNIT_ACTIVE``, triggered when a new unit appears on the active list - `EventManager`: now each registered handler for an event can have its own frequency instead of all handlers using the lowest frequency of all handlers +- `EventManager`: add new event type ``UNIT_ACTION``, triggered when a unit starts an action - `stocks`: allow search terms to match the full item label, even when the label is truncated for length - `dfhack-examples-guide`: add mugs to ``basic`` manager orders - `gui/create-item`: Added "(chain)" annotation text for armours with the [CHAIN_METAL_TEXT] flag set diff --git a/library/include/modules/EventManager.h b/library/include/modules/EventManager.h index 623fa0823e..e0b25fe200 100644 --- a/library/include/modules/EventManager.h +++ b/library/include/modules/EventManager.h @@ -37,6 +37,7 @@ namespace DFHack { UNIT_ATTACK, UNLOAD, INTERACTION, + UNIT_ACTION, EVENT_MAX }; } @@ -95,6 +96,12 @@ namespace DFHack { int32_t defendReport; }; + struct ActionData { + int32_t unitId; + df::unit_action* action; + int32_t actionId; + }; + DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin); DFHACK_EXPORT int32_t registerTick(EventHandler handler, int32_t when, Plugin* plugin, bool absolute=false); DFHACK_EXPORT void unregister(EventType::EventType e, EventHandler handler, Plugin* plugin); diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 80dc254d5a..b3f9046202 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -28,6 +28,7 @@ #include "df/report.h" #include "df/ui.h" #include "df/unit.h" +#include "df/unit_action.h" #include "df/unit_flags1.h" #include "df/unit_inventory_item.h" #include "df/unit_report_type.h" @@ -137,6 +138,7 @@ static void manageReportEvent(color_ostream& out); static void manageUnitAttackEvent(color_ostream& out); static void manageUnloadEvent(color_ostream& out){}; static void manageInteractionEvent(color_ostream& out); +static void manageActionEvent(color_ostream& out); typedef void (*eventManager_t)(color_ostream&); @@ -157,6 +159,7 @@ static const eventManager_t eventManager[] = { manageUnitAttackEvent, manageUnloadEvent, manageInteractionEvent, + manageActionEvent, }; //job initiated @@ -200,6 +203,9 @@ static int32_t reportToRelevantUnitsTime = -1; //interaction static int32_t lastReportInteraction; +//unit action +static std::map > unitToKnownActions; + void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event event) { static bool doOnce = false; // const string eventNames[] = {"world loaded", "world unloaded", "map loaded", "map unloaded", "viewscreen changed", "core initialized", "begin unload", "paused", "unpaused"}; @@ -222,6 +228,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event buildings.clear(); constructions.clear(); equipmentLog.clear(); + unitToKnownActions.clear(); Buildings::clearBuildings(out); lastReport = -1; @@ -1255,3 +1262,31 @@ static void manageInteractionEvent(color_ostream& out) { } } +static void manageActionEvent(color_ostream& out) { + if (!df::global::world) + return; + multimap copy(handlers[EventType::UNIT_ACTION].begin(), handlers[EventType::UNIT_ACTION].end()); + for ( size_t a = 0; a < df::global::world->units.all.size(); a++ ) { + df::unit* unit = df::global::world->units.all[a]; + if ( Units::isActive(unit) ) { + auto knownActions = &unitToKnownActions[unit->id]; + for ( df::unit_action* action : unit->actions ) { + if ( action->type != df::unit_action_type::None) { + if ( std::find(knownActions->begin(), knownActions->end(), action->id) == knownActions->end() ) { + knownActions->push_back(action->id); + for ( auto b = copy.begin(); b != copy.end(); b++ ) { + EventHandler handle = (*b).second; + ActionData data = {unit->id, action, action->id}; + handle.eventHandler(out, (void*)&data); + } + } + } else { + auto newEnd = std::remove(knownActions->begin(), knownActions->end(), action->id); + knownActions->erase(newEnd, knownActions->end()); + } + } + } else { + unitToKnownActions.erase(unit->id); + } + } +} \ No newline at end of file diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 094b251987..f7006c107f 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -20,6 +20,7 @@ #include "df/reaction_reagent_itemst.h" #include "df/reaction_product_itemst.h" #include "df/unit.h" +#include "df/unit_action.h" #include "df/unit_inventory_item.h" #include "df/unit_wound.h" #include "df/world.h" @@ -109,6 +110,7 @@ DEFINE_LUA_EVENT_NH_1(onReport, int32_t); DEFINE_LUA_EVENT_NH_3(onUnitAttack, int32_t, int32_t, int32_t); DEFINE_LUA_EVENT_NH_0(onUnload); DEFINE_LUA_EVENT_NH_6(onInteraction, std::string, std::string, int32_t, int32_t, int32_t, int32_t); +DEFINE_LUA_EVENT_NH_3(onUnitAction, int32_t, df::unit_action*, int32_t); DFHACK_PLUGIN_LUA_EVENTS { DFHACK_LUA_EVENT(onWorkshopFillSidebarMenu), @@ -136,6 +138,7 @@ DFHACK_PLUGIN_LUA_EVENTS { DFHACK_LUA_EVENT(onUnitAttack), DFHACK_LUA_EVENT(onUnload), DFHACK_LUA_EVENT(onInteraction), + DFHACK_LUA_EVENT(onUnitAction), DFHACK_LUA_END }; @@ -220,6 +223,10 @@ static void ev_mng_interaction(color_ostream& out, void* ptr) { EventManager::InteractionData* data = (EventManager::InteractionData*)ptr; onInteraction(out, data->attackVerb, data->defendVerb, data->attacker, data->defender, data->attackReport, data->defendReport); } +static void ev_mng_action(color_ostream& out, void* ptr) { + EventManager::ActionData* data = (EventManager::ActionData*)ptr; + onUnitAction(out, data->unitId, data->action, data->actionId); +} std::vector enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1); typedef void (*handler_t) (color_ostream&,void*); @@ -242,6 +249,7 @@ static const handler_t eventHandlers[] = { ev_mng_unitAttack, ev_mng_unload, ev_mng_interaction, + ev_mng_action, }; static void enableEvent(int evType,int freq) { diff --git a/plugins/lua/eventful.lua b/plugins/lua/eventful.lua index 2938743937..b912c629a4 100644 --- a/plugins/lua/eventful.lua +++ b/plugins/lua/eventful.lua @@ -166,6 +166,7 @@ eventType=invertTable{ "UNIT_ATTACK", "UNLOAD", "INTERACTION", + "UNIT_ACTION", "EVENT_MAX" } return _ENV From d96dcc66814143e95924ec051cb03da22b508537 Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Fri, 15 Apr 2022 13:52:03 -0700 Subject: [PATCH 2/4] Remove actionId from EventManager::ActionData --- library/include/modules/EventManager.h | 1 - plugins/eventful.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/library/include/modules/EventManager.h b/library/include/modules/EventManager.h index e0b25fe200..f63c4af23e 100644 --- a/library/include/modules/EventManager.h +++ b/library/include/modules/EventManager.h @@ -99,7 +99,6 @@ namespace DFHack { struct ActionData { int32_t unitId; df::unit_action* action; - int32_t actionId; }; DFHACK_EXPORT void registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin); diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 1753423acd..94a9e0ac07 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -226,7 +226,7 @@ static void ev_mng_interaction(color_ostream& out, void* ptr) { } static void ev_mng_unitAction(color_ostream& out, void* ptr) { EventManager::ActionData* data = (EventManager::ActionData*)ptr; - onUnitAction(out, data->unitId, data->action, data->actionId); + onUnitAction(out, data->unitId, data->action); } std::vector enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1); typedef void (*handler_t) (color_ostream&,void*); From 62deece988dacd36e54031f83a8948034e8a2846 Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Fri, 15 Apr 2022 13:55:53 -0700 Subject: [PATCH 3/4] Somehow missed the Lua stuff in there --- plugins/eventful.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 94a9e0ac07..f1b01ad6c3 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -111,7 +111,7 @@ DEFINE_LUA_EVENT_NH_1(onReport, int32_t); DEFINE_LUA_EVENT_NH_3(onUnitAttack, int32_t, int32_t, int32_t); DEFINE_LUA_EVENT_NH_0(onUnload); DEFINE_LUA_EVENT_NH_6(onInteraction, std::string, std::string, int32_t, int32_t, int32_t, int32_t); -DEFINE_LUA_EVENT_NH_3(onUnitAction, int32_t, df::unit_action*, int32_t); +DEFINE_LUA_EVENT_NH_2(onUnitAction, int32_t, df::unit_action*); DFHACK_PLUGIN_LUA_EVENTS { DFHACK_LUA_EVENT(onWorkshopFillSidebarMenu), @@ -226,7 +226,7 @@ static void ev_mng_interaction(color_ostream& out, void* ptr) { } static void ev_mng_unitAction(color_ostream& out, void* ptr) { EventManager::ActionData* data = (EventManager::ActionData*)ptr; - onUnitAction(out, data->unitId, data->action); + onUnitAction(out, data->unitId); } std::vector enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1); typedef void (*handler_t) (color_ostream&,void*); From a244d5953ee001059aece7bc51e64980a096767f Mon Sep 17 00:00:00 2001 From: Putnam3145 Date: Fri, 15 Apr 2022 14:25:22 -0700 Subject: [PATCH 4/4] compiling, that's a neat trick --- docs/Lua API.rst | 2 +- library/modules/EventManager.cpp | 2 +- plugins/eventful.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/Lua API.rst b/docs/Lua API.rst index 006d4f0aac..ca6ddbec85 100644 --- a/docs/Lua API.rst +++ b/docs/Lua API.rst @@ -4406,7 +4406,7 @@ These events are straight from EventManager module. Each of them first needs to Called when a unit uses an interaction on another. -14. ``onUnitAction(unit_id, action, action_id)`` +14. ``onUnitAction(unit_id, action)`` Called when a unit does an action (movement, attacking, talking and so on). diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 4eb470d8f8..7d31d8ca86 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -1315,7 +1315,7 @@ static void manageActionEvent(color_ostream& out) { knownActions.push_back(action->id); for ( auto b = copy.begin(); b != copy.end(); b++ ) { EventHandler handle = (*b).second; - ActionData data = {unit->id, action, action->id}; + ActionData data = {unit->id, action}; handle.eventHandler(out, (void*)&data); } } diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index f1b01ad6c3..0bb482e4c8 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -226,7 +226,7 @@ static void ev_mng_interaction(color_ostream& out, void* ptr) { } static void ev_mng_unitAction(color_ostream& out, void* ptr) { EventManager::ActionData* data = (EventManager::ActionData*)ptr; - onUnitAction(out, data->unitId); + onUnitAction(out, data->unitId, data->action); } std::vector enabledEventManagerEvents(EventManager::EventType::EVENT_MAX,-1); typedef void (*handler_t) (color_ostream&,void*);