diff --git a/dfhack-config/quickfort/aliases.txt b/dfhack-config/quickfort/aliases.txt
index c5d34ec39..2b90e67c4 100644
--- a/dfhack-config/quickfort/aliases.txt
+++ b/dfhack-config/quickfort/aliases.txt
@@ -22,12 +22,12 @@
#
# For example, say you have the following build and place blueprints:
#
-# #build start(4;1;upper left corner of stockpile) build masonry workshop
+# #build masonry workshop
# ~, ~,~,`,`,`
# ~,wm,~,`,`,`
# ~, ~,~,`,`,`
#
-# #place start(4;1;upper left corner of stockpile) place stockpile for mason
+# #place stockpile for mason
# ~,~,~,s,s,s
# ~,~,~,s,s,s
# ~,~,~,s,s,s
@@ -63,9 +63,7 @@
# keycode from the DF interface definition file (data/init/interface.txt),
# enclosed in curly brackets like an alias, like: "{Right}" or "{Enter}". In
# order to avoid naming conflicts between aliases and keycodes, the convention
-# is to start aliases with a lowercase letter. You can add spaces in between
-# keystrokes to make them easier to read. Spaces in keystroke sequences will be
-# ignored. To insert a literal space, use "{Space}"
+# is to start aliases with a lowercase letter.
#
# Anything enclosed within curly brackets can also have a number after it,
# indicating how many times that alias or keycode should be repeated. For
diff --git a/dfhack-config/quickfort/quickfort.txt b/dfhack-config/quickfort/quickfort.txt
index 575b7a804..c1d70201f 100644
--- a/dfhack-config/quickfort/quickfort.txt
+++ b/dfhack-config/quickfort/quickfort.txt
@@ -22,6 +22,14 @@ buildings_use_blocks=true
# be designated in marker mode.
force_marker_mode=false
+# Skip query blueprint sanity checks that detect common blueprint errors and
+# halt or skip keycode playback. Checks include ensuring a configurable building
+# exists at the designated cursor position and verifying the active UI screen is
+# the same before and after sending keys for the cursor position. Temporarily
+# enable this if you are running a query blueprint that sends a key sequence
+# that is *not* related to stockpile or building configuration.
+query_unsafe=false
+
# Set to the maximum number of resources you want assigned to stockpiles of the
# relevant types. Set to -1 for DF defaults (number of stockpile tiles for
# stockpiles that take barrels and bins, 1 wheelbarrow for stone stockpiles).
diff --git a/docs/Installing.rst b/docs/Installing.rst
index c0175b820..5b564f45f 100644
--- a/docs/Installing.rst
+++ b/docs/Installing.rst
@@ -150,3 +150,19 @@ DF, DFHack, and other utilities. If you are new to Dwarf Fortress and DFHack,
these may be easier to set up. Note that these packs are not maintained by the
DFHack team and vary in their release schedules and contents. Some may make
significant configuration changes, and some may not include DFHack at all.
+
+Linux packages
+==============
+
+Third-party DFHack packages are available for some Linux distributions,
+including in:
+
+* `AUR `__, for Arch and related
+ distributions
+* `RPM Fusion `__,
+ for Fedora and related distributions
+
+Note that these may lag behind DFHack releases. If you want to use a newer
+version of DFHack, we generally recommended installing it in a clean copy of DF
+in your home folder. Attempting to upgrade an installation of DFHack from a
+package manager may break it.
diff --git a/docs/changelog.txt b/docs/changelog.txt
index faec636dd..7f289c36d 100644
--- a/docs/changelog.txt
+++ b/docs/changelog.txt
@@ -33,6 +33,9 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future
+## Fixes
+- `dwarfmonitor`: fixed a crash when opening the ``prefs`` screen if units have vague preferences
+
# 0.47.04-r3
## New Plugins
diff --git a/plugins/dwarfmonitor.cpp b/plugins/dwarfmonitor.cpp
index fc1679a19..84e9b9abe 100644
--- a/plugins/dwarfmonitor.cpp
+++ b/plugins/dwarfmonitor.cpp
@@ -1155,52 +1155,107 @@ struct preference_map
string getItemLabel()
{
- df::world_raws::T_itemdefs &defs = world->raws.itemdefs;
label = ENUM_ATTR_STR(item_type, caption, pref.item_type);
switch (pref.item_type)
{
case (df::item_type::WEAPON):
- label = defs.weapons[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.weapons, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::TRAPCOMP):
- label = defs.trapcomps[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.trapcomps, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::TOY):
- label = defs.toys[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.toys, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::TOOL):
- label = defs.tools[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.tools, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::INSTRUMENT):
- label = defs.instruments[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.instruments, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::ARMOR):
- label = defs.armor[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.armor, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::AMMO):
- label = defs.ammo[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.ammo, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::SIEGEAMMO):
- label = defs.siege_ammo[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.siege_ammo, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::GLOVES):
- label = defs.gloves[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.gloves, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::SHOES):
- label = defs.shoes[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.shoes, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::SHIELD):
- label = defs.shields[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.shields, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::HELM):
- label = defs.helms[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.helms, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::PANTS):
- label = defs.pants[pref.item_subtype]->name_plural;
+ {
+ auto *def = vector_get(world->raws.itemdefs.pants, pref.item_subtype);
+ if (def)
+ label = def->name_plural;
break;
+ }
case (df::item_type::FOOD):
- label = defs.food[pref.item_subtype]->name;
+ {
+ auto *def = vector_get(world->raws.itemdefs.food, pref.item_subtype);
+ if (def)
+ label = def->name;
break;
+ }
default:
label = ENUM_ATTR_STR(item_type, caption, pref.item_type);
diff --git a/scripts b/scripts
index 0b2748554..a574158ca 160000
--- a/scripts
+++ b/scripts
@@ -1 +1 @@
-Subproject commit 0b274855424e5d0850d2cfc8b10e1cdcc47c6877
+Subproject commit a574158ca3f12ed2911e77632e09972be56beb3a