diff --git a/NEWS b/NEWS
index 706ae939e..6e8c5fe66 100644
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,10 @@
DFHack Future
+ Fixes:
+ - mousequery: Fixed behavior when selecting a tile on the lowest z-level
Internals:
- EventManager: deals with frame_counter getting reset properly now.
- modtools/item-trigger: fixed equip/unequip bug and corrected minor documentation error
+ - teleport: Updated with proper argument handling and proper unit-at-destination handling.
DFHack 0.40.14-r1
Internals:
diff --git a/Readme.html b/Readme.html
index 51a8e8ecf..32dedbdbb 100644
--- a/Readme.html
+++ b/Readme.html
@@ -3158,12 +3158,10 @@ stripcaged weapons 25321 34228
Teleports a unit to given coordinates.
Examples:
-teleport showunitid - prints unitid beneath cursor
-teleport showpos - prints coordinates beneath cursor
-teleport unit 1234 x 56 y 115 z 26 - teleports unit 1234 to 56,115,26
+teleport -showunitid - prints unitid beneath cursor
+teleport -showpos - prints coordinates beneath cursor
+teleport -unit 1234 -x 56 -y 115 -z 26 - teleports unit 1234 to 56,115,26
-One or both of unit and x/y/z coordinate positions must be
-specified. If one is omitted, the unit or position beneath the cursor is used.
diff --git a/Readme.rst b/Readme.rst
index 378b32667..818c6fa6d 100644
--- a/Readme.rst
+++ b/Readme.rst
@@ -1928,20 +1928,63 @@ menu.
autolabor
---------
-Automatically manage dwarf labors.
-
-When enabled, autolabor periodically checks your dwarves and enables or
-disables labors. It tries to keep as many dwarves as possible busy but
+Automatically manage dwarf labors to efficiently complete jobs.
+Autolabor tries to keep as many dwarves as possible busy but
also tries to have dwarves specialize in specific skills.
-.. note::
+The key is that, for almost all labors, once a dwarf begins a job it will finish that
+job even if the associated labor is removed. Autolabor therefore frequently checks
+which dwarf or dwarves should take new jobs for that labor, and sets labors accordingly.
+Labors with equiptment (mining, hunting, and woodcutting), which are abandoned
+if labors change mid-job, are handled slightly differently to minimise churn.
- Warning: autolabor will override any manual changes you make to labors
- while it is enabled.
-
- To prevent particular dwarves from being managed by autolabor, put them in any burrow.
+*Warning: autolabor will override any manual changes you make to labors*
+*while it is enabled, including through other tools such as Dwarf Therapist*
+
+Simple usage:
+
+:enable autolabor: Enables the plugin with default settings. (Persistent per fortress)
+:disable autolabor: Disables the plugin.
+
+Anything beyond this is optional - autolabor works well on the default settings.
+
+Advanced usage:
+
+:`autolabor
[]`: Set number of dwarves assigned to a labor.
+:`autolabor haulers`: Set a labor to be handled by hauler dwarves.
+:`autolabor disable`: Turn off autolabor for a specific labor.
+:`autolabor reset`: Return a labor to the default handling.
+:`autolabor reset-all`: Return all labors to the default handling.
+:`autolabor list`: List current status of all labors.
+:`autolabor status`: Show basic status information.
-For detailed usage information, see 'help autolabor'.
+*Examples:*
+
+:`autolabor MINE 5`: Keep at least 5 dwarves with mining enabled.
+:`autolabor CUT_GEM 1 1`: Keep exactly 1 dwarf with gemcutting enabled.
+:`autolabor FEED_WATER_CIVILIANS haulers`: Have haulers feed and water wounded dwarves.
+:`autolabor CUTWOOD disable`: Turn off autolabor for wood cutting.
+
+By default, each labor is assigned to between 1 and 200 dwarves (2-200 for mining).
+By default 33% of the workforce become haulers, who handle all hauling jobs as well
+as cleaning, pulling levers, recovering wounded, removing constructions, and filling ponds.
+Other jobs are automatically assigned as described above. Each of these settings can be adjusted.
+
+Jobs are rarely assigned to nobles with responsibilities for meeting diplomats or merchants,
+never to the chief medical dwarf, and less often to the bookeeper and manager.
+
+Hunting is never assigned without a butchery, and fishing is nver assigned without a fishery.
+
+For each labor a preference order is calculated based on skill, biased against masters of other
+trades and excluding those who can't do the job. The labor is then added to the best
+dwarves for that labor. We assign at least the minimum number of dwarfs, in order of preference,
+and then assign additional dwarfs that meet any of these conditions:
+
+ * The dwarf is idle and there are no idle dwarves assigned to this labor
+ * The dwarf has nonzero skill associated with the labor
+ * The labor is mining, hunting, or woodcutting and the dwarf currently has it enabled.
+
+We stop assigning dwarfs when we reach the maximum allowed.
Other
=====
@@ -2425,12 +2468,9 @@ Teleports a unit to given coordinates.
Examples::
- teleport showunitid - prints unitid beneath cursor
- teleport showpos - prints coordinates beneath cursor
- teleport unit 1234 x 56 y 115 z 26 - teleports unit 1234 to 56,115,26
-
-One or both of ``unit`` and ``x``/``y``/``z`` coordinate positions must be
-specified. If one is omitted, the unit or position beneath the cursor is used.
+ teleport -showunitid - prints unitid beneath cursor
+ teleport -showpos - prints coordinates beneath cursor
+ teleport -unit 1234 -x 56 -y 115 -z 26 - teleports unit 1234 to 56,115,26
undump-buildings
================
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index bdf8d1402..9c52d2fa6 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -110,7 +110,7 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(digFlood digFlood.cpp)
add_subdirectory(diggingInvaders)
DFHACK_PLUGIN(drybuckets drybuckets.cpp)
- #DFHACK_PLUGIN(dwarfmonitor dwarfmonitor.cpp)
+ DFHACK_PLUGIN(dwarfmonitor dwarfmonitor.cpp)
DFHACK_PLUGIN(embark-tools embark-tools.cpp)
DFHACK_PLUGIN(eventful eventful.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(fastdwarf fastdwarf.cpp)
@@ -142,7 +142,7 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(regrass regrass.cpp)
DFHACK_PLUGIN(remotefortressreader remotefortressreader.cpp PROTOBUFS RemoteFortressReader)
DFHACK_PLUGIN(rename rename.cpp LINK_LIBRARIES lua PROTOBUFS rename)
-# add_subdirectory(rendermax)
+ add_subdirectory(rendermax)
DFHACK_PLUGIN(resume resume.cpp)
DFHACK_PLUGIN(reveal reveal.cpp)
DFHACK_PLUGIN(search search.cpp)
diff --git a/plugins/autolabor.cpp b/plugins/autolabor.cpp
index 23ae71969..ad7992038 100644
--- a/plugins/autolabor.cpp
+++ b/plugins/autolabor.cpp
@@ -467,7 +467,7 @@ static const struct labor_default default_labor_infos[] = {
/* POTTERY */ {AUTOMATIC, false, 1, 200, 0},
/* GLAZING */ {AUTOMATIC, false, 1, 200, 0},
/* PRESSING */ {AUTOMATIC, false, 1, 200, 0},
- /* BEEKEEPING */ {AUTOMATIC, false, 1, 1, 0}, // reduce risk of stuck beekeepers (see http://www.bay12games.com/dwarves/mantisbt/view.php?id=3981)
+ /* BEEKEEPING */ {AUTOMATIC, false, 1, 200, 0},
/* WAX_WORKING */ {AUTOMATIC, false, 1, 200, 0},
/* HANDLE_VEHICLES */ {HAULERS, false, 1, 200, 0},
/* HAUL_TRADE */ {HAULERS, false, 1, 200, 0},
@@ -1474,7 +1474,7 @@ command_result autolabor (color_ostream &out, std::vector & parame
else
{
out.print("Automatically assigns labors to dwarves.\n"
- "Activate with 'autolabor 1', deactivate with 'autolabor 0'.\n"
+ "Activate with 'enable autolabor', deactivate with 'disable autolabor'.\n"
"Current state: %d.\n", enable_autolabor);
return CR_OK;
diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp
index 69df2d279..b795622d9 100644
--- a/plugins/automaterial.cpp
+++ b/plugins/automaterial.cpp
@@ -660,6 +660,10 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest
if (!box_select_enabled)
return;
+ if (ui->main.mode != df::ui_sidebar_mode::Build ||
+ ui_build_selector->building_type != df::building_type::Construction)
+ return;
+
df::coord vport = Gui::getViewportPos();
//Even if selection drawing is disabled, paint a green cursor as we can place box selection anywhere
diff --git a/plugins/dwarfmonitor.cpp b/plugins/dwarfmonitor.cpp
index e443f9f0e..74884a09d 100644
--- a/plugins/dwarfmonitor.cpp
+++ b/plugins/dwarfmonitor.cpp
@@ -71,7 +71,7 @@ static map> work_history;
static int misery[] = { 0, 0, 0, 0, 0, 0, 0 };
static bool misery_upto_date = false;
-static color_value monitor_colors[] =
+static color_value monitor_colors[] =
{
COLOR_LIGHTRED,
COLOR_RED,
@@ -84,20 +84,20 @@ static color_value monitor_colors[] =
static int get_happiness_cat(df::unit *unit)
{
- int happy = unit->status.happiness;
- if (happy == 0) // miserable
+ int stress = unit->status.current_soul->personality.stress_level;
+ if (stress >= 500000)
return 0;
- else if (happy <= 25) // very unhappy
+ else if (stress >= 250000)
return 1;
- else if (happy <= 50) // unhappy
+ else if (stress >= 100000)
return 2;
- else if (happy <= 75) // fine
+ else if (stress >= 60000)
return 3;
- else if (happy <= 125) // quite content
+ else if (stress >= 30000)
return 4;
- else if (happy <= 150) // happy
+ else if (stress >= 0)
return 5;
- else // ecstatic
+ else
return 6;
}
@@ -688,7 +688,7 @@ public:
case job_type::FertilizeField:
real_activity = JOB_AGRICULTURE;
break;
-
+
case job_type::ButcherAnimal:
case job_type::PrepareRawFish:
case job_type::MillPlants:
@@ -913,7 +913,7 @@ public:
populateDwarfColumn();
populateCategoryBreakdownColumn();
}
-
+
return;
}
@@ -1015,7 +1015,7 @@ private:
map> dwarf_activity_values;
size_t fort_activity_count;
size_t window_days;
-
+
vector listed_activities;
void validateColumn()
@@ -1227,7 +1227,7 @@ public:
if (!unit->status.current_soul)
continue;
- for (auto it = unit->status.current_soul->preferences.begin();
+ for (auto it = unit->status.current_soul->preferences.begin();
it != unit->status.current_soul->preferences.end();
it++)
{
@@ -1639,7 +1639,7 @@ static void update_dwarf_stats(bool is_paused)
add_work_history(unit, JOB_LEISURE);
continue;
}
-
+
add_work_history(unit, unit->job.current_job->job_type);
}
}
@@ -1654,7 +1654,7 @@ DFhackCExport command_result plugin_onupdate (color_ostream &out)
return CR_OK;
static decltype(world->frame_counter) last_frame_count = 0;
-
+
bool is_paused = DFHack::World::ReadPauseState();
if (is_paused)
{
@@ -1841,11 +1841,11 @@ DFhackCExport command_result plugin_init(color_ostream &out, std::vector \n"
" Start monitoring \n"
" can be \"work\", \"misery\", or \"all\"\n"
diff --git a/plugins/mousequery.cpp b/plugins/mousequery.cpp
index 95ba0a6cb..c0143e830 100644
--- a/plugins/mousequery.cpp
+++ b/plugins/mousequery.cpp
@@ -497,8 +497,16 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest
return;
Gui::setCursorCoords(mpos.x, mpos.y, mpos.z);
- sendKey(interface_key::CURSOR_DOWN_Z);
- sendKey(interface_key::CURSOR_UP_Z);
+ if (mpos.z == 0)
+ {
+ sendKey(interface_key::CURSOR_UP_Z);
+ sendKey(interface_key::CURSOR_DOWN_Z);
+ }
+ else
+ {
+ sendKey(interface_key::CURSOR_DOWN_Z);
+ sendKey(interface_key::CURSOR_UP_Z);
+ }
}
bool inBuildPlacement()
diff --git a/scripts/devel/export-dt-ini.lua b/scripts/devel/export-dt-ini.lua
index a5a067c08..4e1d1e9df 100644
--- a/scripts/devel/export-dt-ini.lua
+++ b/scripts/devel/export-dt-ini.lua
@@ -9,10 +9,6 @@ local globals = df.global
local global_addr = dfhack.internal.getAddress
local os_type = dfhack.getOSType()
local rdelta = dfhack.internal.getRebaseDelta()
-
-local vbias = 0
-if os_type == 'windows' then vbias = -4 end
-
local lines = {}
local complete = true
@@ -35,12 +31,11 @@ local function value(name,addr)
table.insert(lines, line)
end
-local function address(name,bias,base,field,...)
+local function address(name,base,field,...)
local addr
if base == globals then
addr = global_addr(field)
- bias = bias - rdelta
if addr and select('#',...) > 0 then
_,addr = df.sizeof(ms.field_ref(base,field,...))
end
@@ -58,223 +53,345 @@ local function address(name,bias,base,field,...)
addr = ms.field_offset(base,field,...)
end
- if addr then
- addr = addr + bias
- end
-
value(name, addr)
end
-local function offset(name,base,...)
- address(name,0,base,...)
-end
-local function vector(name,base,...)
- address(name,vbias,base,...)
-end
-- List of actual values
-
header('addresses')
-vector('translation_vector',globals,'world','raws','language','translations')
-vector('language_vector',globals,'world','raws','language','words')
-vector('creature_vector',globals,'world','units','all')
-vector('active_creature_vector',globals,'world','units','active')
-offset('dwarf_race_index',globals,'ui','race_id')
-vector('squad_vector',globals,'world','squads','all')
-offset('current_year',globals,'cur_year')
-offset('cur_year_tick',globals,'cur_year_tick')
-offset('dwarf_civ_index',globals,'ui','civ_id')
-vector('races_vector',globals,'world','raws','creatures','all')
-vector('reactions_vector',globals,'world','raws','reactions')
-vector('historical_figures',globals,'world','history','figures')
-vector('fake_identities',globals,'world','identities','all')
-vector('historical_figures_vector',globals,'world','history','figures')
-vector('fake_identities_vector',globals,'world','identities','all')
-offset('fortress_entity',globals,'ui','main','fortress_entity')
-vector('historical_entities_vector',globals,'world','entities','all')
-vector('weapons_vector',globals,'world','raws','itemdefs','weapons')
-vector('trap_vector',globals,'world','raws','itemdefs','trapcomps')
-vector('toy_vector',globals,'world','raws','itemdefs','toys')
-vector('tool_vector',globals,'world','raws','itemdefs','tools')
-vector('instrument_vector',globals,'world','raws','itemdefs','instruments')
-vector('armor_vector',globals,'world','raws','itemdefs','armor')
-vector('ammo_vector',globals,'world','raws','itemdefs','ammo')
-vector('siegeammo_vector',globals,'world','raws','itemdefs','siege_ammo')
-vector('glove_vector',globals,'world','raws','itemdefs','gloves')
-vector('shoe_vector',globals,'world','raws','itemdefs','shoes')
-vector('shield_vector',globals,'world','raws','itemdefs','shields')
-vector('helm_vector',globals,'world','raws','itemdefs','helms')
-vector('pant_vector',globals,'world','raws','itemdefs','pants')
-vector('food_vector',globals,'world','raws','itemdefs','food')
-vector('colors_vector',globals,'world','raws','language','colors')
-vector('shapes_vector',globals,'world','raws','language','shapes')
-offset('base_materials',globals,'world','raws','mat_table','builtin')
-vector('inorganics_vector',globals,'world','raws','inorganics')
-vector('plants_vector',globals,'world','raws','plants','all')
-vector('material_templates_vector',globals,'world','raws','material_templates')
-offset('world_data',globals,'world','world_data')
-vector('active_sites_vector',df.world_data,'active_site')
-offset('world_site_type',df.world_site,'type')
+address('translation_vector',globals,'world','raws','language','translations')
+address('language_vector',globals,'world','raws','language','words')
+address('creature_vector',globals,'world','units','all')
+address('active_creature_vector',globals,'world','units','active')
+address('dwarf_race_index',globals,'ui','race_id')
+address('squad_vector',globals,'world','squads','all')
+address('current_year',globals,'cur_year')
+address('cur_year_tick',globals,'cur_year_tick')
+address('dwarf_civ_index',globals,'ui','civ_id')
+address('races_vector',globals,'world','raws','creatures','all')
+address('reactions_vector',globals,'world','raws','reactions')
+address('events_vector',globals,'world','history','events')
+address('historical_figures_vector',globals,'world','history','figures')
+address('fake_identities_vector',globals,'world','identities','all')
+address('fortress_entity',globals,'ui','main','fortress_entity')
+address('historical_entities_vector',globals,'world','entities','all')
+address('itemdef_weapons_vector',globals,'world','raws','itemdefs','weapons')
+address('itemdef_trap_vector',globals,'world','raws','itemdefs','trapcomps')
+address('itemdef_toy_vector',globals,'world','raws','itemdefs','toys')
+address('itemdef_tool_vector',globals,'world','raws','itemdefs','tools')
+address('itemdef_instrument_vector',globals,'world','raws','itemdefs','instruments')
+address('itemdef_armor_vector',globals,'world','raws','itemdefs','armor')
+address('itemdef_ammo_vector',globals,'world','raws','itemdefs','ammo')
+address('itemdef_siegeammo_vector',globals,'world','raws','itemdefs','siege_ammo')
+address('itemdef_glove_vector',globals,'world','raws','itemdefs','gloves')
+address('itemdef_shoe_vector',globals,'world','raws','itemdefs','shoes')
+address('itemdef_shield_vector',globals,'world','raws','itemdefs','shields')
+address('itemdef_helm_vector',globals,'world','raws','itemdefs','helms')
+address('itemdef_pant_vector',globals,'world','raws','itemdefs','pants')
+address('itemdef_food_vector',globals,'world','raws','itemdefs','food')
+address('colors_vector',globals,'world','raws','language','colors')
+address('shapes_vector',globals,'world','raws','language','shapes')
+address('base_materials',globals,'world','raws','mat_table','builtin')
+address('inorganics_vector',globals,'world','raws','inorganics')
+address('plants_vector',globals,'world','raws','plants','all')
+address('material_templates_vector',globals,'world','raws','material_templates')
+address('all_syndromes_vector',globals,'world','raws','syndromes','all')
+address('world_data',globals,'world','world_data')
+address('active_sites_vector',df.world_data,'active_site')
+address('world_site_type',df.world_site,'type')
+address('weapons_vector',globals,'world','items','other','WEAPON')
+address('shields_vector',globals,'world','items','other', 'SHIELD')
+address('quivers_vector',globals,'world','items','other', 'QUIVER')
+address('crutches_vector',globals,'world','items','other', 'CRUTCH')
+address('backpacks_vector',globals,'world','items','other', 'BACKPACK')
+address('ammo_vector',globals,'world','items','other', 'AMMO')
+address('flasks_vector',globals,'world','items','other', 'FLASK')
+address('pants_vector',globals,'world','items','other', 'PANTS')
+address('armor_vector',globals,'world','items','other', 'ARMOR')
+address('shoes_vector',globals,'world','items','other', 'SHOES')
+address('helms_vector',globals,'world','items','other', 'HELM')
+address('gloves_vector',globals,'world','items','other', 'GLOVES')
+address('artifacts_vector',globals,'world','artifacts','all')
header('offsets')
-offset('word_table',df.language_translation,'words')
+address('word_table',df.language_translation,'words')
value('string_buffer_offset', 0x0000)
header('word_offsets')
-offset('base',df.language_word,'word')
-offset('noun_singular',df.language_word,'forms','Noun')
-offset('noun_plural',df.language_word,'forms','NounPlural')
-offset('adjective',df.language_word,'forms','Adjective')
-offset('verb',df.language_word,'forms','Verb')
-offset('present_simple_verb',df.language_word,'forms','Verb3rdPerson')
-offset('past_simple_verb',df.language_word,'forms','VerbPast')
-offset('past_participle_verb',df.language_word,'forms','VerbPassive')
-offset('present_participle_verb',df.language_word,'forms','VerbGerund')
-offset('words',df.language_name,'words')
-offset('word_type',df.language_name,'parts_of_speech')
-offset('language_id',df.language_name,'language')
+address('base',df.language_word,'word')
+address('noun_singular',df.language_word,'forms','Noun')
+address('noun_plural',df.language_word,'forms','NounPlural')
+address('adjective',df.language_word,'forms','Adjective')
+address('verb',df.language_word,'forms','Verb')
+address('present_simple_verb',df.language_word,'forms','Verb3rdPerson')
+address('past_simple_verb',df.language_word,'forms','VerbPast')
+address('past_participle_verb',df.language_word,'forms','VerbPassive')
+address('present_participle_verb',df.language_word,'forms','VerbGerund')
+address('words',df.language_name,'words')
+address('word_type',df.language_name,'parts_of_speech')
+address('language_id',df.language_name,'language')
+
+header('general_ref_offsets')
+--WARNING below value should be: "general_ref::vtable","1","0x8","0x4","vmethod","getType","general_ref_type",""
+value('ref_type',0x8)
+address('artifact_id',df.general_ref_artifact,'artifact_id')
+address('item_id',df.general_ref_item,'item_id')
header('race_offsets')
-offset('name_singular',df.creature_raw,'name',0)
-offset('name_plural',df.creature_raw,'name',1)
-offset('adjective',df.creature_raw,'name',2)
-offset('baby_name_singular',df.creature_raw,'general_baby_name',0)
-offset('baby_name_plural',df.creature_raw,'general_baby_name',1)
-offset('child_name_singular',df.creature_raw,'general_child_name',0)
-offset('child_name_plural',df.creature_raw,'general_child_name',1)
-vector('pref_string_vector',df.creature_raw,'prefstring')
-vector('castes_vector',df.creature_raw,'caste')
-vector('pop_ratio_vector',df.creature_raw,'pop_ratio')
-vector('materials_vector',df.creature_raw,'material')
-offset('flags',df.creature_raw,'flags')
+address('name_singular',df.creature_raw,'name',0)
+address('name_plural',df.creature_raw,'name',1)
+address('adjective',df.creature_raw,'name',2)
+address('baby_name_singular',df.creature_raw,'general_baby_name',0)
+address('baby_name_plural',df.creature_raw,'general_baby_name',1)
+address('child_name_singular',df.creature_raw,'general_child_name',0)
+address('child_name_plural',df.creature_raw,'general_child_name',1)
+address('pref_string_vector',df.creature_raw,'prefstring')
+address('castes_vector',df.creature_raw,'caste')
+address('pop_ratio_vector',df.creature_raw,'pop_ratio')
+address('materials_vector',df.creature_raw,'material')
+address('flags',df.creature_raw,'flags')
+address('tissues_vector',df.creature_raw,'tissue')
header('caste_offsets')
-offset('caste_name',df.caste_raw,'caste_name')
-offset('caste_descr',df.caste_raw,'description')
-offset('caste_phys_att_ranges',df.caste_raw,'attributes','phys_att_range')
-offset('caste_ment_att_ranges',df.caste_raw,'attributes','ment_att_range')
-offset('adult_size',df.caste_raw,'misc','adult_size')
-offset('flags',df.caste_raw,'flags')
-vector('extracts',df.caste_raw,'extracts','extract_matidx')
-offset('skill_rates',df.caste_raw,'skill_rates')
-offset('caste_att_rates',df.caste_raw,'attributes','phys_att_rates')
-offset('caste_att_caps',df.caste_raw,'attributes','phys_att_cap_perc')
+address('caste_name',df.caste_raw,'caste_name')
+address('caste_descr',df.caste_raw,'description')
+address('caste_trait_ranges',df.caste_raw,'personality','a')
+address('caste_phys_att_ranges',df.caste_raw,'attributes','phys_att_range')
+address('baby_age',df.caste_raw,'misc','baby_age')
+address('child_age',df.caste_raw,'misc','child_age')
+address('adult_size',df.caste_raw,'misc','adult_size')
+address('flags',df.caste_raw,'flags')
+address('body_info',df.caste_raw,'body_info')
+address('skill_rates',df.caste_raw,'skill_rates')
+address('caste_att_rates',df.caste_raw,'attributes','phys_att_rates')
+address('caste_att_caps',df.caste_raw,'attributes','phys_att_cap_perc')
+address('shearable_tissues_vector',df.caste_raw,'shearable_tissue_layer')
+address('extracts',df.caste_raw,'extracts','extract_matidx')
header('hist_entity_offsets')
-vector('squads',df.historical_entity,'squads')
-vector('positions',df.historical_entity,'positions','own')
-vector('assignments',df.historical_entity,'positions','assignments')
-offset('assign_hist_id',df.entity_position_assignment,'histfig')
-offset('assign_position_id',df.entity_position_assignment,'position_id')
-offset('position_id',df.entity_position,'id')
-offset('position_name',df.entity_position,'name')
-offset('position_female_name',df.entity_position,'name_female')
-offset('position_male_name',df.entity_position,'name_male')
+address('beliefs',df.historical_entity,'resources','values')
+address('squads',df.historical_entity,'squads')
+address('positions',df.historical_entity,'positions','own')
+address('assignments',df.historical_entity,'positions','assignments')
+address('assign_hist_id',df.entity_position_assignment,'histfig')
+address('assign_position_id',df.entity_position_assignment,'position_id')
+address('position_id',df.entity_position,'id')
+address('position_name',df.entity_position,'name')
+address('position_female_name',df.entity_position,'name_female')
+address('position_male_name',df.entity_position,'name_male')
header('hist_figure_offsets')
-offset('hist_race',df.historical_figure,'race')
-offset('hist_name',df.historical_figure,'name')
-offset('id',df.historical_figure,'id')
-offset('hist_fig_info',df.historical_figure,'info')
-offset('reputation',df.historical_figure_info,'reputation')
-offset('current_ident',df.historical_figure_info.T_reputation,'cur_identity')
-offset('fake_name',df.identity,'name')
-offset('fake_birth_year',df.identity,'birth_year')
-offset('fake_birth_time',df.identity,'birth_second')
-
-header('weapon_offsets')
-offset('name_plural',df.itemdef_weaponst,'name_plural')
-offset('single_size',df.itemdef_weaponst,'two_handed')
-offset('multi_size',df.itemdef_weaponst,'minimum_size')
-offset('ammo',df.itemdef_weaponst,'ranged_ammo')
+address('hist_race',df.historical_figure,'race')
+address('hist_name',df.historical_figure,'name')
+address('id',df.historical_figure,'id')
+address('hist_fig_info',df.historical_figure,'info')
+address('reputation',df.historical_figure_info,'reputation')
+address('current_ident',df.historical_figure_info.T_reputation,'cur_identity')
+address('fake_name',df.identity,'name')
+address('fake_birth_year',df.identity,'birth_year')
+address('fake_birth_time',df.identity,'birth_second')
+address('kills',df.historical_figure_info,'kills')
+address('killed_race_vector',df.historical_kills,'killed_race')
+address('killed_undead_vector',df.historical_kills,'killed_undead')
+address('killed_counts_vector',df.historical_kills,'killed_count')
+
+header('hist_event_offsets')
+address('event_year',df.history_event,'year')
+address('id',df.history_event,'id')
+address('killed_hist_id',df.history_event_hist_figure_diedst,'victim_hf')
+
+header('item_offsets')
+address('item_def',df.item_ammost,'subtype') --currently same for all
+address('id',df.item,'id')
+address('general_refs',df.item,'general_refs')
+address('stack_size',df.item_actual,'stack_size')
+address('wear',df.item_actual,'wear')
+address('mat_type',df.item_crafted,'mat_type')
+address('mat_index',df.item_crafted,'mat_index')
+address('quality',df.item_crafted,'quality')
+
+header('item_subtype_offsets')
+address('sub_type',df.itemdef,'subtype')
+address('name',df.itemdef_armorst,'name')
+address('name_plural',df.itemdef_armorst,'name_plural')
+address('adjective',df.itemdef_armorst,'name_preplural')
+
+header('item_filter_offsets')
+address('item_subtype',df.item_filter_spec,'item_subtype')
+address('mat_class',df.item_filter_spec,'material_class')
+address('mat_type',df.item_filter_spec,'mattype')
+address('mat_index',df.item_filter_spec,'matindex')
+
+header('weapon_subtype_offsets')
+address('single_size',df.itemdef_weaponst,'two_handed')
+address('multi_size',df.itemdef_weaponst,'minimum_size')
+address('ammo',df.itemdef_weaponst,'ranged_ammo')
+address('melee_skill',df.itemdef_weaponst,'skill_melee')
+address('ranged_skill',df.itemdef_weaponst,'skill_ranged')
+
+header('armor_subtype_offsets')
+address('layer',df.armor_properties,'layer')
+address('mat_name',df.itemdef_armorst,'material_placeholder')
+address('other_armor_level',df.itemdef_helmst,'armorlevel')
+address('armor_adjective',df.itemdef_armorst,'adjective')
+address('armor_level',df.itemdef_armorst,'armorlevel')
+address('chest_armor_properties',df.itemdef_armorst,'props')
+address('pants_armor_properties',df.itemdef_pantsst,'props')
+address('other_armor_properties',df.itemdef_helmst,'props')
header('material_offsets')
-offset('solid_name',df.material_common,'state_name','Solid')
-offset('liquid_name',df.material_common,'state_name','Liquid')
-offset('gas_name',df.material_common,'state_name','Gas')
-offset('powder_name',df.material_common,'state_name','Powder')
-offset('paste_name',df.material_common,'state_name','Paste')
-offset('pressed_name',df.material_common,'state_name','Pressed')
-offset('inorganic_materials_vector',df.inorganic_raw,'material')
-offset('flags',df.material_common,'flags')
+address('solid_name',df.material_common,'state_name','Solid')
+address('liquid_name',df.material_common,'state_name','Liquid')
+address('gas_name',df.material_common,'state_name','Gas')
+address('powder_name',df.material_common,'state_name','Powder')
+address('paste_name',df.material_common,'state_name','Paste')
+address('pressed_name',df.material_common,'state_name','Pressed')
+address('flags',df.material_common,'flags')
+address('inorganic_materials_vector',df.inorganic_raw,'material')
+address('inorganic_flags',df.inorganic_raw,'flags')
header('plant_offsets')
-offset('name',df.plant_raw,'name')
-offset('name_plural',df.plant_raw,'name_plural')
-offset('name_leaf_plural',df.plant_raw,'leaves_plural')
-offset('name_seed_plural',df.plant_raw,'seed_plural')
-vector('materials_vector',df.plant_raw,'material')
-offset('flags',df.plant_raw,'flags')
-
-header('item_offsets')
-offset('name_plural',df.itemdef_armorst,'name_plural')
-offset('adjective',df.itemdef_armorst,'name_preplural')
-offset('mat_name',df.itemdef_armorst,'material_placeholder')
+address('name',df.plant_raw,'name')
+address('name_plural',df.plant_raw,'name_plural')
+address('name_leaf_plural',df.plant_raw,'leaves_plural')
+address('name_seed_plural',df.plant_raw,'seed_plural')
+address('materials_vector',df.plant_raw,'material')
+address('flags',df.plant_raw,'flags')
header('descriptor_offsets')
-offset('color_name',df.descriptor_color,'name')
-offset('shape_name_plural',df.descriptor_shape,'name_plural')
+address('color_name',df.descriptor_color,'name')
+address('shape_name_plural',df.descriptor_shape,'name_plural')
+
+header('health_offsets')
+address('parent_id',df.body_part_raw,'con_part_id')
+address('layers_vector',df.body_part_raw,'layers')
+address('number',df.body_part_raw,'number')
+address('names_vector',df.body_part_raw,'name_singular')
+address('names_plural_vector',df.body_part_raw,'name_plural')
+address('layer_tissue',df.body_part_layer_raw,'tissue_id')
+address('layer_global_id',df.body_part_layer_raw,'layer_id')
+address('tissue_name',df.tissue_template,'tissue_name_singular')
+address('tissue_flags',df.tissue_template,'flags')
header('dwarf_offsets')
-offset('first_name',df.unit,'name','first_name')
-offset('nick_name',df.unit,'name','nickname')
-offset('last_name',df.unit,'name','words')
-offset('custom_profession',df.unit,'custom_profession')
-offset('profession',df.unit,'profession')
-offset('race',df.unit,'race')
-offset('flags1',df.unit,'flags1')
-offset('flags2',df.unit,'flags2')
-offset('flags3',df.unit,'flags3')
-offset('caste',df.unit,'caste')
-offset('sex',df.unit,'sex')
-offset('id',df.unit,'id')
-offset('animal_type',df.unit,'training_level')
-offset('civ',df.unit,'civ_id')
-vector('specific_refs',df.unit,'specific_refs')
-offset('squad_id',df.unit,'military','squad_id')
-offset('squad_position',df.unit,'military','squad_position')
-offset('recheck_equipment',df.unit,'military','pickup_flags')
-offset('mood',df.unit,'mood')
-offset('birth_year',df.unit,'relations','birth_year')
-offset('birth_time',df.unit,'relations','birth_time')
-offset('current_job',df.unit,'job','current_job')
-offset('physical_attrs',df.unit,'body','physical_attrs')
-vector('body_size',df.unit,'appearance','body_modifiers')
-offset('curse',df.unit,'curse','name')
-offset('curse_add_flags1',df.unit,'curse','add_tags1')
-offset('turn_count',df.unit,'curse','time_on_site')
-vector('souls',df.unit,'status','souls')
-vector('states',df.unit,'status','misc_traits')
-offset('labors',df.unit,'status','labors')
-offset('happiness',df.unit,'status','happiness')
-vector('thoughts',df.unit,'status','recent_events')
-offset('squad_ref_id',df.unit,'hist_figure_id')
-offset('hist_id',df.unit,'hist_figure_id')
-offset('artifact_name',df.unit,'status','artifact_name')
+address('first_name',df.unit,'name','first_name')
+address('nick_name',df.unit,'name','nickname')
+address('last_name',df.unit,'name','words')
+address('custom_profession',df.unit,'custom_profession')
+address('profession',df.unit,'profession')
+address('race',df.unit,'race')
+address('flags1',df.unit,'flags1')
+address('flags2',df.unit,'flags2')
+address('flags3',df.unit,'flags3')
+address('caste',df.unit,'caste')
+address('sex',df.unit,'sex')
+address('id',df.unit,'id')
+address('animal_type',df.unit,'training_level')
+address('civ',df.unit,'civ_id')
+address('specific_refs',df.unit,'specific_refs')
+address('squad_id',df.unit,'military','squad_id')
+address('squad_position',df.unit,'military','squad_position')
+address('recheck_equipment',df.unit,'military','pickup_flags')
+address('mood',df.unit,'mood')
+address('birth_year',df.unit,'relations','birth_year')
+address('birth_time',df.unit,'relations','birth_time')
+address('pet_owner_id',df.unit,'relations','pet_owner_id')
+address('current_job',df.unit,'job','current_job')
+address('physical_attrs',df.unit,'body','physical_attrs')
+address('body_size',df.unit,'appearance','body_modifiers')
+address('size_info',df.unit,'body','size_info')
+address('curse',df.unit,'curse','name')
+address('curse_add_flags1',df.unit,'curse','add_tags1')
+address('turn_count',df.unit,'curse','time_on_site')
+address('souls',df.unit,'status','souls')
+address('states',df.unit,'status','misc_traits')
+address('labors',df.unit,'status','labors')
+--address('thoughts',df.unit,'status','recent_events')
+--address('happiness',df.unit,'status','happiness')
+address('hist_id',df.unit,'hist_figure_id')
+address('artifact_name',df.unit,'status','artifact_name')
+address('active_syndrome_vector',df.unit,'syndromes','active')
+address('syn_sick_flag',df.unit_syndrome,'flags')
+address('unit_health_info',df.unit,'health')
+address('counters1',df.unit,'counters','winded')
+address('counters2',df.unit, 'counters','pain')
+address('counters3',df.unit, 'counters2','paralysis')
+address('limb_counters',df.unit,'status2','limbs_stand_max')
+address('blood',df.unit,'body','blood_max')
+address('body_component_info',df.unit,'body','components')
+address('layer_status_vector',df.body_component_info,'layer_status')
+address('wounds_vector',df.unit,'body','wounds')
+address('mood_skill',df.unit,'job','mood_skill')
+address('used_items_vector',df.unit,'used_items')
+address('affection_level',df.unit_item_use,'affection_level')
+address('inventory',df.unit,'inventory')
+address('inventory_item_mode',df.unit_inventory_item,'mode')
+address('inventory_item_bodypart',df.unit_inventory_item,'body_part_id')
+
+header('syndrome_offsets')
+address('cie_effects',df.syndrome,'ce')
+address('cie_end',df.creature_interaction_effect,'end')
+address('cie_first_perc',df.creature_interaction_effect_phys_att_changest,'phys_att_perc') --same for mental
+address('cie_phys',df.creature_interaction_effect_phys_att_changest,'phys_att_add')
+address('cie_ment',df.creature_interaction_effect_ment_att_changest,'ment_att_add')
+address('syn_classes_vector',df.syndrome,'syn_class')
+address('trans_race_id',df.creature_interaction_effect_body_transformationst,'race')
+
+header('unit_wound_offsets')
+address('parts',df.unit_wound,'parts')
+address('id',df.unit_wound.T_parts,'body_part_id')
+address('layer',df.unit_wound.T_parts,'layer_idx')
+address('general_flags',df.unit_wound,'flags')
+address('flags1',df.unit_wound.T_parts,'flags1')
+address('flags2',df.unit_wound.T_parts,'flags2')
+address('effects_vector',df.unit_wound.T_parts,'effect_type')
+address('bleeding',df.unit_wound.T_parts,'bleeding')
+address('pain',df.unit_wound.T_parts,'pain')
+address('cur_pen',df.unit_wound.T_parts,'cur_penetration_perc')
+address('max_pen',df.unit_wound.T_parts,'max_penetration_perc')
header('soul_details')
-offset('name',df.unit_soul,'name')
-offset('mental_attrs',df.unit_soul,'mental_attrs')
-vector('skills',df.unit_soul,'skills')
-offset('traits',df.unit_soul,'traits')
-vector('preferences',df.unit_soul,'preferences')
+address('name',df.unit_soul,'name')
+address('orientation',df.unit_soul,'orientation_flags')
+address('mental_attrs',df.unit_soul,'mental_attrs')
+address('skills',df.unit_soul,'skills')
+address('preferences',df.unit_soul,'preferences')
+address('personality',df.unit_soul,'personality')
+address('beliefs',df.unit_personality,'values')
+address('goals',df.unit_personality,'dreams')
+address('goal_realized',df.unit_personality.T_dreams,'unk8')
+address('traits',df.unit_personality,'traits')
header('job_details')
-offset('id',df.job,'job_type')
+address('id',df.job,'job_type')
+address('mat_type',df.job,'mat_type')
+address('mat_index',df.job,'mat_index')
+address('mat_category',df.job,'material_category')
value('on_break_flag',df.misc_trait_type.OnBreak)
-offset('sub_job_id',df.job,'reaction_name')
-offset('reaction',df.reaction,'name')
-offset('reaction_skill',df.reaction,'skill')
-offset('mat_type',df.job,'mat_type')
-offset('mat_index',df.job,'mat_index')
-offset('mat_category',df.job,'material_category')
+address('sub_job_id',df.job,'reaction_name')
+address('reaction',df.reaction,'name')
+address('reaction_skill',df.reaction,'skill')
header('squad_offsets')
-offset('id',df.squad,'id')
-offset('name',df.squad,'name')
-offset('name_old',df.squad,'name','words')
-offset('alias',df.squad,'alias')
-vector('members',df.squad,'positions')
+address('id',df.squad,'id')
+address('name',df.squad,'name')
+address('alias',df.squad,'alias')
+address('members',df.squad,'positions')
+address('carry_food',df.squad,'carry_food')
+address('carry_water',df.squad,'carry_water')
+address('ammunition',df.squad,'ammunition')
+address('quiver',df.squad_position,'quiver')
+address('backpack',df.squad_position,'backpack')
+address('flask',df.squad_position,'flask')
+address('armor_vector',df.squad_position,'uniform','body')
+address('helm_vector',df.squad_position,'uniform','head')
+address('pants_vector',df.squad_position,'uniform','pants')
+address('gloves_vector',df.squad_position,'uniform','gloves')
+address('shoes_vector',df.squad_position,'uniform','shoes')
+address('shield_vector',df.squad_position,'uniform','shield')
+address('weapon_vector',df.squad_position,'uniform','weapon')
+address('uniform_item_filter',df.squad_uniform_spec,'item_filter')
+address('uniform_indiv_choice',df.squad_uniform_spec,'indiv_choice')
-- Final creation of the file
@@ -292,11 +409,6 @@ end
out:write[[
-[valid_flags_1]
-size=1
-1\name=Not from around these parts
-1\value=0x80000000
-
[valid_flags_2]
size=0
@@ -306,9 +418,9 @@ size=10
1\value=0x00001000
2\name=a skeleton
2\value=0x00002000
-3\name=a merchant or diplomat
+3\name=a merchant
3\value=0x00000040
-4\name=outpost liason
+4\name=outpost liason or diplomat
4\value=0x00000800
5\name=an invader or hostile
5\value=0x00020000
@@ -316,7 +428,7 @@ size=10
6\value=0x00080000
7\name=an invader or hostile
7\value=0x000C0000
-8\name=a merchant escort
+8\name=part of a merchant caravan
8\value=0x00000080
9\name="Dead, Jim."
9\value=0x00000002
diff --git a/scripts/teleport.lua b/scripts/teleport.lua
index e01665d3d..80a064d12 100644
--- a/scripts/teleport.lua
+++ b/scripts/teleport.lua
@@ -5,32 +5,39 @@
local function teleport(unit,pos)
local unitoccupancy = dfhack.maps.getTileBlock(unit.pos).occupancy[unit.pos.x%16][unit.pos.y%16]
+ local newoccupancy = dfhack.maps.getTileBlock(pos).occupancy[pos.x%16][pos.y%16]
+ if newoccupancy.unit then
+ unit.flags1.on_ground=true
+ end
unit.pos.x = pos.x
unit.pos.y = pos.y
unit.pos.z = pos.z
if not unit.flags1.on_ground then unitoccupancy.unit = false else unitoccupancy.unit_grounded = false end
end
-local function getArgsTogether(args)
- local settings={pos={}}
- for k,v in ipairs(args) do
- v=string.lower(v)
- if v=="unit" then settings.unitID=tonumber(args[k+1]) end
- if v=="x" then settings.pos['x']=tonumber(args[k+1]) end
- if v=="y" then settings.pos['y']=tonumber(args[k+1]) end
- if v=="z" then settings.pos['z']=tonumber(args[k+1]) end
- if v=="showunitid" then print(dfhack.gui.getSelectedUnit(true).id) end
- if v=="showpos" then printall(df.global.cursor) end
- end
- if not settings.pos.x or not settings.pos.y or not settings.pos.z then settings.pos=nil end
- if not settings.unitID and not settings.pos.x then qerror("Needs a position, a unit ID or both, but not neither!") end
- return settings
-end
+utils = require('utils')
-local args = {...}
-local teleportSettings=getArgsTogether(args)
-local unit = teleportSettings.unitID and df.unit.find(teleportSettings.unitID) or dfhack.gui.getSelectedUnit(true)
-local pos = teleportSettings.pos and teleportSettings.pos or df.global.cursor
+validArgs = validArgs or utils.invert({
+ 'unit',
+ 'x',
+ 'y',
+ 'z',
+ 'showunitid',
+ 'showpos'
+})
-teleport(unit,pos)
+local args = utils.processArgs({...}, validArgs)
+
+if args.showunitid or args.showpos then
+ if args.showunitid then
+ print(dfhack.gui.getSelectedUnit(true).id)
+ else
+ printall(df.global.cursor)
+ end
+else
+ local teleportSettings=getArgsTogether(args)
+ local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)
+ local pos = not(not args.x or not args.y or not args.z) and {x=args.x,y=args.y,z=args.z} or df.global.cursor
+ teleport(unit,pos)
+end
\ No newline at end of file