Merge branch 'getplants' of https://github.com/PatrikLundell/dfhack into getplants

develop
PatrikLundell 2020-01-15 21:30:56 +01:00
commit cd4b00e23e
14 changed files with 107 additions and 12 deletions

@ -56,7 +56,9 @@ IndigoFenix
James Logsdon jlogsdon James Logsdon jlogsdon
Japa JapaMala Japa JapaMala
Jared Adams Jared Adams
Jeremy Apthorp nornagon
Jim Lisi stonetoad Jim Lisi stonetoad
Jimbo Whales jimbowhales
jimcarreer jimcarreer jimcarreer jimcarreer
jj jjyg jj`` jj jjyg jj``
Joel Meador janxious Joel Meador janxious

@ -52,6 +52,8 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- `embark-assistant`: - `embark-assistant`:
- fixed bug causing crash on worlds without generated metals (as well as pruning vectors as originally intended). - fixed bug causing crash on worlds without generated metals (as well as pruning vectors as originally intended).
- fixed bug causing mineral matching to fail to cut off at the magma sea, reporting presence of things that aren't (like DF does currently). - fixed bug causing mineral matching to fail to cut off at the magma sea, reporting presence of things that aren't (like DF does currently).
- fixed bug causing half of the river tiles not to be recognized.
- added logic to detect some river tiles DF doesn't generate data for (but are definitely present).
- `getplants`: fixed designation of plants out of season and added verbose flag, but failed to identify picked plants (which are still designated incorrectly) - `getplants`: fixed designation of plants out of season and added verbose flag, but failed to identify picked plants (which are still designated incorrectly)
- `gui/autogems`: fixed error when no world is loaded - `gui/autogems`: fixed error when no world is loaded
- `gui/companion-order`: - `gui/companion-order`:

@ -1611,6 +1611,7 @@ static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, isOwnCiv), WRAPM(Units, isOwnCiv),
WRAPM(Units, isOwnGroup), WRAPM(Units, isOwnGroup),
WRAPM(Units, isOwnRace), WRAPM(Units, isOwnRace),
WRAPM(Units, getPhysicalDescription),
WRAPM(Units, getRaceName), WRAPM(Units, getRaceName),
WRAPM(Units, getRaceNamePlural), WRAPM(Units, getRaceNamePlural),
WRAPM(Units, getRaceBabyName), WRAPM(Units, getRaceBabyName),

@ -45,6 +45,17 @@ using std::endl;
#define DFHACK_FUNCTION_SIG __func__ #define DFHACK_FUNCTION_SIG __func__
#endif #endif
#ifdef _WIN32
// On x86 MSVC, __thiscall passes |this| in ECX. On x86_64, __thiscall is the
// same as the standard calling convention.
// See https://docs.microsoft.com/en-us/cpp/cpp/thiscall for more info.
#define THISCALL __thiscall
#else
// On other platforms, there's no special calling convention for calling member
// functions.
#define THISCALL
#endif
namespace DFHack { namespace DFHack {
class color_ostream; class color_ostream;
} }

@ -120,6 +120,7 @@ DFHACK_EXPORT bool isVisible(df::unit* unit);
DFHACK_EXPORT std::string getRaceNameById(int32_t race_id); DFHACK_EXPORT std::string getRaceNameById(int32_t race_id);
DFHACK_EXPORT std::string getRaceName(df::unit* unit); DFHACK_EXPORT std::string getRaceName(df::unit* unit);
DFHACK_EXPORT std::string getPhysicalDescription(df::unit* unit);
DFHACK_EXPORT std::string getRaceNamePluralById(int32_t race_id); DFHACK_EXPORT std::string getRaceNamePluralById(int32_t race_id);
DFHACK_EXPORT std::string getRaceNamePlural(df::unit* unit); DFHACK_EXPORT std::string getRaceNamePlural(df::unit* unit);
DFHACK_EXPORT std::string getRaceBabyNameById(int32_t race_id); DFHACK_EXPORT std::string getRaceBabyNameById(int32_t race_id);

@ -765,14 +765,15 @@ function dfhack.run_command_silent(...)
end end
function dfhack.run_command(...) function dfhack.run_command(...)
local output, status = _run_command(...) local result = _run_command(...)
for i, fragment in pairs(output) do for i, f in pairs(result) do
if type(fragment) == 'table' then if type(f) == 'table' then
dfhack.color(fragment[1]) dfhack.color(f[1])
dfhack.print(fragment[2]) dfhack.print(f[2])
end end
end end
dfhack.color(COLOR_RESET) dfhack.color(COLOR_RESET)
return result.status
end end
-- Per-save init file -- Per-save init file

