diff --git a/changelog.txt b/changelog.txt index 5ecf8024e..18afcc1b4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -33,6 +33,8 @@ Template for new versions: ## Fixes ## Misc Improvements +- `caravan`: the ``Bring goods to depot``, ``Trade``, and ``Assign items for display`` overlays now allow searching for items with non-ASCII characters in their description +- `caravan`: the ``Trade`` overlay will use the trader's appraisal skill instead of the broker's to round/obfuscate the value of items ## Removed diff --git a/internal/caravan/common.lua b/internal/caravan/common.lua index 996a61656..9fffefe4c 100644 --- a/internal/caravan/common.lua +++ b/internal/caravan/common.lua @@ -10,13 +10,12 @@ CH_DN = string.char(31) CH_MONEY = string.char(15) CH_EXCEPTIONAL = string.char(240) -local to_pen = dfhack.pen.parse -SOME_PEN = to_pen{ch=':', fg=COLOR_YELLOW} -ALL_PEN = to_pen{ch=string.char(251), fg=COLOR_LIGHTGREEN} +SOME_PEN = dfhack.pen.parse{ch=':', fg=COLOR_YELLOW} +ALL_PEN = dfhack.pen.parse{ch=string.char(251), fg=COLOR_LIGHTGREEN} function add_words(words, str) - for word in str:gmatch("[%w]+") do - table.insert(words, word:lower()) + for word in dfhack.toSearchNormalized(str):gmatch("[%w]+") do + table.insert(words, word) end end @@ -35,8 +34,15 @@ function make_container_search_key(item, desc) return table.concat(words, ' ') end -local function get_broker_skill() +function get_broker_skill() local broker = dfhack.units.getUnitByNobleRole('broker') + local interface_trade = df.global.game.main_interface.trade + if interface_trade.open == true + and interface_trade.choosing_merchant == false + and interface_trade.fortress_trader ~= nil + then + broker = interface_trade.fortress_trader + end if not broker then return 0 end for _,skill in ipairs(broker.status.current_soul.skills) do if skill.id == df.job_skill.APPRAISAL then @@ -46,7 +52,7 @@ local function get_broker_skill() return 0 end -local function get_threshold(broker_skill) +function get_threshold(broker_skill) if broker_skill <= df.skill_rating.Dabbling then return 0 end if broker_skill <= df.skill_rating.Novice then return 10 end if broker_skill <= df.skill_rating.Adequate then return 25 end @@ -62,7 +68,7 @@ local function get_threshold(broker_skill) if broker_skill <= df.skill_rating.Master then return 4000 end if broker_skill <= df.skill_rating.HighMaster then return 5000 end if broker_skill <= df.skill_rating.GrandMaster then return 10000 end - return math.huge + return math.maxinteger end local function estimate(value, round_base, granularity) @@ -76,8 +82,8 @@ end -- Otherwise, if it's less than or equal to [threshold + 50] * 3, it will round to the nearest multiple of 100 -- Otherwise, if it's less than or equal to [threshold + 50] * 30, it will round to the nearest multiple of 1000 -- Otherwise, it will display a guess equal to [threshold + 50] * 30 rounded up to the nearest multiple of 1000. -function obfuscate_value(value) - local threshold = get_threshold(get_broker_skill()) +function obfuscate_value(value, threshold) + threshold = threshold or get_threshold(get_broker_skill()) if value < threshold then return dfhack.formatInt(value) end threshold = threshold + 50 if value <= threshold then return ('~%s'):format(estimate(value, 5, 10)) end @@ -267,7 +273,7 @@ function get_slider_widgets(self, suffix) {label='100'..CH_MONEY, value={index=4, value=100}, pen=COLOR_BROWN}, {label='500'..CH_MONEY, value={index=5, value=500}, pen=COLOR_BROWN}, {label='1000'..CH_MONEY, value={index=6, value=1000}, pen=COLOR_BROWN}, - {label='Max', value={index=7, value=math.huge}, pen=COLOR_GREEN}, + {label='Max', value={index=7, value=math.maxinteger}, pen=COLOR_GREEN}, }, initial_option=7, on_change=function(val) diff --git a/internal/caravan/movegoods.lua b/internal/caravan/movegoods.lua index df90d7f88..77e822297 100644 --- a/internal/caravan/movegoods.lua +++ b/internal/caravan/movegoods.lua @@ -399,10 +399,10 @@ local function get_entry_icon(data, item_id) return common.SOME_PEN end -local function make_choice_text(at_depot, dist, value, quantity, desc) +local function make_choice_text(at_depot, dist, value, quantity, desc, cache_threshold) return { {width=DIST_COL_WIDTH-2, rjustify=true, text=at_depot and 'depot' or tostring(dist)}, - {gap=2, width=VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(value)}, + {gap=2, width=VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(value, cache_threshold)}, {gap=2, width=QTY_COL_WIDTH, rjustify=true, text=quantity}, {gap=2, text=desc}, } @@ -559,18 +559,20 @@ function MoveGoods:cache_choices() end local group_choices, nogroup_choices = {}, {} + local cache_threshold = common.get_threshold(common.get_broker_skill()) for _, group in pairs(groups) do local data = group.data for item_id, item_data in pairs(data.items) do local nogroup_choice = copyall(group) nogroup_choice.icon = curry(get_entry_icon, data, item_id) nogroup_choice.text = make_choice_text(item_data.item.flags.in_building, - data.dist, data.per_item_value, 1, data.desc) + data.dist, data.per_item_value, 1, data.desc, cache_threshold) nogroup_choice.item_id = item_id table.insert(nogroup_choices, nogroup_choice) end data.total_value = data.per_item_value * data.quantity - group.text = make_choice_text(data.num_at_depot == data.quantity, data.dist, data.total_value, data.quantity, data.desc) + group.text = make_choice_text(data.num_at_depot == data.quantity, data.dist, + data.total_value, data.quantity, data.desc, cache_threshold) table.insert(group_choices, group) self.value_pending = self.value_pending + (data.per_item_value * data.selected) end diff --git a/internal/caravan/pedestal.lua b/internal/caravan/pedestal.lua index dab100ef4..1184a85c3 100644 --- a/internal/caravan/pedestal.lua +++ b/internal/caravan/pedestal.lua @@ -503,10 +503,10 @@ local function get_status(item, display_bld) return STATUS.AVAILABLE.value end -local function make_choice_text(data) +local function make_choice_text(data, threshold) return { {width=STATUS_COL_WIDTH, text=function() return STATUS[STATUS_REVMAP[data.status]].label end}, - {gap=2, width=VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(data.value)}, + {gap=2, width=VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(data.value, threshold)}, {gap=2, text=data.desc}, } end @@ -530,6 +530,7 @@ end function AssignItems:cache_choices(inside_containers, display_bld) if self.choices_cache[inside_containers] then return self.choices_cache[inside_containers] end + local cache_threshold = common.get_threshold(common.get_broker_skill()) local choices = {} for _, item in ipairs(df.global.world.items.other.IN_PLAY) do if not is_displayable_item(item) then goto continue end @@ -559,7 +560,7 @@ function AssignItems:cache_choices(inside_containers, display_bld) end local entry = { search_key=search_key, - text=make_choice_text(data), + text=make_choice_text(data, cache_threshold), data=data, } table.insert(choices, entry) diff --git a/internal/caravan/trade.lua b/internal/caravan/trade.lua index f27e949ea..f78bc75c0 100644 --- a/internal/caravan/trade.lua +++ b/internal/caravan/trade.lua @@ -315,9 +315,9 @@ local function is_ethical_product(item, animal_ethics, wood_ethics) (not wood_ethics or not common.has_wood(item)) end -local function make_choice_text(value, desc) +local function make_choice_text(value, threshold, desc) return { - {width=STATUS_COL_WIDTH+VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(value)}, + {width=STATUS_COL_WIDTH+VALUE_COL_WIDTH, rjustify=true, text=common.obfuscate_value(value, threshold)}, {gap=2, text=desc}, } end @@ -328,6 +328,7 @@ function Trade:cache_choices(list_idx, trade_bins) local goodflags = trade.goodflag[list_idx] local trade_bins_choices, notrade_bins_choices = {}, {} local parent_data + local cache_threshold = common.get_threshold(common.get_broker_skill()) for item_idx, item in ipairs(trade.good[list_idx]) do local goodflag = goodflags[item_idx] if not goodflag.contained then @@ -374,7 +375,7 @@ function Trade:cache_choices(list_idx, trade_bins) search_key=search_key, icon=curry(get_entry_icon, data), data=data, - text=make_choice_text(data.value, desc), + text=make_choice_text(data.value, cache_threshold, desc), } if not data.update_container_fn then table.insert(trade_bins_choices, choice)