Skip to content
2 changes: 2 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
28 changes: 17 additions & 11 deletions internal/caravan/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 6 additions & 4 deletions internal/caravan/movegoods.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions internal/caravan/pedestal.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down
7 changes: 4 additions & 3 deletions internal/caravan/trade.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down