Merge remote-tracking branch 'DFHack/develop' into develop

develop
Japa 2017-05-07 19:24:39 +05:30
commit de7ef79d76
29 changed files with 568 additions and 104 deletions

@ -94,6 +94,8 @@ IF(CMAKE_CROSSCOMPILING)
INCLUDE("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake") INCLUDE("${DFHACK_NATIVE_BUILD_DIR}/ImportExecutables.cmake")
ENDIF() ENDIF()
find_package(Perl REQUIRED)
# set up folder structures for IDE solutions # set up folder structures for IDE solutions
# MSVC Express won't load solutions that use this. It also doesn't include MFC supported # MSVC Express won't load solutions that use this. It also doesn't include MFC supported
# Check for MFC! # Check for MFC!
@ -137,7 +139,7 @@ endif()
# set up versioning. # set up versioning.
set(DF_VERSION "0.43.05") set(DF_VERSION "0.43.05")
SET(DFHACK_RELEASE "beta1") SET(DFHACK_RELEASE "beta2")
SET(DFHACK_PRERELEASE TRUE) SET(DFHACK_PRERELEASE TRUE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")

@ -14,7 +14,7 @@
Internals Internals
Lua Lua
New [Internal Commands | Plugins | Scripts | Features] New [Internal Commands | Plugins | Scripts | Tweaks | Features]
Fixes Fixes
Misc Improvements Misc Improvements
Removed Removed
@ -35,17 +35,21 @@ Changelog
.. contents:: .. contents::
:depth: 2 :depth: 2
DFHack future DFHack 0.43.05-r1
============= =================
Internals Internals
--------- ---------
- 64-bit support on all platforms - 64-bit support on all platforms
- Visual Studio 2015 now required on Windows instead of 2010
- GCC 4.8 or newer required on Linux and OS X (and now supported on OS X)
- Several structure fixes to match 64-bit DF's memory layout - Several structure fixes to match 64-bit DF's memory layout
- Added ``DFHack::Job::removeJob()`` function - Added ``DFHack::Job::removeJob()`` function
- New module: ``Designations`` - handles designation creation (currently for plants only)
- Added ``Gui::getSelectedPlant()``
- Added ``Units::getMainSocialActivity()``, ``Units::getMainSocialEvent()``
- Visual Studio 2015 now required to build on Windows instead of 2010
- GCC 4.8 or newer required to build on Linux and OS X (and now supported on OS X)
- Updated TinyXML from 2.5.3 to 2.6.2 - Updated TinyXML from 2.5.3 to 2.6.2
- Added the ability to download files manually before building
Lua Lua
--- ---
@ -56,6 +60,8 @@ Lua
- ``df.new()`` supports more types: ``char``, ``intptr_t``, ``uintptr_t``, ``long``, ``unsigned long`` - ``df.new()`` supports more types: ``char``, ``intptr_t``, ``uintptr_t``, ``long``, ``unsigned long``
- String representations of vectors and a few other containers now include their lengths - String representations of vectors and a few other containers now include their lengths
- Added a ``tile-material`` module - Added a ``tile-material`` module
- Added a ``Painter:key_string()`` method
- Made ``dfhack.gui.revealInDwarfmodeMap()`` available
Ruby Ruby
---- ----
@ -71,34 +77,63 @@ New Plugins
New Scripts New Scripts
----------- -----------
- `adv-rumors`: improves the "Bring up specific incident or rumor" menu in adventure mode
- `fix/tile-occupancy`: Clears bad occupancy flags on the selected tile. - `fix/tile-occupancy`: Clears bad occupancy flags on the selected tile.
- `install-info`: Logs basic troubleshooting information about the current DFHack installation
- `load-save`: loads a save non-interactively - `load-save`: loads a save non-interactively
- `modtools/change-build-menu`: Edit the build mode sidebar menus - `modtools/change-build-menu`: Edit the build mode sidebar menus
- `modtools/if-entity`: Run a command if the current entity matches a given ID - `modtools/if-entity`: Run a command if the current entity matches a given ID
- `season-palette`: Swap color palettes with the changes of the seasons - `season-palette`: Swap color palettes with the changes of the seasons
- `unforbid`: Unforbids all items
New Tweaks
----------
- `tweak condition-material <tweak>`: fixes a crash in the work order condition material list
- `tweak hotkey-clear <tweak>`: adds an option to clear bindings from DF hotkeys
Fixes Fixes
----- -----
- The DF path on OS X can now contain spaces and ``:`` characters - The DF path on OS X can now contain spaces and ``:`` characters
- Buildings::setOwner() changes now persist properly when saved - Buildings::setOwner() changes now persist properly when saved
- ``ls`` now lists scripts in folders other than ``hack/scripts``, when applicable - ``ls`` now lists scripts in folders other than ``hack/scripts``, when applicable
- Fixed ``plug`` output alignment for plugins with long names
- `add-thought`: fixed support for emotion names - `add-thought`: fixed support for emotion names
- `autofarm`: Made surface farms detect local biome - `autochop`:
- fixed several issues with job creation and removal
- stopped designating the center tile (unreachable) for large trees
- stopped options from moving when enabling and disabling burrows
- fixed display of unnamed burrows
- `devel/find-offsets`: fixed a crash when vtables used by globals aren't available - `devel/find-offsets`: fixed a crash when vtables used by globals aren't available
- `getplants`:
- fixed several issues with job creation and removal
- stopped designating the center tile (unreachable) for large trees
- `gui/workflow`: added extra keybinding to work with `gui/extended-status`
- `manipulator`: - `manipulator`:
- Fixed crash when selecting a profession from an empty list - Fixed crash when selecting a profession from an empty list
- Custom professions are now sorted alphabetically more reliably - Custom professions are now sorted alphabetically more reliably
- `modtools/create-unit`: stopped permanently overwriting the creature creation - `modtools/create-unit`:
menu in arena mode
- stopped permanently overwriting the creature creation menu in arena mode
- now uses non-English names
- `modtools/item-trigger`: fixed errors with plant growths
- `remotefortressreader`: fixed a crash when serializing the local map
- `title-version`: now hidden when loading an arena - `title-version`: now hidden when loading an arena
Misc Improvements Misc Improvements
----------------- -----------------
- Documented all default keybindings (from :file:`dfhack.init-example`) in the - Documented all default keybindings (from :file:`dfhack.init-example`) in the
docs for the relevant commands; updates enforced by build system. docs for the relevant commands; updates enforced by build system.
- `autounsuspend`: reduced update frequency to address potential performance issues
- `gui/extended-status`: added a feature to queue beds
- `lua` and `gui/gm-editor` now support the same aliases (``scr``, ``unit``, etc.) - `lua` and `gui/gm-editor` now support the same aliases (``scr``, ``unit``, etc.)
- `manipulator`: added social activities to job column
- `remotefortressreader`: Added support for - `remotefortressreader`: Added support for
- world map snow coverage - world map snow coverage
@ -106,8 +141,11 @@ Misc Improvements
- wall info - wall info
- site towers, world buildings - site towers, world buildings
- surface material - surface material
- building items
- DF version info
- `title-version`: Added a prerelease indicator - `title-version`: Added a prerelease indicator
- `workflow`: Re-added ``Alt-W`` keybindings
DFHack 0.43.03-r1 DFHack 0.43.03-r1
================= =================

@ -18,4 +18,4 @@ if (-f $out_file and !exists($args{'--force'})) {
die "output file exists, not overwriting: \"$out_file\""; die "output file exists, not overwriting: \"$out_file\"";
} }
gunzip $in_file => $out_file or die "gunzip failed: $GunzipError\n"; gunzip $in_file => $out_file, BinModeOut => 1 or die "gunzip failed: $GunzipError\n";

