Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trackstop and rollers overlays #884

Merged
merged 4 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Template for new versions:

## New Tools
- `sync-windmills`: synchronize or randomize movement of active windmills
- `trackstop`: new overlay to allow changing track stop dump direction and friction and roller direction and speed after construction

## New Features
- `gui/design`: show selected dimensions next to the mouse cursor when designating with vanilla tools, for example when painting a burrow or designating digging
Expand Down
10 changes: 10 additions & 0 deletions docs/trackstop.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
trackstop
=========

.. dfhack-tool::
:summary: Overlay to allow changing track stop friction and dump direction and roller direction and speed after construction.
myk002 marked this conversation as resolved.
Show resolved Hide resolved
:tags: fort gameplay buildings interface

This script provides 2 overlays that are managed by the `overlay` framework.
myk002 marked this conversation as resolved.
Show resolved Hide resolved
The trackstop overlay allows the player to change the friction and dump direction of a selected track stop after it has been constructed.
The rollers overlay allows the player to change the roller direction and speed of a selected track stop after it has been constructed.
259 changes: 259 additions & 0 deletions trackstop.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
-- Overlay to allow changing track stop friction and dump direction after construction
--@ module = true
local gui = require('gui')
local widgets = require('gui.widgets')
local overlay = require('plugins.overlay')

local NORTH = 'North'
local EAST = 'East'
local SOUTH = 'South'
local WEST = 'West'

local LOW = 'Low'
local MEDIUM = 'Medium'
local HIGH = 'High'
local HIGHER = 'Higher'
local MAX = 'Max'

local NONE = 'None'

local FRICTION_MAP = {
[NONE] = 10,
[LOW] = 50,
[MEDIUM] = 500,
[HIGH] = 10000,
[MAX] = 50000,
}

local FRICTION_MAP_REVERSE = {}
for k, v in pairs(FRICTION_MAP) do
FRICTION_MAP_REVERSE[v] = k
end
myk002 marked this conversation as resolved.
Show resolved Hide resolved

local SPEED_MAP = {
[LOW] = 10000,
[MEDIUM] = 20000,
[HIGH] = 30000,
[HIGHER] = 40000,
[MAX] = 50000,
}

local SPEED_MAP_REVERSE = {}
for k, v in pairs(SPEED_MAP) do
SPEED_MAP_REVERSE[v] = k
end
myk002 marked this conversation as resolved.
Show resolved Hide resolved

local DIRECTION_MAP = {
[NORTH] = df.screw_pump_direction.FromSouth,
[EAST] = df.screw_pump_direction.FromWest,
[SOUTH] = df.screw_pump_direction.FromNorth,
[WEST] = df.screw_pump_direction.FromEast,
}

local DIRECTION_MAP_REVERSE = {}
for k, v in pairs(DIRECTION_MAP) do
DIRECTION_MAP_REVERSE[v] = k
end
myk002 marked this conversation as resolved.
Show resolved Hide resolved

TrackStopOverlay = defclass(TrackStopOverlay, overlay.OverlayWidget)
TrackStopOverlay.ATTRS{
default_pos={x=-71, y=29},
default_enabled=true,
myk002 marked this conversation as resolved.
Show resolved Hide resolved
viewscreens='dwarfmode/ViewSheets/BUILDING/Trap',
frame={w=27, h=4},
frame_style=gui.MEDIUM_FRAME,
frame_background=gui.CLEAR_PEN,
}

function TrackStopOverlay:getFriction()
return dfhack.gui.getSelectedBuilding().friction
end

function TrackStopOverlay:setFriction(friction)
local building = dfhack.gui.getSelectedBuilding()

building.friction = FRICTION_MAP[friction]
end

function TrackStopOverlay:getDumpDirection()
local building = dfhack.gui.getSelectedBuilding()
local use_dump = building.use_dump
local dump_x_shift = building.dump_x_shift
local dump_y_shift = building.dump_y_shift

if use_dump == 0 then
return NONE
else
if dump_x_shift == 0 and dump_y_shift == -1 then
return NORTH
elseif dump_x_shift == 1 and dump_y_shift == 0 then
return EAST
elseif dump_x_shift == 0 and dump_y_shift == 1 then
return SOUTH
elseif dump_x_shift == -1 and dump_y_shift == 0 then
return WEST
end
end
end

function TrackStopOverlay:setDumpDirection(direction)
local building = dfhack.gui.getSelectedBuilding()

if direction == NONE then
building.use_dump = 0
building.dump_x_shift = 0
building.dump_y_shift = 0
elseif direction == NORTH then
building.use_dump = 1
building.dump_x_shift = 0
building.dump_y_shift = -1
elseif direction == EAST then
building.use_dump = 1
building.dump_x_shift = 1
building.dump_y_shift = 0
elseif direction == SOUTH then
building.use_dump = 1
building.dump_x_shift = 0
building.dump_y_shift = 1
elseif direction == WEST then
building.use_dump = 1
building.dump_x_shift = -1
building.dump_y_shift = 0
end
end

function TrackStopOverlay:render(dc)
if not self:shouldRender() then
return
end
Copy link
Member

Choose a reason for hiding this comment

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

can this be removed?


local building = dfhack.gui.getSelectedBuilding()
local friction = building.friction
local friction_cycle = self.subviews.friction

