Merge branch 'develop' of https://github.com/DFHack/dfhack into Units

develop
PatrikLundell 2020-06-26 09:53:41 +02:00
commit 5570a5743b
16 changed files with 248 additions and 185 deletions

@ -15,6 +15,7 @@ serve to show the default.
# pylint:disable=redefined-builtin
import datetime
from io import open
import os
import re
@ -222,7 +223,7 @@ master_doc = 'index'
# General information about the project.
project = 'DFHack'
copyright = '2015, The DFHack Team'
copyright = '2015-%d, The DFHack Team' % datetime.datetime.now().year
author = 'The DFHack Team'
# The version info for the project you're documenting, acts as replacement for

@ -656,129 +656,8 @@ Then build the ``INSTALL`` target listed under ``CMakePredefinedTargets``.
Building the documentation
==========================
DFHack documentation, like the file you are reading now, is created as .rst files,
which are in `reStructuredText (reST) <http://sphinx-doc.org/rest.html>`_ format.
This is a documenation format that has come from the Python community. It is very
similar in concept - and in syntax - to Markdown, as found on GitHub and many other
places. However it is more advanced than Markdown, with more features available when
compiled to HTML, such as automatic tables of contents, cross-linking, special
external links (forum, wiki, etc) and more. The documentation is compiled by a
Python tool, `Sphinx <http://sphinx-doc.org>`_.
The DFHack build process will compile the documentation but this has been disabled
by default. You only need to build the docs if you're changing them, or perhaps
if you want a local HTML copy; otherwise, read them easily online at
`ReadTheDoc's DFHack hosted documentation <https://dfhack.readthedocs.org>`_.
(Note that even if you do want a local copy, it is certainly not necesesary to
compile the documentation in order to read it. Like Markdown, reST documents are
designed to be just as readable in a plain-text editor as they are in HTML format.
The main thing you lose in plain text format is hyperlinking.)
Enabling documentation building
-------------------------------
First, make sure you have followed all the necessary steps for your platform as
outlined in the rest of this document.
To compile documentation with DFHack, add the following flag to your ``cmake`` command::
-DBUILD_DOCS:bool=ON
For example::
cmake .. -DCMAKE_BUILD_TYPE:string=Release -DBUILD_DOCS:bool=ON -DCMAKE_INSTALL_PREFIX=<path to DF>
Alternatively you can use the CMake GUI which allows options to be changed easily.
On Windows you should either use ``generate-msvc-gui.bat`` and set the option
through the GUI, or else if you want to use an alternate file, such as
``generate-msvc-all.bat``, you will need to edit it to add the flag.
Or you could just run ``cmake`` on the command line like in other platforms.
Required dependencies
---------------------
In order to build the documentation, you must have Python with Sphinx
version 1.3.1 or later. Both Python 2.x and 3.x are supported.
When installing Sphinx from OS package managers, be aware that there is
another program called Sphinx, completely unrelated to documentation management.
Be sure you are installing the right Sphinx; it may be called ``python-sphinx``,
for example. To avoid doubt, ``pip`` can be used instead as detailed below.
Linux
-----
Most Linux distributions will include Python as standard.
Check your package manager to see if Sphinx 1.3.1 or later is available,
but at the time of writing Ubuntu for example only has 1.2.x.
You can instead install Sphinx with the pip package manager. This may need
to be installed from your OS package manager; this is the case on Ubuntu.
On Ubuntu/Debian, use the following to first install pip::
sudo apt-get install python-pip
Once pip is available, you can then install the Python Sphinx module with::
pip install sphinx
If you run this as a normal user it will install a local copy for your user only.
Run it with sudo if you want a system-wide install. Either is fine for DFHack,
however if installing locally do check that ``sphinx-build`` is in your path.
It may be installed in a directory such as ``~/.local/bin/``, so after pip
install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``.
macOS
-----
macOS has Python 2.7 installed by default, but it does not have the pip package manager.
You can install Homebrew's Python 3, which includes pip, and then install the
latest Sphinx using pip::
brew install python3
pip3 install sphinx
Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew::
brew install sphinx-doc
This will install Sphinx for macOS's system Python 2.7, without needing pip.
Either method works; if you plan to use Python for other purposes, it might best
to install Homebrew's Python 3 so that you have the latest Python as well as pip.
If not, just installing sphinx-doc for macOS's system Python 2.7 is fine.
Windows
-------
Use the Chocolatey package manager to install Python and pip,
then use pip to install Sphinx.
Run the following commands from an elevated (Admin) ``cmd.exe``, after installing
Chocolatey as outlined in the `Windows section <compile-windows>`::
choco install python pip -y
Then close that Admin ``cmd.exe``, re-open another Admin ``cmd.exe``, and run::
pip install sphinx
.. _build-changelog:
Building the changelogs
-----------------------
If you have Python installed, but do not want to build all of the documentation,
you can build the changelogs with the ``docs/gen_changelog.py`` script.
All changes should be listed in ``changelog.txt``. A description of this file's
format follows:
.. include:: /docs/changelog.txt
:start-after: ===help
:end-before: ===end
The steps above will not build DFHack's documentation by default. If you are
editing documentation, see `documentation` for details on how to build it.
Misc. Notes
===========

