Skip to content

Commit c4d19c1

Browse files
authored
Revert "temporarily back out new features"
1 parent d5836bc commit c4d19c1

File tree

8 files changed

+285
-13
lines changed

8 files changed

+285
-13
lines changed

advtools.lua

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
--@ module=true
22

33
local convo = reqscript('internal/advtools/convo')
4+
local fastcombat = reqscript('internal/advtools/fastcombat')
45
local party = reqscript('internal/advtools/party')
56

67
OVERLAY_WIDGETS = {
78
conversation=convo.AdvRumorsOverlay,
9+
fastcombat=fastcombat.AdvCombatOverlay,
810
}
911

1012
if dfhack_flags.module then

autocheese.lua

+187
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
--@module = true
2+
3+
local ic = reqscript('idle-crafting')
4+
5+
---make cheese using a specific barrel and workshop
6+
---@param barrel df.item
7+
---@param workshop df.building_workshopst
8+
---@return df.job
9+
function makeCheese(barrel, workshop)
10+
---@type df.job
11+
local job = ic.make_job()
12+
job.job_type = df.job_type.MakeCheese
13+
14+
local jitem = df.job_item:new()
15+
jitem.quantity = 0
16+
jitem.vector_id = df.job_item_vector_id.ANY_COOKABLE
17+
jitem.flags1.unrotten = true
18+
jitem.flags1.milk = true
19+
job.job_items.elements:insert('#', jitem)
20+
21+
if not dfhack.job.attachJobItem(job, barrel, df.job_item_ref.T_role.Reagent, 0, -1) then
22+
dfhack.error('could not attach item')
23+
end
24+
25+
ic.assignToWorkshop(job, workshop)
26+
return job
27+
end
28+
29+
30+
31+
---unit is ready to take jobs
32+
---@param unit df.unit
33+
---@return boolean
34+
function unitIsAvailable(unit)
35+
if unit.job.current_job then
36+
return false
37+
elseif #unit.individual_drills > 0 then
38+
return false
39+
elseif unit.flags1.caged or unit.flags1.chained then
40+
return false
41+
elseif unit.military.squad_id ~= -1 then
42+
local squad = df.squad.find(unit.military.squad_id)
43+
-- this lookup should never fail
44+
---@diagnostic disable-next-line: need-check-nil
45+
return #squad.orders == 0 and squad.activity == -1
46+
end
47+
return true
48+
end
49+
50+
---check if unit can perform labor at workshop
51+
---@param unit df.unit
52+
---@param unit_labor df.unit_labor
53+
---@param workshop df.building
54+
---@return boolean
55+
function availableLaborer(unit, unit_labor, workshop)
56+
return unit.status.labors[unit_labor]
57+
and unitIsAvailable(unit)
58+
and ic.canAccessWorkshop(unit, workshop)
59+
end
60+
61+
---find unit with a particular labor enabled
62+
---@param unit_labor df.unit_labor
63+
---@param job_skill df.job_skill
64+
---@param workshop df.building
65+
---@return df.unit|nil
66+
---@return integer|nil
67+
function findAvailableLaborer(unit_labor, job_skill, workshop)
68+
local max_unit = nil
69+
local max_skill = -1
70+
for _, unit in ipairs(dfhack.units.getCitizens(true, false)) do
71+
if
72+
availableLaborer(unit, unit_labor, workshop)
73+
then
74+
local unit_skill = dfhack.units.getNominalSkill(unit, job_skill, true)
75+
if unit_skill > max_skill then
76+
max_unit = unit
77+
max_skill = unit_skill
78+
end
79+
end
80+
end
81+
return max_unit, max_skill
82+
end
83+
84+
local function findMilkBarrel(min_liquids)
85+
for _, container in ipairs(df.global.world.items.other.FOOD_STORAGE) do
86+
if
87+
not (container.flags.in_job or container.flags.forbid) and
88+
container.flags.container and #container.general_refs >= min_liquids
89+
then
90+
local content_reference = dfhack.items.getGeneralRef(container, df.general_ref_type.CONTAINS_ITEM)
91+
local contained_item = df.item.find(content_reference and content_reference.item_id or -1)
92+
if contained_item then
93+
local mat_info = dfhack.matinfo.decode(contained_item)
94+
if mat_info:matches { milk = true } then
95+
return container
96+
end
97+
end
98+
end
99+
end
100+
end
101+
102+
---find a workshop to which the barrel can be brought
103+
---if the workshop has a master, only return workshop and master if the master is available
104+
---@param pos df.coord
105+
---@return df.building_workshopst?
106+
---@return df.unit?
107+
function findWorkshop(pos)
108+
for _,workshop in ipairs(df.global.world.buildings.other.WORKSHOP_FARMER) do
109+
if
110+
dfhack.maps.canWalkBetween(pos, xyz2pos(workshop.centerx, workshop.centery, workshop.z)) and
111+
not workshop.profile.blocked_labors[df.unit_labor.MAKE_CHEESE] and
112+
#workshop.jobs == 0
113+
then
114+
if #workshop.profile.permitted_workers == 0 then
115+
-- immediately return workshop without master
116+
return workshop, nil
117+
else
118+
unit = df.unit.find(workshop.profile.permitted_workers[0])
119+
if
120+
unit and availableLaborer(unit, df.unit_labor.MAKE_CHEESE, workshop)
121+
then
122+
-- return workshop and master, if master is available
123+
return workshop, unit
124+
else
125+
print("autocheese: Skipping farmer's workshop with unavailable master")
126+
end
127+
end
128+
end
129+
end
130+
end
131+
132+
if dfhack_flags.module then
133+
return
134+
end
135+
136+
-- actual script action
137+
138+
local argparse = require('argparse')
139+
140+
local min_number = 50
141+
142+
local _ = argparse.processArgsGetopt({...},
143+
{
144+
{ 'm', 'min-milk', hasArg = true,
145+
handler = function(min)
146+
min_number = argparse.nonnegativeInt(min, 'min-milk')
147+
end }
148+
})
149+
150+
151+
local reagent = findMilkBarrel(min_number)
152+
153+
if not reagent then
154+
-- print('autocheese: no sufficiently full barrel found')
155+
return
156+
end
157+
158+
local workshop, worker = findWorkshop(xyz2pos(dfhack.items.getPosition(reagent)))
159+
160+
if not workshop then
161+
print("autocheese: no Farmer's Workshop available")
162+
return
163+
end
164+
165+
-- try to find laborer for workshop without master
166+
if not worker then
167+
worker, _ = findAvailableLaborer(df.unit_labor.MAKE_CHEESE, df.job_skill.CHEESEMAKING, workshop)
168+
end
169+
170+
if not worker then
171+
print('autocheese: no cheesemaker available')
172+
return
173+
end
174+
local job = makeCheese(reagent, workshop)
175+
176+
print(('autocheese: dispatching cheesemaking job for %s (%d milk) to %s'):format(
177+
dfhack.df2console(dfhack.items.getReadableDescription(reagent)),
178+
#reagent.general_refs,
179+
dfhack.df2console(dfhack.units.getReadableName(worker))
180+
))
181+
182+
183+
-- assign a worker and send it to fetch the barrel
184+
dfhack.job.addWorker(job, worker)
185+
dfhack.units.setPathGoal(worker, reagent.pos, df.unit_path_goal.GrabJobResources)
186+
job.items[0].flags.is_fetching = true
187+
job.flags.fetching = true