@ -135,6 +135,12 @@ keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path
# workshop job details # workshop job details
keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job
# workflow front-end
keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow
keybinding add Alt-W@overallstatus "gui/workflow status"
# equivalent to the one above when gui/extended-status is enabled
keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status"
# autobutcher front-end # autobutcher front-end
keybinding add Shift-B@pet/List/Unit "gui/autobutcher" keybinding add Shift-B@pet/List/Unit "gui/autobutcher"
@ -184,6 +190,9 @@ tweak import-priority-category
# Fixes a crash in the work order contition material list (bug 9905). # Fixes a crash in the work order contition material list (bug 9905).
tweak condition-material tweak condition-material
# Adds an option to clear currently-bound hotkeys
tweak hotkey-clear
# Misc. UI tweaks # Misc. UI tweaks
tweak block-labors # Prevents labors that can't be used from being toggled tweak block-labors # Prevents labors that can't be used from being toggled
tweak civ-view-agreement tweak civ-view-agreement

@ -12,6 +12,7 @@ Name Github Other
8Z 8Z 8Z 8Z
acwatkins acwatkins acwatkins acwatkins
Alexander Gavrilov angavrilov ag Alexander Gavrilov angavrilov ag
Amostubal Amostubal
AndreasPK AndreasPK AndreasPK AndreasPK
Angus Mezick amezick Angus Mezick amezick
Antalia tamarakorr Antalia tamarakorr
@ -75,6 +76,7 @@ Nick Rart nickrart comestible
Nikolay Amiantov abbradar Nikolay Amiantov abbradar
nocico nocico nocico nocico
Omniclasm Omniclasm
Paul Fenwick pjf
PeridexisErrant PeridexisErrant PeridexisErrant PeridexisErrant
Petr Mrázek peterix Petr Mrázek peterix
potato potato
@ -87,7 +89,9 @@ rampaging-poet
Raoul van Putten Raoul van Putten
Raoul XQ raoulxq Raoul XQ raoulxq
reverb reverb
Rich Rauenzahn rrauenza
Rinin Rinin Rinin Rinin
rndmvar rndmvar
Robert Heinrich rh73 Robert Heinrich rh73
Robert Janetzko robertjanetzko Robert Janetzko robertjanetzko
rofl0r rofl0r rofl0r rofl0r
@ -107,6 +111,7 @@ Simon Jackson sizeak
stolencatkarma stolencatkarma
sv-esk sv-esk sv-esk sv-esk
Tacomagic Tacomagic
TheHologram TheHologram
Tim Walberg twalberg Tim Walberg twalberg
Timothy Collett danaris Timothy Collett danaris
Tom Jobbins TheBloke Tom Jobbins TheBloke

@ -921,6 +921,10 @@ Gui module
Returns the building selected via :kbd:`q`, :kbd:`t`, :kbd:`k` or :kbd:`i`. Returns the building selected via :kbd:`q`, :kbd:`t`, :kbd:`k` or :kbd:`i`.
* ``dfhack.gui.getSelectedPlant([silent])``
Returns the plant selected via :kbd:`k`.
* ``dfhack.gui.writeToGamelog(text)`` * ``dfhack.gui.writeToGamelog(text)``
Writes a string to :file:`gamelog.txt` without doing an announcement. Writes a string to :file:`gamelog.txt` without doing an announcement.

@ -37,6 +37,57 @@ Development Changelog
.. contents:: .. contents::
:depth: 2 :depth: 2
DFHack 0.43.05-beta2
====================
Fixes
-----
- Fixed Buildings::updateBuildings(), along with building creation/deletion events
- Fixed ``plug`` output alignment for plugins with long names
- Fixed a crash that happened when a ``LUA_PATH`` environment variable was set
- `add-thought`: fixed number conversion
- `gui/workflow`: fixed range editing producing the wrong results for certain numbers
- `modtools/create-unit`: now uses non-English names
- `modtools/item-trigger`: fixed errors with plant growths
- `remotefortressreader`: fixed a crash when serializing the local map
- `stockflow`: fixed an issue with non-integer manager order limits
- `title-folder`: fixed compatibility issues with certain SDL libraries on macOS
Structures
----------
- Added some missing renderer VTable addresses on macOS
- ``entity.resources.organic``: identified ``parchment``
- ``entity_sell_category``: added ``Parchment`` and ``CupsMugsGoblets``
- ``ui_advmode_menu``: added ``Build``
- ``ui_unit_view_mode``: added ``PrefOccupation``
- ``unit_skill``: identified ``natural_skill_lvl`` (was ``unk_1c``)
- ``viewscreen_jobmanagementst``: identified ``max_workshops``
- ``viewscreen_overallstatusst``: made ``visible_pages`` an enum
- ``viewscreen_pricest``: identified fields
- ``viewscreen_workquota_conditionst``: gave some fields ``unk`` names
API Changes
-----------
- Allowed the Lua API to accept integer-like floats and strings when expecting an integer
- Lua: New ``Painter:key_string()`` method
- Lua: Added ``dfhack.getArchitecture()`` and ``dfhack.getArchitectureName()``
Additions/Removals:
-------------------
- Added `adv-rumors` script: improves the "Bring up specific incident or rumor" menu in adventure mode
- Added `install-info` script for basic troubleshooting
- Added `tweak condition-material <tweak>`: fixes a crash in the work order condition material list
- Added `tweak hotkey-clear <tweak>`: adds an option to clear bindings from DF hotkeys
- `autofarm`: reverted local biome detection (from 0.43.05-alpha3)
Other Changes
-------------
- Added a DOWNLOAD_RUBY CMake option, to allow use of a system/external ruby library
- Added the ability to download files manually before building
- `gui/extended-status`: added a feature to queue beds
- `remotefortressreader`: added building items, DF version info
- `stonesense`: Added support for 64-bit macOS and Linux
DFHack 0.43.05-beta1 DFHack 0.43.05-beta1
==================== ====================