@ -0,0 +1,191 @@
.. _documentation:
####################
DFHack Documentation
####################
DFHack documentation, like the file you are reading now, is created as ``.rst`` files,
which are in `reStructuredText (reST) <http://sphinx-doc.org/rest.html>`_ format.
This is a documentation format common in the Python community. It is very
similar in concept - and in syntax - to Markdown, as found on GitHub and many other
places. However it is more advanced than Markdown, with more features available when
compiled to HTML, such as automatic tables of contents, cross-linking, special
external links (forum, wiki, etc) and more. The documentation is compiled by a
Python tool, `Sphinx <http://sphinx-doc.org>`_.
The DFHack build process will compile the documentation, but this is disabled
by default due to the additional Python and Sphinx requirements. You typically
only need to build the docs if you're changing them, or perhaps
if you want a local HTML copy; otherwise, you can read an
`online version hosted by ReadTheDocs <https://dfhack.readthedocs.org>`_.
(Note that even if you do want a local copy, it is certainly not necessary to
compile the documentation in order to read it. Like Markdown, reST documents are
designed to be just as readable in a plain-text editor as they are in HTML format.
The main thing you lose in plain text format is hyperlinking.)
.. contents::
Required dependencies
=====================
In order to build the documentation, you must have Python with Sphinx
version 1.3.1 or later. Both Python 2.x and 3.x are supported.
When installing Sphinx from OS package managers, be aware that there is
another program called Sphinx, completely unrelated to documentation management.
Be sure you are installing the right Sphinx; it may be called ``python-sphinx``,
for example. To avoid doubt, ``pip`` can be used instead as detailed below.
For more detailed platform-specific instructions, see the sections below:
Linux
-----
Most Linux distributions will include Python as standard.
Check your package manager to see if Sphinx 1.3.1 or later is available,
but at the time of writing Ubuntu for example only has 1.2.x.
You can instead install Sphinx with the pip package manager. This may need
to be installed from your OS package manager; this is the case on Ubuntu.
On Ubuntu/Debian, use the following to first install pip::
sudo apt-get install python-pip
Once pip is available, you can then install the Python Sphinx module with::
pip install sphinx
If you run this as a normal user it will install a local copy for your user only.
Run it with sudo if you want a system-wide install. Either is fine for DFHack,
however if installing locally do check that ``sphinx-build`` is in your path.
It may be installed in a directory such as ``~/.local/bin/``, so after pip
install, find ``sphinx-build`` and ensure its directory is in your local ``$PATH``.
macOS
-----
macOS has Python 2.7 installed by default, but it does not have the pip package manager.
You can install Homebrew's Python 3, which includes pip, and then install the
latest Sphinx using pip::
brew install python3
pip3 install sphinx
Alternatively, you can simply install Sphinx 1.3.x directly from Homebrew::
brew install sphinx-doc
This will install Sphinx for macOS's system Python 2.7, without needing pip.
Either method works; if you plan to use Python for other purposes, it might best
to install Homebrew's Python 3 so that you have the latest Python as well as pip.
If not, just installing sphinx-doc for macOS's system Python 2.7 is fine.
Windows
-------
Python for Windows can be downloaded `from python.org <https://www.python.org/downloads/>`_.
The latest version of Python 3 is recommended, as it includes pip already.
You can also install Python and pip through the Chocolatey package manager.
After installing Chocolatey as outlined in the `Windows compilation instructions <compile-windows>`,
run the following command from an elevated (admin) command prompt (e.g. ``cmd.exe``)::
choco install python pip -y
Once you have pip available, you can install Sphinx with the following command::
pip install sphinx
Note that this may require opening a new (admin) command prompt if you just
installed pip from the same command prompt.
Building the documentation
==========================
Once you have installed Sphinx, ``sphinx-build --version`` should report the
version of Sphinx that you have installed. If this works, CMake should also be
able to find Sphinx.
Using CMake
-----------
Enabling the ``BUILD_DOCS`` CMake option will cause the documentation to be built
whenever it changes as part of the normal DFHack build process. There are several
ways to do this:
* When initially running CMake, add ``-DBUILD_DOCS:bool=ON`` to your ``cmake``
command. For example::
cmake .. -DCMAKE_BUILD_TYPE:string=Release -DBUILD_DOCS:bool=ON -DCMAKE_INSTALL_PREFIX=<path to DF>
* If you have already run CMake, you can simply run it again from your build
folder to update your configuration::
cmake .. -DBUILD_DOCS:bool=ON
* You can edit the ``BUILD_DOCS`` setting in CMakeCache.txt directly
* You can use the CMake GUI to change ``BUILD_DOCS``
* On Windows, if you prefer to use the batch scripts, you can run
``generate-msvc-gui.bat`` and set ``BUILD_DOCS`` through the GUI. If you are
running another file, such as ``generate-msvc-all.bat``, you will need to edit
it to add the flag. You can also run ``cmake`` on the command line, similar to
other platforms.
Running Sphinx manually
-----------------------
You can also build the documentation without going through CMake, which may be
faster. There is a ``docs/build.sh`` script available for Linux and macOS that
will run essentially the same command that CMake runs - see the script for
options.
To build the documentation with default options, run the following command from
the root DFHack folder::
sphinx-build . docs/html
Sphinx has many options to enable clean builds, parallel builds, logging, and
more - run ``sphinx-build --help`` for details.
.. _build-changelog:
Building the changelogs
=======================
If you have Python installed, but do not want to build all of the documentation,
you can build the changelogs with the ``docs/gen_changelog.py`` script. This
script provides additional options, including one to build individual changelogs
for all DFHack versions - run ``python docs/gen_changelog.py --help`` for details.
Changelog entries are obtained from ``changelog.txt`` files in multiple repos.
This allows changes to be listed in the same repo where they were made. These
changelogs are combined as part of the changelog build process:
* ``docs/changelog.txt`` for changes in the main ``dfhack`` repo
* ``scripts/changelog.txt`` for changes made to scripts in the ``scripts`` repo
* ``library/xml/changelog.txt`` for changes made in the ``df-structures`` repo
Building the changelogs generates two files: ``docs/_auto/news.rst`` and
``docs/_auto/news-dev.rst``. These correspond to `changelog` and `dev-changelog`
and contain changes organized by stable and development DFHack releases,
respectively. For example, an entry listed under "0.44.05-alpha1" in
changelog.txt will be listed under that version in the development changelog as
well, but under "0.44.05-r1" in the stable changelog (assuming that is the
closest stable release after 0.44.05-alpha1). An entry listed under a stable
release like "0.44.05-r1" in changelog.txt will be listed under that release in
both the stable changelog and the development changelog.
Changelog syntax
----------------
.. include:: /docs/changelog.txt
:start-after: ===help
:end-before: ===end