changelog.txt

+4
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ Template for new versions:
2727
# Future
2828

2929
## New Tools
30+
- `autocheese`: automatically make cheese using barrels that have accumulated sufficient milk
3031

3132
## New Features
33+
- `advtools`: new overlay ``advtools.fastcombat``; allows you to skip combat animations and the announcement "More" button
3234

3335
## Fixes
3436
- `advtools`: fix dfhack-added conversation options not appearing in the ask whereabouts conversation tree
@@ -37,6 +39,8 @@ Template for new versions:
3739
## Misc Improvements
3840
- `assign-preferences`: new ``--show`` option to display the preferences of the selected unit
3941
- `pref-adjust`: new ``show`` command to display the preferences of the selected unit
42+
- `hide-tutorials`: if enabled, also hide tutorial popups for adventure mode
43+
- `hide-tutorials`: new ``reset`` command that will re-enable popups in the current game
4044

4145
## Removed
4246
- `gui/control-panel`: removed ``craft-age-wear`` tweak for Windows users; the tweak doesn't currently load on Windows

docs/advtools.rst

+13
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,16 @@ enemies will gain the ``slay`` and ``kill`` keywords. It will also add
3535
additional conversation options for asking whereabouts of your relationships --
3636
in vanilla, you can only ask whereabouts of historical figures involved in
3737
rumors you personally witnessed or heard about.
38+
39+
``advtools.fastcombat``
40+
~~~~~~~~~~~~~~~~~~~~~~~
41+
42+
When enabled, this overlay will allow you to skip most combat animations,
43+
including the whooshes and projectiles travelling through the screen. It will
44+
also let you skip the announcements window when the "More" button is active,
45+
scrolling you to the very bottom with the first press, and skipping the window
46+
entirely with the second press. This drastically speeds up combat while still
47+
giving you the option not to skip the announcements. Skip keys are left mouse click,
48+
the SELECT button, the movement keys and combat-related keys that don't bring up a
49+
menu (such as bump attack). If clicking to skip past combat, it will only skip the
50+
announcements if you're clicking outside the announcements panel.

docs/autocheese.rst

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
autocheese
2+
==========
3+
4+
.. dfhack-tool::
5+
:summary: Schedule cheese making jobs based on milk reserves.
6+
:tags: fort auto
7+
8+
Cheese making is difficult to automate using work orders. A single job
9+
can consume anything from a bucket with a single unit of milk to a barrel
10+
with 100 units of milk. This makes it hard to predict how much cheese will
11+
actually be produced by an automated order.
12+
13+
The script will scan your fort for barrels with a certain minimum amount of milk
14+
(default: 50), create a cheese making job specifically for that barrel, and
15+
assign this job to one of your idle dwarves (giving preference to skilled cheese
16+
makers).
17+
18+
When enabled using `gui/control-panel`, the script will run automatically, with
19+
default options, twice a month.
20+
21+
Usage
22+
-----
23+
24+
::
25+
26+
autocheese [<options>]
27+
28+
Examples
29+
--------
30+
31+
``autocheese -m 100``
32+
Only create a job if there is a barrel that is filled to the maximum.
33+
34+
Options
35+
-------
36+
37+
``-m``, ``--min-milk``
38+
Set the minimum number of milk items in a barrel for the barrel to be
39+
considered for cheese making.

