Bay 12 Games Forum

Dwarf Fortress => DF Modding => Utilities and 3rd Party Applications => Topic started by: Bogus on September 23, 2015, 09:39:11 am

Title: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 23, 2015, 09:39:11 am
im trying to implement a menu script for my custom smelter that lets you select a class of ore first before presenting to you a selection of ores from that class to pick from. should be basically the same kind of ui that some built in workshops have, like forge, glassmaker etc.

now the problem is that eventful seems to only provide a callin routine for replacing the whole wokshop menu, not just the "Add new task" submenu. how would i go about just replacing that, while keeping the basic menu?
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Warmist on September 23, 2015, 02:47:14 pm
im trying to implement a menu script for my custom smelter that lets you select a class of ore first before presenting to you a selection of ores from that class to pick from. should be basically the same kind of ui that some built in workshops have, like forge, glassmaker etc.

now the problem is that eventful seems to only provide a callin routine for replacing the whole wokshop menu, not just the "Add new task" submenu. how would i go about just replacing that, while keeping the basic menu?
Eventful only provides a hook: a way to trigger when it's presented. Then you can do anything you want. This includes:
Looks to me that it's enough for you to use the first method. Unless you want something more fancy (e.g. "Souls in workshop: 5 Reactions active!") it should do what you want quite nicely.

I can make an example if you give me more details (and some time...)
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 23, 2015, 04:07:05 pm
well lets see. this is the callin im using for the script, but it only ever gets called when selecting the workshop, not when entering the add task menu.

Spoiler (click to show/hide)


now what i need is to replace the normal list of reactions("dwarfmode/QueryBuilding/Some/Workshop/Addjob") with a 2-level menu.

there are 5 distinct classes of ores that may have different side effects when smelting and may need extra fuel, flux, etc. the first page of the menu would let you select a class, the second page would contain a list of ores that belong to that class.

these are not individual reactions tho, it should rather just select a material to run one of 3 existing reactions with (ideally no reactions are involved but duno if thats possible or desirable) - and then just que that up like any other job at a workshop.

Quote
recreating most of the stuff that is in native workshops (my method of choice)

