diff --git a/docs/changelog.txt b/docs/changelog.txt index 6e669c893..354eec135 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -38,9 +38,12 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes - Fix extra keys appearing in DFHack text boxes when shift (or any other modifier) is released before the other key you were pressing +- `logistics`: don't autotrain domestic animals brought by invaders (they'll get attacked by friendly creatures as soon as you let them out of their cage) +- `logistics`: don't bring trade goods to depot if the only caravans present are tribute caravans ## Misc Improvements - `stockpiles`: include exotic pets in the "tameable" filter +- `logistics`: bring an autotraded bin to the depot if any item inside is tradeable instead of marking all items within the bin as untradeable if any individual item is untradeable - `autonick`: add more variety to nicknames based on famous literary dwarves - ``widgets.EditField``: DFHack edit fields now support cut/copy/paste with the system clipboard with Ctrl-X/Ctrl-C/Ctrl-V - Suppress DF keyboard events when a DFHack keybinding is matched. This prevents, for example, a backtick from appearing in a textbox as text when you launch `gui/launcher` from the backtick keybinding. diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 11bac3f61..6862f1d1e 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -1797,7 +1797,12 @@ Items module * ``dfhack.items.canTradeWithContents(item)`` - Checks whether the item and all items it contains, if any, can be traded. + Returns false if the item or any contained items cannot be traded. + +* ``canTradeAnyWithContents(item)`` + + Returns true if the item is empty and can be traded or if the item contains + any item that can be traded. * ``dfhack.items.markForTrade(item, depot)`` diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 7afb3b9ea..55d265baf 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2025,6 +2025,7 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = { WRAPM(Items, checkMandates), WRAPM(Items, canTrade), WRAPM(Items, canTradeWithContents), + WRAPM(Items, canTradeAnyWithContents), WRAPM(Items, markForTrade), WRAPM(Items, isRouteVehicle), WRAPM(Items, isSquadEquipment), diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h index 7541660f4..beccd669a 100644 --- a/library/include/modules/Items.h +++ b/library/include/modules/Items.h @@ -199,8 +199,10 @@ DFHACK_EXPORT int32_t createItem(df::item_type type, int16_t item_subtype, int16 DFHACK_EXPORT bool checkMandates(df::item *item); /// Checks whether the item can be traded DFHACK_EXPORT bool canTrade(df::item *item); -/// Checks whether the item and all items it contains, if any, can be traded +/// Returns false if the item or any contained items cannot be traded DFHACK_EXPORT bool canTradeWithContents(df::item *item); +/// Returns true if the item is empty and can be traded or if the item contains any item that can be traded +DFHACK_EXPORT bool canTradeAnyWithContents(df::item *item); /// marks the given item for trade at the given depot DFHACK_EXPORT bool markForTrade(df::item *item, df::building_tradedepotst *depot); /// Returns true if an active caravan will pay extra for the given item diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 3fc08813c..3694e0203 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -2172,6 +2172,27 @@ bool Items::canTradeWithContents(df::item *item) return true; } +bool Items::canTradeAnyWithContents(df::item *item) +{ + CHECK_NULL_POINTER(item); + + if (item->flags.bits.in_inventory) + return false; + + vector contained_items; + getContainedItems(item, &contained_items); + + if (contained_items.empty()) + return canTrade(item); + + for (df::item *cit : contained_items) { + if (canTrade(cit)) + return true; + } + + return false; +} + bool Items::markForTrade(df::item *item, df::building_tradedepotst *depot) { CHECK_NULL_POINTER(item); CHECK_NULL_POINTER(depot); diff --git a/plugins/logistics.cpp b/plugins/logistics.cpp index 20b2c343f..643fb4941 100644 --- a/plugins/logistics.cpp +++ b/plugins/logistics.cpp @@ -317,7 +317,7 @@ public: } bool can_designate(color_ostream& out, df::item* item) override { - return Items::canTradeWithContents(item); + return Items::canTradeAnyWithContents(item); } bool designate(color_ostream& out, df::item* item) override { @@ -330,11 +330,13 @@ private: df::building_tradedepotst * const depot; static df::building_tradedepotst * get_active_trade_depot() { - // at least one caravan must be approaching or ready to trade + // at least one non-tribute caravan must be approaching or ready to trade if (!plotinfo->caravans.size()) return NULL; bool found = false; for (auto caravan : plotinfo->caravans) { + if (caravan->flags.bits.tribute) + continue; auto trade_state = caravan->trade_state; auto time_remaining = caravan->time_remaining; if ((trade_state == df::caravan_state::T_trade_state::Approaching || @@ -392,8 +394,9 @@ public: bool can_designate(color_ostream& out, df::item* item) override { auto unit = get_caged_unit(item); - return unit && Units::isTamable(unit) && !Units::isTame(unit) - && !has_training_assignment(unit); + return unit && !Units::isInvader(unit) && + Units::isTamable(unit) && !Units::isTame(unit) && + !has_training_assignment(unit); } bool designate(color_ostream& out, df::item* item) override {