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(DF_VERSION "0.44.05")
set(DFHACK_RELEASE "alpha1")
set(DFHACK_PRERELEASE TRUE)
set(DFHACK_RELEASE "r1")
set(DFHACK_PRERELEASE FALSE)
set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}")

@ -36,47 +36,96 @@ Changelog
.. contents::
:depth: 2
DFHack future
=============
DFHack 0.44.05-r1
=================
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
``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
- `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
-----
- Fixed issues with the console output color affecting the prompt on Windows
- `createitem`: stopped items from teleporting away in some forts
- `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/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
-----------------
- The console now provides suggestions for built-in commands
- `binpatch`: now reports errors for empty patch files
- `devel/export-dt-ini`: avoid hardcoding flags
- `exportlegends`:
- reordered some tags to match DF's order
- 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-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/pathable`: added tile types to sidebar
- `gui/rename`: added "clear" and "special characters" options
- `launch`: can now ride creatures
- `modtools/skill-change`:
- now updates skill levels appropriately
- only prints output if ``-loud`` is passed
- `names`: can now edit names of units
- `remotefortressreader`: includes item stack sizes and some performance improvements
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
---

@ -1930,6 +1930,13 @@ Basic commands:
: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

@ -17,6 +17,7 @@ local function load_patch(name)
local old_bytes = {}
local new_bytes = {}
local has_bytes = false
for line in file:lines() do
if string.match(line, '^%x+:') then
@ -34,10 +35,14 @@ local function load_patch(name)
old_bytes[offset] = oldv
new_bytes[offset] = newv
has_bytes = true
end
end
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 }
end

@ -49,16 +49,21 @@ using namespace DFHack;
#include "df/announcement_flags.h"
#include "df/assign_trade_status.h"
#include "df/building_cagest.h"
#include "df/building_civzonest.h"
#include "df/building_furnacest.h"
#include "df/building_trapst.h"
#include "df/building_type.h"
#include "df/building_workshopst.h"
#include "df/d_init.h"
#include "df/game_mode.h"
#include "df/general_ref.h"
#include "df/global_objects.h"
#include "df/graphic.h"
#include "df/historical_figure.h"
#include "df/interfacest.h"
#include "df/item_corpsepiecest.h"
#include "df/item_corpsest.h"
#include "df/job.h"
#include "df/layer_object_listst.h"
#include "df/occupation.h"
@ -74,8 +79,10 @@ using namespace DFHack;
#include "df/ui_unit_view_mode.h"
#include "df/unit.h"
#include "df/unit_inventory_item.h"
#include "df/viewscreen_announcelistst.h"
#include "df/viewscreen_assign_display_itemst.h"
#include "df/viewscreen_buildinglistst.h"
#include "df/viewscreen_customize_unitst.h"
#include "df/viewscreen_dungeon_monsterstatusst.h"
#include "df/viewscreen_dungeonmodest.h"
#include "df/viewscreen_dwarfmodest.h"
@ -89,6 +96,7 @@ using namespace DFHack;
#include "df/viewscreen_layer_noblelistst.h"
#include "df/viewscreen_layer_overall_healthst.h"
#include "df/viewscreen_layer_stockpilest.h"
#include "df/viewscreen_layer_unit_healthst.h"
#include "df/viewscreen_layer_unit_relationshipst.h"
#include "df/viewscreen_locationsst.h"
#include "df/viewscreen_petst.h"
@ -97,6 +105,7 @@ using namespace DFHack;
#include "df/viewscreen_tradegoodsst.h"
#include "df/viewscreen_unitlistst.h"
#include "df/viewscreen_unitst.h"
#include "df/viewscreen_reportlistst.h"
#include "df/viewscreen_workquota_conditionst.h"
#include "df/viewscreen_workshop_profilest.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_list;
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))
{
@ -934,30 +946,138 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top)
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))
return dfscreen->getSelectedUnit();
if (!Gui::dwarfmode_hotkey(top))
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) {
case ViewUnits:
{
if (!ui_selected_unit)
if (!ui_selected_unit || !ui_selected_unit)
return NULL;
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:
{
if (!ui_look_list || !ui_look_cursor)
return NULL;
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;
else
return NULL;
if (auto item = vector_get(ui_look_list->items, *ui_look_cursor))
{
if (item->type == df::ui_look_list::T_items::Unit)
return item->unit;
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:
return NULL;

@ -53,7 +53,14 @@ size_t convert(const std::string& p,bool ishex=false)
conv>>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)
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();
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
//TODO make something better?
}
@ -106,6 +113,17 @@ void Deinit()
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)
{
@ -177,7 +195,9 @@ command_result memview (color_ostream &out, vector <string> & parameters)
is_enabled = true;
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]);
else
memdata.len=20*16;