Merge remote-tracking branch 'upstream/develop' into quickfort_userguide

develop
Myk Taylor 2020-08-06 23:34:59 -07:00
commit 7f3e936316
11 changed files with 214 additions and 20 deletions

@ -110,6 +110,7 @@ Nikolay Amiantov abbradar
nocico nocico
Omniclasm
OwnageIsMagic OwnageIsMagic
palenerd dlmarquis
Patrik Lundell PatrikLundell
Paul Fenwick pjf
PeridexisErrant PeridexisErrant

@ -13,7 +13,7 @@ Contributing Code
=================
Several things should be kept in mind when contributing code to DFHack.
Code Format
Code format
-----------
* Four space indents for C++. Never use tabs for indentation in any language.
* LF (Unix style) line terminators
@ -26,18 +26,45 @@ Code Format
* #includes should be sorted. C++ libraries first, then dfhack modules, then df structures,
then local includes. Within each category they should be sorted alphabetically.
How to get new code into DFHack
Pull request guidelines
-----------------------
* Pull requests should be based on (and submitted to) the default branch of the
relevant repo, which is the branch you see when you access the repo on GitHub
or clone the repo without specifying a branch. As of 0.47.04-r1, this is
``develop`` for the main DFHack repo and ``master`` for other repos.
* Use a new branch for each feature or bugfix so that your changes can be merged
independently (i.e. not the ``master`` or ``develop`` branch of your fork).
* An exception: for a collection of small miscellaneous changes (e.g.
structures research), one branch instead of many small branches is fine. It
is still preferred that this branch be dedicated to this purpose, i.e. not
``master`` or ``develop``. Your pull request may be merged at any point
unless you indicate that it isn't ready (see below), but you can continue to
push to the same branch and open new pull requests as needed.
* Try to keep pull requests relatively small so that they are easier to review
and merge.
* If you expect to make a large number of related additions or changes (e.g.
adding a large new plugin), multiple PRs are preferred, as they allow more
frequent (and easier) feedback. If development of this feature is expected
to take a while, we may create a dedicated branch to merge your pull
requests into instead of the repo's default branch.
* If you plan to make additional changes to your pull request in the near
future, or if it isn't quite ready to be merged, mark it as a
`draft pull request <https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests>`_
or add "WIP" to the title. Otherwise, your pull request may be reviewed and/or
merged prematurely.
General contribution guidelines
-------------------------------
* Submit pull requests to the ``develop`` branch, not the ``master`` branch.
(The ``master`` branch always points at the most recent release)
* Use a new branch for each feature or bugfix so that your changes can be merged independently
(i.e. not the master or develop branch of your fork).
* If possible, compile on multiple platforms when changing anything that compiles
* It must pass CI - run ``python travis/all.py`` to check this.
* If convenient, compile on multiple platforms when changing anything that
compiles. Our CI should catch anything that fails to build, but checking in
advance can be faster.
* Update documentation when applicable - see `docs-standards` for details.
* Update ``changelog.txt`` and ``docs/Authors.rst`` when applicable. See
`build-changelog` for more information on the changelog format.
* Create a GitHub pull request once finished
* Submit ideas and bug reports as :issue:`issues on GitHub <>`.
Posts in the forum thread can easily get missed or forgotten.
* Work on :issue:`reported problems <?q=is:open+-label:idea>`