docs/hide-tutorials.rst

+10-4
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ hide-tutorials
33

44
.. dfhack-tool::
55
:summary: Hide new fort tutorial popups.
6-
:tags: fort interface
6+
:tags: adventure fort interface
77

88
If you've played the game before and don't need to see the tutorial popups that
99
show up on every new fort, ``hide-tutorials`` can hide them for you. You can
1010
enable this tool as a system service in the "Services" tab of
11-
`gui/control-panel` so it takes effect for all new or loaded forts.
11+
`gui/control-panel` so it takes effect for all forts and adventures.
1212

1313
Specifically, this tool hides:
1414

1515
- The popup displayed when creating a new world
1616
- The "Do you want to start a tutorial embark" popup
1717
- Popups displayed the first time you open the labor, burrows, justice, and
1818
other similar screens in a new fort
19+
- Popups displayed when you perform certain actions for the first time in an
20+
adventure
1921

2022
Note that only unsolicited tutorial popups are hidden. If you directly request
2123
a tutorial page from the help, then it will still function normally.
@@ -27,6 +29,10 @@ Usage
2729

2830
enable hide-tutorials
2931
hide-tutorials
32+
hide-tutorials reset
3033

31-
If you haven't enabled the tool, but you run the command while a fort is
32-
loaded, all future popups for the loaded fort will be hidden.
34+
If you haven't enabled the tool, but you run the command while a fort or
35+
adventure is loaded, all future popups for the loaded game will be hidden.
36+
37+
If you run the command with the ``reset`` option, all popups will be re-enabled
38+
as if they had never been seen or dismissed.

hide-tutorials.lua

+28-9
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ function isEnabled()
1212
return enabled
1313
end
1414

15-
local function is_fort_map_loaded()
16-
return df.global.gamemode == df.game_mode.DWARF and dfhack.isMapLoaded()
17-
end
18-
1915
local help = df.global.game.main_interface.help
2016

2117
local function close_help()
@@ -43,15 +39,36 @@ function skip_tutorial_prompt()
4339
end
4440
end
4541

42+
local function get_prefix()
43+
if dfhack.world.isFortressMode() then
44+
return 'POPUP_'
45+
elseif dfhack.world.isAdventureMode() then
46+
return 'ADVENTURE_POPUP_'
47+
end
48+
end
49+
4650
local function hide_all_popups()
51+
local prefix = get_prefix()
52+
if not prefix then return end
4753
for i,name in ipairs(df.help_context_type) do
48-
if not name:startswith('POPUP_') then goto continue end
54+
if not name:startswith(prefix) then goto continue end
4955
utils.insert_sorted(df.global.plotinfo.tutorial_seen, i)
5056
utils.insert_sorted(df.global.plotinfo.tutorial_hide, i)
5157
::continue::
5258
end
5359
end
5460

61+
local function show_all_popups()
62+
local prefix = get_prefix()
63+
if not prefix then return end
64+
for i,name in ipairs(df.help_context_type) do
65+
if not name:startswith(prefix) then goto continue end
66+
utils.erase_sorted(df.global.plotinfo.tutorial_seen, i)
67+
utils.erase_sorted(df.global.plotinfo.tutorial_hide, i)
68+
::continue::
69+
end
70+
end
71+
5572
dfhack.onStateChange[GLOBAL_KEY] = function(sc)
5673
if not enabled then return end
5774

@@ -65,7 +82,7 @@ dfhack.onStateChange[GLOBAL_KEY] = function(sc)
6582
dfhack.timeout(100, 'frames', skip_tutorial_prompt)
6683
dfhack.timeout(1000, 'frames', skip_tutorial_prompt)
6784
end
68-
elseif sc == SC_MAP_LOADED and df.global.gamemode == df.game_mode.DWARF then
85+
elseif sc == SC_MAP_LOADED then
6986
hide_all_popups()
7087
end
7188
end
@@ -81,13 +98,15 @@ end
8198

8299
if args[1] == "enable" then
83100
enabled = true
84-
if is_fort_map_loaded() then
101+
if dfhack.isMapLoaded() then
85102
hide_all_popups()
86103
end
87104
elseif args[1] == "disable" then
88105
enabled = false
89-
elseif is_fort_map_loaded() then
106+
elseif args[1] == "reset" then
107+
show_all_popups()
108+
elseif dfhack.isMapLoaded() then
90109
hide_all_popups()
91110
else
92-
qerror('hide-tutorials needs a loaded fortress map to work')
111+
qerror('hide-tutorials needs a loaded fortress or adventure map to work')
93112
end

0 commit comments

Comments
 (0)