Merge remote-tracking branch 'refs/remotes/DFHack/develop'

Conflicts:
	library/xml
develop
Japa 2018-02-04 10:26:39 +05:30
commit 60c1bd3c66
6 changed files with 216 additions and 15 deletions

@ -141,8 +141,8 @@ endif()
# set up versioning. # set up versioning.
set(DF_VERSION "0.44.05") set(DF_VERSION "0.44.05")
set(DFHACK_RELEASE "alpha1") set(DFHACK_RELEASE "r1")
set(DFHACK_PRERELEASE TRUE) set(DFHACK_PRERELEASE FALSE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")

@ -36,47 +36,96 @@ Changelog
.. contents:: .. contents::
:depth: 2 :depth: 2
DFHack future DFHack 0.44.05-r1
============= =================
New Scripts New Scripts
----------- -----------
- `break-dance`: Breaks up a stuck dance activity
- `cannibalism`: Allows consumption of sapient corpses
- `devel/check-other-ids`: Checks the validity of "other" vectors in the - `devel/check-other-ids`: Checks the validity of "other" vectors in the
``world`` global ``world`` global
- `fillneeds`: Use with a unit selected to make them focused and unstressed
- `firestarter`: Lights things on fire: items, locations, entire inventories even!
- `flashstep`: Teleports adventurer to cursor
- `ghostly`: Turns an adventurer into a ghost or back
- `gui/cp437-table`: An in-game CP437 table - `gui/cp437-table`: An in-game CP437 table
- `questport`: Sends your adventurer to the location of your quest log cursor
- `view-unit-reports`: opens the reports screen with combat reports for the selected unit
Fixes Fixes
----- -----
- Fixed issues with the console output color affecting the prompt on Windows - Fixed issues with the console output color affecting the prompt on Windows
- `createitem`: stopped items from teleporting away in some forts - `createitem`: stopped items from teleporting away in some forts
- `devel/inject-raws`: now recognizes spaces in reaction names - `devel/inject-raws`: now recognizes spaces in reaction names
- `dig`: added support for designation priorities - fixes issues with
designations from ``digv`` and related commands having extremely high priority
- `dwarfmonitor`:
- fixed display of creatures and poetic/music/dance forms on ``prefs`` screen
- added "view unit" option
- now exposes the selected unit to other tools
- `gui/gm-unit`: can now edit mining skill - `gui/gm-unit`: can now edit mining skill
- `gui/quickcmd`: stopped error from adding too many commands - `gui/quickcmd`: stopped error from adding too many commands
- `names`: fixed many errors
- `quicksave`: fixed an issue where the "Saving..." indicator often wouldn't appear
Misc Improvements Misc Improvements
----------------- -----------------
- The console now provides suggestions for built-in commands - The console now provides suggestions for built-in commands
- `binpatch`: now reports errors for empty patch files
- `devel/export-dt-ini`: avoid hardcoding flags - `devel/export-dt-ini`: avoid hardcoding flags
- `exportlegends`: - `exportlegends`:
- reordered some tags to match DF's order - reordered some tags to match DF's order
- added progress indicators for exporting long lists - added progress indicators for exporting long lists
- `force`: now provides useful help
- `full-heal`:
- can now select corpses to resurrect
- now resets body part temperatures upon resurrection to prevent creatures
from freezing/melting again
- now resets units' vanish countdown to reverse effects of `exterminate`
- `gui/gm-editor`: added enum names to enum edit dialogs - `gui/gm-editor`: added enum names to enum edit dialogs
- `gui/gm-unit`: made skill search case-insensitive - `gui/gm-unit`:
- made skill search case-insensitive
- added a profession editor
- misc. layout improvements
- `gui/liquids`: added more keybindings: 0-7 to change liquid level, P/B to cycle backwards - `gui/liquids`: added more keybindings: 0-7 to change liquid level, P/B to cycle backwards
- `gui/pathable`: added tile types to sidebar - `gui/pathable`: added tile types to sidebar
- `gui/rename`: added "clear" and "special characters" options - `gui/rename`: added "clear" and "special characters" options
- `launch`: can now ride creatures
- `modtools/skill-change`: - `modtools/skill-change`:
- now updates skill levels appropriately - now updates skill levels appropriately
- only prints output if ``-loud`` is passed - only prints output if ``-loud`` is passed
- `names`: can now edit names of units
- `remotefortressreader`: includes item stack sizes and some performance improvements - `remotefortressreader`: includes item stack sizes and some performance improvements
Removed Removed
------- -------
- `warn-stuck-trees`: the corresponding DF bug was fixed in 0.44.01 - `warn-stuck-trees`: :bug:`9252` fixed in DF 0.44.01
- `tweak`: ``kitchen-keys``: :bug:`614` fixed in DF 0.44.04
Internals
---------
- ``Gui::getAnyUnit()`` supports many more screens/menus
- New globals available:
- ``version``
- ``min_load_version``
- ``movie_version``
- ``basic_seed``
- ``title``
- ``title_spaced``
- ``ui_building_resize_radius``
- ``soul_next_id``
Lua Lua
--- ---

@ -1930,6 +1930,13 @@ Basic commands:
:dfhack-keybind:`digv` :dfhack-keybind:`digv`
.. note::
All commands implemented by the `dig` plugin (listed by ``ls dig``) support
specifying the designation priority with ``-p#``, ``-p #``, or ``p=#``,
where ``#`` is a number from 1 to 7. If a priority is not specified, the
priority selected in-game is used as the default.
.. _digexp: .. _digexp:
digexp digexp

@ -17,6 +17,7 @@ local function load_patch(name)
local old_bytes = {} local old_bytes = {}
local new_bytes = {} local new_bytes = {}
local has_bytes = false
for line in file:lines() do for line in file:lines() do
if string.match(line, '^%x+:') then if string.match(line, '^%x+:') then
@ -34,10 +35,14 @@ local function load_patch(name)
old_bytes[offset] = oldv old_bytes[offset] = oldv
new_bytes[offset] = newv new_bytes[offset] = newv
has_bytes = true
end end
end end
file:close() file:close()
if not has_bytes then
return nil, 'no patch bytes found'
end
return { name = name, old_bytes = old_bytes, new_bytes = new_bytes } return { name = name, old_bytes = old_bytes, new_bytes = new_bytes }
end end

@ -49,16 +49,21 @@ using namespace DFHack;
#include "df/announcement_flags.h" #include "df/announcement_flags.h"
#include "df/assign_trade_status.h" #include "df/assign_trade_status.h"
#include "df/building_cagest.h"
#include "df/building_civzonest.h" #include "df/building_civzonest.h"
#include "df/building_furnacest.h" #include "df/building_furnacest.h"
#include "df/building_trapst.h" #include "df/building_trapst.h"
#include "df/building_type.h"
#include "df/building_workshopst.h" #include "df/building_workshopst.h"
#include "df/d_init.h" #include "df/d_init.h"
#include "df/game_mode.h" #include "df/game_mode.h"
#include "df/general_ref.h" #include "df/general_ref.h"
#include "df/global_objects.h" #include "df/global_objects.h"
#include "df/graphic.h" #include "df/graphic.h"
#include "df/historical_figure.h"
#include "df/interfacest.h" #include "df/interfacest.h"
#include "df/item_corpsepiecest.h"
#include "df/item_corpsest.h"
#include "df/job.h" #include "df/job.h"
#include "df/layer_object_listst.h" #include "df/layer_object_listst.h"
#include "df/occupation.h" #include "df/occupation.h"
@ -74,8 +79,10 @@ using namespace DFHack;
#include "df/ui_unit_view_mode.h" #include "df/ui_unit_view_mode.h"
#include "df/unit.h" #include "df/unit.h"
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
#include "df/viewscreen_announcelistst.h"
#include "df/viewscreen_assign_display_itemst.h" #include "df/viewscreen_assign_display_itemst.h"
#include "df/viewscreen_buildinglistst.h" #include "df/viewscreen_buildinglistst.h"
#include "df/viewscreen_customize_unitst.h"
#include "df/viewscreen_dungeon_monsterstatusst.h" #include "df/viewscreen_dungeon_monsterstatusst.h"
#include "df/viewscreen_dungeonmodest.h" #include "df/viewscreen_dungeonmodest.h"
#include "df/viewscreen_dwarfmodest.h" #include "df/viewscreen_dwarfmodest.h"
@ -89,6 +96,7 @@ using namespace DFHack;
#include "df/viewscreen_layer_noblelistst.h" #include "df/viewscreen_layer_noblelistst.h"
#include "df/viewscreen_layer_overall_healthst.h" #include "df/viewscreen_layer_overall_healthst.h"
#include "df/viewscreen_layer_stockpilest.h" #include "df/viewscreen_layer_stockpilest.h"
#include "df/viewscreen_layer_unit_healthst.h"
#include "df/viewscreen_layer_unit_relationshipst.h" #include "df/viewscreen_layer_unit_relationshipst.h"
#include "df/viewscreen_locationsst.h" #include "df/viewscreen_locationsst.h"
#include "df/viewscreen_petst.h" #include "df/viewscreen_petst.h"
@ -97,6 +105,7 @@ using namespace DFHack;
#include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_tradegoodsst.h"
#include "df/viewscreen_unitlistst.h" #include "df/viewscreen_unitlistst.h"
#include "df/viewscreen_unitst.h" #include "df/viewscreen_unitst.h"
#include "df/viewscreen_reportlistst.h"
#include "df/viewscreen_workquota_conditionst.h" #include "df/viewscreen_workquota_conditionst.h"
#include "df/viewscreen_workshop_profilest.h" #include "df/viewscreen_workshop_profilest.h"
#include "df/world.h" #include "df/world.h"
@ -818,6 +827,9 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
using df::global::ui_look_cursor; using df::global::ui_look_cursor;
using df::global::ui_look_list; using df::global::ui_look_list;
using df::global::ui_selected_unit; using df::global::ui_selected_unit;
using df::global::ui_building_in_assign;
using df::global::ui_building_assign_units;
using df::global::ui_building_item_cursor;
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitst, top)) if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitst, top))
{ {
@ -934,30 +946,138 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
return NULL; return NULL;
} }
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_reportlistst, top))
return vector_get(screen->units, screen->cursor);
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_announcelistst, top))
{
if (screen->unit) {
// in (r)eports -> enter
auto *report = vector_get(screen->reports, screen->sel_idx);
if (report)
{
for (df::unit *unit : world->units.all)
{
if (unit && screen->report_type >= 0 && screen->report_type < 3
&& unit != screen->unit) // find 'other' unit related to this report
{
for (int32_t report_id : unit->reports.log[screen->report_type])
{
if (report_id == report->id)
return unit;
}
}
}
}
} else {
// in (a)nnouncements
return NULL; // cannot determine unit from reports
}
}
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_layer_militaryst, top))
{
if (screen->page == df::viewscreen_layer_militaryst::T_page::Positions) {
auto positions = getLayerList(screen, 1);
if (positions && positions->enabled && positions->active)
return vector_get(screen->positions.assigned, positions->cursor);
auto candidates = getLayerList(screen, 2);
if (candidates && candidates->enabled && candidates->active)
return vector_get(screen->positions.candidates, candidates->cursor);
}
if (screen->page == df::viewscreen_layer_militaryst::T_page::Equip) {
auto positions = getLayerList(screen, 1);
if (positions && positions->enabled && positions->active)
return vector_get(screen->equip.units, positions->cursor);
}
}
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_layer_unit_healthst, top))
return screen->unit;
if (VIRTUAL_CAST_VAR(screen, df::viewscreen_customize_unitst, top))
return screen->unit;
if (auto dfscreen = dfhack_viewscreen::try_cast(top)) if (auto dfscreen = dfhack_viewscreen::try_cast(top))
return dfscreen->getSelectedUnit(); return dfscreen->getSelectedUnit();
if (!Gui::dwarfmode_hotkey(top)) if (!Gui::dwarfmode_hotkey(top))
return NULL; return NULL;
if (!ui)
return NULL;
// general assigning units in building, i.e. (q)uery cage -> (a)ssign
if (ui_building_in_assign && *ui_building_in_assign
&& ui_building_assign_units && ui_building_item_cursor
&& ui->main.mode != Zones) // dont show for (i) zone
return vector_get(*ui_building_assign_units, *ui_building_item_cursor);
if (ui->follow_unit != -1)
return df::unit::find(ui->follow_unit);
switch (ui->main.mode) { switch (ui->main.mode) {
case ViewUnits: case ViewUnits:
{ {
if (!ui_selected_unit) if (!ui_selected_unit || !ui_selected_unit)
return NULL; return NULL;
return vector_get(world->units.active, *ui_selected_unit); return vector_get(world->units.active, *ui_selected_unit);
} }
case ZonesPitInfo: // (i) zone -> (P)it
case ZonesPenInfo: // (i) zone -> pe(N)
{
if (ui_building_assign_units || ui_building_item_cursor)
return vector_get(*ui_building_assign_units, *ui_building_item_cursor);
return NULL;
}
case Burrows:
{
if (ui->burrows.in_add_units_mode)
return vector_get(ui->burrows.list_units, ui->burrows.unit_cursor_pos);
return NULL;
}
case QueryBuilding:
{
if (df::building *building = getAnyBuilding(top))
{
if (VIRTUAL_CAST_VAR(cage, df::building_cagest, building))
{
if (ui_building_item_cursor)
return df::unit::find(vector_get(cage->assigned_units, *ui_building_item_cursor));
}
}
return NULL;
}
case LookAround: case LookAround:
{ {
if (!ui_look_list || !ui_look_cursor) if (!ui_look_list || !ui_look_cursor)
return NULL; return NULL;
auto item = vector_get(ui_look_list->items, *ui_look_cursor); if (auto item = vector_get(ui_look_list->items, *ui_look_cursor))
if (item && item->type == df::ui_look_list::T_items::Unit) {
return item->unit; if (item->type == df::ui_look_list::T_items::Unit)
else return item->unit;
return NULL; else if (item->type == df::ui_look_list::T_items::Item)
{
if (VIRTUAL_CAST_VAR(corpse, df::item_corpsest, item->item))
return df::unit::find(corpse->unit_id); // loo(k) at corpse
else if (VIRTUAL_CAST_VAR(corpsepiece, df::item_corpsepiecest, item->item))
return df::unit::find(corpsepiece->unit_id); // loo(k) at corpse piece
}
else if (item->type == df::ui_look_list::T_items::Spatter)
{
// loo(k) at blood/ichor/.. spatter with a name
MaterialInfo mat;
if (mat.decode(item->spatter_mat_type, item->spatter_mat_index) && mat.figure)
return df::unit::find(mat.figure->unit_id);
}
}
return NULL;
} }
default: default:
return NULL; return NULL;

@ -53,7 +53,14 @@ size_t convert(const std::string& p,bool ishex=false)
conv>>ret; conv>>ret;
return ret; return ret;
} }
bool isAddr(uintptr_t *trg,vector<t_memrange> & ranges) bool isAddr(void *trg, vector<t_memrange> &ranges)
{
for (auto &r : ranges)
if (r.isInRange(trg))
return true;
return false;
}
bool isAddrAt(uintptr_t *trg, vector<t_memrange> &ranges)
{ {
if(trg[0]%4==0) if(trg[0]%4==0)
for(size_t i=0;i<ranges.size();i++) for(size_t i=0;i<ranges.size();i++)
@ -76,7 +83,7 @@ void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,color_ostream
{ {
con.reset_color(); con.reset_color();
if(isAddr((uintptr_t *)(buf+j+i),ranges)) if(isAddrAt((uintptr_t *)(buf+j+i),ranges))
con.color(COLOR_LIGHTRED); //coloring in the middle does not work con.color(COLOR_LIGHTRED); //coloring in the middle does not work
//TODO make something better? //TODO make something better?
} }
@ -106,6 +113,17 @@ void Deinit()
delete [] memdata.lbuf; delete [] memdata.lbuf;
} }
} }
size_t detect_size(void *addr) {
size_t *size = (size_t*)((char*)addr - 16);
int32_t *tag = (int32_t*)((char*)addr - 8);
if (isAddr(size, memdata.ranges) && *tag == 0x11223344) {
return *size;
}
// default
return 20 * 16;
}
DFhackCExport command_result plugin_onupdate (color_ostream &out) DFhackCExport command_result plugin_onupdate (color_ostream &out)
{ {
@ -177,7 +195,9 @@ command_result memview (color_ostream &out, vector <string> & parameters)
is_enabled = true; is_enabled = true;
memdata.state=STATE_ON; memdata.state=STATE_ON;
} }
if(parameters.size()>1) if (vector_get(parameters, 1, string("a")).substr(0, 1) == "a")
memdata.len = detect_size(memdata.addr);
else if (parameters.size()>1)
memdata.len=convert(parameters[1]); memdata.len=convert(parameters[1]);
else else
memdata.len=20*16; memdata.len=20*16;