@ -17,4 +17,4 @@ if [ -z "$JOBS" ]; then
JOBS=2
fi
"$sphinx" -a -E -q -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@"
"$sphinx" -a -E -b html . ./docs/html -w ./docs/_sphinx-warnings.txt -j "$JOBS" "$@"

@ -1,16 +1,10 @@
=== Scroll down for changes
===[[[
===help
The text below is included in docs/Documentation.rst - see that file for more details on the changelog setup.
This is kept in this file as a quick syntax reference.
Entries in docs/NEWS.rst and docs/NEWS-dev.rst are generated from
docs/changelog.txt. NEWS.rst groups entries by stable releases, and NEWS-dev.rst
groups them by all releases (stable and development). For example, an entry
listed under "0.44.05-alpha1" in changelog.txt will be listed under that in
NEWS-dev.rst as well, but under "0.44.05-r1" in NEWS.rst (assuming that is the
closest stable release after 0.44.05-alpha1). An entry listed under a stable
release in changelog.txt will be listed under that release in both NEWS.rst and
NEWS-dev.rst.
===help
changelog.txt uses a syntax similar to RST, with a few special sequences:
@ -42,6 +36,10 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
## Fixes
- Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting
- `labormanager`: fixed handling of new jobs in 0.47
- Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste
## Misc Improvements
- `confirm`: added a confirmation dialog for convicting dwarves of crimes
## Ruby
- Updated ``item_find`` and ``building_find`` to use centralized logic that works on more screens

@ -62,6 +62,7 @@ For Developers
/docs/Compile
/docs/NEWS-dev
/docs/Lua API
/docs/Documentation
/library/xml/SYNTAX
/library/xml/how-to-update
/docs/Binpatches

@ -1477,9 +1477,9 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t
df::enums::game_type::game_type type = *df::global::gametype;
prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE,
df::historical_entity::find(unit->civ_id), 0,
0, df::historical_entity::find(unit->civ_id),
((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL,
0);
NULL);
if ( out_items.size() != 1 )
return -1;

@ -637,74 +637,50 @@ bool Units::isEggLayer(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if ((*caste)->flags.is_set(caste_raw_flags::LAYS_EGGS)
|| (*caste)->flags.is_set(caste_raw_flags::LAYS_UNUSUAL_EGGS))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::LAYS_EGGS)
|| caste->flags.is_set(caste_raw_flags::LAYS_UNUSUAL_EGGS);
}
bool Units::isGrazer(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if((*caste)->flags.is_set(caste_raw_flags::GRAZER))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::GRAZER);
}
bool Units::isMilkable(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if((*caste)->flags.is_set(caste_raw_flags::MILKABLE))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::MILKABLE);
}
bool Units::isTrainableWar(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if((*caste)->flags.is_set(caste_raw_flags::TRAINABLE_WAR))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::TRAINABLE_WAR);
}
bool Units::isTrainableHunting(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if((*caste)->flags.is_set(caste_raw_flags::TRAINABLE_HUNTING))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::TRAINABLE_HUNTING);
}
bool Units::isTamable(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
df::creature_raw *raw = world->raws.creatures.all[unit->race];
for (auto caste = raw->caste.begin(); caste != raw->caste.end(); ++caste)
{
if((*caste)->flags.is_set(caste_raw_flags::PET) ||
(*caste)->flags.is_set(caste_raw_flags::PET_EXOTIC))
return true;
}
return false;
df::caste_raw *caste = raw->caste.at(unit->caste);
return caste->flags.is_set(caste_raw_flags::PET)
|| caste->flags.is_set(caste_raw_flags::PET_EXOTIC);
}
bool Units::isMale(df::unit* unit)

