diff --git a/NEWS b/NEWS index 73ab7c5f3..b0802b9be 100644 --- a/NEWS +++ b/NEWS @@ -55,7 +55,9 @@ DFHack future saving you from having to trawl through long lists of materials each time you place one. Dfusion plugin: Reworked to make use of lua modules, now all the scripts can be used from other scripts. - + New Eventful plugin: + A collection of lua events, that will allow new ways to interact with df world. + DFHack v0.34.11-r2 Internals: diff --git a/Readme.rst b/Readme.rst index f2b1edc66..325690ab2 100644 --- a/Readme.rst +++ b/Readme.rst @@ -2576,3 +2576,34 @@ be bought from caravans. :) To be really useful this needs patches from bug 808, ``tweak fix-dimensions`` and ``tweak advmode-contained``. + +Eventful +======== + +This plugin exports some events to lua thus allowing to run lua functions +on DF world events. + +List of events +-------------- + +1. onReactionComplete(reaction,unit,input_items,input_reagents,output_items,call_native) - auto activates if detects reactions starting with ``LUA_HOOK_``. Is called when reaction finishes. +2. onItemContaminateWound(item,unit,wound,number1,number2) - Is called when item tries to contaminate wound (e.g. stuck in) + +Examples +-------- +Spawn dragon breath on each item attempt to contaminate wound: +:: + + b=require "plugins.eventful" + b.onItemContaminateWound.one=function(item,unit,un_wound,x,y) + local flw=dfhack.maps.spawnFlow(unit.pos,6,0,0,50000) + end + +Reaction complete example" +:: + + b.onReactionComplete.one=function(reaction,unit,in_items,in_reag,out_items,call_native) + local pos=copyall(unit.pos) + dfhack.timeout(100,"ticks",function() dfhack.maps.spawnFlow(pos,6,0,0,50000) end) -- spawn dragonbreath after 100 ticks + call_native.value=false --do not call real item creation code + end diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 038b11c9a..267f01c29 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -7,6 +7,8 @@ #include #include "df/unit.h" #include "df/item.h" +#include "df/item_actual.h" +#include "df/unit_wound.h" #include "df/world.h" #include "df/reaction.h" #include "df/reaction_reagent_itemst.h" @@ -82,12 +84,14 @@ static bool is_lua_hook(const std::string &name) static void handle_reaction_done(color_ostream &out,df::reaction*, df::unit *unit, std::vector *in_items,std::vector *in_reag , std::vector *out_items,bool *call_native){}; +static void handle_contaminate_wound(color_ostream &out,df::item_actual*,df::unit* unit, df::unit_wound* wound, uint8_t a1, int16_t a2){}; DEFINE_LUA_EVENT_6(onReactionComplete, handle_reaction_done,df::reaction*, df::unit *, std::vector *,std::vector *,std::vector *,bool *); - +DEFINE_LUA_EVENT_5(onItemContaminateWound, handle_contaminate_wound, df::item_actual*,df::unit* , df::unit_wound* , uint8_t , int16_t ); DFHACK_PLUGIN_LUA_EVENTS { DFHACK_LUA_EVENT(onReactionComplete), + DFHACK_LUA_EVENT(onItemContaminateWound), DFHACK_LUA_END }; @@ -120,7 +124,18 @@ struct product_hook : item_product { IMPLEMENT_VMETHOD_INTERPOSE(product_hook, produce); +struct item_hooks :df::item_actual { + typedef df::item_actual interpose_base; + DEFINE_VMETHOD_INTERPOSE(void, contaminateWound,(df::unit* unit, df::unit_wound* wound, uint8_t a1, int16_t a2)) + { + CoreSuspendClaimer suspend; + color_ostream_proxy out(Core::getInstance().getConsole()); + onItemContaminateWound(out,this,unit,wound,a1,a2); + INTERPOSE_NEXT(contaminateWound)(unit,wound,a1,a2); + } +}; +IMPLEMENT_VMETHOD_INTERPOSE(item_hooks, contaminateWound); /* @@ -176,22 +191,27 @@ static bool find_reactions(color_ostream &out) static void enable_hooks(bool enable) { - INTERPOSE_HOOK(product_hook, produce).apply(enable); + INTERPOSE_HOOK(item_hooks,contaminateWound).apply(enable); } static void world_specific_hooks(color_ostream &out,bool enable) { if(enable && find_reactions(out)) { out.print("Detected reaction hooks - enabling plugin.\n"); - enable_hooks(true); + INTERPOSE_HOOK(product_hook, produce).apply(true); } else { - enable_hooks(false); + INTERPOSE_HOOK(product_hook, produce).apply(false); reactions.clear(); products.clear(); } } +void disable_all_hooks(color_ostream &out) +{ + world_specific_hooks(out,false); + enable_hooks(false); +} DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { switch (event) { @@ -213,12 +233,12 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector