Skip to content

Commit

Permalink
Added modtools/reaction-product-trigger.
Browse files Browse the repository at this point in the history
  • Loading branch information
expwnent committed Feb 2, 2015
1 parent 712892f commit e5e0d93
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 14 deletions.
16 changes: 16 additions & 0 deletions library/include/LuaTools.h
Expand Up @@ -500,3 +500,19 @@ namespace DFHack {namespace Lua {
name##_event.invoke(out, 6); \
} \
}

#define DEFINE_LUA_EVENT_7(name, handler, arg_type1, arg_type2, arg_type3, arg_type4, arg_type5,arg_type6,arg_type7) \
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2, arg_type3 arg3, arg_type4 arg4,arg_type5 arg5, arg_type6 arg6, arg_type7 arg7) { \
handler(out, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \
if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
DFHack::Lua::Push(state, arg2); \
DFHack::Lua::Push(state, arg3); \
DFHack::Lua::Push(state, arg4); \
DFHack::Lua::Push(state, arg5); \
DFHack::Lua::Push(state, arg6); \
DFHack::Lua::Push(state, arg7); \
name##_event.invoke(out, 7); \
} \
}
29 changes: 18 additions & 11 deletions plugins/eventful.cpp
Expand Up @@ -94,7 +94,7 @@ static bool is_lua_hook(const std::string &name)
static void handle_fillsidebar(color_ostream &out,df::building_workshopst*,bool *call_native){};
static void handle_postfillsidebar(color_ostream &out,df::building_workshopst*){};

static void handle_reaction_done(color_ostream &out,df::reaction*, df::unit *unit, std::vector<df::item*> *in_items,std::vector<df::reaction_reagent*> *in_reag
static void handle_reaction_done(color_ostream &out,df::reaction*, df::reaction_product_itemst*, df::unit *unit, std::vector<df::item*> *in_items,std::vector<df::reaction_reagent*> *in_reag
, std::vector<df::item*> *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){};
static void handle_projitem_ci(color_ostream &out,df::proj_itemst*,bool){};
Expand All @@ -105,7 +105,7 @@ static void handle_projunit_cm(color_ostream &out,df::proj_unitst*){};
DEFINE_LUA_EVENT_2(onWorkshopFillSidebarMenu, handle_fillsidebar, df::building_workshopst*,bool* );
DEFINE_LUA_EVENT_1(postWorkshopFillSidebarMenu, handle_postfillsidebar, df::building_workshopst*);

DEFINE_LUA_EVENT_6(onReactionComplete, handle_reaction_done,df::reaction*, df::unit *, std::vector<df::item*> *,std::vector<df::reaction_reagent*> *,std::vector<df::item*> *,bool *);
DEFINE_LUA_EVENT_7(onReactionComplete, handle_reaction_done,df::reaction*, df::reaction_product_itemst*, df::unit *, std::vector<df::item*> *,std::vector<df::reaction_reagent*> *,std::vector<df::item*> *,bool *);
DEFINE_LUA_EVENT_5(onItemContaminateWound, handle_contaminate_wound, df::item_actual*,df::unit* , df::unit_wound* , uint8_t , int16_t );
//projectiles
DEFINE_LUA_EVENT_2(onProjItemCheckImpact, handle_projitem_ci, df::proj_itemst*,bool );
Expand Down Expand Up @@ -298,18 +298,25 @@ struct product_hook : item_product {
int32_t quantity, df::job_skill skill,
df::historical_entity *entity, df::world_site *site)
) {
if (auto product = products[this])
{
df::reaction* this_reaction=product->react;
CoreSuspendClaimer suspend;
color_ostream_proxy out(Core::getInstance().getConsole());
bool call_native=true;
onReactionComplete(out,this_reaction,unit,in_items,in_reag,out_items,&call_native);
if(!call_native)
return;
color_ostream_proxy out(Core::getInstance().getConsole());
auto product = products[this];
if ( !product ) {
INTERPOSE_NEXT(produce)(unit, out_items, in_reag, in_items, quantity, skill, entity, site);
return;
}
df::reaction* this_reaction=product->react;
CoreSuspendClaimer suspend;
bool call_native=true;
onReactionComplete(out,this_reaction,(df::reaction_product_itemst*)this,unit,in_items,in_reag,out_items,&call_native);
if(!call_native)
return;

size_t out_item_count = out_items->size();
INTERPOSE_NEXT(produce)(unit, out_items, in_reag, in_items, quantity, skill, entity, site);
if ( out_items->size() == out_item_count )
return;
//if it produced something, call the scripts
onReactionComplete(out,this_reaction,(df::reaction_product_itemst*)this,unit,in_items,in_reag,out_items,NULL);
}
};