@ -541,6 +541,25 @@ string Units::getRaceName(df::unit* unit)
return getRaceNameById(unit->race); return getRaceNameById(unit->race);
} }
void df_unit_get_physical_description(df::unit* unit, string* out_str)
{
static auto* const fn =
reinterpret_cast<void(THISCALL *)(df::unit*, string*)>(
Core::getInstance().vinfo->getAddress("unit_get_physical_description"));
if (fn)
fn(unit, out_str);
else
*out_str = "";
}
string Units::getPhysicalDescription(df::unit* unit)
{
CHECK_NULL_POINTER(unit);
string str;
df_unit_get_physical_description(unit, &str);
return str;
}
// get plural of race name (used for display in autobutcher UI and for sorting the watchlist) // get plural of race name (used for display in autobutcher UI and for sorting the watchlist)
string Units::getRaceNamePluralById(int32_t id) string Units::getRaceNamePluralById(int32_t id)
{ {
@ -1549,8 +1568,8 @@ bool Units::isGay(df::unit* unit)
if (!unit->status.current_soul) if (!unit->status.current_soul)
return false; return false;
df::orientation_flags orientation = unit->status.current_soul->orientation_flags; df::orientation_flags orientation = unit->status.current_soul->orientation_flags;
return (Units::isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male))) return (!Units::isFemale(unit) || !(orientation.whole & (orientation.mask_marry_male | orientation.mask_romance_male)))
|| (!Units::isFemale(unit) && ! (orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female))); && (!Units::isMale(unit) || !(orientation.whole & (orientation.mask_marry_female | orientation.mask_romance_female)));
} }
bool Units::isNaked(df::unit* unit) bool Units::isNaked(df::unit* unit)

@ -1 +1 @@
Subproject commit abdcb2e17ff29e754a8a7661b697035a0ee702ba Subproject commit 779de23111409635b5644daae5338ba0199945e4

@ -69,6 +69,16 @@ fi
PRELOAD_LIB="${PRELOAD_LIB:+$PRELOAD_LIB:}${LIBSAN}${LIB}" PRELOAD_LIB="${PRELOAD_LIB:+$PRELOAD_LIB:}${LIBSAN}${LIB}"
setarch_arch=$(cat hack/dfhack_setarch.txt || printf i386) setarch_arch=$(cat hack/dfhack_setarch.txt || printf i386)
if ! setarch "$setarch_arch" -R true 2>/dev/null; then
echo "warn: architecture '$setarch_arch' not supported by setarch" >&2
if [ "$setarch_arch" = "i386" ]; then
setarch_arch=linux32
else
setarch_arch=linux64
fi
echo "using '$setarch_arch' instead. To silence this warning, edit" >&2
echo "hack/dfhack_setarch.txt to contain an architecture that works on your system." >&2
fi
case "$1" in case "$1" in
-g | --gdb) -g | --gdb)