friction_cycle:setOption(FRICTION_MAP_REVERSE[friction])

self.subviews.dump_direction:setOption(self:getDumpDirection())

TrackStopOverlay.super.render(self, dc)
end

function TrackStopOverlay:shouldRender()
local building = dfhack.gui.getSelectedBuilding()
return building and building.trap_type == df.trap_type.TrackStop
Copy link
Member

Choose a reason for hiding this comment

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

if you expect building can be nil, then be sure to call getSelectedBuilding(true) instead of just getSelectedBuilding() so you don't spam the console with errors

Copy link
Member

Choose a reason for hiding this comment

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

on the other hand, though, why would this ever return false? You're already attached to viewscreens='dwarfmode/ViewSheets/BUILDING/Trap'

Choose a reason for hiding this comment

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

Yeah I assume the building will always be there

Copy link
Member

Choose a reason for hiding this comment

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

so maybe this function can be removed entirely (and onInput() as well)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, so there is currently a spot where the console can get spammed with errors with the way I have this written.

If you have gm-editor open and try to edit a field that opens a dialog to input the new value, then getSelectedBuilding() is returning nil and the console is spammed with errors. Maybe I should use getSelectedBuilding(true) and guard against it being nil after all?

Copy link
Member

Choose a reason for hiding this comment

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

maybe that's a good idea, at least for the time being. once the dialogs are updated to use ZScreens, this will no longer be an issue, but I don't know when I'm going to get around to doing that.

end

function TrackStopOverlay:onInput(keys)
if not self:shouldRender() then
return
end
TrackStopOverlay.super.onInput(self, keys)
end
Copy link
Member

Choose a reason for hiding this comment

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

Oh, I forgot -- can this function be removed?


function TrackStopOverlay:init()
self:addviews{
widgets.Label{
frame={t=0, l=0},
text='Dump',
},
myk002 marked this conversation as resolved.
Show resolved Hide resolved
widgets.CycleHotkeyLabel{
frame={t=0, l=9},
key='CUSTOM_CTRL_X',
options={NONE, NORTH, EAST, SOUTH, WEST},
myk002 marked this conversation as resolved.
Show resolved Hide resolved
view_id='dump_direction',
on_change=function(val) self:setDumpDirection(val) end,
},
widgets.Label{
frame={t=1, l=0},
text='Friction',
},
myk002 marked this conversation as resolved.
Show resolved Hide resolved
widgets.CycleHotkeyLabel{
frame={t=1, l=9},
key='CUSTOM_CTRL_F',
options={NONE, LOW, MEDIUM, HIGH, MAX},
myk002 marked this conversation as resolved.
Show resolved Hide resolved
view_id='friction',
on_change=function(val) self:setFriction(val) end,
},
}
end

RollerOverlay = defclass(RollerOverlay, overlay.OverlayWidget)
RollerOverlay.ATTRS{
default_pos={x=-71, y=29},
default_enabled=true,
myk002 marked this conversation as resolved.
Show resolved Hide resolved
viewscreens='dwarfmode/ViewSheets/BUILDING/Rollers',
frame={w=27, h=4},
frame_style=gui.MEDIUM_FRAME,
frame_background=gui.CLEAR_PEN,
}

function RollerOverlay:getDirection()
local building = dfhack.gui.getSelectedBuilding()
local direction = building.direction

return DIRECTION_MAP_REVERSE[direction]
end

function RollerOverlay:setDirection(direction)
local building = dfhack.gui.getSelectedBuilding()

building.direction = DIRECTION_MAP[direction]
end

function RollerOverlay:getSpeed()
local building = dfhack.gui.getSelectedBuilding()
local speed = building.speed

return SPEED_MAP_REVERSE[speed]
end

function RollerOverlay:setSpeed(speed)
local building = dfhack.gui.getSelectedBuilding()

building.speed = SPEED_MAP[speed]
end

function RollerOverlay:render(dc)
local building = dfhack.gui.getSelectedBuilding()

self.subviews.direction:setOption(DIRECTION_MAP_REVERSE[building.direction])
self.subviews.speed:setOption(SPEED_MAP_REVERSE[building.speed])

TrackStopOverlay.super.render(self, dc)
end

function RollerOverlay:init()
myk002 marked this conversation as resolved.
Show resolved Hide resolved
self:addviews{
widgets.Label{
frame={t=0, l=0},
text='Direction',
},
widgets.CycleHotkeyLabel{
frame={t=0, l=10},
key='CUSTOM_CTRL_X',
options={NORTH, EAST, SOUTH, WEST},
view_id='direction',
on_change=function(val) self:setDirection(val) end,
},
widgets.Label{
frame={t=1, l=0},
text='Speed',
},
widgets.CycleHotkeyLabel{
frame={t=1, l=10},
key='CUSTOM_CTRL_F',
options={LOW, MEDIUM, HIGH, HIGHER, MAX},
view_id='speed',
on_change=function(val) self:setSpeed(val) end,
},
}
end

OVERLAY_WIDGETS = {
trackstop=TrackStopOverlay,
rollers=RollerOverlay,
}

if not dfhack_flags.module then
main{...}
myk002 marked this conversation as resolved.
Show resolved Hide resolved
end