@ -287,6 +287,7 @@ Subcommands that persist until disabled or DF quits:
the current item (fully, in case of a stack), and scroll down one line. the current item (fully, in case of a stack), and scroll down one line.
:fps-min: Fixes the in-game minimum FPS setting :fps-min: Fixes the in-game minimum FPS setting
:hide-priority: Adds an option to hide designation priority indicators :hide-priority: Adds an option to hide designation priority indicators
:hotkey-clear: Adds an option to clear currently-bound hotkeys (in the :kbd:`H` menu)
:import-priority-category: :import-priority-category:
Allows changing the priority of all goods in a Allows changing the priority of all goods in a
category when discussing an import agreement with the liaison category when discussing an import agreement with the liaison
@ -1656,13 +1657,14 @@ quotas.
Open the dashboard by running:: Open the dashboard by running::
getplants autochop enable autochop
The plugin must be activated (with ``c``) before it can be used. You can then set logging quotas The plugin must be activated (with :kbd:`d`-:kbd:`t`-:kbd:`c`-:kbd:`a`) before
and restrict designations to specific burrows (with 'Enter') if desired. The plugin's activity it can be used. You can then set logging quotas and restrict designations to
cycle runs once every in game day. specific burrows (with 'Enter') if desired. The plugin's activity cycle runs
once every in game day.
If you add ``enable getplants`` to your dfhack.init there will be a hotkey to If you add ``enable autochop`` to your dfhack.init there will be a hotkey to
open the dashboard from the chop designation menu. open the dashboard from the chop designation menu.

@ -16,8 +16,6 @@ ENDIF()
include_directories (proto) include_directories (proto)
include_directories (include) include_directories (include)
SET(PERL_EXECUTABLE "perl" CACHE FILEPATH "This is the perl executable to run in the codegen step. Tweak it if you need to run a specific one.")
execute_process(COMMAND ${PERL_EXECUTABLE} xml/list.pl xml ${dfapi_SOURCE_DIR}/include/df ";" execute_process(COMMAND ${PERL_EXECUTABLE} xml/list.pl xml ${dfapi_SOURCE_DIR}/include/df ";"
WORKING_DIRECTORY ${dfapi_SOURCE_DIR} WORKING_DIRECTORY ${dfapi_SOURCE_DIR}
OUTPUT_VARIABLE GENERATED_HDRS) OUTPUT_VARIABLE GENERATED_HDRS)
@ -115,36 +113,39 @@ SET(MODULE_HEADERS
include/modules/Buildings.h include/modules/Buildings.h
include/modules/Burrows.h include/modules/Burrows.h
include/modules/Constructions.h include/modules/Constructions.h
include/modules/Units.h include/modules/Designations.h
include/modules/Engravings.h include/modules/Engravings.h
include/modules/EventManager.h include/modules/EventManager.h
include/modules/Filesystem.h
include/modules/Graphic.h
include/modules/Gui.h include/modules/Gui.h
include/modules/GuiHooks.h include/modules/GuiHooks.h
include/modules/Items.h include/modules/Items.h
include/modules/Job.h include/modules/Job.h
include/modules/kitchen.h include/modules/kitchen.h
include/modules/Maps.h
include/modules/MapCache.h include/modules/MapCache.h
include/modules/Maps.h
include/modules/Materials.h include/modules/Materials.h
include/modules/Notes.h include/modules/Notes.h
include/modules/Once.h
include/modules/Random.h include/modules/Random.h
include/modules/Renderer.h include/modules/Renderer.h
include/modules/Screen.h include/modules/Screen.h
include/modules/Translation.h include/modules/Translation.h
include/modules/Units.h
include/modules/Vermin.h include/modules/Vermin.h
include/modules/World.h include/modules/World.h
include/modules/Graphic.h
include/modules/Once.h
include/modules/Filesystem.h
) )
SET( MODULE_SOURCES SET( MODULE_SOURCES
modules/Buildings.cpp modules/Buildings.cpp
modules/Burrows.cpp modules/Burrows.cpp
modules/Constructions.cpp modules/Constructions.cpp
modules/Units.cpp modules/Designations.cpp
modules/Engravings.cpp modules/Engravings.cpp
modules/EventManager.cpp modules/EventManager.cpp
modules/Filesystem.cpp
modules/Graphic.cpp
modules/Gui.cpp modules/Gui.cpp
modules/Items.cpp modules/Items.cpp
modules/Job.cpp modules/Job.cpp
@ -153,16 +154,15 @@ modules/MapCache.cpp
modules/Maps.cpp modules/Maps.cpp
modules/Materials.cpp modules/Materials.cpp
modules/Notes.cpp modules/Notes.cpp
modules/Once.cpp
modules/Random.cpp modules/Random.cpp
modules/Renderer.cpp modules/Renderer.cpp
modules/Screen.cpp modules/Screen.cpp
modules/Translation.cpp modules/Translation.cpp
modules/Units.cpp
modules/Vermin.cpp modules/Vermin.cpp
modules/World.cpp
modules/Graphic.cpp
modules/Windows.cpp modules/Windows.cpp
modules/Once.cpp modules/World.cpp
modules/Filesystem.cpp
) )
SET(STATIC_FIELDS_FILES) SET(STATIC_FIELDS_FILES)