@ -1 +1 @@
Subproject commit cbeed8b52482ce749fc2ff13a9db9733931e7da0
Subproject commit 2ed5fae13f721b73b71bc31a062fb66abd1f3920

@ -249,7 +249,7 @@ struct product_hook : improvement_product {
std::vector<df::reaction_reagent*> *in_reag,
std::vector<df::item*> *in_items,
int32_t quantity, df::job_skill skill,
df::historical_entity *entity, int32_t unk, df::world_site *site, void* unk2)
int32_t quality, df::historical_entity *entity, df::world_site *site, std::vector<void *> *unk2)
) {
if (auto product = products[this])
{
@ -295,7 +295,7 @@ struct product_hook : improvement_product {
return;
}
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2);
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2);
}
};

@ -18,6 +18,7 @@
#include "df/general_ref.h"
#include "df/general_ref_contained_in_itemst.h"
#include "df/viewscreen_dwarfmodest.h"
#include "df/viewscreen_justicest.h"
#include "df/viewscreen_layer_militaryst.h"
#include "df/viewscreen_locationsst.h"
#include "df/viewscreen_tradegoodsst.h"
@ -479,6 +480,7 @@ DEFINE_CONFIRMATION(uniform_delete, viewscreen_layer_militaryst);
DEFINE_CONFIRMATION(note_delete, viewscreen_dwarfmodest);
DEFINE_CONFIRMATION(route_delete, viewscreen_dwarfmodest);
DEFINE_CONFIRMATION(location_retire, viewscreen_locationsst);
DEFINE_CONFIRMATION(convict, viewscreen_justicest);
DFhackCExport command_result plugin_init (color_ostream &out, vector <PluginCommand> &commands)
{

@ -86,8 +86,8 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it
building = df::building::find(dest_building);
prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE,
df::historical_entity::find(unit->civ_id), 0,
(World::isFortressMode()) ? df::world_site::find(ui->site_id) : NULL, 0);
0, df::historical_entity::find(unit->civ_id),
(World::isFortressMode()) ? df::world_site::find(ui->site_id) : NULL, NULL);
if (!out_items.size())
return false;
// if we asked to make shoes and we got twice as many as we asked, then we're okay

