diff --git a/docs/changelog.txt b/docs/changelog.txt index 57cd2f6f6..4c034b5bc 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -66,6 +66,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: - ``widgets.EditField``: the ``key_sep`` string is now configurable - ``widgets.EditField``: can now display an optional string label in addition to the activation key - ``widgets.EditField``: views that have an ``EditField`` subview no longer need to manually manage the ``EditField`` activation state and input routing. This is now handled automatically by the new ``gui.View`` keyboard focus subsystem. +- ``materials.ItemTraitsDialog``: new dialog to edit item traits (where "item" is part of a job or work order or similar). The list of traits is the same as in vanilla work order conditions "``t`` change traits". # 0.47.05-r5 diff --git a/library/lua/gui/materials.lua b/library/lua/gui/materials.lua index 8894b36af..c9eaaf38d 100644 --- a/library/lua/gui/materials.lua +++ b/library/lua/gui/materials.lua @@ -343,4 +343,266 @@ function ItemTypeDialog(args) return dlg.ListBox(args) end +function ItemTraitsDialog(args) + local job_item_flags_map = {} + for i = 1, 3 do + for _, f in ipairs(df['job_item_flags'..i]) do + if f then + job_item_flags_map[f] = 'flags'..i + end + end + end + local job_item_flags = {} + for k, _ in pairs(job_item_flags_map) do + job_item_flags[#job_item_flags + 1] = k + end + table.sort(job_item_flags) + -------------------------------------- + local tool_uses = {} + for i, _ in ipairs(df.tool_uses) do + tool_uses[#tool_uses + 1] = df.tool_uses[i] + end + local restore_none = false + if tool_uses[1] == 'NONE' then + restore_none = true + table.remove(tool_uses, 1) + end + table.sort(tool_uses) + if restore_none then + table.insert(tool_uses, 1, 'NONE') + end + -------------------------------------- + local set_ore_ix = {} + for i, raw in ipairs(df.global.world.raws.inorganics) do + for _, ix in ipairs(raw.metal_ore.mat_index) do + set_ore_ix[ix] = true + end + end + local ores = {} + for ix in pairs(set_ore_ix) do + local raw = df.global.world.raws.inorganics[ix] + ores[#ores+1] = {mat_index = ix, name = raw.material.state_name.Solid} + end + table.sort(ores, function(a,b) return a.name < b.name end) + + -------------------------------------- + -- CALCIUM_CARBONATE, CAN_GLAZE, FAT, FLUX, + -- GYPSUM, PAPER_PLANT, PAPER_SLURRY, TALLOW, WAX + local reaction_classes_set = {} + for ix,reaction in ipairs(df.global.world.raws.reactions.reactions) do + if #reaction.reagents > 0 then + for _, r in ipairs(reaction.reagents) do + if r.reaction_class and r.reaction_class ~= '' then + reaction_classes_set[r.reaction_class] = true + end + end + end --if + end + local reaction_classes = {} + for k in pairs(reaction_classes_set) do + reaction_classes[#reaction_classes + 1] = k + end + table.sort(reaction_classes) + -------------------------------------- + -- PRESS_LIQUID_MAT, TAN_MAT, BAG_ITEM etc + local product_materials_set = {} + for ix,reaction in ipairs(df.global.world.raws.reactions.reactions) do + if #reaction.products > 0 then + --for _, p in ipairs(reaction.products) do + -- in the list in work order conditions there is no SEED_MAT. + -- I think it's because the game doesn't iterate over all products. + local p = reaction.products[0] + local mat = p.get_material + if mat and mat.product_code ~= '' then + product_materials_set[mat.product_code] = true + end + --end + end --if + end + local product_materials = {} + for k in pairs(product_materials_set) do + product_materials[#product_materials + 1] = k + end + table.sort(product_materials) + --==================================-- + + local function set_search_keys(choices) + for _, choice in ipairs(choices) do + if not choice.search_key then + if type(choice.text) == 'table' then + local search_key = {} + for _, token in ipairs(choice.text) do + search_key[#search_key+1] = string.lower(token.text or '') + end + choice.search_key = table.concat(search_key, ' ') + elseif choice.text then + choice.search_key = string.lower(choice.text) + end + end + end + end + + args.text = args.prompt or 'Type or select an item trait' + args.text_pen = COLOR_WHITE + args.with_filter = true + args.icon_width = 2 + args.dismiss_on_select = false + + local pen_active = COLOR_LIGHTCYAN + local pen_active_d = COLOR_CYAN + local pen_not_active = COLOR_LIGHTRED + local pen_not_active_d = COLOR_RED + local pen_action = COLOR_WHITE + local pen_action_d = COLOR_GREY + + local job_item = args.job_item + local choices = {} + + local pen_cb = function(args, fnc) + if not (args and fnc) then + return COLOR_YELLOW + end + return fnc(args) and pen_active or pen_not_active + end + local pen_d_cb = function(args, fnc) + if not (args and fnc) then + return COLOR_YELLOW + end + return fnc(args) and pen_active_d or pen_not_active_d + end + local icon_cb = function(args, fnc) + if not (args and fnc) then + return '\19' -- ‼ + end + -- '\251' is a checkmark + -- '\254' is a square + return fnc(args) and '\251' or '\254' + end + + if not args.hide_none then + table.insert(choices, { + icon = '!', + text = {{text = args.none_caption or 'none', pen = pen_action, dpen = pen_action_d}}, + reset_all_traits = true + }) + end + + local isActiveFlag = function (obj) + return obj.job_item[obj.ffield][obj.flag] + end + table.insert(choices, { + icon = '!', + text = {{text = 'unset flags', pen = pen_action, dpen = pen_action_d}}, + reset_flags = true + }) + for _, flag in ipairs(job_item_flags) do + local ffield = job_item_flags_map[flag] + local text = 'is ' .. (value and '' or 'any ') .. string.lower(flag) + local args = {job_item=job_item, ffield=ffield, flag=flag} + table.insert(choices, { + icon = curry(icon_cb, args, isActiveFlag), + text = {{text = text, + pen = curry(pen_cb, args, isActiveFlag), + dpen = curry(pen_d_cb, args, isActiveFlag), + }}, + ffield = ffield, flag = flag + }) + end + + local isActiveTool = function (args) + return df.tool_uses[args.tool_use] == args.job_item.has_tool_use + end + for _, tool_use in ipairs(tool_uses) do + if tool_use == 'NONE' then + table.insert(choices, { + icon = '!', + text = {{text = 'unset use', pen = pen_action, dpen = pen_action_d}}, + tool_use = tool_use + }) + else + local args = {job_item = job_item, tool_use=tool_use} + table.insert(choices, { + icon = ' ', + text = {{text = 'has use ' .. tool_use, + pen = curry(pen_cb, args, isActiveTool), + dpen = curry(pen_d_cb, args, isActiveTool), + }}, + tool_use = tool_use + }) + end + end + + local isActiveOre = function(args) + return (args.job_item.metal_ore == args.mat_index) + end + table.insert(choices, { + icon = '!', + text = {{text = 'unset ore', pen = pen_action, dpen = pen_action_d}}, + ore_ix = -1 + }) + for _, ore in ipairs(ores) do + local args = {job_item = job_item, mat_index=ore.mat_index} + table.insert(choices, { + icon = ' ', + text = {{text = 'ore of ' .. ore.name, + pen = curry(pen_cb, args, isActiveOre), + dpen = curry(pen_d_cb, args, isActiveOre), + }}, + ore_ix = ore.mat_index + }) + end + + local isActiveReactionClass = function(args) + return (args.job_item.reaction_class == args.reaction_class) + end + table.insert(choices, { + icon = '!', + text = {{text = 'unset reaction class', pen = pen_action, dpen = pen_action_d}}, + reaction_class = '' + }) + for _, reaction_class in ipairs(reaction_classes) do + local args = {job_item = job_item, reaction_class=reaction_class} + table.insert(choices, { + icon = ' ', + text = {{text = 'reaction class ' .. reaction_class, + pen = curry(pen_cb, args, isActiveReactionClass), + dpen = curry(pen_d_cb, args, isActiveReactionClass) + }}, + reaction_class = reaction_class + }) + end + + local isActiveProduct = function(args) + return (args.job_item.has_material_reaction_product == args.product_materials) + end + table.insert(choices, { + icon = '!', + text = {{text = 'unset producing', pen = pen_action, dpen = pen_action_d}}, + product_materials = '' + }) + for _, product_materials in ipairs(product_materials) do + local args = {job_item = job_item, product_materials=product_materials} + table.insert(choices, { + icon = ' ', + text = {{text = product_materials .. '-producing', + pen = curry(pen_cb, args, isActiveProduct), + dpen = curry(pen_d_cb, args, isActiveProduct) + }}, + product_materials = product_materials + }) + end + + set_search_keys(choices) + args.choices = choices + + if args.on_select then + local cb = args.on_select + args.on_select = function(idx, obj) + return cb(obj) + end + end + + return dlg.ListBox(args) +end + return _ENV