@ -56,12 +56,15 @@ distribution.
#include "modules/Constructions.h" #include "modules/Constructions.h"
#include "modules/Random.h" #include "modules/Random.h"
#include "modules/Filesystem.h" #include "modules/Filesystem.h"
#include "modules/Designations.h"
#include "LuaWrapper.h" #include "LuaWrapper.h"
#include "LuaTools.h" #include "LuaTools.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/activity_entry.h"
#include "df/activity_event.h"
#include "df/job.h" #include "df/job.h"
#include "df/job_item.h" #include "df/job_item.h"
#include "df/building.h" #include "df/building.h"
@ -90,6 +93,7 @@ distribution.
#include "df/itemdef.h" #include "df/itemdef.h"
#include "df/enabler.h" #include "df/enabler.h"
#include "df/feature_init.h" #include "df/feature_init.h"
#include "df/plant.h"
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
@ -1449,6 +1453,7 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
WRAPM(Gui, getSelectedUnit), WRAPM(Gui, getSelectedUnit),
WRAPM(Gui, getSelectedItem), WRAPM(Gui, getSelectedItem),
WRAPM(Gui, getSelectedBuilding), WRAPM(Gui, getSelectedBuilding),
WRAPM(Gui, getSelectedPlant),
WRAPM(Gui, writeToGamelog), WRAPM(Gui, writeToGamelog),
WRAPM(Gui, makeAnnouncement), WRAPM(Gui, makeAnnouncement),
WRAPM(Gui, addCombatReport), WRAPM(Gui, addCombatReport),
@ -1457,6 +1462,7 @@ static const LuaWrapper::FunctionReg dfhack_gui_module[] = {
WRAPM(Gui, showZoomAnnouncement), WRAPM(Gui, showZoomAnnouncement),
WRAPM(Gui, showPopupAnnouncement), WRAPM(Gui, showPopupAnnouncement),
WRAPM(Gui, showAutoAnnouncement), WRAPM(Gui, showAutoAnnouncement),
WRAPM(Gui, revealInDwarfmodeMap),
{ NULL, NULL } { NULL, NULL }
}; };
@ -1580,6 +1586,8 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isUndead), WRAPM(Units, isUndead),
WRAPM(Units, isGelded), WRAPM(Units, isGelded),
WRAPM(Units, isDomesticated), WRAPM(Units, isDomesticated),
WRAPM(Units, getMainSocialActivity),
WRAPM(Units, getMainSocialEvent),
{ NULL, NULL } { NULL, NULL }
}; };
@ -2309,6 +2317,27 @@ static const luaL_Reg dfhack_filesystem_funcs[] = {
{NULL, NULL} {NULL, NULL}
}; };
/***** Designations module *****/
static const LuaWrapper::FunctionReg dfhack_designations_module[] = {
WRAPM(Designations, markPlant),
WRAPM(Designations, unmarkPlant),
WRAPM(Designations, canMarkPlant),
WRAPM(Designations, canUnmarkPlant),
WRAPM(Designations, isPlantMarked),
{NULL, NULL}
};
static int designations_getPlantDesignationTile(lua_State *state)
{
return Lua::PushPosXYZ(state, Designations::getPlantDesignationTile(Lua::CheckDFObject<df::plant>(state, 1)));
}
static const luaL_Reg dfhack_designations_funcs[] = {
{"getPlantDesignationTile", designations_getPlantDesignationTile},
{NULL, NULL}
};
/***** Internal module *****/ /***** Internal module *****/
static void *checkaddr(lua_State *L, int idx, bool allow_null = false) static void *checkaddr(lua_State *L, int idx, bool allow_null = false)
@ -2787,5 +2816,6 @@ void OpenDFHackApi(lua_State *state)
OpenModule(state, "constructions", dfhack_constructions_module); OpenModule(state, "constructions", dfhack_constructions_module);
OpenModule(state, "screen", dfhack_screen_module, dfhack_screen_funcs); OpenModule(state, "screen", dfhack_screen_module, dfhack_screen_funcs);
OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs); OpenModule(state, "filesystem", dfhack_filesystem_module, dfhack_filesystem_funcs);
OpenModule(state, "designations", dfhack_designations_module, dfhack_designations_funcs);
OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs); OpenModule(state, "internal", dfhack_internal_module, dfhack_internal_funcs);
} }

@ -1,10 +1,10 @@
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --long execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=8 --long
WORKING_DIRECTORY "${dfhack_SOURCE_DIR}" WORKING_DIRECTORY "${dfhack_SOURCE_DIR}"
OUTPUT_VARIABLE DFHACK_GIT_DESCRIPTION) OUTPUT_VARIABLE DFHACK_GIT_DESCRIPTION)
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
WORKING_DIRECTORY "${dfhack_SOURCE_DIR}" WORKING_DIRECTORY "${dfhack_SOURCE_DIR}"
OUTPUT_VARIABLE DFHACK_GIT_COMMIT) OUTPUT_VARIABLE DFHACK_GIT_COMMIT)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=8 --exact-match
WORKING_DIRECTORY "${dfhack_SOURCE_DIR}" WORKING_DIRECTORY "${dfhack_SOURCE_DIR}"
RESULT_VARIABLE DFHACK_GIT_TAGGED_RESULT RESULT_VARIABLE DFHACK_GIT_TAGGED_RESULT
OUTPUT_QUIET ERROR_QUIET) OUTPUT_QUIET ERROR_QUIET)

@ -0,0 +1,21 @@
#pragma once
namespace df {
struct plant;
}
namespace DFHack {
namespace Designations {
// Mark or un-mark a plant (e.g. fell trees, gather plants)
// Return value indicates whether the plant's designation was changed or not
// (This can be false if markPlant() is called on an already-designated plant, for example)
DFHACK_EXPORT bool markPlant(const df::plant *plant);
DFHACK_EXPORT bool unmarkPlant(const df::plant *plant);
DFHACK_EXPORT bool canMarkPlant(const df::plant *plant);
DFHACK_EXPORT bool canUnmarkPlant(const df::plant *plant);
DFHACK_EXPORT bool isPlantMarked(const df::plant *plant);
// Return the tile that should be designated for this plant
DFHACK_EXPORT df::coord getPlantDesignationTile(const df::plant *plant);
}
}