Expand Down
4 changes: 2 additions & 2 deletions plugins/lua/eventful.lua
Expand Up @@ -44,9 +44,9 @@ local function unregall(state)
_registeredStuff={}
end
end
local function onReact(reaction,unit,input_items,input_reagents,output_items,call_native)
local function onReact(reaction,reaction_product,unit,input_items,input_reagents,output_items,call_native)
if _registeredStuff.reactionCallbacks and _registeredStuff.reactionCallbacks[reaction.code] then
_registeredStuff.reactionCallbacks[reaction.code](reaction,unit,input_items,input_reagents,output_items,call_native)
_registeredStuff.reactionCallbacks[reaction.code](reaction,reaction_product,unit,input_items,input_reagents,output_items,call_native)
end
end
local function onPostSidebar(workshop)
Expand Down
129 changes: 129 additions & 0 deletions scripts/modtools/reaction-product-trigger.lua
@@ -0,0 +1,129 @@
-- scripts/modtools/reaction-product-trigger.lua
-- author expwnent
-- trigger commands just before and after custom reactions produce items

local eventful = require 'plugins.eventful'
local utils = require 'utils'

--TODO: onUnload
productHooks = productHooks or {}

reactionInputItems = reactionInputItems

eventful.enableEvent(eventful.eventType.UNLOAD,1)
eventful.onUnload.reactionProductTrigger = function()
productHooks = {}
end

--productHooks.before = productHooks.before or {}
--productHooks.after = productHooks.after or {}

local function processArgs(args, reaction, reaction_product, unit, input_items, input_reagents, output_items, buildingId)
local result = {}
for _,arg in ipairs(args) do
if arg == '\\WORKER_ID' then
table.insert(result,tostring(unit.id))
elseif arg == '\\REACTION' then
table.insert(result,reaction.code)
-- elseif arg == '\\REACTION_PRODUCT' then
-- table.insert(result,reaction_product)
elseif arg == '\\INPUT_ITEMS' then
--table.insert(result,'[')
for _,item in ipairs(input_items) do
table.insert(result,tostring(item.id))
end
--table.insert(result,']')
elseif arg == '\\OUTPUT_ITEMS' then
--table.insert(result,'[')
for _,item in ipairs(output_items) do
table.insert(result,tostring(item.id))
end
--table.insert(result,']')
elseif arg == '\\BUILDING_ID' then
table.insert(result,tostring(buildingId))
elseif string.sub(arg,1,1) == '\\' then
table.insert(result,string.sub(arg,2))
else
table.insert(result,arg)
end
end
return result
end

local function afterProduce(reaction,reaction_product,unit,input_items,input_reagents,output_items)
--printall(unit.job.current_job)
local _,buildingId = dfhack.script_environment('modtools/reaction-trigger').getWorkerAndBuilding(unit.job.current_job)
for _,hook in ipairs(productHooks[reaction.code] or {}) do
local command = hook.command
local processed = processArgs(command, reaction, reaction_product, unit, input_items, input_reagents, output_items, buildingId)
dfhack.run_command(table.unpack(processed))
end
end

eventful.onReactionComplete.reactionProductTrigger = function(reaction,reaction_product,unit,input_items,input_reagents,output_items,call_native)
reactionInputItems = input_items
--print(reaction.code)
--print(#output_items)
--print('call_native exists? ' .. tostring(not not call_native))
--print('\n')
if call_native then
--beforeProduce(reaction,unit,input_items,input_reagents,output_items,call_native)
else
afterProduce(reaction,reaction_product,unit,input_items,input_reagents,output_items)
end
reactionInputItems = nil
end

validArgs = validArgs or utils.invert({
'help',
'clear',
'reactionName',
'command',
})

if moduleMode then
return
end

local args = {...} or {}
args = utils.processArgs(args, validArgs)

if args.help then
print([[scripts/modtools/reaction-product-trigger.lua
arguments:
-help
print this help message
-clear
unregister all reaction hooks
-reactionName name
specify the name of the reaction
-command [ commandStrs ]
specify the command to be run on the target(s)
special args
\\WORKER_ID
\\REACTION
\\BUILDING_ID
\\LOCATION
\\INPUT_ITEMS
\\OUTPUT_ITEMS
\\anything -> \anything
anything -> anything
]])
return
end

if args.clear then
productHooks = {}
end

if not args.reactionName then
error('No reactionName.')
end

if not args.command then
error('No command.')
end

productHooks[args.reactionName] = productHooks[args.reactionName] or {}
table.insert(productHooks[args.reactionName], args)

6 changes: 5 additions & 1 deletion scripts/modtools/reaction-trigger.lua
Expand Up @@ -13,7 +13,7 @@ eventful.onUnload.reactionTrigger = function()
reactionHooks = {}
end

local function getWorkerAndBuilding(job)
function getWorkerAndBuilding(job)
local workerId = -1
local buildingId = -1
for _,generalRef in ipairs(job.general_refs) do
Expand Down Expand Up @@ -157,6 +157,10 @@ validArgs = validArgs or utils.invert({
'allowNonworkerTargets',
'allowMultipleTargets'
})

if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs)

if args.help then
Expand Down

1 comment on commit e5e0d93

@warmist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;((((

Couldn't you add the new parameter at the end?

Please sign in to comment.