@ -2077,7 +2077,7 @@ namespace embark_assist {
uint32_t preliminary_world_match(embark_assist::defs::world_tile_data *survey_results, uint32_t preliminary_world_match(embark_assist::defs::world_tile_data *survey_results,
embark_assist::defs::finders *finder, embark_assist::defs::finders *finder,
embark_assist::defs::match_results *match_results) { embark_assist::defs::match_results *match_results) {
// color_ostream_proxy out(Core::getInstance().getConsole()); // color_ostream_proxy out(Core::getInstance().getConsole());
uint32_t count = 0; uint32_t count = 0;
for (uint16_t i = 0; i < world->worldgen.worldgen_parms.dim_x; i++) { for (uint16_t i = 0; i < world->worldgen.worldgen_parms.dim_x; i++) {
for (uint16_t k = 0; k < world->worldgen.worldgen_parms.dim_y; k++) { for (uint16_t k = 0; k < world->worldgen.worldgen_parms.dim_y; k++) {

@ -1043,11 +1043,11 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
mlt->at(i).at(k).river_present = false; mlt->at(i).at(k).river_present = false;
mlt->at(i).at(k).river_elevation = 100; mlt->at(i).at(k).river_elevation = 100;
if (details->rivers_vertical.active[i][k] == 1) { if (details->rivers_vertical.active[i][k] != 0) {
mlt->at(i).at(k).river_present = true; mlt->at(i).at(k).river_present = true;
mlt->at(i).at(k).river_elevation = details->rivers_vertical.elevation[i][k]; mlt->at(i).at(k).river_elevation = details->rivers_vertical.elevation[i][k];
} }
else if (details->rivers_horizontal.active[i][k] == 1) { else if (details->rivers_horizontal.active[i][k] != 0) {
mlt->at(i).at(k).river_present = true; mlt->at(i).at(k).river_present = true;
mlt->at(i).at(k).river_elevation = details->rivers_horizontal.elevation[i][k]; mlt->at(i).at(k).river_elevation = details->rivers_horizontal.elevation[i][k];
} }
@ -1179,6 +1179,51 @@ void embark_assist::survey::survey_mid_level_tile(embark_assist::defs::geo_data
} }
} }
// This is messy. DF has some weird logic to leave out river bends with a South and an East connection, as well
// as river sources (and presumably sinks) that are to the North or the West of the connecting river.
// Experiments indicate these implicit river bends inherit their River Elevation from the lower of the two
// "parents", and it's assumed river sources and sinks similarly inherit it from their sole "parent".
// Two issues are known:
// - Lake and Ocean tiles may be marked as having a river when DF doesn't. However, DF does allow for rivers to
// exist in Ocean/Lake tiles, as well as sources/sinks.
// - DF generates rivers on/under glaciers, but does not display them (as they're frozen), nor are their names
// displayed.
//
for (uint8_t i = 1; i < 16; i++) {
for (uint8_t k = 0; k < 15; k++) {
if (details->rivers_horizontal.active[i][k] != 0 &&
details->rivers_vertical.active[i - 1][k + 1] != 0 &&
!mlt->at(i - 1).at(k).river_present) { // Probably never true
mlt->at(i - 1).at(k).river_present = true;
mlt->at(i - 1).at(k).river_elevation = mlt->at(i).at(k).river_elevation;
if (mlt->at(i - 1).at(k).river_elevation > mlt->at(i - 1).at(k + 1).river_elevation) {
mlt->at(i - 1).at(k).river_elevation = mlt->at(i - 1).at(k + 1).river_elevation;
}
}
}
}
for (uint8_t i = 0; i < 16; i++) {
for (uint8_t k = 1; k < 16; k++) {
if (details->rivers_vertical.active[i][k] != 0 &&
!mlt->at(i).at(k - 1).river_present) {
mlt->at(i).at(k - 1).river_present = true;
mlt->at(i).at(k - 1).river_elevation = mlt->at(i).at(k).river_elevation;
}
}
}
for (uint8_t i = 1; i < 16; i++) {
for (uint8_t k = 0; k < 16; k++) {
if (details->rivers_horizontal.active[i][k] != 0 &&
!mlt->at(i - 1).at(k).river_present) {
mlt->at(i - 1).at(k).river_present = true;
mlt->at(i - 1).at(k).river_elevation = mlt->at(i).at(k).river_elevation;
}
}
}
survey_results->at(x).at(y).aquifer_count = 0; survey_results->at(x).at(y).aquifer_count = 0;
survey_results->at(x).at(y).clay_count = 0; survey_results->at(x).at(y).clay_count = 0;
survey_results->at(x).at(y).sand_count = 0; survey_results->at(x).at(y).sand_count = 0;

@ -457,6 +457,7 @@ message UnitAppearance
optional Hair beard = 6; optional Hair beard = 6;
optional Hair moustache = 7; optional Hair moustache = 7;
optional Hair sideburns = 8; optional Hair sideburns = 8;
optional string physical_description = 9;
} }
message InventoryItem message InventoryItem

@ -1734,6 +1734,8 @@ static command_result GetUnitListInside(color_ostream &stream, const BlockReques
appearance->add_colors(unit->appearance.colors[j]); appearance->add_colors(unit->appearance.colors[j]);
appearance->set_size_modifier(unit->appearance.size_modifier); appearance->set_size_modifier(unit->appearance.size_modifier);
appearance->set_physical_description(Units::getPhysicalDescription(unit));
send_unit->set_profession_id(unit->profession); send_unit->set_profession_id(unit->profession);
std::vector<Units::NoblePosition> pvec; std::vector<Units::NoblePosition> pvec;

@ -1 +1 @@
Subproject commit abcb0cffbbcaaeefc7effca25ff947ab8ea91c43 Subproject commit 5d0f00eae3bd8eef41c860369550e05f95a1282a