@ -45,6 +45,7 @@ namespace df {
struct job; struct job;
struct unit; struct unit;
struct item; struct item;
struct plant;
}; };
/** /**
@ -104,6 +105,11 @@ namespace DFHack
DFHACK_EXPORT df::building *getAnyBuilding(df::viewscreen *top); DFHACK_EXPORT df::building *getAnyBuilding(df::viewscreen *top);
DFHACK_EXPORT df::building *getSelectedBuilding(color_ostream &out, bool quiet = false); DFHACK_EXPORT df::building *getSelectedBuilding(color_ostream &out, bool quiet = false);
// A plant is selected, e.g. via 'k'
DFHACK_EXPORT bool any_plant_hotkey(df::viewscreen *top);
DFHACK_EXPORT df::plant *getAnyPlant(df::viewscreen *top);
DFHACK_EXPORT df::plant *getSelectedPlant(color_ostream &out, bool quiet = false);
// Low-level API that gives full control over announcements and reports // Low-level API that gives full control over announcements and reports
DFHACK_EXPORT void writeToGamelog(std::string message); DFHACK_EXPORT void writeToGamelog(std::string message);

@ -44,6 +44,7 @@ namespace df
struct item; struct item;
struct unit; struct unit;
struct building; struct building;
struct plant;
} }
/** /**
@ -326,10 +327,11 @@ namespace DFHack
virtual std::string getFocusString() = 0; virtual std::string getFocusString() = 0;
virtual void onShow() {}; virtual void onShow() {};
virtual void onDismiss() {}; virtual void onDismiss() {};
virtual df::unit *getSelectedUnit() { return NULL; } virtual df::unit *getSelectedUnit() { return nullptr; }
virtual df::item *getSelectedItem() { return NULL; } virtual df::item *getSelectedItem() { return nullptr; }
virtual df::job *getSelectedJob() { return NULL; } virtual df::job *getSelectedJob() { return nullptr; }
virtual df::building *getSelectedBuilding() { return NULL; } virtual df::building *getSelectedBuilding() { return nullptr; }
virtual df::plant *getSelectedPlant() { return nullptr; }
}; };
class DFHACK_EXPORT dfhack_lua_viewscreen : public dfhack_viewscreen { class DFHACK_EXPORT dfhack_lua_viewscreen : public dfhack_viewscreen {
@ -369,5 +371,6 @@ namespace DFHack
virtual df::item *getSelectedItem(); virtual df::item *getSelectedItem();
virtual df::job *getSelectedJob(); virtual df::job *getSelectedJob();
virtual df::building *getSelectedBuilding(); virtual df::building *getSelectedBuilding();
virtual df::plant *getSelectedPlant();
}; };
} }

@ -41,6 +41,8 @@ distribution.
namespace df namespace df
{ {
struct activity_entry;
struct activity_event;
struct nemesis_record; struct nemesis_record;
struct burrow; struct burrow;
struct identity; struct identity;
@ -301,6 +303,10 @@ DFHACK_EXPORT int8_t getProfessionColor(df::unit *unit, bool ignore_noble = fals
DFHACK_EXPORT int8_t getCasteProfessionColor(int race, int caste, df::profession pid); DFHACK_EXPORT int8_t getCasteProfessionColor(int race, int caste, df::profession pid);
DFHACK_EXPORT std::string getSquadName(df::unit *unit); DFHACK_EXPORT std::string getSquadName(df::unit *unit);
DFHACK_EXPORT df::activity_entry *getMainSocialActivity(df::unit *unit);
DFHACK_EXPORT df::activity_event *getMainSocialEvent(df::unit *unit);
} }
} }
#endif #endif

@ -144,14 +144,14 @@ function make_citizen(unit)
hf.caste = unit.caste hf.caste = unit.caste
hf.sex = unit.sex hf.sex = unit.sex
hf.appeared_year = dfg.cur_year hf.appeared_year = dfg.cur_year
hf.born_year = unit.relations.birth_year hf.born_year = unit.birth_year
hf.born_seconds = unit.relations.birth_time hf.born_seconds = unit.birth_time
hf.curse_year = unit.relations.curse_year hf.curse_year = unit.curse_year
hf.curse_seconds = unit.relations.curse_time hf.curse_seconds = unit.curse_time
hf.anon_1 = unit.relations.anon_2 hf.birth_year_bias=unit.bias_birth_bias
hf.anon_2 = unit.relations.anon_3 hf.birth_time_bias=unit.birth_time_bias
hf.old_year = unit.relations.old_year hf.old_year = unit.old_year
hf.old_seconds = unit.relations.old_time hf.old_seconds = unit.old_time
hf.died_year = -1 hf.died_year = -1
hf.died_seconds = -1 hf.died_seconds = -1
hf.name:assign(unit.name) hf.name:assign(unit.name)
@ -299,4 +299,4 @@ end
return _ENV return _ENV

@ -635,6 +635,8 @@ function df_shortcut_var(k)
return dfhack.gui.getSelectedWorkshopJob() return dfhack.gui.getSelectedWorkshopJob()
elseif k == 'unit' then elseif k == 'unit' then
return dfhack.gui.getSelectedUnit() return dfhack.gui.getSelectedUnit()
elseif k == 'plant' then
return dfhack.gui.getSelectedPlant()
else else
for g in pairs(df.global) do for g in pairs(df.global) do
if g == k then if g == k then

@ -0,0 +1,153 @@
#include "DataDefs.h"
#include "Error.h"
#include "modules/Designations.h"
#include "modules/Job.h"
#include "modules/Maps.h"
#include "df/job.h"
#include "df/map_block.h"
#include "df/plant.h"
#include "df/plant_tree_info.h"
#include "df/plant_tree_tile.h"
#include "df/tile_dig_designation.h"
#include "df/world.h"
using namespace DFHack;
using namespace df::enums;
using df::global::world;
static df::map_block *getPlantBlock(const df::plant *plant)
{
if (!world)
return nullptr;
return Maps::getTileBlock(Designations::getPlantDesignationTile(plant));
}
df::coord Designations::getPlantDesignationTile(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
if (!plant->tree_info)
return plant->pos;
int dimx = plant->tree_info->dim_x;
int dimy = plant->tree_info->dim_y;
int cx = dimx / 2;
int cy = dimy / 2;
// Find the southeast trunk tile
int x = cx;
int y = cy;
while (x + 1 < dimx && y + 1 < dimy)
{
if (plant->tree_info->body[0][(y * dimx) + (x + 1)].bits.trunk)
++x;
else if (plant->tree_info->body[0][((y + 1) * dimx) + x].bits.trunk)
++y;
else
break;
}
return df::coord(plant->pos.x - cx + x, plant->pos.y - cy + y, plant->pos.z);
}
bool Designations::isPlantMarked(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
df::coord des_pos = getPlantDesignationTile(plant);
df::map_block *block = Maps::getTileBlock(des_pos);
if (!block)
return false;
if (block->designation[des_pos.x % 16][des_pos.y % 16].bits.dig == tile_dig_designation::Default)
return true;
for (auto *link = world->job_list.next; link; link = link->next)
{
df::job *job = link->item;
if (!job)
continue;
if (job->job_type != job_type::FellTree && job->job_type != job_type::GatherPlants)
continue;
if (job->pos == des_pos)
return true;
}
return false;
}
bool Designations::canMarkPlant(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
if (!getPlantBlock(plant))
return false;
return !isPlantMarked(plant);
}
bool Designations::markPlant(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
if (canMarkPlant(plant))
{
df::coord des_pos = getPlantDesignationTile(plant);
df::map_block *block = Maps::getTileBlock(des_pos);
block->designation[des_pos.x % 16][des_pos.y % 16].bits.dig = tile_dig_designation::Default;
block->flags.bits.designated = true;
return true;
}
else
{
return false;
}
}
bool Designations::canUnmarkPlant(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
if (!getPlantBlock(plant))
return false;
return isPlantMarked(plant);
}
bool Designations::unmarkPlant(const df::plant *plant)
{
CHECK_NULL_POINTER(plant);
if (canUnmarkPlant(plant))
{
df::coord des_pos = getPlantDesignationTile(plant);
df::map_block *block = Maps::getTileBlock(des_pos);
block->designation[des_pos.x % 16][des_pos.y % 16].bits.dig = tile_dig_designation::No;
block->flags.bits.designated = true;
auto *link = world->job_list.next;
while (link)
{
auto *next = link->next;
df::job *job = link->item;
if (job &&
(job->job_type == job_type::FellTree || job->job_type == job_type::GatherPlants) &&
job->pos == des_pos)
{
Job::removeJob(job);
}
link = next;
}
return true;
}
else
{
return false;
}
}

@ -92,6 +92,7 @@ using namespace DFHack;
#include "df/game_mode.h" #include "df/game_mode.h"
#include "df/unit.h" #include "df/unit.h"
#include "df/occupation.h" #include "df/occupation.h"
#include "df/plant.h"
using namespace df::enums; using namespace df::enums;
using df::global::gview; using df::global::gview;
@ -1120,6 +1121,50 @@ df::building *Gui::getSelectedBuilding(color_ostream &out, bool quiet)
return building; return building;
} }
df::plant *Gui::getAnyPlant(df::viewscreen *top)
{
using df::global::cursor;
using df::global::ui;
using df::global::world;
if (auto dfscreen = dfhack_viewscreen::try_cast(top))
return dfscreen->getSelectedPlant();
if (Gui::dwarfmode_hotkey(top))
{
if (!cursor || !ui || !world)
return nullptr;
if (ui->main.mode == ui_sidebar_mode::LookAround)
{
for (df::plant *plant : world->plants.all)
{
if (plant->pos.x == cursor->x && plant->pos.y == cursor->y && plant->pos.z == cursor->z)
{
return plant;
}
}
}
}
return nullptr;
}
bool Gui::any_plant_hotkey(df::viewscreen *top)
{
return getAnyPlant(top) != nullptr;
}
df::plant *Gui::getSelectedPlant(color_ostream &out, bool quiet)
{
df::plant *plant = getAnyPlant(Core::getTopViewscreen());
if (!plant && !quiet)
out.printerr("No plant is selected in the UI.\n");
return plant;
}
// //
DFHACK_EXPORT void Gui::writeToGamelog(std::string message) DFHACK_EXPORT void Gui::writeToGamelog(std::string message)

@ -57,6 +57,7 @@ using namespace DFHack;
#include "df/job.h" #include "df/job.h"
#include "df/building.h" #include "df/building.h"
#include "df/renderer.h" #include "df/renderer.h"
#include "df/plant.h"
using namespace df::enums; using namespace df::enums;
using df::global::init; using df::global::init;
@ -934,3 +935,11 @@ df::building *dfhack_lua_viewscreen::getSelectedBuilding()
safe_call_lua(do_notify, 1, 1); safe_call_lua(do_notify, 1, 1);
return Lua::GetDFObject<df::building>(Lua::Core::State, -1); return Lua::GetDFObject<df::building>(Lua::Core::State, -1);
} }
df::plant *dfhack_lua_viewscreen::getSelectedPlant()
{
Lua::StackUnwinder frame(Lua::Core::State);
lua_pushstring(Lua::Core::State, "onGetSelectedPlant");
safe_call_lua(do_notify, 1, 1);
return Lua::GetDFObject<df::plant>(Lua::Core::State, -1);
}

@ -48,6 +48,7 @@ using namespace std;
#include "Core.h" #include "Core.h"
#include "MiscUtils.h" #include "MiscUtils.h"
#include "df/activity_entry.h"
#include "df/burrow.h" #include "df/burrow.h"
#include "df/caste_raw.h" #include "df/caste_raw.h"
#include "df/creature_raw.h" #include "df/creature_raw.h"
@ -1831,6 +1832,24 @@ std::string Units::getSquadName(df::unit *unit)
return Translation::TranslateName(&squad->name, true); return Translation::TranslateName(&squad->name, true);
} }
df::activity_entry *Units::getMainSocialActivity(df::unit *unit)
{
CHECK_NULL_POINTER(unit);
if (unit->social_activities.empty())
return nullptr;
return df::activity_entry::find(unit->social_activities[unit->social_activities.size() - 1]);
}
df::activity_event *Units::getMainSocialEvent(df::unit *unit)
{
CHECK_NULL_POINTER(unit);
df::activity_entry *entry = getMainSocialActivity(unit);
if (!entry || entry->events.empty())
return nullptr;
return entry->events[entry->events.size() - 1];
}
bool Units::isMerchant(df::unit* unit) bool Units::isMerchant(df::unit* unit)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);

@ -1 +1 @@
Subproject commit 9b834c089efb4657d43a8fa4f8f0822e8224e576 Subproject commit b48397cf5b4c954a098151943f7314a1a6eacf90

@ -10,24 +10,26 @@
#include "DataDefs.h" #include "DataDefs.h"
#include "TileTypes.h" #include "TileTypes.h"
#include "df/world.h"
#include "df/map_block.h"
#include "df/tile_dig_designation.h"
#include "df/plant_raw.h"
#include "df/plant.h"
#include "df/ui.h"
#include "df/burrow.h" #include "df/burrow.h"
#include "df/item_flags.h"
#include "df/item.h" #include "df/item.h"
#include "df/item_flags.h"
#include "df/items_other_id.h" #include "df/items_other_id.h"
#include "df/job.h"
#include "df/map_block.h"
#include "df/plant.h"
#include "df/plant_raw.h"
#include "df/tile_dig_designation.h"
#include "df/ui.h"
#include "df/viewscreen_dwarfmodest.h" #include "df/viewscreen_dwarfmodest.h"
#include "df/world.h"
#include "modules/Screen.h"
#include "modules/Maps.h"
#include "modules/Burrows.h" #include "modules/Burrows.h"
#include "modules/World.h" #include "modules/Designations.h"
#include "modules/MapCache.h"
#include "modules/Gui.h" #include "modules/Gui.h"
#include "modules/MapCache.h"
#include "modules/Maps.h"
#include "modules/Screen.h"
#include "modules/World.h"
#include <set> #include <set>
@ -228,38 +230,33 @@ static int do_chop_designation(bool chop, bool count_only)
if (!count_only && !watchedBurrows.isValidPos(plant->pos)) if (!count_only && !watchedBurrows.isValidPos(plant->pos))
continue; continue;
bool dirty = false; if (chop && !Designations::isPlantMarked(plant))
if (chop && cur->designation[x][y].bits.dig == tile_dig_designation::No)
{ {
if (count_only) if (count_only)
{ {
++count; if (Designations::canMarkPlant(plant))
count++;
} }
else else
{ {
cur->designation[x][y].bits.dig = tile_dig_designation::Default; if (Designations::markPlant(plant))
dirty = true; count++;
} }
} }
if (!chop && cur->designation[x][y].bits.dig == tile_dig_designation::Default) if (!chop && Designations::isPlantMarked(plant))
{ {
if (count_only) if (count_only)
{ {
++count; if (Designations::canUnmarkPlant(plant))
count++;
} }
else else
{ {
cur->designation[x][y].bits.dig = tile_dig_designation::No; if (Designations::unmarkPlant(plant))
dirty = true; count++;
} }
} }
if (dirty)
{
cur->flags.bits.designated = true;
++count;
}
} }
return count; return count;
@ -390,10 +387,12 @@ public:
auto last_selected_index = burrows_column.highlighted_index; auto last_selected_index = burrows_column.highlighted_index;
burrows_column.clear(); burrows_column.clear();
for (auto iter = ui->burrows.list.begin(); iter != ui->burrows.list.end(); iter++) for (df::burrow *burrow : ui->burrows.list)
{ {
df::burrow* burrow = *iter; string name = burrow->name;
auto elem = ListEntry<df::burrow *>(burrow->name, burrow); if (name.empty())
name = "Burrow " + int_to_string(burrow->id + 1);
auto elem = ListEntry<df::burrow *>(name, burrow);
elem.selected = watchedBurrows.isBurrowWatched(burrow); elem.selected = watchedBurrows.isBurrowWatched(burrow);
burrows_column.add(elem); burrows_column.add(elem);
} }
@ -590,6 +589,7 @@ public:
if (burrows_column.getSelectedElems().size() > 0) if (burrows_column.getSelectedElems().size() > 0)
{ {
OutputString(COLOR_GREEN, x, y, "Will chop in selected burrows", true, left_margin); OutputString(COLOR_GREEN, x, y, "Will chop in selected burrows", true, left_margin);
++y;
} }
else else
{ {

@ -1,5 +1,7 @@
// (un)designate matching plants for gathering/cutting // (un)designate matching plants for gathering/cutting
#include <set>
#include "Core.h" #include "Core.h"
#include "Console.h" #include "Console.h"
#include "Export.h" #include "Export.h"
@ -7,18 +9,19 @@
#include "DataDefs.h" #include "DataDefs.h"
#include "TileTypes.h" #include "TileTypes.h"
#include "df/world.h"
#include "df/map_block.h" #include "df/map_block.h"
#include "df/tile_dig_designation.h"
#include "df/plant_raw.h"
#include "df/plant.h" #include "df/plant.h"
#include "df/plant_raw.h"
#include "df/tile_dig_designation.h"
#include "df/world.h"
#include "modules/Designations.h"
#include "modules/Maps.h" #include "modules/Maps.h"
#include <set>
using std::string; using std::string;
using std::vector; using std::vector;
using std::set; using std::set;
using namespace DFHack; using namespace DFHack;
using namespace df::enums; using namespace df::enums;
@ -129,20 +132,14 @@ command_result df_getplants (color_ostream &out, vector <string> & parameters)
continue; continue;
if (cur->designation[x][y].bits.hidden) if (cur->designation[x][y].bits.hidden)
continue; continue;
if (deselect && cur->designation[x][y].bits.dig == tile_dig_designation::Default) if (deselect && Designations::unmarkPlant(plant))
{ {
cur->designation[x][y].bits.dig = tile_dig_designation::No;
dirty = true;
++count; ++count;
} }
if (!deselect && cur->designation[x][y].bits.dig == tile_dig_designation::No) if (!deselect && Designations::markPlant(plant))
{ {
cur->designation[x][y].bits.dig = tile_dig_designation::Default;
dirty = true;
++count; ++count;
} }
if (dirty)
cur->flags.bits.designated = true;
} }
if (count) if (count)
out.print("Updated %d plant designations.\n", count); out.print("Updated %d plant designations.\n", count);
@ -171,4 +168,4 @@ DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCom
DFhackCExport command_result plugin_shutdown ( color_ostream &out ) DFhackCExport command_result plugin_shutdown ( color_ostream &out )
{ {
return CR_OK; return CR_OK;
} }

@ -15,8 +15,9 @@
#include <set> #include <set>
#include <algorithm> #include <algorithm>
#include <tuple> #include <tuple>
#include <VTableInterpose.h> #include <VTableInterpose.h>
#include "df/activity_event.h"
#include "df/world.h" #include "df/world.h"
#include "df/ui.h" #include "df/ui.h"
#include "df/graphic.h" #include "df/graphic.h"
@ -289,7 +290,8 @@ struct UnitInfo
int active_index; int active_index;
string squad_effective_name; string squad_effective_name;
string squad_info; string squad_info;
string job_info; string job_desc;
enum { IDLE, SOCIAL, JOB } job_mode;
bool selected; bool selected;
struct { struct {
// Used for custom professions, 1-indexed // Used for custom professions, 1-indexed
@ -363,16 +365,18 @@ bool sortBySquad (const UnitInfo *d1, const UnitInfo *d2)
bool sortByJob (const UnitInfo *d1, const UnitInfo *d2) bool sortByJob (const UnitInfo *d1, const UnitInfo *d2)
{ {
bool gt = false; if (d1->job_mode != d2->job_mode)
{
if (descending)
return int(d1->job_mode) < int(d2->job_mode);
else
return int(d1->job_mode) > int(d2->job_mode);
}
if (d1->job_info == "Idle") if (descending)
gt = false; return d1->job_desc > d2->job_desc;
else if (d2->job_info == "Idle")
gt = true;
else else
gt = (d1->job_info > d2->job_info); return d1->job_desc < d2->job_desc;
return descending ? gt : !gt;
} }
bool sortByStress (const UnitInfo *d1, const UnitInfo *d2) bool sortByStress (const UnitInfo *d1, const UnitInfo *d2)
@ -1234,9 +1238,18 @@ void viewscreen_unitlaborsst::refreshNames()
cur->profession = Units::getProfessionName(unit); cur->profession = Units::getProfessionName(unit);
if (unit->job.current_job == NULL) { if (unit->job.current_job == NULL) {
cur->job_info = "Idle"; df::activity_event *event = Units::getMainSocialEvent(unit);
if (event) {
event->getName(unit->id, &cur->job_desc);
cur->job_mode = UnitInfo::SOCIAL;
}
else {
cur->job_desc = "Idle";
cur->job_mode = UnitInfo::IDLE;
}
} else { } else {
cur->job_info = DFHack::Job::getName(unit->job.current_job); cur->job_desc = DFHack::Job::getName(unit->job.current_job);
cur->job_mode = UnitInfo::JOB;
} }
if (unit->military.squad_id > -1) { if (unit->military.squad_id > -1) {
cur->squad_effective_name = Units::getSquadName(unit); cur->squad_effective_name = Units::getSquadName(unit);
@ -1283,7 +1296,7 @@ void viewscreen_unitlaborsst::calcSize()
if (detail_mode == DETAIL_MODE_SQUAD) { if (detail_mode == DETAIL_MODE_SQUAD) {
detail_cmp = units[i]->squad_info.size(); detail_cmp = units[i]->squad_info.size();
} else if (detail_mode == DETAIL_MODE_JOB) { } else if (detail_mode == DETAIL_MODE_JOB) {
detail_cmp = units[i]->job_info.size(); detail_cmp = units[i]->job_desc.size();
} else { } else {
detail_cmp = units[i]->profession.size(); detail_cmp = units[i]->profession.size();
} }
@ -1954,11 +1967,13 @@ void viewscreen_unitlaborsst::render()
fg = 11; fg = 11;
detail_str = cur->squad_info; detail_str = cur->squad_info;
} else if (detail_mode == DETAIL_MODE_JOB) { } else if (detail_mode == DETAIL_MODE_JOB) {
detail_str = cur->job_info; detail_str = cur->job_desc;
if (detail_str == "Idle") { if (cur->job_mode == UnitInfo::IDLE) {
fg = 14; fg = COLOR_YELLOW;
} else if (cur->job_mode == UnitInfo::SOCIAL) {
fg = COLOR_LIGHTGREEN;
} else { } else {
fg = 10; fg = COLOR_LIGHTCYAN;
} }
} else { } else {
fg = cur->color; fg = cur->color;

@ -1 +1 @@
Subproject commit 1925760b2f611d246d1715a2e3cfb591a02ef00b Subproject commit 1ffdc984d0c3d50e790b9ff5991c02fb21dec463

@ -90,6 +90,7 @@
#include "tweaks/fast-trade.h" #include "tweaks/fast-trade.h"
#include "tweaks/fps-min.h" #include "tweaks/fps-min.h"
#include "tweaks/hide-priority.h" #include "tweaks/hide-priority.h"
#include "tweaks/hotkey-clear.h"
#include "tweaks/import-priority-category.h" #include "tweaks/import-priority-category.h"
#include "tweaks/kitchen-keys.h" #include "tweaks/kitchen-keys.h"
#include "tweaks/kitchen-prefs-color.h" #include "tweaks/kitchen-prefs-color.h"
@ -205,6 +206,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" Fixes the in-game minimum FPS setting (bug 6277)\n" " Fixes the in-game minimum FPS setting (bug 6277)\n"
" tweak hide-priority [disable]\n" " tweak hide-priority [disable]\n"
" Adds an option to hide designation priority indicators\n" " Adds an option to hide designation priority indicators\n"
" tweak hotkey-clear [disable] \n"
" Adds an option to clear currently-bound hotkeys\n"
" tweak import-priority-category [disable]\n" " tweak import-priority-category [disable]\n"
" When meeting with a liaison, makes Shift+Left/Right arrow adjust\n" " When meeting with a liaison, makes Shift+Left/Right arrow adjust\n"
" the priority of an entire category of imports.\n" " the priority of an entire category of imports.\n"
@ -272,6 +275,9 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
TWEAK_HOOK("hide-priority", hide_priority_hook, feed); TWEAK_HOOK("hide-priority", hide_priority_hook, feed);
TWEAK_HOOK("hide-priority", hide_priority_hook, render); TWEAK_HOOK("hide-priority", hide_priority_hook, render);
TWEAK_HOOK("hotkey-clear", hotkey_clear_hook, feed);
TWEAK_HOOK("hotkey-clear", hotkey_clear_hook, render);
TWEAK_HOOK("import-priority-category", takerequest_hook, feed); TWEAK_HOOK("import-priority-category", takerequest_hook, feed);
TWEAK_HOOK("import-priority-category", takerequest_hook, render); TWEAK_HOOK("import-priority-category", takerequest_hook, render);

@ -0,0 +1,41 @@
#include "df/viewscreen_dwarfmodest.h"
using df::global::ui;
struct hotkey_clear_hook : df::viewscreen_dwarfmodest {
typedef df::viewscreen_dwarfmodest interpose_base;
DEFINE_VMETHOD_INTERPOSE(void, render, ())
{
INTERPOSE_NEXT(render)();
if (ui->main.mode == df::ui_sidebar_mode::Hotkeys)
{
int x = 26, y = 19;
OutputHotkeyString(x, y, "Clear", df::interface_key::CUSTOM_C, false, 0, COLOR_WHITE, COLOR_LIGHTRED);
}
}
DEFINE_VMETHOD_INTERPOSE(void, feed, (set<df::interface_key> *input))
{
if (ui->main.mode == df::ui_sidebar_mode::Hotkeys &&
input->count(df::interface_key::CUSTOM_C) &&
!ui->main.in_rename_hotkey)
{
auto &hotkey = ui->main.hotkeys[ui->main.selected_hotkey];
hotkey.name = "";
hotkey.cmd = df::ui_hotkey::T_cmd::None;
hotkey.x = 0;
hotkey.y = 0;
hotkey.z = 0;
hotkey.unit_id = 0;
hotkey.item_id = 0;
}
else
{
INTERPOSE_NEXT(feed)(input);
}
}
};
IMPLEMENT_VMETHOD_INTERPOSE(hotkey_clear_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(hotkey_clear_hook, render);

@ -1 +1 @@
Subproject commit cf367974b5e1513d454b2988d45122e98cd28f52 Subproject commit e9c3119e751c3e2073eb02bbcda01d140cc6ae4a