Skip to content

Add overlay to queue lever pull jobs from linked building view#5725

Open
pajawojciech wants to merge 7 commits into
DFHack:developfrom
pajawojciech:levers
Open

Add overlay to queue lever pull jobs from linked building view#5725
pajawojciech wants to merge 7 commits into
DFHack:developfrom
pajawojciech:levers

Conversation

@pajawojciech
Copy link
Copy Markdown
Contributor

@pajawojciech pajawojciech commented Feb 26, 2026

How it works

  • New overlay display button next to lever in 'Show linked buildings' tab.
  • Button show lever status indicator: slash or backslash, representing current position of lever.
  • Button adds / removes pull lever jobs
  • Works fine even with more than one linked levers.
obraz

Click button

After click text changes to "Pulling" with yellow color, and job is queued. Now you can click again if you change your mind - it removes queued job.
obraz

obraz

Job assigned

When job is assigned text changes color to green:
obraz
obraz

Pulled

After pull text, color and indicator changes
obraz

When Unlink is enabled button moves to the left

obraz

What I tried

Instead of pull text i tried to set Open / opening / close / closing labels. For standard bridges it works fine, but for example retracting bridges or cages should have reversed operation naming, so I use 'Pull' text and lever position indicator

Issue

#3938

@chdoc chdoc added this to 53.10-r2 Apr 7, 2026
@github-project-automation github-project-automation Bot moved this to Needs review in 53.10-r2 Apr 7, 2026
@chdoc chdoc self-requested a review April 7, 2026 11:37
@chdoc
Copy link
Copy Markdown
Member

chdoc commented Apr 7, 2026

I like the idea. However, I don't see any reason why this should be extending the buildingplan tool. In fact, I don't see why this couldn't be in scripts, for instance as part of the lever tool.

@pajawojciech
Copy link
Copy Markdown
Contributor Author

I like the idea. However, I don't see any reason why this should be extending the buildingplan tool. In fact, I don't see why this couldn't be in scripts, for instance as part of the lever tool.

Thanks for review.
I made it this way because overlay reuses code from unlink_mechanisms.lua file (for example mech_iter, get_trigger_index and more). Also one new and two old overlays share the same screen space (and pull overlay checks whether unlink is enabled for good positioning), so splitting them would create duplicated code and fragille coordination.
Can scripts register overlay widgets?

@chdoc
Copy link
Copy Markdown
Member

chdoc commented May 14, 2026

I still maintain that an overlay that exclusively deals with pulling levers does not belong in a file that is called unlink_mechanisms. So, at the very least, the existing module should be modified to export the functionality that needs to be reused and the new overlay should be put into a separate module. Just because things are not in the same file doesn't mean you can't reuse functionality. And once the relevant functionality is exported, there really isn't a whole lot of a reason anymore for this to be part of buildingplan. There are plenty of scripts that define overlays, and quite a few of them need to be positioned not to conflict with other overlays: https://github.com/DFHack/scripts/blob/af457f9b5c86fc041a064ef5bdfbcab38f38a50f/idle-crafting.lua#L611-L613

The only slightly annoying part of moving this to scripts is that merging the pull request to scripts will be contingent on merging the pull request for exporting the functionality. But that can be dealt with.

Copy link
Copy Markdown
Member

@chdoc chdoc left a comment

Choose a reason for hiding this comment

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

Finally got around to providing an in-depth review.

Comment on lines +417 to +428
function MechLeverPullOverlay:is_lever(building)
return building._type == df.building_trapst and building.trap_type == df.trap_type.Lever
end

function MechLeverPullOverlay:get_lever_pull_job(lever)
for _, job in ipairs(lever.jobs) do
if job.job_type == df.job_type.PullLever then
return job
end
end
return nil
end
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These neither read nor write member variables, so there is no need for them to be member functions.

local building_ref = df.general_ref_building_holderst:new()
building_ref.building_id = lever.id

local job = df.job:new()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please use dfhack.job.createLinked() and remove the call to linkIntoWorld (or better reuse the existing functionality from the lever script),

y = lever.centery,
z = lever.z
}
job.flags.do_now = false
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
job.flags.do_now = false
job.flags.do_now = true

I think one can argue that the default for pulling levers should be with urgency.

for i = #lever.jobs, 1, -1 do
local job = lever.jobs[i-1]
if job.job_type == df.job_type.PullLever then
lever.jobs:erase(i-1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it really necessary to call erase? removeJob should already remove all references to the job,

function MechLeverPullOverlay:onRenderFrame(dc, rect)
if self.bld_id ~= sheet.viewing_bldid then
self.bld_id = sheet.viewing_bldid
self.building = df.building.find(self.bld_id)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since buildings can be destroyed at any time, storing buildings is generally not safe. This may be fine, because none of this is called unless there is a viewscreen open and therefore the game is paused, but please double check.

end
end

function MechLeverPullOverlay:update_buttons()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I find it really hard to understand what is going on in these methods. I would really appreciate 1-3 lines of comments about the general idea here.

@github-project-automation github-project-automation Bot moved this from Needs review to Needs revision in 53.10-r2 May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs revision

Development

Successfully merging this pull request may close these issues.

2 participants