@ -256,8 +256,8 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map<df:
vector<df::reaction_reagent*> in_reag;
vector<df::item*> in_items;
prod->produce(firstInvader, &out_products, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE,
df::historical_entity::find(firstInvader->civ_id), 0,
df::world_site::find(df::global::ui->site_id), 0);
0, df::historical_entity::find(firstInvader->civ_id),
df::world_site::find(df::global::ui->site_id), NULL);
if ( out_items.size() != 1 ) {
out.print("%s, %d: wrong size: %zu.\n", __FILE__, __LINE__, out_items.size());

@ -287,12 +287,12 @@ struct product_hook : item_product {
std::vector<df::reaction_reagent*> *in_reag,
std::vector<df::item*> *in_items,
int32_t quantity, df::job_skill skill,
df::historical_entity *entity, int32_t unk, df::world_site *site, void* unk2)
int32_t quality, df::historical_entity *entity, df::world_site *site, std::vector<void *> *unk2)
) {
color_ostream_proxy out(Core::getInstance().getConsole());
auto product = products[this];
if ( !product ) {
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2);
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2);
return;
}
df::reaction* this_reaction=product->react;
@ -304,7 +304,7 @@ struct product_hook : item_product {
size_t out_item_count = out_items->size();
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, entity, unk, site, unk2);
INTERPOSE_NEXT(produce)(unit, out_products, out_items, in_reag, in_items, quantity, skill, quality, entity, site, unk2);
if ( out_items->size() == out_item_count )
return;
//if it produced something, call the scripts

@ -204,6 +204,21 @@ end
location_retire.title = "Retire location"
location_retire.message = "Are you sure you want to retire this location?"
convict = defconf('convict')
convict.title = "Confirm conviction"
function convict.intercept_key(key)
return key == keys.SELECT and
screen.cur_column == df.viewscreen_justicest.T_cur_column.ConvictChoices
end
function convict.get_message()
name = dfhack.TranslateName(screen.convict_choices[screen.cursor_right].name)
if name == "" then
name = "this creature"
end
return "Are you sure you want to convict " .. name .. "?\n" ..
"This action is irreversible."
end
-- End of confirmation definitions
function check()

@ -1 +1 @@
Subproject commit 2079b9fb69b8b4db48aa35ec54a96f5cca7cc8ef
Subproject commit 47d9b3c9390d21ecc49ddaba477b16071884ee87