@ -291,6 +291,8 @@ One-shot subcommands:
Subcommands that persist until disabled or DF quits:
.. comment: sort these alphabetically
:adamantine-cloth-wear: Prevents adamantine clothing from wearing out while being worn (:bug:`6481`).
:advmode-contained: Works around :bug:`6202`, custom reactions with container inputs
in advmode. The issue is that the screen tries to force you to select
@ -305,6 +307,7 @@ Subcommands that persist until disabled or DF quits:
:craft-age-wear: Fixes the behavior of crafted items wearing out over time (:bug:`6003`).
With this tweak, items made from cloth and leather will gain a level of
wear every 20 years.
:do-job-now: Adds a job priority toggle to the jobs list
:embark-profile-name: Allows the use of lowercase letters when saving embark profiles
:eggs-fertile: Displays a fertility indicator on nestboxes
:farm-plot-select: Adds "Select all" and "Deselect all" options to farm plot menus
@ -335,12 +338,14 @@ Subcommands that persist until disabled or DF quits:
i.e. stop the rightmost list of the Positions page of the military
screen from constantly resetting to the top.
:nestbox-color: Fixes the color of built nestboxes
:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`)
:shift-8-scroll: Gives Shift-8 (or :kbd:`*`) priority when scrolling menus, instead of scrolling the map
:stable-cursor: Saves the exact cursor position between t/q/k/d/b/etc menus of fortress mode.
:stone-status-all: Adds an option to toggle the economic status of all stones
:title-start-rename: Adds a safe rename option to the title screen "Start Playing" menu
:tradereq-pet-gender: Displays pet genders on the trade request screen
:reaction-gloves: Fixes reactions to produce gloves in sets with correct handedness (:bug:`6273`)
.. comment: sort these alphabetically
.. _fix-armory:

@ -34,12 +34,14 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
# Future
## New Tweaks
- `tweak` do-job-now: adds a job priority toggle to the jobs list
- `tweak` reaction-gloves: adds an option to make reactions produce gloves in sets with correct handedness
## Fixes
- Fixed a segfault when attempting to start a headless session with a graphical PRINT_MODE setting
- Fixed an issue with the macOS launcher failing to un-quarantine some files
- Linux: fixed ``dfhack.getDFPath()`` (Lua) and ``Process::getPath()`` (C++) to always return the DF root path, even if the working directory has changed
- `getplants`: fixed issues causing plants to be collected even if they have no growths (or unripe growths)
- `labormanager`: fixed handling of new jobs in 0.47
- `embark-assistant`: fixed a couple of incursion handling bugs.
- Fixed ``Units::isEggLayer``, ``Units::isGrazer``, ``Units::isMilkable``, ``Units::isTrainableHunting``, ``Units::isTrainableWar``, and ``Units::isTamable`` ignoring the unit's caste

@ -316,8 +316,8 @@ bool Plugin::load(color_ostream &con)
{
std::string msg = stl_sprintf("Warning: Plugin %s compiled for DFHack %s, running DFHack %s\n",
*plug_name, plug_git_desc, dfhack_git_desc);
con << msg;
cerr << msg;
con << msg << flush;
cerr << msg << flush;
}
}
else

@ -204,14 +204,15 @@ void Units::setNickname(df::unit *unit, std::string nick)
df::historical_figure *id_hfig = NULL;
switch (identity->type) {
case df::identity_type::None:
case df::identity_type::HidingCurse:
case df::identity_type::Identity:
case df::identity_type::FalseIdentity:
case df::identity_type::InfiltrationIdentity:
case df::identity_type::Identity:
break; // We want the nickname to end up in the identity
case df::identity_type::Unk_1: // Guess, but that's how it worked in the past
case df::identity_type::Impersonating:
case df::identity_type::TrueName:
case df::identity_type::Unk_4: // Pure guess, as this is a new case, still unseen
id_hfig = df::historical_figure::find(identity->histfig_id);
break;
}

@ -1 +1 @@
Subproject commit ecd6bcc9ed67c62fa605561b27574467df792342
Subproject commit 9fca46ccca28e0948014b9d56a096ad7343473f1

@ -9,11 +9,16 @@
#include "TileTypes.h"
#include "df/map_block.h"
#include "df/map_block_column.h"
#include "df/plant.h"
#include "df/plant_growth.h"
#include "df/plant_raw.h"
#include "df/tile_dig_designation.h"
#include "df/ui.h"
#include "df/world.h"
#include "df/world_data.h"
#include "df/world_object_data.h"
#include "df/world_site.h"
#include "modules/Designations.h"
#include "modules/Maps.h"
@ -27,7 +32,9 @@ using namespace DFHack;
using namespace df::enums;
DFHACK_PLUGIN("getplants");
REQUIRE_GLOBAL(ui);
REQUIRE_GLOBAL(world);
REQUIRE_GLOBAL(cur_year);
REQUIRE_GLOBAL(cur_year_tick);
enum class selectability {
@ -224,6 +231,106 @@ selectability selectablePlant(const df::plant_raw *plant, bool farming)
}
}
// Formula for determination of the variance in plant growth maturation time, determined via disassembly.
// The x and y parameters are in tiles relative to the embark.
bool ripe(int32_t x, int32_t y, int32_t start, int32_t end) {
int32_t time = (((435522653 - (((y + 3) * x + 5) * ((y + 7) * y * 400181475 + 289700012))) & 0x3FFFFFFF) % 2000 + *cur_year_tick) % 403200;
return time >= start && (end == -1 || time <= end);
}
// Looks in the picked growths vector to see if a matching growth has been marked as picked.
bool picked(const df::plant *plant, int32_t growth_subtype) {
df::world_data *world_data = world->world_data;
df::world_site *site = df::world_site::find(ui->site_id);
int32_t pos_x = site->global_min_x + plant->pos.x / 48;
int32_t pos_y = site->global_min_y + plant->pos.y / 48;
size_t id = pos_x + pos_y * 16 * world_data->world_width;
df::world_object_data *object_data = df::world_object_data::find(id);
df::map_block_column *column = world->map.map_block_columns[(plant->pos.x / 16) * world->map.x_count_block + (plant->pos.y / 16)];
for (size_t i = 0; i < object_data->picked_growths.x.size(); i++) {
if (object_data->picked_growths.x[i] == plant->pos.x &&
object_data->picked_growths.y[i] == plant->pos.y &&
object_data->picked_growths.z[i] - column->z_base == plant->pos.z &&
object_data->picked_growths.subtype[i] == growth_subtype &&
object_data->picked_growths.year[i] == *cur_year) {
return true;
}
}
return false;
}
bool designate(const df::plant *plant, bool farming) {
df::plant_raw *plant_raw = world->raws.plants.all[plant->material];
const DFHack::MaterialInfo basic_mat = DFHack::MaterialInfo(plant_raw->material_defs.type[plant_material_def::basic_mat], plant_raw->material_defs.idx[plant_material_def::basic_mat]);
if (basic_mat.material->flags.is_set(material_flags::EDIBLE_RAW) ||
basic_mat.material->flags.is_set(material_flags::EDIBLE_COOKED))
{
return Designations::markPlant(plant);
}
if (plant_raw->flags.is_set(plant_raw_flags::THREAD) ||
plant_raw->flags.is_set(plant_raw_flags::MILL) ||
plant_raw->flags.is_set(plant_raw_flags::EXTRACT_VIAL) ||
plant_raw->flags.is_set(plant_raw_flags::EXTRACT_BARREL) ||
plant_raw->flags.is_set(plant_raw_flags::EXTRACT_STILL_VIAL))
{
if (!farming) {
return Designations::markPlant(plant);
}
}
if (basic_mat.material->reaction_product.id.size() > 0 ||
basic_mat.material->reaction_class.size() > 0)
{
if (!farming) {
return Designations::markPlant(plant);
}
}
for (size_t i = 0; i < plant_raw->growths.size(); i++)
{
if (plant_raw->growths[i]->item_type == df::item_type::SEEDS || // Only trees have seed growths in vanilla, but raws can be modded...
plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH)
{
const DFHack::MaterialInfo growth_mat = DFHack::MaterialInfo(plant_raw->growths[i]->mat_type, plant_raw->growths[i]->mat_index);
if ((plant_raw->growths[i]->item_type == df::item_type::SEEDS &&
(growth_mat.material->flags.is_set(material_flags::EDIBLE_COOKED) ||
growth_mat.material->flags.is_set(material_flags::EDIBLE_RAW))) ||
(plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH &&
growth_mat.material->flags.is_set(material_flags::LEAF_MAT))) // Will change name to STOCKPILE_PLANT_GROWTH any day now...
{
bool seedSource = plant_raw->growths[i]->item_type == df::item_type::SEEDS;
if (plant_raw->growths[i]->item_type == df::item_type::PLANT_GROWTH)
{
for (size_t k = 0; growth_mat.material->reaction_product.material.mat_type.size(); k++)
{
if (growth_mat.material->reaction_product.material.mat_type[k] == plant_raw->material_defs.type[plant_material_def::seed] &&
growth_mat.material->reaction_product.material.mat_index[k] == plant_raw->material_defs.idx[plant_material_def::seed])
{
seedSource = true;
break;
}
}
}
if ((!farming || seedSource) &&
ripe(plant->pos.x, plant->pos.y, plant_raw->growths[i]->timing_1, plant_raw->growths[i]->timing_2) &&
!picked(plant, i))
{
return Designations::markPlant(plant);
}
}
}
}
return false;
}
command_result df_getplants (color_ostream &out, vector <string> & parameters)
{
string plantMatStr = "";
@ -448,7 +555,7 @@ command_result df_getplants (color_ostream &out, vector <string> & parameters)
collectionCount[plant->material]++;
++count;
}
if (!deselect && Designations::markPlant(plant))
if (!deselect && designate(plant, farming))
{
// out.print("Designated %s at (%i, %i, %i), %d\n", world->raws.plants.all[plant->material]->id.c_str(), plant->pos.x, plant->pos.y, plant->pos.z, (int)i);
collectionCount[plant->material]++;

@ -86,6 +86,7 @@
#include "tweaks/civ-agreement-ui.h"
#include "tweaks/condition-material.h"
#include "tweaks/craft-age-wear.h"
#include "tweaks/do-job-now.h"
#include "tweaks/eggs-fertile.h"
#include "tweaks/embark-profile-name.h"
#include "tweaks/farm-plot-select.h"
@ -182,6 +183,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
/*" tweak fix-dimensions [disable]\n"
" Fixes subtracting small amount of thread/cloth/liquid from a stack\n"
" by splitting the stack and subtracting from the remaining single item.\n"*/
// sort these alphabetically
" tweak adamantine-cloth-wear [disable]\n"
" Stops adamantine clothing from wearing out while being worn (bug 6481).\n"
" tweak advmode-contained [disable]\n"
@ -200,6 +202,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" Fixes a crash in the work order contition material list (bug 9905).\n"
" tweak craft-age-wear [disable]\n"
" Makes cloth and leather items wear out at the correct rate (bug 6003).\n"
" tweak do-job-now [disable]\n"
" Adds a job priority toggle to the jobs list.\n"
" tweak embark-profile-name [disable]\n"
" Allows the use of lowercase letters when saving embark profiles\n"
" tweak eggs-fertile [disable]\n"
@ -243,6 +247,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" tweak pausing-fps-counter [disable]\n"
" Replace fortress mode FPS counter with one that stops counting \n"
" when paused.\n"
" tweak reaction-gloves [disable]\n"
" Changes custom reactions to produce gloves in sets with correct handedness\n"
" tweak shift-8-scroll [disable]\n"
" Gives Shift+8 (or *) priority when scrolling menus, instead of \n"
" scrolling the map\n"
@ -252,8 +258,7 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" Adds a safe rename option to the title screen \"Start Playing\" menu\n"
" tweak tradereq-pet-gender [disable]\n"
" Displays the gender of pets in the trade request list\n"
" tweak reaction-gloves [disable]\n"
" Changes custom reactions to produce gloves in sets with correct handedness\n"
// sort these alphabetically
// " tweak military-training [disable]\n"
// " Speed up melee squad training, removing inverse dependency on unit count.\n"
));
@ -280,6 +285,9 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
TWEAK_HOOK("craft-age-wear", craft_age_wear_hook, ageItem);
TWEAK_HOOK("do-job-now", do_job_now_hook, feed);
TWEAK_HOOK("do-job-now", do_job_now_hook, render);
TWEAK_HOOK("eggs-fertile", egg_fertile_hook, render);
TWEAK_HOOK("embark-profile-name", embark_profile_name_hook, feed);

@ -0,0 +1,43 @@
#include "df/viewscreen_joblistst.h"
struct do_job_now_hook : public df::viewscreen_joblistst {
typedef df::viewscreen_joblistst interpose_base;
bool handleInput(std::set<df::interface_key> *input) {
if (input->count(interface_key::BUILDJOB_NOW)) {
df::job *job = vector_get(jobs, cursor_pos);
if (job) {
job->flags.bits.do_now = !job->flags.bits.do_now;
}
return true;
}
return false;
}
DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set<df::interface_key> *input)) {
if (!handleInput(input)) {
INTERPOSE_NEXT(feed)(input);
}
}
DEFINE_VMETHOD_INTERPOSE(void, render, ()) {
INTERPOSE_NEXT(render)();
int x = 32;
auto dim = Screen::getWindowSize();
int y = dim.y - 2;
bool do_now = false;
df::job *job = vector_get(jobs, cursor_pos);
if (job) {
do_now = job->flags.bits.do_now;
}
OutputHotkeyString(x, y, (!do_now ? "Do job now!" : "Reset priority"),
interface_key::BUILDJOB_NOW, false, x, job ? COLOR_WHITE : COLOR_DARKGREY, COLOR_LIGHTRED);
}
};
IMPLEMENT_VMETHOD_INTERPOSE(do_job_now_hook, feed);
IMPLEMENT_VMETHOD_INTERPOSE(do_job_now_hook, render);

@ -1 +1 @@
Subproject commit 70ce0a12bc0eb14b3782abe7033a6d2dd31863fe
Subproject commit 823d47c4d181ac5b754dce5d605f3e7f242aed26