i guess that could work too. do you have some code of this for me to look at?
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: milo christiansen on September 23, 2015, 04:11:10 pm
If someone figures out how to do this I want to know! AFAIK it is impossible, but there may be a way to simulate something similar (I just wouldn't know how...).

BTW: I thought something like that was coming in the next version? Wasn't there something like custom reactions menus listed as a coming feature?
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Warmist on September 23, 2015, 04:35:01 pm
If someone figures out how to do this I want to know! AFAIK it is impossible, but there may be a way to simulate something similar (I just wouldn't know how...).

BTW: I thought something like that was coming in the next version? Wasn't there something like custom reactions menus listed as a coming feature?
It's already in. Though largely undocumented...

here's a minimal working example:
here (https://github.com/warmist/df-mini-mods/blob/master/displayCase/display_case.lua)
The idea is that it shows a screen that inherits from "gui.dwarfmode.WorkshopOverlay". The parent class gives most of "natural functionality" like moving pointer around, selecting other shops etc... (though not extensively tested and might be missing some features).
You only define what you need and with dfhacks gui tools it's easy and quick to make some strange contraction that works differently.
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: milo christiansen on September 23, 2015, 04:41:07 pm
That is adding a replacement sidebar, not adding submenus. Adding a submenu is something completely different.

A submenu would allow you to select a GUI item, that would switch sidebars to display a different menu with a list of workshop job buttons based on your previous choice. Unless that is somehow possible, in that case an example that actually does it would be a lot more helpful...
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Warmist on September 23, 2015, 11:27:10 pm
That is adding a replacement sidebar, not adding submenus. Adding a submenu is something completely different.

A submenu would allow you to select a GUI item, that would switch sidebars to display a different menu with a list of workshop job buttons based on your previous choice. Unless that is somehow possible, in that case an example that actually does it would be a lot more helpful...

-.- this saddens me... I offer you the world and you want this small thingy.

Yes it's possible (though how i did not thing about this :D). I'll work up an example when i get free time. It involves with messing the "df.global.ui_sidebar_menus" in that callback (i.e. after they been filled in) or instead of it (callnative.value=false) to replace the buttons.

There are limitations on what could be done (e.g. no lua scripts on buttons) but it's easier and more native-like.
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 24, 2015, 05:12:23 am
making the menu itself doesnt seem so much of a problem, workshop_job already does a similar thing and hooks into the normal menu structure, but it runs on hotkey and doesnt replace anything.

capturing the moment of when the "add new task" submenu is opened and then running the script is what is needed. maybe eventful already provides a way to do this that im not aware of?
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 24, 2015, 08:47:43 am
i got part of it to work. it will select material and create a regular job based on a reaction with selected material, job shows up in the normal wokshop menu and seems to behave itself.

however, the script still gets called when entering the workshop menu. "Add new task" menu isnt replaced either. rather you can leave the replacement sidebar with escape and then you end up in the normal workshop menu. so what is needed is a hook to show my menu only when entering "Add new task", the rest seems to work fine.

also the job description only shows the name of the underlying reaction, i dont know how to insert custom name for the description, which would be very desirable because "melt ore" is not very informative.
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 24, 2015, 06:08:49 pm
managed to get the menu pop up over the "Add new task" menu with this somewhat hacky construction, basically polling the focus state of the ui every couple of frames after entering the basic menu for the workshop in question. when the focus changes to the task submenu, the overlay is shown.

Code: [Select]
local function focuschangeCallback() -- this gets called every 3 frames while in the workshop menu
    local wshop = dfhack.gui.getSelectedBuilding() -- we check if were still in the correct shop type...
    if not wshop or df.building_def_workshopst.find(wshop.custom_type).code ~= 'GUNSMITH' then
print("left workshop menu")
dfhack.timeout_active(timer, nil) -- ...and if not, unhook the callin
return
else  -- if we are still in the correct workshop, we check if the focus is right...
local valid_focus = "dwarfmode/QueryBuilding/Some/Workshop/AddJob"
                if dfhack.gui.getFocusString(dfhack.gui.getCurViewscreen()) == valid_focus and wshop:getMaxBuildStage() == wshop:getBuildStage() then
                        -- ... and if so, we can now display the menu. yay!
print("entered job menu")
SmeltMenu{wshop=wshop}:show()
dfhack.timeout_active(timer, nil)
return
end
timer = dfhack.timeout(3,'frames',focuschangeCallback) -- otherwise, we just restart the timer for every cycle because it just runs once
end
end

function fillSideBarCallback(wshop) -- this gets called when the workshop is selected. it just hooks the callin
timer = dfhack.timeout(3,'frames',focuschangeCallback)
end

eventful.registerSidebar('GUNSMITH', fillSideBarCallback, true)

one problem remains tho, when returning from the overlay menu you end up in the normal "Add new task" submenu.

Code: [Select]
function SmeltMenu:on_close()
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'LEAVESCREEN')
gui.simulateInput(dfhack.gui.getCurViewscreen(), 'D_BUILDJOB')
end

this kinda works to solve that problem, after queing jobs or leaving the menu you would end up in the root of the workshop menu.

from the looks of it you can replicate vanilla workshop menus using that method pretty much 100%. ill post whole code tomorrow when i did some cleanup.
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: Bogus on September 25, 2015, 12:53:32 pm
full script (tutorialized):
Spoiler (click to show/hide)

reaction classes
Spoiler (click to show/hide)

it is rather specific in what it does, because it just checks for reaction classes/material types and builds the selections around that. it also needs to be tailored to one workshop, which needs to be custom(although with some slight modification it may work with built in shops too).

i didnt do a whole lot of testing yet but it should be fairly easy to change the selection criteria, add new levels or modify item types instead of materials, or both. the only major weak point is that the job names cant be customized, so the material names will not show up in the job list, the name of the reaction thats being used is shown instead.

the only way to work around that seems to be to actually have a reaction for each one of the entries/possible combinations. reactions can however be created by lua script, so by way of templates one can create dozends of reactions to cover each selection with a custom description (like a vanilla workshop would do).

i tried doing that, but turns out it crashes the game on reload if reactions were saved that dont have an entry in the raw files.
Title: Re: [DFHack/Eventful]how to replace workshop "Add new task" page with custom menu
Post by: milo christiansen on September 26, 2015, 11:43:41 am
Complicated, but less so than it could be... That could be very useful (with a few tweaks of my own) in my First Landing mod.