Files
factorio-scenario-ExpCluster/exp_commands/module/search.lua
Cooldude2606 7ab721b4b6 Refactor some of the Guis from the legacy plugin (#399)
* Fix bugs in core and add default args to Gui defs

* Refactor production Gui

* Refactor landfill blueprint button

* Fix more bugs in core

* Consistent naming of new guis

* Refactor module inserter gui

* Refactor surveillance gui

* Add shorthand for data from arguments

* Make element names consistent

* Add types

* Change how table rows work

* Refactor player stats gui

* Refactor quick actions gui

* Refactor research milestones gui

* Refactor player bonus gui

* Refactor science production gui

* Refactor autofill gui

* Cleanup use of aligned flow

* Rename "Gui.element" to "Gui.define"

* Rename Gui types

* Rename property_from_arg

* Add guide for making guis

* Add full reference document

* Add condensed reference

* Apply style guide to refactored guis

* Bug fixes
2025-08-29 14:30:30 +01:00

113 lines
4.0 KiB
Lua

local Search = {}
local Storage = require("modules/exp_util/storage")
--- Setup the storage to contain the pending translations and the completed ones
local pending = {} --- @type { [1]: string, [2]: string }[]
local translations = {} --- @type table<string, table<string, string>>
Storage.register({
pending,
translations,
}, function(tbl)
pending = tbl[1]
translations = tbl[2]
end)
local command_names = {} --- @type string[]
local command_objects = {} --- @type table<string, Commands.Command>
local required_translations = {} --- @type LocalisedString[]
--- Gets the descriptions of all commands, not including their aliases
--- @param custom_commands table<string, ExpCommand> The complete list of registered custom commands
function Search.prepare(custom_commands)
local known_aliases = {} --- @type table<string, string>
for name, command in pairs(custom_commands) do
for _, alias in ipairs(command.aliases) do
known_aliases[alias] = name
end
end
local index = 0
for name, locale_desc in pairs(commands.commands) do
if not known_aliases[name] then
index = index + 1
command_names[index] = name
required_translations[index] = locale_desc
command_objects[name] = custom_commands[name] or {
name = name,
description = locale_desc,
help_text = locale_desc,
aliases = {},
}
end
end
for name, locale_desc in pairs(commands.game_commands) do
index = index + 1
command_names[index] = name
required_translations[index] = locale_desc
command_objects[name] = {
name = name,
description = locale_desc,
help_text = locale_desc,
aliases = {},
}
end
end
--- Called when a locale changes so the new translations can be requested
--- @param event EventData.on_player_locale_changed | EventData.on_player_joined_game
function Search.on_player_locale_changed(event)
local player = game.players[event.player_index]
local locale = player.locale
if not translations[locale] then
translations[locale] = {}
local ids = player.request_translations(required_translations)
assert(ids, "Translation ids was nil")
for i, command_name in ipairs(command_names) do
pending[ids[i]] = { locale, command_name }
end
end
end
--- Called when a translation request is completed
--- @param event EventData.on_string_translated
--- @return nil
function Search.on_string_translated(event)
local info = pending[event.id]
if not info then return end
pending[event.id] = nil
if not event.translated then
return log("Failed translation for " .. info[1] .. " " .. info[2])
end
translations[info[1]][info[2]] = event.result:lower()
end
--- Searches all game commands and the provided custom commands for the given keyword
--- @param keyword string The keyword to search for
--- @param custom_commands table<string, ExpCommand> A dictionary of commands to search
--- @param locale string? The local to search, default is english ("en")
--- @return table<string, Commands.Command> # A dictionary of commands
function Search.search_commands(keyword, custom_commands, locale)
local rtn = {} --- @type table<string, Commands.Command>
keyword = keyword:lower()
locale = locale or "en"
local searchable_commands = translations[locale]
if not searchable_commands then return {} end
-- Search all custom commands
for name, search_text in pairs(searchable_commands) do
if search_text:match(keyword) or name:match(keyword) then
local obj = command_objects[name]
if not obj.defined_at or custom_commands[name] then
rtn[name] = obj
end
end
end
return rtn
end
return Search