diff --git a/.emmyrc.json b/.emmyrc.json
new file mode 100644
index 00000000..213157cc
--- /dev/null
+++ b/.emmyrc.json
@@ -0,0 +1,34 @@
+{
+ "$schema": "https://raw.githubusercontent.com/EmmyLuaLs/emmylua-analyzer-rust/refs/heads/main/crates/emmylua_code_analysis/resources/schema.json",
+ "runtime": {
+ "version": "Lua5.2",
+ "requirePattern": [ "?", "?.lua" ]
+ },
+ "workspace": {
+ "$comment-moduleMap": "Replaces the fmtk --clusterio-modules plugin, rewrites each file's own module path rather than the require string",
+ "$comment-library": "clusterio is outside this repo, set CLUSTERIO to your checkout. The factorio typedefs come from .luarc.json, which the factoriomod-debug extension manages",
+ "library": [ "$CLUSTERIO/packages/host" ],
+ "ignoreDir": [ ".github", "web", "dist", "factorio" ],
+ "ignoreGlobs": [ "**/node_modules/**", "**/dist/**", "**/campaigns/**" ],
+ "moduleMap": [
+ { "pattern": "^([^.]+)\\.module\\.module_exports$", "replace": "modules.$1" },
+ { "pattern": "^([^.]+)\\.module\\.(.+)$", "replace": "modules.$1.$2" }
+ ]
+ },
+ "doc": {
+ "privateName": [ "__*" ]
+ },
+ "$comment-disable": "Carried over from the luals config, which had these as editor only rather than checked in ci",
+ "$comment-unnecessary-if": "Disabled by the config fmtk generates for itself, the api union types make it unreliable",
+ "diagnostics": {
+ "globals": [ "__DebugAdapter", "__Profiler" ],
+ "disable": [
+ "assign-type-mismatch",
+ "param-type-mismatch",
+ "preferred-local-alias",
+ "unnecessary-assert",
+ "unnecessary-if",
+ "unused"
+ ]
+ }
+}
diff --git a/.github/workflows/fmtk.yml b/.github/workflows/fmtk.yml
index 4050b457..227585f1 100644
--- a/.github/workflows/fmtk.yml
+++ b/.github/workflows/fmtk.yml
@@ -1,76 +1,94 @@
-name: FMTK Lint
-
-on:
- push:
- pull_request:
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: pnpm/action-setup@v4
- with:
- version: 10
- - uses: actions/setup-node@v4
- with:
- node-version: lts/*
- - name: Install FMTK
- run: |
- # Pinned: 2.1.4+ generates typedefs targeting EmmyLua that LuaLS misreads
- pnpm install factoriomod-debug@2.1.3
- pnpm exec fmtk luals-addon
- jq '.["workspace.library"] += ["${{ github.workspace }}/factorio/library"] | .["runtime.plugin"] = "${{ github.workspace }}/factorio/plugin.lua"' .luarc.json > temp.luarc.json
- jq -s '.[0] * .[1].settings' temp.luarc.json ${{ github.workspace }}/factorio/config.json > check.luarc.json
- - name: Install LuaLS
- run: |
- wget https://github.com/LuaLS/lua-language-server/releases/download/3.18.2/lua-language-server-3.18.2-linux-x64.tar.gz -q -O lusls.tar.gz
- mkdir luals && tar -xf lusls.tar.gz -C luals && rm lusls.tar.gz
- - name: Run Lint Report
- shell: bash
- run: |
- ./luals/bin/lua-language-server --check=. --logpath=. --configpath=check.luarc.json --checklevel=Information --check_out_path=check.json
-
- # Credit to https://github.com/Krealle/luals-check-action/blob/main/action.yml
- # Although some minor fixes were needed
-
- # Format and print the messages (would be nice to format as a table, but that's too complex for jq)
- cat check.json | \
- jq -r \
- 'to_entries | map(.key as $file | .value[] |
- {
- file: $file | sub("file://${{ github.workspace }}/./"; ""),
- code: .code,
- line: .range.start.line,
- message: (.message | split("\n")
- | map(if startswith("- ") then .[2:] else . end)
- | join("\n")),
- severity: (if .severity <= 1 then "ERR" else "WARN" end)
- }) |
- map("**[\(.severity)] \(.code):** \(.file)#L\(.line)
\(.message)") | .[]' \
- > $GITHUB_STEP_SUMMARY
-
- echo ""
-
- # Github Annotations (limited to 10)
- cat check.json | \
- jq -r \
- 'to_entries | map(.key as $file | .value[] |
- {
- file: $file | sub("file://${{ github.workspace }}/./"; ""),
- title: .code,
- line: .range.start.line,
- endLine: .range.end.line,
- col: .range.start.character,
- endColumn: .range.end.character,
- message: .message | gsub("\n"; "%0A"; "m"),
- level: (if .severity <= 1 then "error" else "warning" end)
- }) |
- map("::\(.level) file=\(.file),line=\(.line+1),endLine=\(.line+1),col=\(.col+1),endColumn=\(.endColumn+1),title=\(.title)::\(.message) (\(.title))") | .[]'
-
- if [[ $(wc -l < check.json) > 1 ]] ; then
- exit 1
- else
- echo "✅ All checks succeeded!" | tee $GITHUB_STEP_SUMMARY
- fi
-
\ No newline at end of file
+name: Lua Lint
+
+on:
+ push:
+ pull_request:
+
+env:
+ EMMYLUA_CHECK_VERSION: "0.24.0"
+ CLUSTERIO: ${{ github.workspace }}/.clusterio
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Checkout clusterio modules
+ uses: actions/checkout@v4
+ with:
+ repository: clusterio/clusterio
+ path: .clusterio
+ sparse-checkout: packages/host/modules
+ sparse-checkout-cone-mode: false
+ - uses: pnpm/action-setup@v4
+ with:
+ version: 10
+ - uses: actions/setup-node@v4
+ with:
+ node-version: lts/*
+ - name: Generate Factorio typedefs
+ run: |
+ pnpm install factoriomod-debug
+ pnpm exec fmtk luals-addon "$RUNNER_TEMP"
+ - name: Install emmylua_check
+ run: |
+ curl -fsSL "https://github.com/EmmyLuaLs/emmylua-analyzer-rust/releases/download/${EMMYLUA_CHECK_VERSION}/emmylua_check-linux-x64.tar.gz" \
+ | tar -xz -C "$RUNNER_TEMP"
+ - name: Run Lint Report
+ shell: bash
+ run: |
+ # The typedefs are generated per run, clusterio comes from CLUSTERIO above
+ jq -n --arg lib "$RUNNER_TEMP/factorio/library" \
+ '{ workspace: { library: [ $lib ], ignoreGlobs: [ ".clusterio/**" ] } }' \
+ > "$RUNNER_TEMP/ci.emmyrc.json"
+
+ # Exits non zero on error severity, so the gate below is used instead
+ "$RUNNER_TEMP/emmylua_check" . --config ".emmyrc.json,$RUNNER_TEMP/ci.emmyrc.json" \
+ --output-format json --output check.json || true
+
+ # Credit to https://github.com/Krealle/luals-check-action/blob/main/action.yml
+ # Although some minor fixes were needed
+
+ # Format and print the messages (would be nice to format as a table, but that's too complex for jq)
+ jq -r --arg root "$PWD/" \
+ '.[] | (.file | ltrimstr($root)) as $file | .diagnostics[] |
+ {
+ file: $file,
+ code: .code,
+ line: .range.start.line,
+ message: (.message | split("\n")
+ | map(if startswith("- ") then .[2:] else . end)
+ | join("\n")),
+ severity: (if .severity <= 1 then "ERR" else "WARN" end)
+ } |
+ "**[\(.severity)] \(.code):** \(.file)#L\(.line + 1)
\(.message)"' \
+ check.json > "$GITHUB_STEP_SUMMARY"
+
+ echo ""
+
+ # Github Annotations (limited to 10)
+ jq -r --arg root "$PWD/" \
+ '.[] | (.file | ltrimstr($root)) as $file | .diagnostics[] |
+ {
+ file: $file,
+ title: .code,
+ line: .range.start.line,
+ endLine: .range.end.line,
+ col: .range.start.character,
+ endColumn: .range.end.character,
+ message: (.message | gsub("\n"; "%0A"; "m")),
+ level: (if .severity <= 1 then "error" else "warning" end)
+ } |
+ "::\(.level) file=\(.file),line=\(.line + 1),endLine=\(.endLine + 1),col=\(.col + 1),endColumn=\(.endColumn + 1),title=\(.title)::\(.message) (\(.title))"' \
+ check.json
+
+ # An entry is emitted for every file checked, including clean ones, so
+ # the gate counts diagnostics and asserts the workspace was actually read
+ if [[ $(jq 'length' check.json) -lt 100 ]] ; then
+ echo "::error::Only $(jq 'length' check.json) files were checked, expected the whole workspace"
+ exit 1
+ elif [[ $(jq '[.[].diagnostics[]] | length' check.json) -gt 0 ]] ; then
+ exit 1
+ else
+ echo "✅ All checks succeeded!" | tee "$GITHUB_STEP_SUMMARY"
+ fi
diff --git a/.gitignore b/.gitignore
index a331c19a..bf2406f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
dist/
node_modules/
.vscode
+.luarc.json
diff --git a/.luarc.json b/.luarc.json
deleted file mode 100644
index ba4b39f0..00000000
--- a/.luarc.json
+++ /dev/null
@@ -1,103 +0,0 @@
-{
- "$schema": "https://raw.githubusercontent.com/LuaLS/vscode-lua/master/setting/schema.json",
- "workspace.ignoreDir": [
- ".vscode", ".github", "luals", "factorio", "web"
- ],
- "completion.requireSeparator": "/",
- "runtime.pluginArgs": [
- "--clusterio-modules"
- ],
- "doc": {
- "regengine": "glob",
- "privateName": [ "__*" ],
- "packageName": [ "_*" ]
- },
- "type": {
- "checkTableShape": true,
- "inferParamType": true
- },
- "$comment-name-style-check": "Disabled below until config issue fixed: https://github.com/LuaLS/lua-language-server/issues/2643",
- "$comment-type-mismatch": "Disabled unless opened due to performance concerns, time reduced to 10s from 400s",
- "diagnostics": {
- "unusedLocalExclude": [ "_*", "i", "j", "k", "v" ],
- "groupFileStatus": {
- "ambiguity": "Any",
- "await": "None",
- "codestyle": "Opened",
- "conventions": "Any",
- "duplicate": "Any",
- "global": "Any",
- "luadoc": "Opened",
- "redefined": "Opened",
- "strict": "Any",
- "strong": "Any",
- "type-check": "Any",
- "unbalanced": "Opened",
- "unused": "Opened"
- },
- "neededFileStatus": {
- "no-unknown": "None!",
- "spell-check": "None!",
- "name-style-check": "None!",
- "assign-type-mismatch": "Opened!",
- "return-type-mismatch": "Opened!",
- "param-type-mismatch": "Opened!"
- }
- },
- "nameStyle.config": {
- "local_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }],
- "module_local_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }, {
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "upper_snake_case"
- }, {
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "pascal_case"
- }],
- "function_param_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }],
- "function_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }],
- "local_function_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }],
- "table_field_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }],
- "global_variable_name_style": [{
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "snake_case"
- }, {
- "type" : "pattern",
- "param": "_?_?(\\S*)",
- "$1": "upper_snake_case"
- }],
- "module_name_style": [ "pascal_case", "snake_case" ],
- "require_module_name_style": [ "pascal_case", "snake_case" ],
- "class_name_style": "pascal_case",
- "const_variable_name_style": "upper_snake_case"
- },
- "format.defaultConfig": {
- "continuation_indent.in_expr": "0"
- }
-}
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1d1e0254..9fa851c4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,6 +5,8 @@ All are welcome to make bug reports, feature requests, and pull requests for our
For developers wanting to add features please follow these guidelines:
- All lua code is documented using ldoc.
+- Set the `CLUSTERIO` environment variable to your clusterio development install path, the lint needs it to resolve `modules/clusterio/*`.
+- Lua is checked with [emmylua](https://github.com/EmmyLuaLs/emmylua-analyzer-rust), configured by `.emmyrc.json`. Install the EmmyLua extension rather than sumnekolua / luals, and use factoriomod-debug to generate the factorio api types. Note that an inline cast must be written `--[[@as T]]`, the spaced form is not parsed.
- Changes should be made on your own fork and merged into `main` through a pull request.
- Each pull request should be limited to one feature or a few bug fixes and link to the related issue page.
- Pull requests are automatically linted and documentation checked.
diff --git a/exp_commands/module/commands/authorities.lua b/exp_commands/module/commands/authorities.lua
index db82a6ce..c1ec3309 100644
--- a/exp_commands/module/commands/authorities.lua
+++ b/exp_commands/module/commands/authorities.lua
@@ -10,7 +10,7 @@ The default permission authorities controlled by the flags: admin_only, system_o
local Storage = require("modules/exp_util/storage")
-local Commands = require("modules/exp_commands") --- @class Commands
+local Commands = require("modules/exp_commands") --- @class (partial) Commands
local add, allow, deny = Commands.add_permission_authority, Commands.status.success, Commands.status.unauthorised
local authorities = {}
@@ -28,13 +28,13 @@ end)
--- Allow a player access to system commands, use for debug purposes only
--- @param player_name string? The name of the player to give access to, default is the current player
function Commands.unlock_system_commands(player_name)
- system_players[player_name or game.player.name] = true
+ system_players[player_name or assert(game.player).name] = true
end
--- Remove access from system commands for a player, use for debug purposes only
--- @param player_name string? The name of the player to give access to, default is the current player
function Commands.lock_system_commands(player_name)
- system_players[player_name or game.player.name] = nil
+ system_players[player_name or assert(game.player).name] = nil
end
--- Get a list of all players who have system commands unlocked
diff --git a/exp_commands/module/commands/help.lua b/exp_commands/module/commands/help.lua
index 602b84c4..bb8c6c8b 100644
--- a/exp_commands/module/commands/help.lua
+++ b/exp_commands/module/commands/help.lua
@@ -25,18 +25,18 @@ end)
--- @param page_size number The number of requests to show per page
--- @return LocalisedString[][], number
local function format_as_pages(commands, page_size)
- local pages = { {} }
+ local current_page = {}
+ local pages = { current_page }
local page_length = 0
- local current_page = 1
local total = 0
for _, command in pairs(commands) do
total = total + 1
page_length = page_length + 1
if page_length > page_size then
- current_page = current_page + 1
- pages[current_page] = {}
page_length = 1
+ current_page = {}
+ pages[#pages + 1] = current_page
end
local description
@@ -48,7 +48,7 @@ local function format_as_pages(commands, page_size)
end
local aliases = #command.aliases > 0 and { "exp-commands_help.aliases", table.concat(command.aliases, ", ") } or ""
- pages[current_page][page_length] = { "exp-commands_help.format", command.name, description, aliases }
+ current_page[page_length] = { "exp-commands_help.format", command.name, description, aliases }
end
return pages, total
@@ -71,7 +71,7 @@ Commands.new("commands", { "exp-commands_help.description" })
page = as_number
end
- keyword = keyword:lower()
+ keyword = tostring(keyword):lower()
local pages, found
if cache and cache.keyword == keyword then
-- Cached value found, no search is needed
diff --git a/exp_commands/module/commands/rcon.lua b/exp_commands/module/commands/rcon.lua
index 1e1d2ec5..77da68f6 100644
--- a/exp_commands/module/commands/rcon.lua
+++ b/exp_commands/module/commands/rcon.lua
@@ -12,7 +12,7 @@ local ExpUtil = require("modules/exp_util")
local Async = require("modules/exp_util/async")
local Storage = require("modules/exp_util/storage")
-local Commands = require("modules/exp_commands") --- @class Commands
+local Commands = require("modules/exp_commands") --- @class (partial) Commands
local rcon_env = {} --- @type table
local rcon_static = {} --- @type table
@@ -21,12 +21,10 @@ setmetatable(rcon_static, { __index = _G })
setmetatable(rcon_env, { __index = rcon_static })
--- Some common static values which can be added now
---- @diagnostic disable: name-style-check
rcon_static.Async = Async
rcon_static.ExpUtil = ExpUtil
rcon_static.Commands = Commands
rcon_static.print = Commands.print
---- @diagnostic enable: name-style-check
--- Some common callback values which are useful when a player uses the command
--- @alias ExpCommand.RconDynamic fun(player: LuaPlayer?): any
diff --git a/exp_commands/module/commands/sudo.lua b/exp_commands/module/commands/sudo.lua
index c56ef29d..33fb9e3c 100644
--- a/exp_commands/module/commands/sudo.lua
+++ b/exp_commands/module/commands/sudo.lua
@@ -19,7 +19,7 @@ Commands.new("_sudo", { "exp-commands_sudo.description" })
--- @cast command ExpCommand
--- @cast parameter string
- --- @diagnostic disable-next-line: invisible
+ --- @diagnostic disable-next-line: access-invisible
return Commands._event_handler{
name = command.name,
tick = game.tick,
diff --git a/exp_commands/module/commands/types.lua b/exp_commands/module/commands/types.lua
index 11511b4f..0cef9b84 100644
--- a/exp_commands/module/commands/types.lua
+++ b/exp_commands/module/commands/types.lua
@@ -25,7 +25,7 @@ local Commands = require("modules/exp_commands")
local add, parse = Commands.add_data_type, Commands.parse_input
local valid, invalid = Commands.status.success, Commands.status.invalid_input
-local types = {} --- @class Commands.types
+local types = {} --- @class (partial) Commands.types
--- A boolean value where true is one of: yes, y, true, 1
types.boolean =
diff --git a/exp_commands/module/module_exports.lua b/exp_commands/module/module_exports.lua
index 93a5c626..af8fffc4 100644
--- a/exp_commands/module/module_exports.lua
+++ b/exp_commands/module/module_exports.lua
@@ -61,7 +61,7 @@ local Search = require("modules/exp_commands/search")
--- @type LuaPlayer?
local _print_player
---- @class Commands
+--- @class (partial) Commands
local Commands = {
color = ExpUtil.color,
format_rich_text_color = ExpUtil.format_rich_text_color,
@@ -84,7 +84,7 @@ local Commands = {
--- Contains the different status values a command can return
Commands.status = {}
---- @class Commands.types: table
+--- @class (partial) Commands.types: table | Commands.InputParserFactory>
--- Stores all input parsers and validators for different data types
Commands.types = {}
@@ -103,7 +103,7 @@ end
--- @class Commands.Argument
--- @field name string The name of the argument
--- @field description LocalisedString? The description of the argument
---- @field input_parser Commands.InputParser The input parser for the argument
+--- @field input_parser Commands.InputParser The input parser for the argument
--- @field optional boolean True when the argument is optional
--- @field default any? The default value of the argument
@@ -159,7 +159,7 @@ Commands.server = setmetatable({
Commands.error("Command does not support rcon usage, requires LuaPlayer." .. key)
error("Command does not support rcon usage, requires LuaPlayer." .. key)
end,
-}) --[[ @as LuaPlayer ]]
+}) --[[@as LuaPlayer]]
--- Status Returns.
-- Return values used by command callbacks
@@ -170,7 +170,8 @@ Commands.server = setmetatable({
--- @param msg LocalisedString? An optional message to be included when a command completes (only has an effect in command callbacks)
--- @return Commands.Status, LocalisedString # Should be returned directly without modification
function Commands.status.success(msg)
- return Commands.status.success, msg == nil and { "exp-commands.success" } or msg
+ if msg == nil then return Commands.status.success, { "exp-commands.success" } end
+ return Commands.status.success, msg
end
--- Used to signal an error has occurred in a command, data type parser, or permission authority
@@ -178,7 +179,8 @@ end
--- @param msg LocalisedString? An optional error message to be included in the output, a generic message is used if not provided
--- @return Commands.Status, LocalisedString # Should be returned directly without modification
function Commands.status.error(msg)
- return Commands.status.error, { "exp-commands.error", msg == nil and { "exp-commands.error-default" } or msg }
+ if msg == nil then msg = { "exp-commands.error-default" } end
+ return Commands.status.error, { "exp-commands.error", msg }
end
--- Used to signal the player is unauthorised to use a command, primarily used by permission authorities but can be used in a command callback
@@ -186,7 +188,8 @@ end
--- @param msg LocalisedString? An optional error message to be included in the output, a generic message is used if not provided
--- @return Commands.Status, LocalisedString # Should be returned directly without modification
function Commands.status.unauthorised(msg)
- return Commands.status.unauthorised, { "exp-commands.unauthorized", msg == nil and { "exp-commands.unauthorized-default" } or msg }
+ if msg == nil then msg = { "exp-commands.unauthorized-default" } end
+ return Commands.status.unauthorised, { "exp-commands.unauthorized", msg }
end
--- Used to signal the player provided invalid input to an command, primarily used by data type parsers but can be used in a command callback
@@ -194,15 +197,16 @@ end
--- @param msg LocalisedString? An optional error message to be included in the output, a generic message is used if not provided
--- @return Commands.Status, LocalisedString # Should be returned directly without modification
function Commands.status.invalid_input(msg)
- return Commands.status.invalid_input, msg == nil and { "exp-commands.invalid-input" } or msg
+ if msg == nil then return Commands.status.invalid_input, { "exp-commands.invalid-input" } end
+ return Commands.status.invalid_input, msg
end
--- Used to signal an internal error has occurred, this is reserved for internal use only
---- @param msg LocalisedString A message detailing the error which has occurred, will be logged and outputted
+--- @param msg LocalisedString? A message detailing the error which has occurred, will be logged and outputted
--- @return Commands.Status, LocalisedString # Should be returned directly without modification
--- @package
function Commands.status.internal_error(msg)
- return Commands.status.internal_error, { "exp-commands.internal-error", msg }
+ return Commands.status.internal_error, { "exp-commands.internal-error", msg or "" }
end
--- @type table
@@ -281,7 +285,7 @@ end
--- @alias Commands.InputParserFactory fun(...: any): Commands.InputParser
--- Add a new input parser to the command library, this method validates that it does not already exist
---- @generic T : Commands.InputParser | Commands.InputParserFactory
+--- @generic T : Commands.InputParser | Commands.InputParserFactory
--- @param data_type string The name of the data type the input parser reads in and validates, becomes a key of Commands.types
--- @param input_parser T The function used to parse and validate the data type
--- @return T # The function which was provided as the second argument
@@ -295,7 +299,7 @@ function Commands.add_data_type(data_type, input_parser)
end
--- Remove an input parser for a data type, must be the same string that was passed to add_input_parser
---- @param data_type string | Commands.InputParser | Commands.InputParserFactory The data type or input parser you want to remove the input parser for
+--- @param data_type string | Commands.InputParser | Commands.InputParserFactory The data type or input parser you want to remove the input parser for
function Commands.remove_data_type(data_type)
Commands.types[data_type] = nil
for k, v in pairs(Commands.types) do
@@ -433,7 +437,7 @@ end
--- Add a new required argument to the command of the given data type
--- @param name string The name of the argument being added
--- @param description LocalisedString? The description of the argument being added
---- @param input_parser Commands.InputParser The input parser to be used for the argument
+--- @param input_parser Commands.InputParser The input parser to be used for the argument
--- @return ExpCommand
function Commands._prototype:argument(name, description, input_parser)
assert_command_mutable(self)
@@ -454,7 +458,7 @@ end
--- Add a new optional argument to the command of the given data type
--- @param name string The name of the argument being added
--- @param description LocalisedString? The description of the argument being added
---- @param input_parser Commands.InputParser The input parser to be used for the argument
+--- @param input_parser Commands.InputParser The input parser to be used for the argument
--- @return ExpCommand
function Commands._prototype:optional(name, description, input_parser)
assert_command_mutable(self)
diff --git a/exp_commands/module/search.lua b/exp_commands/module/search.lua
index 56fe8b05..f4ddbaea 100644
--- a/exp_commands/module/search.lua
+++ b/exp_commands/module/search.lua
@@ -3,7 +3,7 @@ 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 pending = {} --- @type table
local translations = {} --- @type table>
Storage.register({
pending,
@@ -50,6 +50,7 @@ function Search.prepare(custom_commands)
name = name,
description = locale_desc,
help_text = locale_desc,
+ usage = locale_desc,
aliases = {},
}
end
@@ -65,7 +66,7 @@ function Search.on_player_locale_changed(event)
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 }
+ pending[assert(ids[i])] = { locale, command_name }
end
end
end
diff --git a/exp_groups/module/control.lua b/exp_groups/module/control.lua
index 0c61af71..232fd6e3 100644
--- a/exp_groups/module/control.lua
+++ b/exp_groups/module/control.lua
@@ -3,7 +3,7 @@ Adds permission group syncing to clusterio
]]
local clusterio_api = require("modules/clusterio/api")
-local compat = require("modules/clusterio/compat")
+local compat = require("modules/clusterio/compat") --[[@as LibCompat]]
--- Top level module table, contains event handlers and public methods
--- @class ExpGroups
diff --git a/exp_groups/module/globals.lua b/exp_groups/module/globals.lua
index ce036c21..27ecdb31 100644
--- a/exp_groups/module/globals.lua
+++ b/exp_groups/module/globals.lua
@@ -5,7 +5,7 @@ Therefore, we advise that this should be the only file in your module to expose
Typically this would be your control file as shown in the example below
]]
---- @diagnostic disable: global-element
+--- @diagnostic disable: global-in-non-module
-- Access using `/sc exp_groups.foo()`
exp_groups = require("modules/exp_groups/control")
diff --git a/exp_gui/module/control.lua b/exp_gui/module/control.lua
index e6c7989a..6c7114ec 100644
--- a/exp_gui/module/control.lua
+++ b/exp_gui/module/control.lua
@@ -16,7 +16,7 @@ Storage.register(player_elements, function(tbl)
player_elements = tbl
end)
---- @class Gui
+--- @class (partial) Gui
local Gui = {
define = ExpElement.new,
from_argument = ExpElement.from_argument,
@@ -46,9 +46,11 @@ end
--- @return LuaPlayer
function Gui.get_player(input)
if type(input) == "table" and not input.player_index then
- return assert(game.get_player(input.element.player_index))
+ --- @cast input { element: LuaGuiElement }
+ return (assert(game.get_player(input.element.player_index)))
end
- return assert(game.get_player(input.player_index))
+ --- @cast input LuaGuiElement | { player_index: uint }
+ return (assert(game.get_player(input.player_index)))
end
--- Toggle the enable state of an element
@@ -88,7 +90,7 @@ end
--- @param define ExpElement
--- @param visible Gui.VisibleCallback | boolean | nil
function Gui.add_top_element(define, visible)
- assert(Gui.top_elements[define.name] == nil, "Element is already added to the top flow")
+ assert(Gui.top_elements[define] == nil, "Element is already added to the top flow")
Gui.top_elements[define] = visible or false
end
@@ -96,7 +98,7 @@ end
--- @param define ExpElement
--- @param visible Gui.VisibleCallback | boolean | nil
function Gui.add_left_element(define, visible)
- assert(Gui.left_elements[define.name] == nil, "Element is already added to the left flow")
+ assert(Gui.left_elements[define] == nil, "Element is already added to the left flow")
Gui.left_elements[define] = visible or false
end
@@ -105,7 +107,7 @@ end
--- @param define ExpElement
--- @param visible Gui.VisibleCallback | boolean | nil
function Gui.add_relative_element(define, visible)
- assert(Gui.relative_elements[define.name] == nil, "Element is already added to the relative flow")
+ assert(Gui.relative_elements[define] == nil, "Element is already added to the relative flow")
Gui.relative_elements[define] = visible or false
end
@@ -114,7 +116,8 @@ end
--- @param player LuaPlayer
--- @return LuaGuiElement
function Gui.get_top_element(define, player)
- return assert(player_elements[player.index].top[define.name], "Element is not on the top flow")
+ local elements = assert(player_elements[player.index])
+ return (assert(elements.top[define.name], "Element is not on the top flow"))
end
--- Register a element define to be drawn to the left flow on join
@@ -122,7 +125,8 @@ end
--- @param player LuaPlayer
--- @return LuaGuiElement
function Gui.get_left_element(define, player)
- return assert(player_elements[player.index].left[define.name], "Element is not on the left flow")
+ local elements = assert(player_elements[player.index])
+ return (assert(elements.left[define.name], "Element is not on the left flow"))
end
--- Register a element define to be drawn to the relative flow on join
@@ -130,7 +134,8 @@ end
--- @param player LuaPlayer
--- @return LuaGuiElement
function Gui.get_relative_element(define, player)
- return assert(player_elements[player.index].relative[define.name], "Element is not on the relative flow")
+ local elements = assert(player_elements[player.index])
+ return (assert(elements.relative[define.name], "Element is not on the relative flow"))
end
--- Ensure all the correct elements are visible and exist
@@ -188,9 +193,9 @@ function Gui._ensure_consistency(event)
-- This check isn't needed, but allows the toolbar file to be deleted without modifying any lib code
if Gui.toolbar then
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
Gui.toolbar._create_elements(player)
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
Gui.toolbar._ensure_consistency(player)
end
end
@@ -211,7 +216,7 @@ local function on_gui_opened(event)
if visible then
event.element = element
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
define:raise_event(event)
end
end
diff --git a/exp_gui/module/data.lua b/exp_gui/module/data.lua
index 8ae9e15e..327a11f1 100644
--- a/exp_gui/module/data.lua
+++ b/exp_gui/module/data.lua
@@ -62,6 +62,7 @@ local GuiData = {
--- @field player_data table
--- @field force_data table
--- @field global_data table
+--- @field [DataKey] any
-- This class has no prototype methods
-- Same as raw but __index ensures the values exist
@@ -89,13 +90,16 @@ function GuiData._metatable.__index(self, key)
assert(type(key) == "userdata", "Index type '" .. ExpUtil.get_class_name(key) .. "' given to GuiData. Must be of type userdata.")
local object_name = key.object_name --- @diagnostic disable-line assign-type-mismatch
if object_name == "LuaGuiElement" then
+ --- @cast key LuaGuiElement
local data = self._raw.element_data
local player_elements = data and data[key.player_index]
return player_elements and player_elements[key.index]
elseif object_name == "LuaPlayer" then
+ --- @cast key LuaPlayer
local data = self._raw.player_data
return data and data[key.index]
elseif object_name == "LuaForce" then
+ --- @cast key LuaForce
local data = self._raw.force_data
return data and data[key.index]
else
@@ -153,7 +157,7 @@ end
--- @param scope string
--- @return GuiData
function GuiData.get(scope)
- return GuiData._scopes[scope] --[[ @as GuiData ]]
+ return GuiData._scopes[scope] --[[@as GuiData]]
end
--- Used to clean up data from destroyed elements
@@ -168,7 +172,7 @@ local function on_object_destroyed(event)
for _, scope in pairs(registered_scopes) do
local data = scope._raw.element_data
local player_elements = data and data[player_index]
- if player_elements then
+ if data and player_elements then
player_elements[element_index] = nil
if not next(player_elements) then
data[player_index] = nil
diff --git a/exp_gui/module/elements.lua b/exp_gui/module/elements.lua
index f8df5853..b4dbd472 100644
--- a/exp_gui/module/elements.lua
+++ b/exp_gui/module/elements.lua
@@ -1,4 +1,4 @@
---- @class Gui
+--- @class (partial) Gui
local Gui = require("modules/exp_gui")
--- @class Gui.elements
@@ -28,7 +28,7 @@ Elements.aligned_flow = Gui.define("aligned_flow")
vertically_stretchable = vertical_align ~= "center",
horizontally_stretchable = horizontal_align ~= "center",
}
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A solid horizontal white bar element
--- @class Gui.elements.bar: ExpElement
@@ -48,11 +48,11 @@ Elements.bar = Gui.define("bar")
else
style.horizontally_stretchable = true
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A label which is centered
--- @class Gui.elements.centered_label: ExpElement
---- @overload fun(parent: LuaGuiElement, width: number, caption: LocalisedString, tooltip: LocalisedString?): LuaGuiElement
+--- @overload fun(parent: LuaGuiElement, width: number, caption: LocalisedString?, tooltip: LocalisedString?): LuaGuiElement
Elements.centered_label = Gui.define("centered_label")
:draw{
type = "label",
@@ -63,7 +63,7 @@ Elements.centered_label = Gui.define("centered_label")
horizontal_align = "center",
single_line = false,
width = Gui.from_argument(1),
- } --[[ @as any ]]
+ } --[[@as any]]
--- A label which has two white bars on either side of it
--- @class Gui.elements.title_label: ExpElement
@@ -91,7 +91,7 @@ Elements.title_label = Gui.define("title_label")
Elements.bar(flow)
return label
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A fixed size vertical scroll pane
--- @class Gui.elements.scroll_pane: ExpElement
@@ -109,7 +109,7 @@ Elements.scroll_pane = Gui.define("scroll_pane")
padding = { 1, 3 },
maximal_height = Gui.from_argument(1),
horizontally_stretchable = true,
- } --[[ @as any ]]
+ } --[[@as any]]
--- A fixed size vertical scroll pane containing a table
--- @class Gui.elements.scroll_table: ExpElement
@@ -132,7 +132,7 @@ Elements.scroll_table = Gui.define("scroll_table")
cell_padding = 1,
vertical_align = "center",
horizontally_stretchable = true,
- } --[[ @as any ]]
+ } --[[@as any]]
--- A container frame
--- @class Gui.elements.container: ExpElement
@@ -159,13 +159,13 @@ Elements.container = Gui.define("container")
vertically_stretchable = false,
horizontally_stretchable = false,
minimal_width = Gui.from_argument(1),
- } --[[ @as any ]]
+ } --[[@as any]]
--- Get the root element of a container
--- @param container LuaGuiElement
--- @return LuaGuiElement
function Elements.container.get_root_element(container)
- return container.parent
+ return assert(container.parent)
end
--- A frame within a container
@@ -183,7 +183,7 @@ Elements.subframe_base = Gui.define("container_subframe")
padding = { 3, 6, 0, 6 },
use_header_filler = false,
horizontally_stretchable = true,
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class Gui.elements.header.opts
--- @field name string?
@@ -212,7 +212,7 @@ Elements.header = Gui.define("container_header")
subframe.add{ type = "empty-widget" }.style.horizontally_stretchable = true
return subframe
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class Gui.elements.footer.opts
--- @field name string?
@@ -241,7 +241,7 @@ Elements.footer = Gui.define("container_footer")
subframe.add{ type = "empty-widget" }.style.horizontally_stretchable = true
return subframe
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A button used to destroy its target when clicked, intended for screen frames
--- @class Gui.elements.screen_frame_close: ExpElement
@@ -259,7 +259,7 @@ Elements.screen_frame_close = Gui.define("screen_frame_close")
:on_click(function(def, player, element, event)
--- @cast def Gui.elements.screen_frame_close
Gui.destroy_if_valid(def.data[element])
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A draggable frame with close button and button flow
--- @class Gui.elements.screen_frame: ExpElement
@@ -313,20 +313,20 @@ Elements.screen_frame = Gui.define("screen_frame")
direction = "vertical",
style = "inside_shallow_frame_packed",
}
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Get the button flow for a screen frame
--- @param screen_frame LuaGuiElement
--- @return LuaGuiElement
function Elements.screen_frame.get_button_flow(screen_frame)
- return assert(Elements.screen_frame.data[screen_frame.parent], "Screen frame has no button flow")
+ return (assert(Elements.screen_frame.data[assert(screen_frame.parent)], "Screen frame has no button flow"))
end
--- Get the root element of a screen frame
--- @param screen_frame LuaGuiElement
--- @return LuaGuiElement
function Elements.screen_frame.get_root_element(screen_frame)
- return screen_frame.parent
+ return assert(screen_frame.parent)
end
return Elements
diff --git a/exp_gui/module/iter.lua b/exp_gui/module/iter.lua
index 9d8db2ea..ad1d609c 100644
--- a/exp_gui/module/iter.lua
+++ b/exp_gui/module/iter.lua
@@ -166,7 +166,6 @@ end
function GuiIter.get_tracked_elements(scope, filter)
local class_name = ExpUtil.get_class_name(filter)
if class_name == "nil" then
- --- @cast filter nil
return GuiIter.all_elements(scope)
elseif class_name == "LuaPlayer" then
--- @cast filter LuaPlayer
@@ -189,7 +188,6 @@ end
function GuiIter.get_online_elements(scope, filter)
local class_name = ExpUtil.get_class_name(filter)
if class_name == "nil" then
- --- @cast filter nil
return GuiIter.filtered_elements(scope, game.connected_players)
elseif class_name == "LuaPlayer" then
--- @cast filter LuaPlayer
@@ -235,7 +233,7 @@ end
function GuiIter.remove_element(scope, player_index, element_index)
local scope_elements = registered_scopes[scope]
if not scope_elements then return end
- local player_elements = registered_scopes[player_index]
+ local player_elements = scope_elements[player_index]
if not player_elements then return end
player_elements[element_index] = nil
end
diff --git a/exp_gui/module/prototype.lua b/exp_gui/module/prototype.lua
index ea1e6a31..07890a2d 100644
--- a/exp_gui/module/prototype.lua
+++ b/exp_gui/module/prototype.lua
@@ -43,6 +43,8 @@ ExpElement.events = {}
--- @field _force_data ExpElement.PostDrawCallback?
--- @field _global_data ExpElement.PostDrawCallback?
--- @field _events table[]>
+--- @field _has_handlers boolean
+--- @field _track_elements boolean
--- @overload fun(parent: LuaGuiElement, ...: any): LuaGuiElement
ExpElement._prototype = {
_track_elements = false,
@@ -158,7 +160,7 @@ function ExpElement.new(name)
},
}
- ExpElement._elements[element_name] = instance --[[ @as ExpElement ]]
+ ExpElement._elements[element_name] = instance --[[@as ExpElement]]
return setmetatable(instance, ExpElement._metatable)
end
@@ -166,7 +168,7 @@ end
--- @param name string
--- @return ExpElement
function ExpElement.get(name)
- return assert(ExpElement._elements[name], "ExpElement is not defined: " .. tostring(name))
+ return (assert(ExpElement._elements[name], "ExpElement is not defined: " .. tostring(name)))
end
--- Create a new instance of this element definition
@@ -460,7 +462,7 @@ function ExpElement._prototype:raise_event(event)
for _, handler in ipairs(handlers) do
-- All gui elements will contain player and element, other events might have these as nil
-- Therefore only the signature of on_event has these values as optional
- handler(self, player --[[ @as LuaPlayer ]], event.element, event --[[ @as EventData ]])
+ handler(self, player --[[@as LuaPlayer]], event.element, event --[[@as EventData]])
end
end
diff --git a/exp_gui/module/styles.lua b/exp_gui/module/styles.lua
index ca04a907..b459d1c9 100644
--- a/exp_gui/module/styles.lua
+++ b/exp_gui/module/styles.lua
@@ -1,4 +1,4 @@
---- @class Gui
+--- @class (partial) Gui
local Gui = require("modules/exp_gui")
--- @class Gui.styles
diff --git a/exp_gui/module/toolbar.lua b/exp_gui/module/toolbar.lua
index 401d9bd6..e4a3ebe2 100644
--- a/exp_gui/module/toolbar.lua
+++ b/exp_gui/module/toolbar.lua
@@ -1,5 +1,5 @@
---- @class Gui
+--- @class (partial) Gui
local Gui = require("modules/exp_gui")
local ExpElement = require("modules/exp_gui/prototype")
local mod_gui = require("mod-gui")
@@ -29,7 +29,7 @@ Toolbar.on_gui_button_toggled = script.generate_event_name()
--- @class _ExpElement._prototype
--- @field on_button_toggled ExpElement.OnEventAdder
---- @diagnostic disable-next-line: invisible, inject-field
+--- @diagnostic disable-next-line: access-invisible, inject-field
function ExpElement._prototype.on_button_toggled(self, handler)
return self:on_event(Toolbar.on_gui_button_toggled, handler)
end
@@ -85,7 +85,7 @@ function Toolbar.set_button_toggled_state(define, player, state, _from_left)
button.style = state and toolbar_button_active_style or toolbar_button_default_style
-- Make the extra required adjustments
- local style = button.style
+ local style = button.style --[[@as LuaStyle]]
style.minimal_width = original_width
style.maximal_height = original_height
if button.type == "sprite-button" then
@@ -335,9 +335,10 @@ Below here is the toolbar settings GUI and its associated functions
--- @param dst LuaGuiElement
local function copy_style(src, dst)
dst.style = src.style.name
- dst.style.height = toolbar_button_small
- dst.style.width = toolbar_button_small
- dst.style.padding = -2
+ local style = dst.style --[[@as LuaStyle]]
+ style.height = toolbar_button_small
+ style.width = toolbar_button_small
+ style.padding = -2
end
--- Reorder the buttons relative to each other, this will update the datastore
@@ -350,7 +351,7 @@ local function move_toolbar_button(player, item, offset)
-- Swap the position in the list
local list = assert(item.parent)
- local other_item = list.children[new_index]
+ local other_item = assert(list.children[new_index])
list.swap_children(old_index, new_index)
-- Swap the position in the top flow, offset by 1 because of settings button
@@ -365,7 +366,7 @@ local function move_toolbar_button(player, item, offset)
local other_element = Gui.get_left_element(other_left_element, player)
local left_index = element.get_index_in_parent()
local other_index = other_element.get_index_in_parent()
- element.parent.swap_children(left_index, other_index)
+ assert(element.parent).swap_children(left_index, other_index)
end
-- If we are moving in/out of first/last place we need to update the move buttons
@@ -393,7 +394,7 @@ end
--- @param player LuaPlayer
--- @param order Gui.ToolbarOrder
function Toolbar.set_order(player, order)
- local list = elements.toolbar_settings.data[player] --[[ @as LuaGuiElement ]]
+ local list = elements.toolbar_settings.data[player] --[[@as LuaGuiElement]]
local left_flow = Gui.get_left_flow(player)
local top_flow = Gui.get_top_flow(player)
@@ -466,7 +467,7 @@ end
function Toolbar.get_state(player)
-- Get the order of toolbar buttons
local order = {}
- local list = elements.toolbar_settings.data[player] --[[ @as LuaGuiElement ]]
+ local list = elements.toolbar_settings.data[player] --[[@as LuaGuiElement]]
for index, item in pairs(list.children) do
order[index] = { name = item.name, favourite = elements.toolbar_list_item.data[item].set_favourite.state }
end
@@ -487,7 +488,7 @@ end
--- @param player LuaPlayer
function Toolbar._create_elements(player)
-- Add any missing items to the gui
- local toolbar_list = elements.toolbar_settings.data[player] --[[ @as LuaGuiElement ]]
+ local toolbar_list = elements.toolbar_settings.data[player] --[[@as LuaGuiElement]]
local previous_last_index = #toolbar_list.children_names
for define in pairs(Gui.top_elements) do
if define ~= elements.close_toolbar and toolbar_list[define.name] == nil then
@@ -499,7 +500,8 @@ function Toolbar._create_elements(player)
-- Reset the state of the previous last child
local children = toolbar_list.children
if previous_last_index > 0 then
- elements.toolbar_list_item.data[children[previous_last_index]].move_item_down.enabled = true
+ local previous_last = assert(children[previous_last_index])
+ elements.toolbar_list_item.data[previous_last].move_item_down.enabled = true
end
-- Set the state of the move buttons for the first and last element
@@ -513,7 +515,7 @@ end
--- @param player LuaPlayer
function Toolbar._ensure_consistency(player)
-- Update the toolbar buttons
- local list = elements.toolbar_settings.data[player] --[[ @as LuaGuiElement ]]
+ local list = elements.toolbar_settings.data[player] --[[@as LuaGuiElement]]
for _, button in ipairs(toolbar_buttons) do
-- Update the visible state based on if the player is allowed the button
local element = Gui.get_top_element(button, player)
@@ -619,7 +621,7 @@ elements.move_item_up = Gui.define("move_item_up")
size = toolbar_button_small,
})
:on_click(function(def, player, element)
- local item = assert(element.parent.parent)
+ local item = assert(assert(element.parent).parent)
move_toolbar_button(player, item, -1)
end)
@@ -634,7 +636,7 @@ elements.move_item_down = Gui.define("move_item_down")
size = toolbar_button_small,
})
:on_click(function(def, player, element)
- local item = assert(element.parent.parent)
+ local item = assert(assert(element.parent).parent)
move_toolbar_button(player, item, 1)
end)
@@ -658,7 +660,7 @@ elements.set_favourite = Gui.define("set_favourite")
width = 180,
}
:on_checked_state_changed(function(def, player, element)
- local define = ExpElement.get(element.tags.element_name --[[ @as string ]])
+ local define = ExpElement.get(element.tags.element_name --[[@as string]])
local top_element = Gui.get_top_element(define, player)
local had_visible = Toolbar.has_visible_buttons(player)
top_element.visible = element.state
diff --git a/exp_legacy/module/config/chat_reply.lua b/exp_legacy/module/config/chat_reply.lua
index 1321f96d..5eabb22d 100644
--- a/exp_legacy/module/config/chat_reply.lua
+++ b/exp_legacy/module/config/chat_reply.lua
@@ -24,6 +24,7 @@ local afk_time_units = {
}
return {
+ --- @type table
messages = { --- @setting messages will trigger when ever the word is said
["discord"] = { "info.discord" },
["expgaming"] = { "info.website" },
@@ -66,6 +67,7 @@ return {
command_admin_only = false, --- @setting command_admin_only when true will only allow chat commands for admins
command_permission = "command/chat-commands", --- @setting command_permission the permission used to allow command prefixes
command_prefix = "!", --- @setting command_prefix prefix used for commands below and to print to all players (if enabled above)
+ --- @type table
commands = { --- @setting commands will trigger only when command prefix is given
["dev"] = { "exp_chat-auto-reply.reply-dev" },
["magic"] = { "exp_chat-auto-reply.reply-magic" },
diff --git a/exp_legacy/module/config/gui/player_list_actions.lua b/exp_legacy/module/config/gui/player_list_actions.lua
index f692b47f..c6bb968c 100644
--- a/exp_legacy/module/config/gui/player_list_actions.lua
+++ b/exp_legacy/module/config/gui/player_list_actions.lua
@@ -15,7 +15,8 @@ local Colors = require("modules/exp_util/include/color")
local format_player_name = ExpUtil.format_player_name_locale
--- Accessors injected by the gui so the actions can read the selected player and set the selected action
-local get_selected_player, set_selected_action
+local get_selected_player --- @type fun(player: LuaPlayer): LuaPlayer
+local set_selected_action --- @type fun(player: LuaPlayer, action: string?)
local function set_accessors(player_getter, action_setter)
get_selected_player, set_selected_action = player_getter, action_setter
end
@@ -31,7 +32,7 @@ end
-- gets the action player and a coloured name for the action to be used on
local function get_action_player(player)
- local selected_player = get_selected_player(player) --[[ @as LuaPlayer ]]
+ local selected_player = get_selected_player(player) --[[@as LuaPlayer]]
local selected_player_color = format_player_name(selected_player)
return selected_player, selected_player_color
end
diff --git a/exp_legacy/module/config/spawn_area.lua b/exp_legacy/module/config/spawn_area.lua
index 70ffd243..6c228d1e 100644
--- a/exp_legacy/module/config/spawn_area.lua
+++ b/exp_legacy/module/config/spawn_area.lua
@@ -87,7 +87,7 @@ return {
amount = 4000,
size = { 26, 27 },
-- offset = {-64,-32}
- offset = { -64, -64 },
+ offset = { x = -64, y = -64 },
},
{
enabled = false,
@@ -95,7 +95,7 @@ return {
amount = 4000,
size = { 26, 27 },
-- offset = {-64, 0}
- offset = { 64, -64 },
+ offset = { x = 64, y = -64 },
},
{
enabled = false,
@@ -103,7 +103,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, 32}
- offset = { -64, 64 },
+ offset = { x = -64, y = 64 },
},
{
enabled = false,
@@ -111,7 +111,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, -64}
- offset = { 64, 64 },
+ offset = { x = 64, y = 64 },
},
{
enabled = false,
@@ -119,7 +119,7 @@ return {
amount = 4000,
size = { 22, 20 },
-- offset = {-64, -96}
- offset = { 0, 64 },
+ offset = { x = 0, y = 64 },
},
},
},
@@ -132,7 +132,7 @@ return {
num_patches = 4,
amount = 4000000,
-- offset = {-80, -12},
- offset = { -12, 64 },
+ offset = { x = -12, y = 64 },
-- offset_next = {0, 6}
offset_next = { 6, 0 },
},
diff --git a/exp_legacy/module/config/vlayer.lua b/exp_legacy/module/config/vlayer.lua
index d80ed827..c2e0761a 100644
--- a/exp_legacy/module/config/vlayer.lua
+++ b/exp_legacy/module/config/vlayer.lua
@@ -35,6 +35,20 @@ return {
storage_output = 1, -- >0 allows for item teleportation (allowed_items only)
},
+ --- @class Vlayer.ItemProperties
+ --- @field starting_value number
+ --- @field required_area number
+ --- @field production number?
+ --- @field discharge number?
+ --- @field capacity number?
+ --- @field surface_area number?
+ --- @field fuel_value number?
+ --- @field power boolean?
+ --- @field modded boolean? Set when the item is registered from a modded equivalent
+ --- @field base_game_equivalent string?
+ --- @field multiplier number?
+
+ --- @type table
allowed_items = { --- @setting allowed_items List of all items allowed in vlayer storage and their properties
--[[
Allowed properties:
diff --git a/exp_legacy/module/config/warnings.lua b/exp_legacy/module/config/warnings.lua
index e098dc2f..b60e003b 100644
--- a/exp_legacy/module/config/warnings.lua
+++ b/exp_legacy/module/config/warnings.lua
@@ -2,6 +2,7 @@
-- @config Warnings
return {
+ --- @type (LocalisedString[] | fun(player: LuaPlayer, by_player_name: string, number_of_warnings: number))[]
actions = { --- @setting actions what actions are taking at number of warnings
-- if a localized string is used then __1__ will by_player_name and __2__ will be the current warning count (auto inserted)
{ "warnings.received", "" },
diff --git a/exp_legacy/module/expcore/datastore.lua b/exp_legacy/module/expcore/datastore.lua
index 9d498787..08fe4de1 100644
--- a/exp_legacy/module/expcore/datastore.lua
+++ b/exp_legacy/module/expcore/datastore.lua
@@ -149,9 +149,23 @@ PlayerData.Statistics:combine('JoinCount')
local Storage = require("modules/exp_util/storage")
local DatastoreManager = {}
-local Datastores = {}
-local Datastore = {}
+local Datastores = {} --- @type table
local Data = {}
+
+--- @class Datastore
+--- @field name string
+--- @field value_name string
+--- @field auto_save boolean
+--- @field save_to_disk boolean
+--- @field propagate_changes boolean
+--- @field serializer function | false
+--- @field parent Datastore | false
+--- @field children table
+--- @field metadata table
+--- @field events table
+--- @field data table
+local Datastore = {}
+
local copy = table.deep_copy
local trace = debug.traceback
local table_to_json = helpers.table_to_json
diff --git a/exp_legacy/module/expcore/external.lua b/exp_legacy/module/expcore/external.lua
index f4065c53..be8fb078 100644
--- a/exp_legacy/module/expcore/external.lua
+++ b/exp_legacy/module/expcore/external.lua
@@ -14,7 +14,8 @@ end
]]
-local ext, var
+local ext --- @type table
+local var --- @type table
local concat = table.concat
local External = {}
@@ -29,12 +30,13 @@ end
]]
function External.valid()
- if storage.ext == nil then return false end
- if ext == storage.ext and var == ext.var then
+ local stored = storage.ext
+ if stored == nil then return false end
+ if ext == stored and var == ext.var then
return var ~= nil
else
- ext = storage.ext
- var = ext.var
+ ext = stored
+ var = stored.var
return var ~= nil
end
end
@@ -48,7 +50,7 @@ local servers = External.get_servers()
]]
function External.get_servers()
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
- return assert(ext.servers, "No server list was found, please ensure that the external service is running")
+ return (assert(ext.servers, "No server list was found, please ensure that the external service is running"))
end
--[[-- Gets a table of all the servers filtered by name, key is the server id, value is the server details
@@ -83,7 +85,7 @@ function External.get_current_server()
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
local server_id = assert(ext.current, "No current id was found, please ensure that the external service is running")
- return assert(servers[server_id], "No details found for server with id: " .. tostring(server_id))
+ return (assert(servers[server_id], "No details found for server with id: " .. tostring(server_id)))
end
--[[-- Gets the details of the given server
@@ -97,7 +99,7 @@ local server = External.get_server_details('eu-01')
function External.get_server_details(server_id)
assert(ext, "No external data was found, use External.valid() to ensure external data exists.")
local servers = assert(ext.servers, "No server list was found, please ensure that the external service is running")
- return assert(servers[server_id], "No details found for server with id: " .. tostring(server_id))
+ return (assert(servers[server_id], "No details found for server with id: " .. tostring(server_id)))
end
--[[-- Gets the status of the given server
diff --git a/exp_legacy/module/expcore/permission_groups.lua b/exp_legacy/module/expcore/permission_groups.lua
index b4477df5..35be0d9e 100644
--- a/exp_legacy/module/expcore/permission_groups.lua
+++ b/exp_legacy/module/expcore/permission_groups.lua
@@ -142,7 +142,7 @@ group:set_action('toggle_map_editor', false)
]]
function PermissionsGroups._prototype:set_action(action, state)
- local input_action = defines.input_action[action] --[[ @as defines.input_action? ]]
+ local input_action = defines.input_action[action] --[[@as defines.input_action?]]
if input_action == nil then input_action = action end
assert(type(input_action) == "number", tostring(action) .. " is not a valid input action")
self.actions[input_action] = state
diff --git a/exp_legacy/module/expcore/player_data.lua b/exp_legacy/module/expcore/player_data.lua
index b6862873..07318191 100644
--- a/exp_legacy/module/expcore/player_data.lua
+++ b/exp_legacy/module/expcore/player_data.lua
@@ -55,7 +55,7 @@ PlayerData:set_serializer(Datastore.name_serializer) -- use player name
--- Store and enum for the data saving preference
local DataSavingPreference = PlayerData:combine("DataSavingPreference")
-local PreferenceEnum = { "All", "Statistics", "Settings", "Required" }
+local PreferenceEnum = { "All", "Statistics", "Settings", "Required" } --- @type table
for k, v in ipairs(PreferenceEnum) do PreferenceEnum[v] = k end
DataSavingPreference:set_default("All")
diff --git a/exp_legacy/module/expcore/roles.lua b/exp_legacy/module/expcore/roles.lua
index b84875f2..641eeaea 100644
--- a/exp_legacy/module/expcore/roles.lua
+++ b/exp_legacy/module/expcore/roles.lua
@@ -117,11 +117,28 @@ local Groups = require("modules.exp_legacy.expcore.permission_groups")
local Colours = ExpUtil.color
local write_json = ExpUtil.write_json
+
+--- @class Roles.Role
+--- @field name string
+--- @field short_hand string
+--- @field index number Position within the role order
+--- @field allowed_actions table
+--- @field allow_all_actions boolean
+--- @field flags table
+--- @field disallowed_actions table?
+--- @field permission_group ([boolean, string] | string)?
+--- @field custom_tag string?
+--- @field custom_color Color?
+--- @field parent string?
+--- @field block_auto_assign boolean?
+--- @field auto_assign_condition function?
+--- @field set_allow_all fun(self: Roles.Role, state: boolean?): Roles.Role Defined on Roles._prototype
+
local Roles = {
_prototype = {},
config = {
- order = {}, -- Contains the order of the roles, lower index is better
- roles = {}, -- Contains the raw info for the roles, indexed by role name
+ order = {}, --- @type string[] Contains the order of the roles, lower index is better
+ roles = {}, --- @type table Contains the raw info for the roles, indexed by role name
flags = {}, -- Contains functions that run when a flag is added/removed from a player
internal = {}, -- Contains all internally accessed roles, such as root, default
players = {}, -- Contains the roles that players have
@@ -200,7 +217,7 @@ function Roles.debug()
local output = ""
for index, role_name in ipairs(Roles.config.order) do
local role = Roles.config.roles[role_name]
- local color = role.custom_color or Colours.white
+ local color = (role.custom_color or Colours.white) --[[@as Color.struct]]
local color_str = string.format("[color=%d, %d, %d]", color.r, color.g, color.b)
output = output .. string.format("\n%s %s) %s[/color]", color_str, index, serpent.line(role))
end
@@ -287,6 +304,7 @@ local role = Roles.get_role_by_name(2)
]]
function Roles.get_role_by_order(index)
local name = Roles.config.order[index]
+ if not name then return end
return Roles.config.roles[name]
end
@@ -348,16 +366,17 @@ end
local role = Roles.get_player_highest_role(game.player)
]]
+--- @return Roles.Role
function Roles.get_player_highest_role(player)
local roles = Roles.get_player_roles(player)
- local highest
+ local highest --- @type Roles.Role?
for _, role in ipairs(roles) do
if not highest or role.index < highest.index then
highest = role
end
end
- return highest
+ return (assert(highest, "Player has no roles"))
end
--- Assignment.
@@ -458,7 +477,7 @@ function Roles.unassign_player(player, roles, by_player_name, skip_checks, silen
-- If the player has a role that needs to defer the role changes, save the roles that need to be unassigned later into a table
local defer_changes = Roles.player_has_flag(player, "defer_role_changes")
- if defer_changes then
+ if defer_changes and valid_player then
local assign_later = Roles.config.deferred_roles[valid_player.name] or {}
for _, role in ipairs(role_objects) do
local role_change = assign_later[role.name]
@@ -719,7 +738,7 @@ local role = Roles.new_role('Moderator', 'Mod')
]]
function Roles.new_role(name, short_hand)
ExpUtil.assert_not_runtime()
- if Roles.config.roles[name] then return error("Role name is non unique") end
+ if Roles.config.roles[name] then error("Role name is non unique") end
local role = setmetatable({
name = name,
short_hand = short_hand or name,
@@ -894,10 +913,9 @@ role:set_permission_group('Admin')
function Roles._prototype:set_permission_group(name, use_factorio_api)
ExpUtil.assert_not_runtime()
if use_factorio_api then
- self.permission_group = { true, name }
+ self.permission_group = { true, name } --[[@as [boolean, string] ]]
else
- local group = Groups.get_group_by_name(name)
- if not group then return end
+ assert(Groups.get_group_by_name(name), "Permission group not found: " .. name)
self.permission_group = name
end
return self
@@ -1115,8 +1133,9 @@ local function role_update(event)
-- Updates the players permission group
local highest = Roles.get_player_highest_role(player)
if highest.permission_group then
- if highest.permission_group[1] then
- local group = game.permissions.get_group(highest.permission_group[2])
+ local permission_group = highest.permission_group --[[@as [boolean, string] ]]
+ if permission_group[1] then
+ local group = game.permissions.get_group(permission_group[2])
if group then
Groups.add_to_permission_group_async(group, player)
end
diff --git a/exp_legacy/module/modules/control/protection.lua b/exp_legacy/module/modules/control/protection.lua
index 79415756..506d889d 100644
--- a/exp_legacy/module/modules/control/protection.lua
+++ b/exp_legacy/module/modules/control/protection.lua
@@ -34,7 +34,7 @@ for _, config_key in ipairs{ "always_protected_names", "always_protected_types",
end
-- Require roles if a permission is assigned in the config
-local Roles
+local Roles --- @type table
if config.ignore_permission then
Roles = require("modules.exp_legacy.expcore.roles") --- @dep expcore.roles
end
diff --git a/exp_legacy/module/modules/control/spectate.lua b/exp_legacy/module/modules/control/spectate.lua
index 1c1d1c70..dc2784f8 100644
--- a/exp_legacy/module/modules/control/spectate.lua
+++ b/exp_legacy/module/modules/control/spectate.lua
@@ -4,7 +4,7 @@ local Gui = require("modules/exp_gui")
local Event = require("modules/exp_legacy/utils/event") --- @dep utils.event
----- Locals -----
-local follow_label -- Gui constructor
+local follow_label --- @type ExpElement Gui constructor
local following = {}
local spectating = {}
local Public = {}
diff --git a/exp_legacy/module/modules/control/vlayer.lua b/exp_legacy/module/modules/control/vlayer.lua
index 39346063..72afba6c 100644
--- a/exp_legacy/module/modules/control/vlayer.lua
+++ b/exp_legacy/module/modules/control/vlayer.lua
@@ -14,10 +14,10 @@ local mega = 1000000
local vlayer = {}
local vlayer_data = {
entity_interfaces = {
- energy = {},
- circuit = {},
- storage_input = {},
- storage_output = {},
+ energy = {}, --- @type LuaEntity[]
+ circuit = {}, --- @type LuaEntity[]
+ storage_input = {}, --- @type LuaEntity[]
+ storage_output = {}, --- @type LuaEntity[]
},
properties = {
total_surface_area = 0,
@@ -28,10 +28,10 @@ local vlayer_data = {
capacity = 0,
},
storage = {
- items = {},
- power_items = {},
+ items = {}, --- @type table
+ power_items = {}, --- @type table
energy = 0,
- unallocated = {},
+ unallocated = {}, --- @type table
},
surface = table.deep_copy(config.surface),
}
@@ -45,7 +45,7 @@ for name, properties in pairs(config.allowed_items) do
if properties.power then
vlayer_data.storage.power_items[name] = {
- value = properties.fuel_value * 1000000,
+ value = assert(properties.fuel_value) * 1000000,
count = 0,
}
end
@@ -361,7 +361,7 @@ local function handle_input_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.storage_input[index] = nil
else
- local inventory = interface.get_inventory(defines.inventory.chest)
+ local inventory = assert(interface.get_inventory(defines.inventory.chest))
for _, v in pairs(inventory.get_contents()) do
if config.allowed_items[v.name] then
@@ -384,8 +384,9 @@ local function handle_input_interfaces()
if count_deduct and count_add then
if config.allowed_items[v.name].modded then
+ local modded_item = assert(config.modded_items[v.name])
if config.modded_auto_downgrade then
- vlayer.insert_item(config.modded_items[v.name].base_game_equivalent, count_add * config.modded_items[v.name].multiplier)
+ vlayer.insert_item(modded_item.base_game_equivalent, count_add * modded_item.multiplier)
else
vlayer.insert_item(v.name, count_add)
end
@@ -439,14 +440,14 @@ local function handle_output_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.storage_output[index] = nil
else
- local inventory = interface.get_inventory(defines.inventory.chest)
- local inventory_request_sections = interface.get_logistic_sections().sections
+ local inventory = assert(interface.get_inventory(defines.inventory.chest))
+ local inventory_request_sections = assert(interface.get_logistic_sections()).sections
for i = 1, #inventory_request_sections do
for _, v in pairs(inventory_request_sections[i].filters) do
if v.value and config.allowed_items[v.value.name] then
local current_amount = inventory.get_item_count(v.value.name)
- local request_amount = math.min(v.min - current_amount, vlayer_data.storage.items[v.value.name])
+ local request_amount = math.min(assert(v.min) - current_amount, vlayer_data.storage.items[v.value.name])
if request_amount > 0 and inventory.can_insert{ name = v.value.name, count = request_amount } then
local removed_item_count = vlayer.remove_item(v.value.name, request_amount)
@@ -582,11 +583,11 @@ local function handle_circuit_interfaces()
if not interface.valid then
vlayer_data.entity_interfaces.circuit[index] = nil
else
- local circuit_oc = interface.get_or_create_control_behavior()
- if circuit_oc.sections_count == 0 then
- circuit_oc.add_section()
+ local control = interface.get_or_create_control_behavior() --[[@as LuaConstantCombinatorControlBehavior]]
+ if control.sections_count == 0 then
+ control.add_section()
end
- circuit_oc = circuit_oc.sections[1]
+ local circuit_oc = assert(control.sections[1])
local signal_index = 1
local circuit = vlayer.get_circuits()
@@ -617,7 +618,7 @@ local function handle_circuit_interfaces()
-- Clear remaining signals to prevent outdated values being present (caused by count > 0 check)
for clear_index = signal_index, #circuit do
- if not circuit_oc.get_slot(clear_index).signal then
+ if not circuit_oc.get_slot(clear_index).value then
break -- There are no more signals to clear
end
diff --git a/exp_legacy/module/modules/control/warnings.lua b/exp_legacy/module/modules/control/warnings.lua
index 628fc8d0..6a0fa116 100644
--- a/exp_legacy/module/modules/control/warnings.lua
+++ b/exp_legacy/module/modules/control/warnings.lua
@@ -107,7 +107,7 @@ function Warnings.add_warning(player, by_player_name, reason)
reason = reason or "None given."
- local warning_count
+ local warning_count --- @type number
PlayerWarnings:update(player.name, function(_, warnings)
local warning = {
by_player_name = by_player_name,
diff --git a/exp_legacy/module/modules/data/toolbar.lua b/exp_legacy/module/modules/data/toolbar.lua
index a714ae0b..177aba50 100644
--- a/exp_legacy/module/modules/data/toolbar.lua
+++ b/exp_legacy/module/modules/data/toolbar.lua
@@ -18,7 +18,7 @@ ToolbarState:on_load(function(player_name, value)
local decompressed = helpers.json_to_table(assert(helpers.decode_string(value), "Failed String Decode"))
local player = assert(game.get_player(player_name))
- Gui.toolbar.set_state(player, decompressed --[[ @as Gui.ToolbarState ]])
+ Gui.toolbar.set_state(player, decompressed --[[@as Gui.ToolbarState]])
return nil -- We don't save the state, use Gui.toolbar.get_state
end)
diff --git a/exp_legacy/module/modules/graftorio/forcestats.lua b/exp_legacy/module/modules/graftorio/forcestats.lua
index a515869a..195f2e4c 100644
--- a/exp_legacy/module/modules/graftorio/forcestats.lua
+++ b/exp_legacy/module/modules/graftorio/forcestats.lua
@@ -126,19 +126,19 @@ lib.collect_loginet = function()
end
if config.modules.logistorage then
- for name, v in pairs(network.get_contents()) do
- stats.items[name] = (stats.items[name] or 0) + v
+ for _, item in pairs(network.get_contents()) do
+ stats.items[item.name] = (stats.items[item.name] or 0) + item.count
end
-- pickups and deliveries of items
for _, point_list in pairs{ network.provider_points, network.requester_points, network.storage_points } do
for _, point in pairs(point_list) do
- for name, qty in pairs(point.targeted_items_pickup) do
- stats.pickups[name] = (stats.pickups[name] or 0) + qty
+ for _, item in pairs(point.targeted_items_pickup) do
+ stats.pickups[item.name] = (stats.pickups[item.name] or 0) + item.count
end
- for name, qty in pairs(point.targeted_items_deliver) do
- stats.deliveries[name] = (stats.deliveries[name] or 0) + qty
+ for _, item in pairs(point.targeted_items_deliver) do
+ stats.deliveries[item.name] = (stats.deliveries[item.name] or 0) + item.count
end
end
end
diff --git a/exp_legacy/module/modules/gui/_role_updates.lua b/exp_legacy/module/modules/gui/_role_updates.lua
index 75273b57..ac171b49 100644
--- a/exp_legacy/module/modules/gui/_role_updates.lua
+++ b/exp_legacy/module/modules/gui/_role_updates.lua
@@ -2,6 +2,6 @@ local Gui = require("modules/exp_gui")
local Roles = require("modules.exp_legacy.expcore.roles")
local Event = require("modules/exp_legacy/utils/event")
---- @diagnostic disable invisible
+--- @diagnostic disable: access-invisible
Event.add(Roles.events.on_role_assigned, Gui._ensure_consistency)
Event.add(Roles.events.on_role_unassigned, Gui._ensure_consistency)
diff --git a/exp_legacy/module/modules/gui/vlayer.lua b/exp_legacy/module/modules/gui/vlayer.lua
index a57f090a..727f9b9d 100644
--- a/exp_legacy/module/modules/gui/vlayer.lua
+++ b/exp_legacy/module/modules/gui/vlayer.lua
@@ -22,9 +22,9 @@ local function aabb_align_expand(aabb)
}
end
-local vlayer_container
-local vlayer_gui_control_type
-local vlayer_gui_control_list
+local vlayer_container --- @type ExpElement
+local vlayer_gui_control_type --- @type ExpElement
+local vlayer_gui_control_list --- @type ExpElement
local vlayer_control_type_list = {
[1] = "energy",
@@ -87,10 +87,10 @@ SelectArea:on_selection(function(event)
local container = Gui.get_left_element(vlayer_container, player)
local disp = container.frame["vlayer_st_2"].disp.table
local target = vlayer_control_type_list[disp[vlayer_gui_control_type.name].selected_index]
- local entities
+ local entities --- @type LuaEntity[]
if config.power_on_space and event.surface and event.surface.platform and target == "energy" then
- if player.force.technologies[config.power_on_space_research.name].level >= config.power_on_space_research.level then
+ if (player.force --[[@as LuaForce]]).technologies[config.power_on_space_research.name].level >= config.power_on_space_research.level then
entities = event.surface.find_entities_filtered{ area = area, name = "constant-combinator", force = player.force }
else
player.print{ "vlayer.power-on-space-research", config.power_on_space_research.name, config.power_on_space_research.level }
@@ -116,7 +116,7 @@ SelectArea:on_selection(function(event)
local e_pos = { x = string.format("%.1f", e.position.x), y = string.format("%.1f", e.position.y) }
local e_circ = nil -- e.get_wire_connectors{ or_create = false }
- if e.name and e.name == "steel-chest" and (not e.get_inventory(defines.inventory.chest).is_empty()) then
+ if e.name and e.name == "steel-chest" and (not assert(e.get_inventory(defines.inventory.chest)).is_empty()) then
player.print{ "vlayer.steel-chest-empty" }
return
end
@@ -325,7 +325,9 @@ local function vlayer_gui_list_refresh(player)
local interface = vlayer.get_interfaces()[vlayer_control_type_list[target]]
for i = 1, vlayer.get_interface_counts()[vlayer_control_type_list[target]], 1 do
- table.insert(full_list, i .. " X " .. interface[i].position.x .. " Y " .. interface[i].position.y)
+ local entity = assert(interface[i])
+ local entity_position = entity.position
+ table.insert(full_list, i .. " X " .. entity_position.x .. " Y " .. entity_position.y)
end
disp[vlayer_gui_control_list.name].items = full_list
@@ -379,14 +381,13 @@ local vlayer_gui_control_see = Gui.define("vlayer_gui_control_see")
}:style{
width = 200,
}:on_click(function(def, player, element, event)
- local target = element.parent[vlayer_gui_control_type.name].selected_index
- local n = element.parent[vlayer_gui_control_list.name].selected_index
+ local target = assert(element.parent)[vlayer_gui_control_type.name].selected_index
+ local n = assert(element.parent)[vlayer_gui_control_list.name].selected_index
if target and vlayer_control_type_list[target] and n > 0 then
local i = vlayer.get_interfaces()
local entity = i[vlayer_control_type_list[target]][n]
if entity and entity.valid then
- local player = Gui.get_player(event)
player.set_controller{ type = defines.controllers.remote, position = entity.position, surface = entity.surface }
player.print{ "vlayer.result-interface-location", { "vlayer.control-type-" .. vlayer_control_type_list[target]:gsub("_", "-") }, pos_to_gps_string(entity.position, entity.surface.name) }
end
@@ -423,14 +424,15 @@ local vlayer_gui_control_remove = Gui.define("vlayer_gui_control_remove")
}:style{
width = 200,
}:on_click(function(def, player, element)
- local target = element.parent[vlayer_gui_control_type.name].selected_index
- local n = element.parent[vlayer_gui_control_list.name].selected_index
+ local target = assert(element.parent)[vlayer_gui_control_type.name].selected_index
+ local n = assert(element.parent)[vlayer_gui_control_list.name].selected_index
if target and vlayer_control_type_list[target] and n > 0 then
local i = vlayer.get_interfaces()
if i and i[vlayer_control_type_list[target]] then
- local interface_type, interface_surface, interface_position = vlayer.remove_interface(i[vlayer_control_type_list[target]][n].surface, i[vlayer_control_type_list[target]][n].position)
+ local entity = assert(i[vlayer_control_type_list[target]][n])
+ local interface_type, interface_surface, interface_position = vlayer.remove_interface(entity.surface, entity.position)
if interface_type then
game.print{ "vlayer.interface-result", player.name, pos_to_gps_string(interface_position, interface_surface.name), { "vlayer.result-remove" }, { "vlayer.control-type-" .. interface_type } }
diff --git a/exp_legacy/module/modules/gui/warp-list.lua b/exp_legacy/module/modules/gui/warp-list.lua
index 39759287..15359dbc 100644
--- a/exp_legacy/module/modules/gui/warp-list.lua
+++ b/exp_legacy/module/modules/gui/warp-list.lua
@@ -180,7 +180,7 @@ local warp_icon_button = Gui.define("warp_icon_button")
:style(Styles.sprite32)
:on_click(function(def, player, element)
if element.type == "choose-elem-button" then return end
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
Warps.teleport_player(warp_id, player)
-- Reset the warp cooldown if the player does not have unlimited warps
@@ -226,7 +226,7 @@ local warp_label = Gui.define("warp_label")
horizontally_stretchable = true,
}
:on_click(function(def, player, element)
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
local warp = Warps.get_warp(warp_id)
player.set_controller{ type = defines.controllers.remote, position = warp.position, surface = warp.surface }
end)
@@ -271,9 +271,9 @@ local warp_textfield = Gui.define("warp_textfield")
right_margin = 2,
}
:on_confirmed(function(def, player, element)
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
local warp_name = element.text
- local warp_icon = element.parent.parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[ @as SignalID ]]
+ local warp_icon = assert(element.parent).parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[@as SignalID]]
if warp_icon.type == nil then warp_icon.type = "item" end
Warps.set_editing(warp_id, player.name)
Warps.update_warp(warp_id, warp_name, warp_icon, player.name)
@@ -291,9 +291,13 @@ local confirm_edit_button = Gui.define("confirm_edit_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
- local warp_id = element.parent.caption
- local warp_name = element.parent.parent["name-" .. warp_id][warp_textfield.name].text
- local warp_icon = element.parent.parent["icon-" .. warp_id][warp_icon_editing.name].elem_value --[[ @as SignalID ]]
+ local parent = assert(element.parent)
+ local grandparent = assert(parent.parent)
+ local warp_id = parent.caption --[[@as string]]
+ local name_flow = grandparent["name-" .. warp_id]
+ local icon_flow = grandparent["icon-" .. warp_id]
+ local warp_name = name_flow[warp_textfield.name].text
+ local warp_icon = icon_flow[warp_icon_editing.name].elem_value --[[@as SignalID]]
if warp_icon.type == nil then warp_icon.type = "item" end
Warps.set_editing(warp_id, player.name)
Warps.update_warp(warp_id, warp_name, warp_icon, player.name)
@@ -311,7 +315,7 @@ local cancel_edit_button = Gui.define("cancel_edit_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
-- Check if this is the first edit, if so remove the warp.
local warp = Warps.get_warp(warp_id)
if warp.updates == 1 then
@@ -333,7 +337,7 @@ local remove_warp_button = Gui.define("remove_warp_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
Warps.remove_warp(warp_id)
end)
@@ -349,7 +353,7 @@ local edit_warp_button = Gui.define("edit_warp_button")
}
:style(Styles.sprite22)
:on_click(function(def, player, element)
- local warp_id = element.parent.caption
+ local warp_id = assert(element.parent).caption
Warps.set_editing(warp_id, player.name, true)
end)
@@ -429,8 +433,8 @@ local function update_warp_elements(element, warp, warp_player_is_on, on_cooldow
-- Check if button element is valid
if not element or not element.valid then return end
- local label_style = element.parent.parent["name-" .. warp.warp_id][warp_label.name].style
- local warp_status_element = element.parent.parent["name-" .. warp.warp_id][warp_status.name]
+ local label_style = assert(element.parent).parent["name-" .. warp.warp_id][warp_label.name].style
+ local warp_status_element = assert(element.parent).parent["name-" .. warp.warp_id][warp_status.name]
-- If player is not on a warp
if not warp_player_is_on then
@@ -669,7 +673,7 @@ warp_list_container = Gui.define("warp_list_container")
-- Draw the scroll table for the warps
local scroll_table = Gui.elements.scroll_table(container, 250, 3, "scroll")
-- Set the scroll panel to always show the scrollbar (not doing this will result in a changing gui size)
- scroll_table.parent.vertical_scroll_policy = "always"
+ assert(scroll_table.parent).vertical_scroll_policy = "always"
-- Change the style of the scroll table
local scroll_table_style = scroll_table.style
@@ -778,7 +782,7 @@ Event.on_nth_tick(math.floor(60 / config.update_smoothing), function()
end
-- Check if the force has any warps
- local closest_warp = nil
+ local closest_warp = nil --- @type { warp_id: string, name: string }?
local closest_distance = nil
if #warp_ids > 0 then
local surface = player.surface
@@ -838,7 +842,7 @@ end)
Event.add(defines.events.on_player_created, function(event)
-- If the force has no spawn then make a spawn warp
local player = game.players[event.player_index]
- local force = player.force
+ local force = player.force --[[@as LuaForce]]
local spawn_id = Warps.get_spawn_warp_id(force.name)
if not spawn_id then
local spawn_position = force.get_spawn_position(player.surface)
@@ -870,7 +874,7 @@ local function role_update_event(event)
-- Check if user has permission to add warps
local allow_add_warp = check_player_permissions(player, "allow_add_warp")
-- Update container size depending on whether the player is allowed to add warps
- frame.parent.style.width = allow_add_warp and 268 or 220
+ assert(frame.parent).style.width = allow_add_warp and 268 or 220
-- Update the warps, in case the user can now edit them
local scroll_table = frame.scroll.table
diff --git a/exp_roles/module/control.lua b/exp_roles/module/control.lua
index 59b5696e..f0622a0b 100644
--- a/exp_roles/module/control.lua
+++ b/exp_roles/module/control.lua
@@ -12,7 +12,7 @@ made with `assign_player_local`.
]]
local clusterio_api = require("modules/clusterio/api")
-local compat = require("modules/clusterio/compat")
+local compat = require("modules/clusterio/compat") --[[@as LibCompat]]
local Async = require("modules/exp_util/async")
--- @class ExpRoles
@@ -284,7 +284,7 @@ local server_role = setmetatable({
--- @param player LuaPlayer | string | nil
--- @return ExpRoles.Role[]
function ExpRoles.get_player_roles(player)
- local player_name = type(player) == "table" and player.name or player --[[ @as string? ]]
+ local player_name = type(player) == "table" and player.name or player --[[@as string?]]
-- The server is not a player and is allowed to do anything
if player_name == nil then return { server_role } end
@@ -399,7 +399,7 @@ end
--- @param self ExpRoles.Role
--- @param action string
--- @return boolean
-function Role:is_allowed(action)
+function Role.is_allowed(self, action)
local allowed = self.allowed_actions
return allowed["core.admin"] or allowed[permission_from_action(action)] or false
end
@@ -408,7 +408,7 @@ end
--- @param self ExpRoles.Role
--- @param name string
--- @return boolean
-function Role:has_flag(name)
+function Role.has_flag(self, name)
return self.allowed_actions[permission_from_flag(name)] or false
end
@@ -416,7 +416,7 @@ end
--- @param self ExpRoles.Role
--- @param online boolean? When given, filter by connected state
--- @return LuaPlayer[]
-function Role:get_players(online)
+function Role.get_players(self, online)
local players = {}
for player_name, role_names in pairs(ExpRoles.config.players) do
for _, role_name in pairs(role_names) do
@@ -437,7 +437,7 @@ end
--- @param self ExpRoles.Role
--- @param message LocalisedString
--- @return number # Number of players the message was sent to
-function Role:print(message)
+function Role.print(self, message)
local players = self:get_players(true)
for _, player in pairs(players) do
player.print(message)
@@ -678,7 +678,7 @@ end
--- @param silent boolean?
--- @param sync boolean
local function change_player_roles(player, roles, change_type, by_player_name, silent, sync)
- local player_name = type(player) == "table" and player.name or player --[[ @as string? ]]
+ local player_name = type(player) == "table" and player.name or player --[[@as string?]]
if not player_name then return end
local role_objects = resolve_roles(roles)
diff --git a/exp_roles/module/events.lua b/exp_roles/module/events.lua
index 6537b5c1..12d8456d 100644
--- a/exp_roles/module/events.lua
+++ b/exp_roles/module/events.lua
@@ -9,7 +9,10 @@ had, and event_handler expects `events` to be the handlers to register.
local clusterio_api = require("modules/clusterio/api")
local ExpRoles = require("modules/exp_roles/control")
-return {
+--- @class ExpRoles.EventHandlers
+--- @field on_load fun()
+--- @field events table
+local handlers = {
on_load = ExpRoles.on_load,
events = {
[clusterio_api.events.on_server_startup] = ExpRoles.on_server_startup,
@@ -17,3 +20,5 @@ return {
[defines.events.on_player_joined_game] = ExpRoles.on_player_joined_game,
},
}
+
+return handlers
diff --git a/exp_roles/module/globals.lua b/exp_roles/module/globals.lua
index 10d74063..2a982c2e 100644
--- a/exp_roles/module/globals.lua
+++ b/exp_roles/module/globals.lua
@@ -4,7 +4,7 @@ However, sometimes you need globals, for example to access functions within rcon
Therefore, we advise that this should be the only file in your module to expose globals
]]
---- @diagnostic disable: global-element
+--- @diagnostic disable: global-in-non-module
-- Access using `/sc exp_roles.foo()`
exp_roles = require("modules/exp_roles/control")
diff --git a/exp_scenario/.luacheckrc b/exp_scenario/.luacheckrc
deleted file mode 100644
index 9b043265..00000000
--- a/exp_scenario/.luacheckrc
+++ /dev/null
@@ -1,1697 +0,0 @@
---[[----------------------------------------------------------------------------
- LICENSE
- .luacheckrc for Factorio Version 0.18.8, luacheck version 0.23.0
- This file is free and unencumbered software released into the public domain.
-
- Anyone is free to copy, modify, publish, use, compile, sell, or
- distribute this file, either in source code form or as a compiled
- binary, for any purpose, commercial or non-commercial, and by any
- means.
-
- In jurisdictions that recognize copyright laws, the author or authors
- of this file dedicate any and all copyright interest in the
- software to the public domain. We make this dedication for the benefit
- of the public at large and to the detriment of our heirs and
- successors. We intend this dedication to be an overt act of
- relinquishment in perpetuity of all present and future rights to this
- software under copyright law.
-
- THE FILE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- OTHER DEALINGS IN THE SOFTWARE.
-
- For more information, please refer to
-------------------------------------------------------------------------------]]
-local LINE_LENGTH = false
-
-local IGNORE = {'21./%w+_$', '21./^_%w+$', '213/[ijk]', '213/index', '213/key'}
-
--- These globals are not available to the factorio API
-local NOT_GLOBALS = {'coroutine', 'io', 'socket', 'dofile', 'loadfile'}
-
-local STD_CONTROL = 'lua52+factorio+factorio_control+stdlib+factorio_defines'
-local STD_DATA = 'lua52+factorio+factorio_data+stdlib+stdlib_data+factorio_defines'
-
--- For Base and Core Mods
-local STD_BASE_DATA = 'lua52+factorio+factorio_data+factorio_defines+factorio_base_data'
-local STD_BASE_CONTROL = 'lua52+factorio+factorio_control+factorio_defines+factorio_base_control'
-
-do -- Assume Factorio Control Stage as Default
- std = STD_CONTROL
- --cache = true
- not_globals = NOT_GLOBALS
- ignore = IGNORE
- quiet = 1 -- pass -q option
- max_cyclomatic_complexity = false
- codes = true
- max_line_length = LINE_LENGTH
- max_code_line_length = LINE_LENGTH
- max_string_line_length = LINE_LENGTH
- max_comment_line_length = LINE_LENGTH
-
- --List of files and directories to exclude
- exclude_files = {
- --Ignore special folders
- '**/.trash/',
- '**/.history/',
- '**/stdlib/vendor/',
-
- --Ignore development mods
- '**/combat-tester/',
- '**/test-maker/',
- '**/trailer/',
-
- --Ignore love Includes
- '**/love/includes/'
- }
-end
-
-do -- Set default prototype files
- files['**/data.lua'].std = STD_DATA
- files['**/data-updates.lua'].std = STD_DATA
- files['**/data-final-fixes.lua'].std = STD_DATA
- files['**/settings.lua'].std = STD_DATA
- files['**/settings-updates.lua'].std = STD_DATA
- files['**/settings-final-fixes.lua'].std = STD_DATA
- files['**/prototypes/'].std = STD_DATA
- files['**/settings/'].std = STD_DATA
-end
-
-do -- Base and Core mod files
- local base_scenarios = {
- std = STD_BASE_CONTROL .. '+factorio_base_scenarios+factorio_base_story',
- --ignore = {'212/event', '111', '112', '113', '211', '212', '213', '311', '411', '412', '421', '422', '423', '431', '432', '512'}
- ignore = {'...'}
- }
- files['**/base/scenarios/'] = base_scenarios
- files['**/base/tutorials/'] = base_scenarios
- files['**/base/campaigns/'] = base_scenarios
- files['**/wip-scenario/'] = base_scenarios
-
- files['**/base/migrations/'] = {std = STD_BASE_CONTROL}
-
- files['**/core/lualib/'] = {std = STD_BASE_CONTROL}
- files['**/core/lualib/util.lua'] = {globals = {'util', 'table'}, ignore = {'432/object'}}
- files['**/core/lualib/silo-script.lua'] = {globals = {'silo_script'}, ignore = {'4../player'}}
- files['**/core/lualib/production-score.lua'] = {globals = {'production_score', 'get_price_recursive'}, ignore = {'4../player'}}
- files['**/core/lualib/story*'] = {std = '+factorio_base_story', ignore = {'42./k', '42./filter'}}
- files['**/core/lualib/mod-gui.lua'] = {globals = {'mod_gui'}}
- files['**/core/lualib/camera.lua'] = {globals = {'camera'}}
- files['**/core/lualib/builder.lua'] = {globals = {'Builder', 'builder', 'action', 'down', 'right'}}
-
- files['**/core/lualib/bonus-gui-ordering/'] = {std = STD_BASE_DATA}
- files['**/core/lualib/dataloader.lua'] = {globals = {'data'}}
- files['**/core/lualib/circuit-connector-*'] = {std = STD_BASE_DATA..'+factorio_circuit_connector_generated'}
- files['**/core/lualib/bonus-gui-ordering.lua'] = {globals = {'bonus_gui_ordering'}}
-
- files['**/base/prototypes/'] = {std = STD_BASE_DATA}
- files['**/core/prototypes/'] = {std = STD_BASE_DATA}
- files['**/core/prototypes/noise-programs.lua'] = {ignore = {'212/x', '212/y', '212/tile', '212/map'}}
-end
-
-do -- Stdlib Files
- local stdlib_control = {
- std = 'lua52+factorio+factorio_control+stdlib+factorio_defines',
- max_line_length = LINE_LENGTH
- }
-
- local stdlib_data = {
- std = 'lua52+factorio+factorio_data+stdlib+factorio_defines',
- max_line_length = LINE_LENGTH
- }
-
- -- Assume control stage for stdlib
- files['**/stdlib/'] = stdlib_control
-
- -- Assume generic lua for stdlib utils
- files['**/stdlib/utils/**'].std = 'lua52+stdlib'
-
- -- STDLIB data stage files
- files['**/stdlib/data/'] = stdlib_data
-
- -- STDLIB Busted Spec
- files['**/spec/**'] = {
- globals = {'serpent', 'log', 'package.remove_stdlib'},
- std = 'lua52c+busted+factorio_defines+factorio_control+stdlib'
- }
-
- -- Love
- files['**/love/'].std = 'luajit+love+love_extra+stdlib+stdlib_data'
-end
-
-do -- Factorio STDs--
- stds.factorio = {
- --Set the read only variables
- read_globals = {
- -- @log@: Gives writing access to Factorio's logger instance.
- "log",
- -- @serpent@: Lua serializer and pretty printer. (https://github.com/pkulchenko/serpent).
- "serpent",
- -- @table_size@: Returns the number of elements inside an LUA table.
- "table_size",
- -- @lldebugger@: Provided by lua local debugger vscode extension.
- lldebugger = {
- fields = {'requestBreak'},
- other_fields = true,
- read_only = false,
- },
- -- @__DebugAdapter@: Provided by Factorio Mod Debug vscode extension.
- __DebugAdapter = {
- fields = {'print', 'stepIgnoreAll', 'stepIgnore', 'breakpoint'},
- other_fields = true,
- read_only = false
- },
- util = {
- fields = {
- "by_pixel", "distance", "findfirstentity", "positiontostr", "formattime", "moveposition", "oppositedirection",
- "ismoduleavailable", "multiplystripes", "format_number", "increment", "color", "conditional_return",
- "add_shift", "merge", "premul_color", "encode", "decode", "insert_safe",
- table = {
- fields = {
- "compare", "deepcopy"
- },
- },
- },
- },
- table = {
- fields = {
- "compare", "deepcopy"
- },
- },
- },
- }
-
- stds.factorio_control = {
- read_globals = {
-
- -- @commands@:
- commands = {
- fields = {
- "add_command", "commands", "game_commands", "remove_command"
- },
- },
-
- -- @settings@:
- settings = {
- fields = {
- "get_player_settings",
- startup = {other_fields = true},
- global = {other_fields = true},
- player = {other_fields = true},
- get = {read_only = false}, -- stdlib added
- get_startup = {read_only = false} -- stdlib added
- },
- },
-
- -- @script@: Provides an interface for registering event handlers.
- -- (http://lua-api.factorio.com/latest/LuaBootstrap.html)
- script = {
- fields = {
- "on_event", "on_nth_tick", "on_configuration_changed", "on_init", "on_load", "generate_event_name",
- "raise_event", "get_event_handler", "mod_name", "get_event_order",
- "is_game_in_debug_mode", "object_name", "set_event_filter", "get_event_filter", "register_metatable",
- active_mods = {read_only = true, other_fields = true},
- },
- other_fields = false,
- },
-
- -- @remote@: Allows inter-mod communication by providing a repository of interfaces that is shared by all mods.
- -- (http://lua-api.factorio.com/latest/LuaRemote.html)
- remote = {
- fields = {
- interfaces = {read_only = false, other_fields = true},
- "add_interface", "remove_interface", "call"
- },
- read_only = true,
- other_fields = false,
- },
-
- rcon = {
- fields = {'print'}
- },
-
- rendering = {
- other_fields = false,
- read_only = true,
- fields = {
- 'draw_animation',
- 'draw_line',
- 'draw_text',
- 'draw_circle',
- 'draw_rectangle',
- 'draw_arc',
- 'draw_polygon',
- 'draw_sprite',
- 'draw_light',
- 'destroy',
- 'is_font_valid',
- 'is_valid',
- 'get_all_ids',
- 'clear',
- 'get_type',
- 'get_surface',
- 'get_time_to_live',
- 'set_time_to_live',
- 'get_forces',
- 'set_forces',
- 'get_players',
- 'set_players',
- 'get_color',
- 'set_color',
- 'get_width',
- 'set_width',
- 'get_from',
- 'set_from',
- 'get_to',
- 'set_to',
- 'get_gap_amount',
- 'set_gap_amount',
- 'get_gap_length',
- 'set_gap_length',
- 'get_target',
- 'set_target',
- 'get_orientation',
- 'set_orientation',
- 'get_scale',
- 'set_scale',
- 'get_text',
- 'set_text',
- 'get_font',
- 'set_font',
- 'get_alignment',
- 'set_alignment',
- 'get_scale_with_zoom',
- 'set_scale_with_zoom',
- 'get_filled',
- 'set_filled',
- 'get_radius',
- 'set_radius',
- 'get_left_top',
- 'set_left_top',
- 'get_right_bottom',
- 'set_right_bottom',
- 'get_max_radius',
- 'set_max_radius',
- 'get_min_radius',
- 'set_min_radius',
- 'get_start_angle',
- 'set_start_angle',
- 'get_angle',
- 'set_angle',
- 'get_vertices',
- 'set_vertices',
- 'get_sprite',
- 'set_sprite',
- 'get_x_scale',
- 'set_x_scale',
- 'get_y_scale',
- 'set_y_scale',
- 'get_render_layer',
- 'set_render_layer',
- 'get_orientation_target',
- 'set_orientation_target',
- 'get_oriented_offset',
- 'set_oriented_offset',
- 'get_intensity',
- 'set_intensity',
- 'get_minimum_darkness',
- 'set_minimum_darkness'
- }
- },
-
- -- @game@: Main object through which most of the API is accessed.
- -- It is, however, not available inside handlers registered with @script.on_load@.
- -- (http://lua-api.factorio.com/latest/LuaGameScript.html)
- game ={
- other_fields = false,
- read_only = false,
- fields = {
- 'auto_save',
- 'ban_player',
- 'check_consistency',
- 'check_prototype_translations',
- 'count_pipe_groups',
- 'create_force',
- 'create_profiler',
- 'create_random_generator',
- 'create_surface',
- 'decode_string',
- 'delete_surface',
- 'direction_to_string',
- 'disable_replay',
- 'disable_tips_and_tricks',
- 'disable_tutorial_triggers',
- 'encode_string',
- 'evaluate_expression',
- 'force_crc',
- 'get_active_entities_count',
- 'get_entity_by_tag',
- 'get_filtered_achievement_prototypes',
- 'get_filtered_decorative_prototypes',
- 'get_filtered_entity_prototypes',
- 'get_filtered_equipment_prototypes',
- 'get_filtered_fluid_prototypes',
- 'get_filtered_item_prototypes',
- 'get_filtered_mod_setting_prototypes',
- 'get_filtered_recipe_prototypes',
- 'get_filtered_technology_prototypes',
- 'get_filtered_tile_prototypes',
- 'get_map_exchange_string',
- 'get_player',
- 'get_surface',
- 'get_train_stops',
- 'help',
- 'is_demo',
- 'is_multiplayer',
- 'is_valid_sound_path',
- 'is_valid_sprite_path',
- 'json_to_table',
- 'kick_player',
- 'log_recipe_locale',
- 'merge_forces',
- 'mute_player',
- 'parse_map_exchange_string',
- 'play_sound',
- 'print',
- 'print_stack_size',
- 'purge_player',
- 'regenerate_entity',
- 'reload_mods',
- 'reload_script',
- 'remove_offline_players',
- 'remove_path',
- 'reset_time_played',
- 'save_atlas',
- 'server_save',
- 'set_game_state',
- 'set_wait_for_screenshots_to_finish',
- 'show_message_dialog',
- 'table_to_json',
- 'take_screenshot',
- 'take_technology_screenshot',
- 'unban_player',
- 'unmute_player',
- 'write_file',
-
- achievement_prototypes = {read_only = true, other_fields = true},
- active_mods = {read_only = true, other_fields = true},
- ammo_category_prototypes = {read_only = true, other_fields = true},
- autoplace_control_prototypes = {read_only = true, other_fields = true},
- backer_names = {read_only = true, other_fields = true},
- connected_players = {read_only = true, other_fields = true},
- custom_input_prototypes = {read_only = true, other_fields = true},
- damage_prototypes = {read_only = true, other_fields = true},
- decorative_prototypes = {read_only = true, other_fields = true},
- default_map_gen_settings = {read_only = true, other_fields = true},
- difficulty = {read_only = true, other_fields = true},
- difficulty_settings = {read_only = true, other_fields = true},
- entity_prototypes = {read_only = true, other_fields = true},
- equipment_category_prototypes = {read_only = true, other_fields = true},
- equipment_grid_prototypes = {read_only = true, other_fields = true},
- equipment_prototypes = {read_only = true, other_fields = true},
- finished = {read_only = true, other_fields = true},
- fluid_prototypes = {read_only = true, other_fields = true},
- forces = {read_only = true, other_fields = true},
- fuel_category_prototypes = {read_only = true, other_fields = true},
- item_group_prototypes = {read_only = true, other_fields = true},
- item_prototypes = {read_only = true, other_fields = true},
- item_subgroup_prototypes = {read_only = true, other_fields = true},
- map_settings = {read_only = true, other_fields = true},
- mod_setting_prototypes = {read_only = true, other_fields = true},
- module_category_prototypes = {read_only = true, other_fields = true},
- named_noise_expressions = {read_only = true, other_fields = true},
- noise_layer_prototypes = {read_only = true, other_fields = true},
- object_name = {read_only = true, other_fields = true},
- particle_prototypes = {read_only = true, other_fields = true},
- permissions = {read_only = true, other_fields = true},
- player = {read_only = true, other_fields = true},
- players = {read_only = true, other_fields = true},
- pollution_statistics = {read_only = true, other_fields = true},
- recipe_category_prototypes = {read_only = true, other_fields = true},
- recipe_prototypes = {read_only = true, other_fields = true},
- resource_category_prototypes = {read_only = true, other_fields = true},
- shortcut_prototypes = {read_only = true, other_fields = true},
- styles = {read_only = true, other_fields = true},
- surfaces = {read_only = true, other_fields = true},
- technology_prototypes = {read_only = true, other_fields = true},
- tick = {read_only = true, other_fields = true},
- ticks_played = {read_only = true, other_fields = true},
- tile_prototypes = {read_only = true, other_fields = true},
- trivial_smoke_prototypes = {read_only = true, other_fields = true},
- virtual_signal_prototypes = {read_only = true, other_fields = true},
-
- autosave_enabled = {read_only = false, other_fields = false},
- draw_resource_selection = {read_only = false, other_fields = false},
- enemy_has_vision_on_land_mines = {read_only = false, other_fields = false},
- speed = {read_only = false, other_fields = false},
- tick_paused = {read_only = false, other_fields = false},
- ticks_to_run = {read_only = false, other_fields = false}
- },
- },
- },
-
- globals = {
- -- @global@: The global dictionary, useful for storing data persistent across a save-load cycle.
- -- Writing access is given to the mod-id field (for mod-wise saved data).
- -- (http://lua-api.factorio.com/latest/Global.html)
- "global",
-
- -- @MOD@: Keep it organized, use this variable for anything that "NEEDS" to be global for some reason.
- "MOD"
- },
- }
-
- stds.factorio_data = {
-
- read_globals = {
- data = {
- fields = {
- raw = {
- other_fields = true,
- read_only = false
- },
- "extend", "is_demo"
- },
- },
-
- settings = {
- fields = {
- "startup", "global", "player", "get", "get_startup"
- },
- },
-
- mods = {
- other_fields = true
- },
-
- -- Popular mods that think they need globals!
- angelsmods = {
- other_fields = true
- },
-
- -- Popular mods that think they need globals!
- bobmods = {
- other_fields = true
- },
-
-
- }
- }
-end
-
-do -- Factorio Base/Core STDs--
- stds.factorio_base_control = {
- read_globals = {"silo_script", "mod_gui", "camera"}
- }
-
- stds.factorio_base_scenarios = {
- globals = {
- "check_automate_science_packs_advice", "check_research_hints", "check_supplies", "manage_attacks", "all_dead",
- "on_win", "difficulty_number", "init_attack_data", "handle_attacks", "count_items_in_container", "progress", "scanned",
- "check_light", "check_machine_gun", "level", "story_table",
-
- "tightspot_prices", "tightspot_make_offer", "tightspot_init", "tightspot_get_required_balance",
- "tightspot_init_level", "tightspot_init_spending_frame", "tightspot_init_progress_frame", "tightspot_update_progress", "tightspot_update_spending",
- "tightspot_get_missing_to_win", "tightspot_sell_back", "tightspot_start_level", "tightspot_show_level_description", "tightspot_update_speed_label",
- "map_ignore", "tightspot_check_level", "land_price",
-
- "transport_belt_madness_init", "transport_belt_madness_init_level", "transport_belt_madness_create_chests", "transport_belt_madness_fill_chests",
- "transport_belt_madness_start_level", "map_ignore", "map_clear", "map_load", "map_save", "transport_belt_madness_show_level_description",
- "transport_belt_madness_check_level", "transport_belt_madness_next_level", "transport_belt_madness_clear_level", "transport_belt_madness_contains_next_level",
-
- "restricted", "check_built_items", "result", "disable_combat_technologies", "apply_character_modifiers", "apply_combat_modifiers", "apply_balance",
- "load_config", "starting_area_constant", "create_next_surface", "end_round", "prepare_next_round", "silo_died","choose_joining_gui",
- "destroy_joining_guis", "create_random_join_gui", "create_auto_assign_gui", "create_pick_join_gui", "create_config_gui", "make_config_table", "default",
- "make_team_gui", "make_team_gui_config", "add_team_button_press", "trash_team_button_press", "remove_team_from_team_table", "add_team_to_team_table",
- "set_teams_from_gui", "on_team_button_press", "make_color_dropdown", "create_balance_option", "create_disable_frame", "disable_frame", "parse_disabled_items",
- "set_balance_settings", "config_confirm", "parse_config_from_gui", "get_color", "roll_starting_area", "delete_roll_surfaces", "auto_assign",
- "destroy_config_for_all", "prepare_map", "set_evolution_factor", "update_players_on_team_count", "random_join", "init_player_gui",
- "destroy_player_gui", "objective_button_press", "admin_button_press", "admin_frame_button_press", "diplomacy_button_press", "update_diplomacy_frame",
- "diplomacy_frame_button_press", "team_changed_diplomacy", "diplomacy_check_press", "get_stance", "give_inventory", "setup_teams", "disable_items_for_all",
- "set_random_team", "set_diplomacy", "create_spawn_positions", "set_spawn_position", "set_team_together_spawns", "chart_starting_area_for_force_spawns",
- "check_starting_area_chunks_are_generated", "check_player_color", "check_round_start", "clear_starting_area_enemies", "check_no_rush_end", "check_no_rush_players",
- "finish_setup", "chart_area_for_force", "setup_start_area_copy", "update_copy_progress", "update_progress_bar", "copy_paste_starting_area_tiles",
- "copy_paste_starting_area_entities", "create_silo_for_force", "setup_research", "on_chunk_generated", "get_distance_to_nearest_spawn",
- "create_wall_for_force", "fpn", "give_items", "create_item_frame", "create_technologies_frame", "create_cheat_frame", "create_day_frame",
- "time_modifier", "points_per_second_start", "points_per_second_level_subtract", "levels", "update_info", "get_time_left", "update_time_left",
- "on_joined", "make_frame", "update_frame", "update_table", "calculate_task_item_multiplayer", "setup_config", "select_from_probability_table",
- "select_inventory", "select_equipment", "select_challange_type", "save_round_statistics", "start_challenge", "create_teams", "set_areas",
- "decide_player_team", "set_teams", "refresh_leaderboard", "set_player", "generate_technology_list", "generate_research_task","setup_unlocks",
- "check_technology_progress", "generate_production_task", "generate_shopping_list_task", "set_gui_flow_table", "create_visibility_button",
- "check_item_lists", "update_task_gui", "check_end_of_round", "end_round_gui_update", "try_to_check_victory", "update_gui", "check_start_round",
- "check_start_set_areas", "check_start_setting_entities", "check_set_areas", "check_clear_areas", "check_chests", "check_chests_shopping_list",
- "check_chests_production", "check_input_chests", "fill_input_chests", "check_victory", "shopping_task_finished", "calculate_force_points",
- "update_research_task_table", "update_production_task_table", "update_shopping_list_task_table", "create_joined_game_gui", "pre_ending_round",
- "player_ending_prompt", "update_end_timer", "update_begin_timer", "team_finished", "save_points_list", "give_force_players_points",
- "update_winners_list", "set_spectator", "set_character", "give_starting_inventory", "give_equipment", "shuffle_table", "format_time",
- "spairs", "fill_leaderboard", "create_grid", "simple_entities", "save_map_data", "clear_map", "create_tiles", "recreate_entities",
- "map_sets", "give_points", "init_forces", "init_globals", "init_unit_settings", "check_next_wave", "next_wave", "calculate_wave_power",
- "wave_end", "make_next_spawn_tick", "check_spawn_units", "get_wave_units", "spawn_units", "randomize_ore", "set_command", "command_straglers",
- "unit_config", "make_next_wave_tick", "time_to_next_wave", "time_to_wave_end", "rocket_died", "unit_died", "get_bounty_price", "setup_waypoints",
- "insert_items", "give_starting_equipment", "give_spawn_equipment", "next_round_button_visible", "gui_init", "create_wave_frame", "create_money_frame",
- "create_upgrade_gui", "update_upgrade_listing", "upgrade_research", "get_upgrades", "get_money", "update_connected_players", "update_round_number",
- "set_research", "set_recipes", "check_deconstruction", "check_blueprint_placement", "loop_entities", "experiment_items",
- "setup", "story_gui_click", "clear_surface", "add_run_trains_button", "puzzle_condition", "basic_signals",
- "loop_trains", "Y_offset", "ghosts_1", "ghosts_2", "required_path", "through_wall_path", "count", "check_built_real_rail",
- "current_ghosts_count", "other", "rails", "set_rails", "straight_section", "late_entities", "entities", "stop",
- "get_spawn_coordinate",
-
- --tutorials
- "intermission", "create_entities_on_tick", "on_player_created", "required_count", "non_player_entities", "clear_rails",
- "chest", "damage", "furnace", "init_prototypes", "build_infi_table", "junk", "update_player_tags", "time_left", "team_production",
- "create_task_frame", "create_visibilty_buttons", "update_leaderboard", "in_in_area"
- }
- }
-
- stds.factorio_base_data = {
- globals = {
- --Style
- "make_cursor_box", "make_full_cursor_box",
- "default_container_padding", "default_orange_color", "default_light_orange_color", "warning_red_color",
- "achievement_green_color", "achievement_tan_color", "orangebuttongraphcialset", "bluebuttongraphcialset",
- "bonus_gui_ordering", "trivial_smoke", "technology_slot_base_width", "technology_slot_base_height", "default_frame_font_vertical_compensation",
-
- --Belts
- "transport_belt_connector_frame_sprites", "transport_belt_circuit_wire_connection_point", "transport_belt_circuit_wire_max_distance",
- "transport_belt_circuit_connector_sprites", "ending_patch_prototype", "basic_belt_horizontal", "basic_belt_vertical",
- "basic_belt_ending_top", "basic_belt_ending_bottom", "basic_belt_ending_side", "basic_belt_starting_top", "basic_belt_starting_bottom",
- "basic_belt_starting_side", "fast_belt_horizontal", "fast_belt_vertical", "fast_belt_ending_top", "fast_belt_ending_bottom",
- "fast_belt_ending_side", "fast_belt_starting_top", "fast_belt_starting_bottom", "fast_belt_starting_side", "express_belt_horizontal",
- "express_belt_vertical", "express_belt_ending_top", "express_belt_ending_bottom", "express_belt_ending_side", "express_belt_starting_top",
- "express_belt_starting_bottom", "express_belt_starting_side",
-
- --Circuit Connectors
- "circuit_connector_definitions", "default_circuit_wire_max_distance", "inserter_circuit_wire_max_distance",
- "universal_connector_template", "belt_connector_template", "belt_frame_connector_template", "inserter_connector_template",
-
- --Inserter Circuit Connectors
- "inserter_circuit_wire_max_distance", "inserter_default_stack_control_input_signal",
-
- --Sounds/beams
- "make_heavy_gunshot_sounds", "make_light_gunshot_sounds", "make_laser_sounds",
-
- --Gun/Laser
- "gun_turret_extension", "gun_turret_extension_shadow", "gun_turret_extension_mask", "gun_turret_attack",
- "laser_turret_extension", "laser_turret_extension_shadow", "laser_turret_extension_mask",
-
- --Pipes
- "pipecoverspictures", "pipepictures", "assembler2pipepictures", "assembler3pipepictures", "make_heat_pipe_pictures",
-
- --Combinators
- "generate_arithmetic_combinator", "generate_decider_combinator", "generate_constant_combinator",
-
- --Rail
- "destroyed_rail_pictures", "rail_pictures", "rail_pictures_internal", "standard_train_wheels", "drive_over_tie",
- "rolling_stock_back_light", "rolling_stock_stand_by_light",
-
- --Enemies
- "make_enemy_autoplace", "make_enemy_spawner_autoplace", "make_enemy_worm_autoplace",
- "make_spitter_attack_animation", "make_spitter_run_animation", "make_spitter_dying_animation",
- "make_spitter_attack_parameters", "make_spitter_roars", "make_spitter_dying_sounds",
- "make_spawner_idle_animation", "make_spawner_die_animation",
- "make_biter_run_animation", "make_biter_attack_animation", "make_biter_die_animation",
- "make_biter_roars", "make_biter_dying_sounds", "make_biter_calls",
- "make_worm_roars", "make_worm_dying_sounds", "make_worm_folded_animation", "make_worm_preparing_animation",
- "make_worm_prepared_animation", "make_worm_attack_animation", "make_worm_die_animation",
-
- --Other
- "tile_variations_template", "make_water_autoplace_settings",
- "make_unit_melee_ammo_type", "make_trivial_smoke", "make_4way_animation_from_spritesheet", "flying_robot_sounds",
- "productivitymodulelimitation", "crash_trigger", "capsule_smoke", "make_beam", "playeranimations",
- "make_blood_tint", "make_shadow_tint",
-
- --tiles
- "water_transition_template", "make_water_transition_template", "water_autoplace_settings", "water_tile_type_names",
- "patch_for_inner_corner_of_transition_between_transition",
- }
- }
-
- stds.factorio_base_story = {
- globals = {
- "story_init_helpers", "story_update_table", "story_init", "story_update", "story_on_tick", "story_add_update",
- "story_remove_update", "story_jump_to", "story_elapsed", "story_elapsed_check", "story_show_message_dialog",
- "set_goal", "player_set_goal", "on_player_joined", "flash_goal", "set_info", "player_set_info", "export_entities",
- "list", "recreate_entities", "entity_to_connect", "limit_camera", "find_gui_recursive", "enable_entity_export",
- "add_button", "on_gui_click", "set_continue_button_style", "add_message_log", "story_add_message_log",
- "player_add_message_log", "message_log_frame", "message_log_scrollpane", "message_log_close_button",
- "message_log_table", "toggle_message_log_button", "toggle_objective_button", "message_log_init",
- "add_gui_recursive", "add_toggle_message_log_button", "add_toggle_objective_button", "mod_gui",
- "flash_message_log_button", "flash_message_log_on_tick", "story_gui_click", "story_points_by_name", "story_branches",
- "player", "surface", "deconstruct_on_tick", "recreate_entities_on_tick", "flying_congrats", "story_table"
- }
- }
-
- stds.factorio_circuit_connector_generated = {
- globals = {
- 'default_circuit_wire_max_distance', 'circuit_connector_definitions', 'universal_connector_template',
- 'belt_connector_template', 'belt_frame_connector_template', 'inserter_connector_template', 'inserter_connector_template',
- 'inserter_circuit_wire_max_distance', 'inserter_default_stack_control_input_signal', 'transport_belt_connector_frame_sprites',
- 'transport_belt_circuit_wire_max_distance',
- }
- }
-end
-
-do -- STDLIB STDs--
- stds.stdlib = {
- read_globals = {},
- globals = {
- 'STDLIB',
- 'prequire',
- 'rawtostring',
- 'traceback',
- 'data_traceback',
- 'inspect',
- 'serpent',
- 'inline_if',
- 'install',
- 'log',
- 'concat',
- 'GAME',
- 'AREA',
- 'POSITION',
- 'TILE',
- 'SURFACE',
- 'CHUNK',
- 'COLOR',
- 'ENTITY',
- 'INVENTORY',
- 'RESOURCE',
- 'CONFIG',
- 'LOGGER',
- 'QUEUE',
- 'EVENT',
- 'GUI',
- 'PLAYER',
- 'FORCE',
- 'MATH',
- 'STRING',
- 'TABLE'
- }
- }
-
- stds.stdlib_control = {}
-
- stds.stdlib_data = {
- globals = {
- 'DATA',
- 'RECIPE',
- 'ITEM',
- 'FLUID',
- 'ENTITY',
- 'TECHNOLOGY',
- 'CATEGORY'
- }
- }
-end
-
-do -- Love STDs
- stds.love_extra = {
- read_globals = {
- love = {
- fields = {
- arg = {
- fields = {
- 'parseGameArguments',
- 'parseOption',
- 'getLow',
- 'optionIndices',
- 'options'
- }
- }
- }
- },
- 'coroutine',
- 'io',
- 'socket',
- 'dofile',
- 'loadfile'
- },
- globals = {
- love = {
- fields = {
- 'handlers'
- }
- }
- }
- }
-end
-
-do -- Factorio Defines STDs--
- stds.factorio_defines = {
- read_globals = {
- defines = {
- fields = {
- alert_type = {
- fields = {
- 'entity_destroyed',
- 'entity_under_attack',
- 'not_enough_construction_robots',
- 'no_material_for_construction',
- 'not_enough_repair_packs',
- 'turret_fire',
- 'custom',
- 'no_storage',
- 'train_out_of_fuel',
- 'fluid_mixing'
- }
- },
- behavior_result = {
- fields = {
- 'in_progress',
- 'fail',
- 'success',
- 'deleted'
- }
- },
- build_check_type = {
- fields = {
- 'script',
- 'manual',
- 'ghost_place',
- 'ghost_revive'
- }
- },
- chain_signal_state = {
- fields = {
- 'all_open',
- 'partially_open',
- 'none_open'
- }
- },
- chunk_generated_status = {
- fields = {
- 'nothing',
- 'custom_tiles',
- 'basic_tiles',
- 'corrected_tiles',
- 'tiles',
- 'entities'
- }
- },
- circuit_condition_index = {
- fields = {
- 'inserter_circuit',
- 'inserter_logistic',
- 'lamp',
- 'arithmetic_combinator',
- 'decider_combinator',
- 'constant_combinator',
- 'offshore_pump',
- 'pump'
- }
- },
- circuit_connector_id = {
- fields = {
- 'accumulator',
- 'constant_combinator',
- 'container',
- 'programmable_speaker',
- 'rail_signal',
- 'rail_chain_signal',
- 'roboport',
- 'storage_tank',
- 'wall',
- 'electric_pole',
- 'inserter',
- 'lamp',
- 'combinator_input',
- 'combinator_output',
- 'offshore_pump',
- 'pump'
- }
- },
- command = {
- fields = {
- 'attack',
- 'go_to_location',
- 'compound',
- 'group',
- 'attack_area',
- 'wander',
- 'flee',
- 'stop',
- 'build_base'
- }
- },
- compound_command = {
- fields = {
- 'logical_and',
- 'logical_or',
- 'return_last'
- }
- },
- control_behavior = {
- fields = {
- inserter = {
- fields = {
- circuit_mode_of_operation = {
- fields = {
- 'enable_disable',
- 'set_filters',
- 'read_hand_contents',
- 'set_stack_size'
- }
- },
- hand_read_mode = {
- fields = {
- 'hold',
- 'pulse'
- }
- }
- }
- },
- lamp = {
- fields = {
- circuit_mode_of_operation = {
- fields = {
- 'use_colors'
- }
- }
- }
- },
- logistic_container = {
- fields = {
- circuit_mode_of_operation = {
- fields = {
- 'send_contents',
- 'set_requests'
- }
- }
- }
- },
- mining_drill = {
- fields = {
- resource_read_mode = {
- fields = {
- 'this_miner',
- 'entire_patch'
- }
- }
- }
- },
- roboport = {
- fields = {
- circuit_mode_of_operation = {
- fields = {
- 'read_logistics',
- 'read_robot_stats'
- }
- }
- }
- },
- train_stop = {
- fields = {
- circuit_mode_of_operation = {
- fields = {
- 'enable_disable',
- 'send_to_train',
- 'read_from_train',
- 'read_stopped_train'
- }
- }
- }
- },
- transport_belt = {
- fields = {
- content_read_mode = {
- fields = {
- 'pulse',
- 'hold'
- }
- }
- }
- },
- type = {
- fields = {
- 'container',
- 'generic_on_off',
- 'inserter',
- 'lamp',
- 'logistic_container',
- 'roboport',
- 'storage_tank',
- 'train_stop',
- 'decider_combinator',
- 'arithmetic_combinator',
- 'constant_combinator',
- 'transport_belt',
- 'accumulator',
- 'rail_signal',
- 'rail_chain_signal',
- 'wall',
- 'mining_drill',
- 'programmable_speaker'
- }
- }
- }
- },
- controllers = {
- fields = {
- 'ghost',
- 'character',
- 'god',
- 'editor',
- 'cutscene',
- 'spectator'
- }
- },
- deconstruction_item = {
- fields = {
- entity_filter_mode = {
- fields = {
- 'whitelist',
- 'blacklist'
- }
- },
- tile_filter_mode = {
- fields = {
- 'whitelist',
- 'blacklist'
- }
- },
- tile_selection_mode = {
- fields = {
- 'normal',
- 'always',
- 'never',
- 'only'
- }
- }
- }
- },
- difficulty = {
- fields = {
- 'easy',
- 'normal',
- 'hard'
- }
- },
- difficulty_settings = {
- fields = {
- recipe_difficulty = {
- fields = {
- 'normal',
- 'expensive'
- }
- },
- technology_difficulty = {
- fields = {
- 'normal',
- 'expensive'
- }
- }
- }
- },
- direction = {
- fields = {
- 'north',
- 'northeast',
- 'east',
- 'southeast',
- 'south',
- 'southwest',
- 'west',
- 'northwest'
- }
- },
- distraction = {
- fields = {
- 'by_enemy',
- 'by_anything',
- 'by_damage'
- }
- },
- entity_status = {
- fields = {
- 'working',
- 'no_power',
- 'no_fuel',
- 'no_recipe',
- 'no_input_fluid',
- 'no_research_in_progress',
- 'no_minable_resources',
- 'low_input_fluid',
- 'low_power',
- 'disabled_by_control_behavior',
- 'disabled_by_script',
- 'fluid_ingredient_shortage',
- 'fluid_production_overload',
- 'item_ingredient_shortage',
- 'item_production_overload',
- 'marked_for_deconstruction',
- 'missing_required_fluid',
- 'missing_science_packs',
- 'waiting_for_source_items',
- 'waiting_for_space_in_destination',
- 'waiting_to_launch_rocket'
- }
- },
- events = {
- fields = {
- 'on_tick',
- 'on_gui_click',
- 'on_gui_confirmed',
- 'on_gui_text_changed',
- 'on_gui_checked_state_changed',
- 'on_entity_died',
- 'on_post_entity_died',
- 'on_entity_damaged',
- 'on_picked_up_item',
- 'on_built_entity',
- 'on_sector_scanned',
- 'on_player_mined_item',
- 'on_put_item',
- 'on_rocket_launched',
- 'on_pre_player_mined_item',
- 'on_chunk_generated',
- 'on_player_crafted_item',
- 'on_robot_built_entity',
- 'on_robot_pre_mined',
- 'on_robot_mined',
- 'on_research_started',
- 'on_research_finished',
- 'on_player_rotated_entity',
- 'on_player_set_quickbar_slot',
- 'on_marked_for_deconstruction',
- 'on_cancelled_deconstruction',
- 'on_trigger_created_entity',
- 'on_trigger_fired_artillery',
- 'on_train_changed_state',
- 'on_player_created',
- 'on_resource_depleted',
- 'on_player_driving_changed_state',
- 'on_force_created',
- 'on_forces_merging',
- 'on_player_cursor_stack_changed',
- 'on_pre_entity_settings_pasted',
- 'on_entity_settings_pasted',
- 'on_player_main_inventory_changed',
- 'on_player_armor_inventory_changed',
- 'on_player_ammo_inventory_changed',
- 'on_player_gun_inventory_changed',
- 'on_player_placed_equipment',
- 'on_player_removed_equipment',
- 'on_pre_player_died',
- 'on_player_died',
- 'on_player_respawned',
- 'on_player_joined_game',
- 'on_player_left_game',
- 'on_player_built_tile',
- 'on_player_mined_tile',
- 'on_robot_built_tile',
- 'on_robot_mined_tile',
- 'on_player_selected_area',
- 'on_player_alt_selected_area',
- 'on_player_changed_surface',
- 'on_selected_entity_changed',
- 'on_market_item_purchased',
- 'on_player_dropped_item',
- 'on_biter_base_built',
- 'on_player_changed_force',
- 'on_entity_renamed',
- 'on_gui_selection_state_changed',
- 'on_runtime_mod_setting_changed',
- 'on_difficulty_settings_changed',
- 'on_surface_created',
- 'on_surface_deleted',
- 'on_pre_surface_deleted',
- 'on_player_mined_entity',
- 'on_robot_mined_entity',
- 'on_train_created',
- 'on_gui_elem_changed',
- 'on_player_setup_blueprint',
- 'on_player_deconstructed_area',
- 'on_player_configured_blueprint',
- 'on_console_chat',
- 'on_console_command',
- 'on_player_removed',
- 'on_pre_player_removed',
- 'on_player_used_capsule',
- 'script_raised_built',
- 'script_raised_destroy',
- 'script_raised_revive',
- 'on_player_promoted',
- 'on_player_demoted',
- 'on_combat_robot_expired',
- 'on_player_changed_position',
- 'on_mod_item_opened',
- 'on_gui_opened',
- 'on_gui_closed',
- 'on_gui_value_changed',
- 'on_player_muted',
- 'on_player_unmuted',
- 'on_player_cheat_mode_enabled',
- 'on_player_cheat_mode_disabled',
- 'on_character_corpse_expired',
- 'on_pre_ghost_deconstructed',
- 'on_player_pipette',
- 'on_player_display_resolution_changed',
- 'on_player_display_scale_changed',
- 'on_pre_player_crafted_item',
- 'on_player_cancelled_crafting',
- 'on_chunk_charted',
- 'on_technology_effects_reset',
- 'on_land_mine_armed',
- 'on_forces_merged',
- 'on_player_trash_inventory_changed',
- 'on_pre_player_left_game',
- 'on_pre_surface_cleared',
- 'on_surface_cleared',
- 'on_chunk_deleted',
- 'on_pre_chunk_deleted',
- 'on_train_schedule_changed',
- 'on_player_banned',
- 'on_player_kicked',
- 'on_player_unbanned',
- 'on_rocket_launch_ordered',
- 'on_script_path_request_finished',
- 'on_ai_command_completed',
- 'on_marked_for_upgrade',
- 'on_cancelled_upgrade',
- 'on_player_toggled_map_editor',
- 'on_entity_cloned',
- 'on_area_cloned',
- 'on_brush_cloned',
- 'on_game_created_from_scenario',
- 'on_surface_imported',
- 'on_surface_renamed',
- 'on_player_toggled_alt_mode',
- 'on_player_repaired_entity',
- 'on_player_fast_transferred',
- 'on_pre_robot_exploded_cliff',
- 'on_robot_exploded_cliff',
- 'on_entity_spawned',
- 'on_cutscene_waypoint_reached',
- 'on_unit_group_created',
- 'on_unit_added_to_group',
- 'on_unit_removed_from_group',
- 'on_unit_group_finished_gathering',
- 'on_build_base_arrived',
- 'on_chart_tag_added',
- 'on_chart_tag_modified',
- 'on_chart_tag_removed',
- 'on_lua_shortcut',
- 'on_gui_location_changed',
- 'on_gui_selected_tab_changed',
- 'on_gui_switch_state_changed',
- 'on_force_cease_fire_changed',
- 'on_force_friends_changed',
- 'on_string_translated',
- 'on_script_trigger_effect'
- }
- },
- flow_precision_index = {
- fields = {
- 'one_second',
- 'one_minute',
- 'ten_minutes',
- 'one_hour',
- 'ten_hours',
- 'fifty_hours',
- 'two_hundred_fifty_hours',
- 'one_thousand_hours'
- }
- },
- group_state = {
- fields = {
- 'gathering',
- 'moving',
- 'attacking_distraction',
- 'attacking_target',
- 'finished',
- 'pathfinding',
- 'wander_in_group'
- }
- },
- gui_type = {
- fields = {
- 'entity',
- 'research',
- 'controller',
- 'production',
- 'item',
- 'bonus',
- 'trains',
- 'achievement',
- 'blueprint_library',
- 'equipment',
- 'logistic',
- 'other_player',
- 'kills',
- 'permissions',
- 'tutorials',
- 'custom',
- 'server_management',
- 'player_management',
- 'tile'
- }
- },
- input_action = {
- fields = {
- 'activate_copy',
- 'activate_cut',
- 'activate_paste',
- 'add_permission_group',
- 'add_train_station',
- 'admin_action',
- 'alt_select_area',
- 'alt_select_blueprint_entities',
- 'alternative_copy',
- 'begin_mining',
- 'begin_mining_terrain',
- 'build_item',
- 'build_rail',
- 'build_terrain',
- 'cancel_craft',
- 'cancel_deconstruct',
- 'cancel_new_blueprint',
- 'cancel_research',
- 'cancel_upgrade',
- 'change_active_item_group_for_crafting',
- 'change_active_item_group_for_filters',
- 'change_active_quick_bar',
- 'change_arithmetic_combinator_parameters',
- 'change_blueprint_book_record_label',
- 'change_decider_combinator_parameters',
- 'change_item_label',
- 'change_multiplayer_config',
- 'change_picking_state',
- 'change_programmable_speaker_alert_parameters',
- 'change_programmable_speaker_circuit_parameters',
- 'change_programmable_speaker_parameters',
- 'change_riding_state',
- 'change_shooting_state',
- 'change_single_blueprint_record_label',
- 'change_train_stop_station',
- 'change_train_wait_condition',
- 'change_train_wait_condition_data',
- 'clean_cursor_stack',
- 'clear_selected_blueprint',
- 'clear_selected_deconstruction_item',
- 'clear_selected_upgrade_item',
- 'connect_rolling_stock',
- 'copy',
- 'copy_entity_settings',
- 'craft',
- 'create_blueprint_like',
- 'cursor_split',
- 'cursor_transfer',
- 'custom_input',
- 'cycle_blueprint_book_backwards',
- 'cycle_blueprint_book_forwards',
- 'deconstruct',
- 'delete_blueprint_library',
- 'delete_blueprint_record',
- 'delete_custom_tag',
- 'delete_permission_group',
- 'destroy_opened_item',
- 'disconnect_rolling_stock',
- 'drag_train_schedule',
- 'drag_train_wait_condition',
- 'drop_blueprint_record',
- 'drop_item',
- 'drop_to_blueprint_book',
- 'edit_custom_tag',
- 'edit_permission_group',
- 'export_blueprint',
- 'fast_entity_split',
- 'fast_entity_transfer',
- 'go_to_train_station',
- 'grab_blueprint_record',
- 'gui_checked_state_changed',
- 'gui_click',
- 'gui_confirmed',
- 'gui_elem_changed',
- 'gui_location_changed',
- 'gui_selected_tab_changed',
- 'gui_selection_state_changed',
- 'gui_switch_state_changed',
- 'gui_text_changed',
- 'gui_value_changed',
- 'import_blueprint',
- 'import_blueprint_string',
- 'import_permissions_string',
- 'inventory_split',
- 'inventory_transfer',
- 'launch_rocket',
- 'lua_shortcut',
- 'map_editor_action',
- 'market_offer',
- 'mod_settings_changed',
- 'open_achievements_gui',
- 'open_blueprint_library_gui',
- 'open_blueprint_record',
- 'open_bonus_gui',
- 'open_character_gui',
- 'open_equipment',
- 'open_gui',
- 'open_item',
- 'open_kills_gui',
- 'open_logistic_gui',
- 'open_mod_item',
- 'open_production_gui',
- 'open_technology_gui',
- 'open_train_gui',
- 'open_train_station_gui',
- 'open_trains_gui',
- 'open_tutorials_gui',
- 'paste_entity_settings',
- 'place_equipment',
- 'quick_bar_pick_slot',
- 'quick_bar_set_selected_page',
- 'quick_bar_set_slot',
- 'remove_cables',
- 'remove_train_station',
- 'reset_assembling_machine',
- 'rotate_entity',
- 'select_area',
- 'select_blueprint_entities',
- 'select_entity_slot',
- 'select_item',
- 'select_mapper_slot',
- 'select_next_valid_gun',
- 'select_tile_slot',
- 'set_auto_launch_rocket',
- 'set_autosort_inventory',
- 'set_behavior_mode',
- 'set_car_weapons_control',
- 'set_circuit_condition',
- 'set_circuit_mode_of_operation',
- 'set_deconstruction_item_tile_selection_mode',
- 'set_deconstruction_item_trees_and_rocks_only',
- 'set_entity_color',
- 'set_entity_energy_property',
- 'set_filter',
- 'set_heat_interface_mode',
- 'set_heat_interface_temperature',
- 'set_infinity_container_filter_item',
- 'set_infinity_container_remove_unfiltered_items',
- 'set_infinity_pipe_filter',
- 'set_inserter_max_stack_size',
- 'set_inventory_bar',
- 'set_logistic_filter_item',
- 'set_logistic_filter_signal',
- 'set_logistic_trash_filter_item',
- 'set_request_from_buffers',
- 'set_research_finished_stops_game',
- 'set_signal',
- 'set_single_blueprint_record_icon',
- 'set_splitter_priority',
- 'set_train_stopped',
- 'setup_assembling_machine',
- 'setup_blueprint',
- 'setup_single_blueprint_record',
- 'smart_pipette',
- 'stack_split',
- 'stack_transfer',
- 'start_repair',
- 'start_research',
- 'start_walking',
- 'stop_building_by_moving',
- 'switch_connect_to_logistic_network',
- 'switch_constant_combinator_state',
- 'switch_inserter_filter_mode_state',
- 'switch_power_switch_state',
- 'switch_to_rename_stop_gui',
- 'take_equipment',
- 'toggle_deconstruction_item_entity_filter_mode',
- 'toggle_deconstruction_item_tile_filter_mode',
- 'toggle_driving',
- 'toggle_enable_vehicle_logistics_while_moving',
- 'toggle_equipment_movement_bonus',
- 'toggle_map_editor',
- 'toggle_personal_roboport',
- 'toggle_show_entity_info',
- 'translate_string',
- 'undo',
- 'upgrade',
- 'upgrade_opened_blueprint',
- 'use_artillery_remote',
- 'use_item',
- 'wire_dragging',
- 'write_to_console'
- }
- },
- inventory = {
- fields = {
- 'fuel',
- 'burnt_result',
- 'chest',
- 'furnace_source',
- 'furnace_result',
- 'furnace_modules',
- 'character_main',
- 'character_guns',
- 'character_ammo',
- 'character_armor',
- 'character_vehicle',
- 'character_trash',
- 'god_main',
- 'editor_main',
- 'editor_guns',
- 'editor_ammo',
- 'editor_armor',
- 'roboport_robot',
- 'roboport_material',
- 'robot_cargo',
- 'robot_repair',
- 'assembling_machine_input',
- 'assembling_machine_output',
- 'assembling_machine_modules',
- 'lab_input',
- 'lab_modules',
- 'mining_drill_modules',
- 'item_main',
- 'rocket_silo_rocket',
- 'rocket_silo_result',
- 'rocket',
- 'car_trunk',
- 'car_ammo',
- 'cargo_wagon',
- 'turret_ammo',
- 'beacon_modules',
- 'character_corpse',
- 'artillery_turret_ammo',
- 'artillery_wagon_ammo'
- }
- },
- logistic_member_index = {
- fields = {
- 'logistic_container',
- 'vehicle_storage',
- 'character_requester',
- 'character_storage',
- 'character_provider',
- 'generic_on_off_behavior'
- }
- },
- logistic_mode = {
- fields = {
- 'active_provider',
- 'storage',
- 'requester',
- 'passive_provider',
- 'buffer'
- }
- },
- mouse_button_type = {
- fields = {
- 'left',
- 'right',
- 'middle'
- }
- },
- rail_connection_direction = {
- fields = {
- 'left',
- 'straight',
- 'right'
- }
- },
- rail_direction = {
- fields = {
- 'front',
- 'back'
- }
- },
- render_mode = {
- fields = {
- 'game',
- 'chart',
- 'chart_zoomed_in'
- }
- },
- rich_text_setting = {
- fields = {
- 'enabled',
- 'disabled',
- 'highlight'
- }
- },
- riding = {
- fields = {
- acceleration = {
- fields = {
- 'nothing',
- 'accelerating',
- 'braking',
- 'reversing'
- }
- },
- direction = {
- fields = {
- 'left',
- 'straight',
- 'right'
- }
- }
- }
- },
- shooting = {
- fields = {
- 'not_shooting',
- 'shooting_enemies',
- 'shooting_selected'
- }
- },
- signal_state = {
- fields = {
- 'open',
- 'closed',
- 'reserved',
- 'reserved_by_circuit_network'
- }
- },
- train_state = {
- fields = {
- 'on_the_path',
- 'path_lost',
- 'no_schedule',
- 'no_path',
- 'arrive_signal',
- 'wait_signal',
- 'arrive_station',
- 'wait_station',
- 'manual_control_stop',
- 'manual_control'
- }
- },
- transport_line = {
- fields = {
- 'left_line',
- 'right_line',
- 'left_underground_line',
- 'right_underground_line',
- 'secondary_left_line',
- 'secondary_right_line',
- 'left_split_line',
- 'right_split_line',
- 'secondary_left_split_line',
- 'secondary_right_split_line'
- }
- },
- wire_connection_id = {
- fields = {
- 'electric_pole',
- 'power_switch_left',
- 'power_switch_right'
- }
- },
- wire_type = {
- fields = {
- 'red',
- 'green',
- 'copper'
- }
- },
- -- Defines additional modules
- color = {
- other_fields = true
- },
- anticolor = {
- other_fields = true
- },
- lightcolor = {
- other_fields = true
- },
- time = {
- fields = {
- 'second',
- 'minute',
- 'hour',
- 'day',
- 'week',
- 'month',
- 'year'
- }
- }
- }
- }
- }
- }
-end
-
---[[ Options
- "ignore", "std", "globals", "unused_args", "self", "compat", "global", "unused", "redefined",
- "unused_secondaries", "allow_defined", "allow_defined_top", "module",
- "read_globals", "new_globals", "new_read_globals", "enable", "only", "not_globals",
- "max_line_length", "max_code_line_length", "max_string_line_length", "max_comment_line_length",
- "max_cyclomatic_complexity"
---]]
-
---[[ Warnings list
- -- 011 A syntax error.
- -- 021 An invalid inline option.
- -- 022 An unpaired inline push directive.
- -- 023 An unpaired inline pop directive.
- -- 111 Setting an undefined global variable.
- -- 112 Mutating an undefined global variable.
- -- 113 Accessing an undefined global variable.
- -- 121 Setting a read-only global variable.
- -- 122 Setting a read-only field of a global variable.
- -- 131 Unused implicitly defined global variable.
- -- 142 Setting an undefined field of a global variable.
- -- 143 Accessing an undefined field of a global variable.
- -- 211 Unused local variable.
- -- 212 Unused argument.
- -- 213 Unused loop variable.
- -- 221 Local variable is accessed but never set.
- -- 231 Local variable is set but never accessed.
- -- 232 An argument is set but never accessed.
- -- 233 Loop variable is set but never accessed.
- -- 241 Local variable is mutated but never accessed.
- -- 311 Value assigned to a local variable is unused.
- -- 312 Value of an argument is unused.
- -- 313 Value of a loop variable is unused.
- -- 314 Value of a field in a table literal is unused.
- -- 321 Accessing uninitialized local variable.
- -- 331 Value assigned to a local variable is mutated but never accessed.
- -- 341 Mutating uninitialized local variable.
- -- 411 Redefining a local variable.
- -- 412 Redefining an argument.
- -- 413 Redefining a loop variable.
- -- 421 Shadowing a local variable.
- -- 422 Shadowing an argument.
- -- 423 Shadowing a loop variable.
- -- 431 Shadowing an upvalue.
- -- 432 Shadowing an upvalue argument.
- -- 433 Shadowing an upvalue loop variable.
- -- 511 Unreachable code.
- -- 512 Loop can be executed at most once.
- -- 521 Unused label.
- -- 531 Left-hand side of an assignment is too short.
- -- 532 Left-hand side of an assignment is too long.
- -- 541 An empty do end block.
- -- 542 An empty if branch.
- -- 551 An empty statement.
- -- 611 A line consists of nothing but whitespace.
- -- 612 A line contains trailing whitespace.
- -- 613 Trailing whitespace in a string.
- -- 614 Trailing whitespace in a comment.
- -- 621 Inconsistent indentation (SPACE followed by TAB).
- -- 631 Line is too long.
---]]
diff --git a/exp_scenario/module/commands/_types.lua b/exp_scenario/module/commands/_types.lua
index 0acfeb82..f23ff943 100644
--- a/exp_scenario/module/commands/_types.lua
+++ b/exp_scenario/module/commands/_types.lua
@@ -18,7 +18,7 @@ local valid, invalid = Commands.status.success, Commands.status.invalid_input
local Roles = require("modules.exp_legacy.expcore.roles")
local highest_role = Roles.get_player_highest_role
-local types = {} --- @class Commands.types
+local types = {} --- @class (partial) Commands.types
--- A role defined by exp roles
types.role = add("role", Commands.types.key_of(Roles.config.roles))
diff --git a/exp_scenario/module/commands/artillery.lua b/exp_scenario/module/commands/artillery.lua
index 95749da9..9f93732b 100644
--- a/exp_scenario/module/commands/artillery.lua
+++ b/exp_scenario/module/commands/artillery.lua
@@ -15,11 +15,11 @@ local abs = math.abs
local commands = {}
--- @param player LuaPlayer
---- @param area BoundingBox
+--- @param area BoundingBox.struct
--- @return boolean
local function location_break(player, area)
local surface = player.surface -- Allow remote view
- local is_charted = player.force.is_chunk_charted
+ local is_charted = (player.force --[[@as LuaForce]]).is_chunk_charted
if is_charted(surface, { x = floor(area.left_top.x / 32), y = floor(area.left_top.y / 32) }) then
return true
elseif is_charted(surface, { x = floor(area.left_top.x / 32), y = floor(area.right_bottom.y / 32) }) then
@@ -43,7 +43,7 @@ commands.artillery = Commands.new("artillery", { "exp-commands_artillery.descrip
end
SelectArea:start(player)
return Commands.status.success{ "exp-commands_artillery.enter" }
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- when an area is selected to add protection to the area
SelectArea:on_selection(function(event)
@@ -63,13 +63,14 @@ SelectArea:on_selection(function(event)
}
local count = 0
- local hits = {} --- @type MapPosition[]
+ local hits = {} --- @type MapPosition.struct[]
for _, entity in ipairs(entities) do
local skip = false
+ local entity_position = entity.position
for _, pos in ipairs(hits) do
- local x = abs(entity.position.x - pos.x)
- local y = abs(entity.position.y - pos.y)
+ local x = abs(entity_position.x - pos.x)
+ local y = abs(entity_position.y - pos.y)
if x * x + y * y < 36 then
skip = true
break
diff --git a/exp_scenario/module/commands/connect.lua b/exp_scenario/module/commands/connect.lua
index b935b45d..cf53b181 100644
--- a/exp_scenario/module/commands/connect.lua
+++ b/exp_scenario/module/commands/connect.lua
@@ -41,7 +41,7 @@ local function get_server_id(server)
elseif status == "Offline" then
return false, { "exp-commands_connect.offline", server_details.name }
end
- return true, server_id
+ return true, server_id --[[@as string]]
elseif server_count_before > 0 then
return false, { "exp-commands_connect.wrong-version", concat(server_names_before, ", ") }
else
diff --git a/exp_scenario/module/commands/kill.lua b/exp_scenario/module/commands/kill.lua
index 17d291fd..a71528ed 100644
--- a/exp_scenario/module/commands/kill.lua
+++ b/exp_scenario/module/commands/kill.lua
@@ -25,7 +25,7 @@ Commands.new("kill", { "exp-commands_kill.description" })
if script.active_mods["space-age"] then
other_player.surface.create_entity{ name = "lightning", position = { other_player.position.x, other_player.position.y - 16 }, target = other_player.character }
end
- other_player.character.die()
+ assert(other_player.character).die()
else
return Commands.status.unauthorised{ "exp-commands_kill.lower-role" }
end
diff --git a/exp_scenario/module/commands/lawnmower.lua b/exp_scenario/module/commands/lawnmower.lua
index 5ff1d2e1..b77014e3 100644
--- a/exp_scenario/module/commands/lawnmower.lua
+++ b/exp_scenario/module/commands/lawnmower.lua
@@ -22,7 +22,7 @@ commands.lawnmower = Commands.new("lawnmower", { "exp-commands_lawnmower.descrip
SelectArea:start(player)
return Commands.status.success{ "exp-commands_lawnmower.enter" }
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- When an area is selected to be handled
SelectArea:on_selection(function(event)
diff --git a/exp_scenario/module/commands/protected_entities.lua b/exp_scenario/module/commands/protected_entities.lua
index 34426b24..7f906413 100644
--- a/exp_scenario/module/commands/protected_entities.lua
+++ b/exp_scenario/module/commands/protected_entities.lua
@@ -37,7 +37,7 @@ end
--- Get the key used in protected_areas
--- TODO expose this from EntityProtection
---- @param area BoundingBox
+--- @param area BoundingBox.struct
--- @return string
local function get_area_key(area)
return format_string("%i,%i", floor(area.left_top.x), floor(area.left_top.y))
@@ -49,13 +49,15 @@ end
local function show_protected_entity(player, entity)
local key = get_entity_key(entity)
if renders[player.index][key] then return end
- local rb = entity.selection_box.right_bottom
+ local selection_box = entity.selection_box
+ local rb = selection_box.right_bottom
+ local position = entity.position
renders[player.index][key] = rendering.draw_sprite{
sprite = "utility/notification",
target = entity,
target_offset = {
- (rb.x - entity.position.x) * 0.75,
- (rb.y - entity.position.y) * 0.75,
+ (rb.x - position.x) * 0.75,
+ (rb.y - position.y) * 0.75,
},
x_scale = 2,
y_scale = 2,
@@ -67,7 +69,7 @@ end
--- Show a protected area to a player
--- @param player LuaPlayer
--- @param surface LuaSurface
---- @param area BoundingBox
+--- @param area BoundingBox.struct
local function show_protected_area(player, surface, area)
local key = get_area_key(area)
if renders[player.index][key] then return end
diff --git a/exp_scenario/module/commands/protected_tags.lua b/exp_scenario/module/commands/protected_tags.lua
index 1667b008..fce30257 100644
--- a/exp_scenario/module/commands/protected_tags.lua
+++ b/exp_scenario/module/commands/protected_tags.lua
@@ -7,7 +7,7 @@ local Storage = require("modules/exp_util/storage")
--- Storage variables
local active_players = {} --- @type table Stores all players in in protected mode
-local map_tags = {} --- @type table Stores all protected map tags
+local map_tags = {} --- @type table Stores all protected map tags
Storage.register({
active_players = active_players,
diff --git a/exp_scenario/module/commands/rainbow.lua b/exp_scenario/module/commands/rainbow.lua
index 1084f84c..c5fd1a36 100644
--- a/exp_scenario/module/commands/rainbow.lua
+++ b/exp_scenario/module/commands/rainbow.lua
@@ -6,6 +6,12 @@ local Commands = require("modules/exp_commands")
local format_player_name = Commands.format_player_name_locale
local format_text = Commands.format_rich_text_color
+--- A colour with every channel set, Color.struct leaves them optional
+--- @class ExpCommands_Rainbow.Color
+--- @field r number
+--- @field g number
+--- @field b number
+
--- Wraps one component into the next
--- @param c1 number
--- @param c2 number
@@ -21,8 +27,8 @@ local function step_component(c1, c2)
end
--- Wraps all components of a colour ensuring it remains valid
---- @param color Color
---- @return Color
+--- @param color ExpCommands_Rainbow.Color
+--- @return ExpCommands_Rainbow.Color
local function step_color(color)
color.r, color.g = step_component(color.r, color.g)
color.g, color.b = step_component(color.g, color.b)
@@ -32,9 +38,9 @@ local function step_color(color)
end
--- Get the next colour in the rainbow by the given step
---- @param color Color
+--- @param color ExpCommands_Rainbow.Color
--- @param step number
---- @return Color
+--- @return ExpCommands_Rainbow.Color
local function next_color(color, step)
step = step or 0.1
local new_color = { r = 0, g = 0, b = 0 }
diff --git a/exp_scenario/module/commands/ratio.lua b/exp_scenario/module/commands/ratio.lua
index 2e12e444..201dd339 100644
--- a/exp_scenario/module/commands/ratio.lua
+++ b/exp_scenario/module/commands/ratio.lua
@@ -29,7 +29,7 @@ Commands.new("ratio", { "exp-commands_ratio.description" })
local amount_of_machines = 1
if items_per_second then
- amount_of_machines = math.ceil(products[1].amount * crafts_per_second)
+ amount_of_machines = math.ceil(assert(assert(products[1]).amount) * crafts_per_second)
end
for _, ingredient in ipairs(ingredients) do
@@ -43,7 +43,7 @@ Commands.new("ratio", { "exp-commands_ratio.description" })
for i, product in ipairs(products) do
Commands.print{
product.type == "item" and "exp-commands_ratio.item-out" or "exp-commands_ratio.fluid-out",
- math.round(product.amount * crafts_per_second, 3),
+ math.round(assert(product.amount) * crafts_per_second, 3),
product.name
}
end
diff --git a/exp_scenario/module/commands/reports.lua b/exp_scenario/module/commands/reports.lua
index e0f845aa..aab4351c 100644
--- a/exp_scenario/module/commands/reports.lua
+++ b/exp_scenario/module/commands/reports.lua
@@ -11,7 +11,10 @@ local player_has_flag = Roles.player_has_flag
local Reports = require("modules.exp_legacy.modules.control.reports") --- @dep modules.control.reports
---- @type Commands.InputParser
+--- @param input string
+--- @param player LuaPlayer
+--- @return Commands.Status
+--- @return LuaPlayer | LocalisedString
local function reportable_player(input, player)
local success, status, result = parse_input(input, player, Commands.types.player)
if not success then return status, result end
@@ -40,11 +43,11 @@ Commands.new("create-report", { "exp-commands_reports.description-create" })
if Reports.report_player(other_player, player.name, reason) then
local user_message = { "exp-commands_reports.response", other_player_name, reason }
local admin_message = { "exp-commands_reports.response-admin", other_player_name, player_name, reason }
- for _, player in ipairs(game.connected_players) do
- if player.admin then
- player.print(admin_message)
+ for _, connected_player in ipairs(game.connected_players) do
+ if connected_player.admin then
+ connected_player.print(admin_message)
else
- player.print(user_message)
+ connected_player.print(user_message)
end
end
else
diff --git a/exp_scenario/module/commands/roles.lua b/exp_scenario/module/commands/roles.lua
index 7adbb3a1..b8a510ad 100644
--- a/exp_scenario/module/commands/roles.lua
+++ b/exp_scenario/module/commands/roles.lua
@@ -42,7 +42,7 @@ Commands.new("get-roles", { "exp-commands_roles.description-get" })
--- @cast other_player LuaPlayer?
local roles = get_roles_ordered()
local roles_formatted = { "" } --- @type LocalisedString
- local response = { "exp-commands_roles.list-roles", roles_formatted }
+ local response = { "exp-commands_roles.list-roles", roles_formatted } --[[@as LocalisedString]]
if other_player then
roles = get_player_roles(other_player)
response[1] = "exp-commands_roles.list-player"
@@ -55,8 +55,7 @@ Commands.new("get-roles", { "exp-commands_roles.description-get" })
end
local last = #roles_formatted
- --- @diagnostic disable-next-line nil-check
- roles_formatted[last] = roles_formatted[last][2]
+ roles_formatted[last] = assert(roles_formatted[last])[2]
return Commands.status.success(response)
end)
diff --git a/exp_scenario/module/commands/search.lua b/exp_scenario/module/commands/search.lua
index 13bc03b8..fe4bba77 100644
--- a/exp_scenario/module/commands/search.lua
+++ b/exp_scenario/module/commands/search.lua
@@ -10,7 +10,10 @@ local format_player_name = Commands.format_player_name_locale
local format_number = require("util").format_number
--- A player who is of a lower role than the executing player
---- @type Commands.InputParser
+--- @param input string
+--- @param player LuaPlayer
+--- @return Commands.Status
+--- @return LuaItemPrototype | LocalisedString
local function parse_item(input, player)
-- First Case - internal name is given
-- Second Case - rich text is given
@@ -88,7 +91,7 @@ local function sort_results(results, func)
end
end
- return sorted
+ return sorted --[[@as SearchResult[] ]]
end
local display_players_time_format = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true }
@@ -146,7 +149,8 @@ Commands.new("search-online", { "exp-commands_search.description-online" })
end)
--- Return the amount of an item a player has
---- @type SortFunction
+--- @param data SearchResult
+--- @return number
local function sort_by_count(data)
return data.count
end
diff --git a/exp_scenario/module/commands/surface.lua b/exp_scenario/module/commands/surface.lua
index 18504724..0cb2bc43 100644
--- a/exp_scenario/module/commands/surface.lua
+++ b/exp_scenario/module/commands/surface.lua
@@ -69,7 +69,7 @@ commands.clear_blueprints = Commands.new("clear-blueprints", { "exp-commands_sur
SelectArea:start(player)
return Commands.status.success{ "exp-commands_surface.enter" }
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- When an area is selected
SelectArea:on_selection(function(event)
diff --git a/exp_scenario/module/commands/teleport.lua b/exp_scenario/module/commands/teleport.lua
index 964e8ed7..a7892047 100644
--- a/exp_scenario/module/commands/teleport.lua
+++ b/exp_scenario/module/commands/teleport.lua
@@ -34,7 +34,7 @@ commands.teleport = Commands.new("teleport", { "exp-commands_teleport.descriptio
elseif not teleport_player(other_player, target_player.physical_surface, target_player.physical_position) then
return Commands.status.error{ "exp-commands_teleport.unavailable" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Teleports a player to you.
--- @class ExpCommands_Teleport.commands.bring: ExpCommand
@@ -49,7 +49,7 @@ commands.bring = Commands.new("bring", { "exp-commands_teleport.description-brin
elseif not teleport_player(other_player, player.physical_surface, player.physical_position) then
return Commands.status.error{ "exp-commands_teleport.unavailable" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Teleports you to a player.
--- @class ExpCommands_Teleport.commands.goto: ExpCommand
@@ -64,7 +64,7 @@ commands["goto"] = Commands.new("goto", { "exp-commands_teleport.description-got
elseif not teleport_player(player, other_player.physical_surface, other_player.physical_position) then
return Commands.status.error{ "exp-commands_teleport.unavailable" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Teleport to spawn
--- @class ExpCommands_Teleport.commands.spawn: ExpCommand
@@ -92,7 +92,7 @@ commands.spawn = Commands.new("spawn", { "exp-commands_teleport.description-spaw
else
return Commands.status.unauthorised()
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
return {
commands = commands,
diff --git a/exp_scenario/module/commands/trains.lua b/exp_scenario/module/commands/trains.lua
index ee8885a5..9d79b755 100644
--- a/exp_scenario/module/commands/trains.lua
+++ b/exp_scenario/module/commands/trains.lua
@@ -10,7 +10,7 @@ local format_number = require("util").format_number
local commands = {}
--- Set all trains to automatic
---- @class ExpCommand_Artillery.commands.artillery: ExpCommand
+--- @class ExpCommand_Trains.commands.set_trains_to_automatic: ExpCommand
--- @overload fun(player: LuaPlayer, surface: LuaSurface?, force: LuaForce?)
commands.set_trains_to_automatic = Commands.new("set-trains-to-automatic", { "exp-commands_trains.description" })
:optional("surface", { "exp-commands_trains.arg-surface" }, Commands.types.surface)
@@ -32,7 +32,7 @@ commands.set_trains_to_automatic = Commands.new("set-trains-to-automatic", { "ex
end
game.print{ "exp-commands_trains.response", format_player_name(player), format_number(#trains, false) }
- end) --[[ @as any ]]
+ end) --[[@as any]]
return {
commands = commands,
diff --git a/exp_scenario/module/commands/warnings.lua b/exp_scenario/module/commands/warnings.lua
index bcc8c38d..14be9aad 100644
--- a/exp_scenario/module/commands/warnings.lua
+++ b/exp_scenario/module/commands/warnings.lua
@@ -35,7 +35,7 @@ Commands.new("get-warnings", { "exp-commands_warnings.description-get" })
local warnings = Warnings.get_warnings(player)
local script_warnings = Warnings.get_script_warnings(player)
local other_player_name = format_player_name(other_player)
- Commands.print{ "exp-commands_warnings.player-title", other_player_name, #warnings, #script_warnings, config.temp_warning_limit }
+ Commands.print{ "exp-commands_warnings.player-title", other_player_name, #warnings, #script_warnings, config.script_warning_limit }
for _, warning in pairs(warnings) do
local by_player_name_formatted = format_player_name(warning.by_player_name)
Commands.print{ "exp-commands_warnings.list-element-player", by_player_name_formatted, warning.reason }
@@ -47,12 +47,12 @@ Commands.new("get-warnings", { "exp-commands_warnings.description-get" })
for player_name, player_warnings in pairs(warnings) do
local player_name_formatted = format_player_name(player_name)
local script_warning_count = script_warnings[player_name] and #script_warnings[player_name] or 0
- Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, #player_warnings, script_warning_count, config.temp_warning_limit }
+ Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, #player_warnings, script_warning_count, config.script_warning_limit }
end
for player_name, player_warnings in pairs(script_warnings) do
if not warnings[player_name] then
local player_name_formatted = format_player_name(player_name)
- Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, 0, #player_warnings, config.temp_warning_limit }
+ Commands.print{ "exp-commands_warnings.list-element", player_name_formatted, 0, #player_warnings, config.script_warning_limit }
end
end
end
diff --git a/exp_scenario/module/commands/waterfill.lua b/exp_scenario/module/commands/waterfill.lua
index 6e1a8e24..a9313f92 100644
--- a/exp_scenario/module/commands/waterfill.lua
+++ b/exp_scenario/module/commands/waterfill.lua
@@ -36,7 +36,7 @@ commands.waterfill = Commands.new("waterfill", { "exp-commands_waterfill.descrip
SelectArea:start(player)
return Commands.status.success{ "exp-commands_waterfill.enter" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- When an area is selected to be converted to water
SelectArea:on_selection(function(event)
@@ -70,7 +70,7 @@ SelectArea:on_selection(function(event)
if #chests > 0 then
for _, chest in pairs(chests) do
tile_count = tile_count + 1
- if chest.get_inventory(defines.inventory.chest).is_empty() and tile_count <= item_count_total then
+ if assert(chest.get_inventory(defines.inventory.chest)).is_empty() and tile_count <= item_count_total then
tiles_to_make[tile_count] = { name = tile_to_apply, position = { chest.position.x, chest.position.y } }
chest.destroy()
else
diff --git a/exp_scenario/module/control/custom_start.lua b/exp_scenario/module/control/custom_start.lua
index 1c4e64ff..62d59a1a 100644
--- a/exp_scenario/module/control/custom_start.lua
+++ b/exp_scenario/module/control/custom_start.lua
@@ -8,7 +8,7 @@ local floor = math.floor
--- Give a player their starting items
--- @param player LuaPlayer
local function give_starting_items(player)
- local get_prod_stats = player.force.get_item_production_statistics(player.physical_surface)
+ local get_prod_stats = (player.force --[[@as LuaForce]]).get_item_production_statistics(player.physical_surface)
local get_input_count = get_prod_stats.get_input_count
local insert_param = { name = "", count = 0 }
local insert = player.insert
diff --git a/exp_scenario/module/control/damage_popups.lua b/exp_scenario/module/control/damage_popups.lua
index 54dfc0e1..803f95b6 100644
--- a/exp_scenario/module/control/damage_popups.lua
+++ b/exp_scenario/module/control/damage_popups.lua
@@ -26,11 +26,12 @@ local function on_entity_damaged(event)
-- Outputs the message as floating text
if message then
+ local entity_position = entity.position
local entity_radius = max(1, entity.get_radius())
local offset = (random() - 0.5) * entity_radius * config.damage_location_variance
- local position = { x = entity.position.x + offset, y = entity.position.y - entity_radius }
+ local position = { x = entity_position.x + offset, y = entity_position.y - entity_radius }
- local health_percentage = entity.get_health_ratio()
+ local health_percentage = assert(entity.get_health_ratio())
local color = { r = 1 - health_percentage, g = health_percentage, b = 0 }
FlyingText.create{
diff --git a/exp_scenario/module/control/death_markers.lua b/exp_scenario/module/control/death_markers.lua
index efb25694..24a74f30 100644
--- a/exp_scenario/module/control/death_markers.lua
+++ b/exp_scenario/module/control/death_markers.lua
@@ -31,7 +31,7 @@ local function create_map_tag(corpse_data)
message = message .. " at " .. time
end
- corpse_data.tag = player.force.add_chart_tag(corpse_data.corpse.surface, {
+ corpse_data.tag = (player.force --[[@as LuaForce]]).add_chart_tag(corpse_data.corpse.surface, {
position = corpse_data.corpse.position,
icon = config.map_icon,
text = message,
diff --git a/exp_scenario/module/control/deconstruction_log.lua b/exp_scenario/module/control/deconstruction_log.lua
index 087030ab..b6d2b05d 100644
--- a/exp_scenario/module/control/deconstruction_log.lua
+++ b/exp_scenario/module/control/deconstruction_log.lua
@@ -42,7 +42,7 @@ local function format_position(pos)
end
--- Convert an area to a string
---- @param area BoundingBox
+--- @param area BoundingBox.struct
--- @return string
local function format_area(area)
return format_string("%.1f,%.1f,%.1f,%.1f", area.left_top.x, area.left_top.y, area.right_bottom.x, area.right_bottom.y)
@@ -137,7 +137,8 @@ local function on_player_ammo_inventory_changed(event)
if not player or not player.character then return end
local character_ammo = assert(player.get_inventory(defines.inventory.character_ammo))
- local item = character_ammo[player.character.selected_gun_index]
+ local gun_index = player.character.selected_gun_index --[[@as uint]]
+ local item = character_ammo[gun_index]
if not item or not item.valid or not item.valid_for_read then
return
end
diff --git a/exp_scenario/module/control/degrading_tiles.lua b/exp_scenario/module/control/degrading_tiles.lua
index ad16dbfd..dc3a1b11 100644
--- a/exp_scenario/module/control/degrading_tiles.lua
+++ b/exp_scenario/module/control/degrading_tiles.lua
@@ -16,10 +16,9 @@ end
--- Replace a tile with the next tile in the degrade chain
--- @param surface LuaSurface
---- @param position MapPosition
+--- @param position MapPosition.struct
local function degrade_tile(surface, position)
- --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761
- local tile = surface.get_tile(position)
+ local tile = surface.get_tile(position.x, position.y)
local tile_name = tile.name
local degrade_tile_name = config.degrade_order[tile_name]
if not degrade_tile_name then return end
@@ -33,8 +32,9 @@ local function degrade_entity(entity)
local tiles = {}
local surface = entity.surface
- local left_top = entity.bounding_box.left_top
- local right_bottom = entity.bounding_box.right_bottom
+ local bounding_box = entity.bounding_box
+ local left_top = bounding_box.left_top
+ local right_bottom = bounding_box.right_bottom
for x = left_top.x, right_bottom.x do
for y = left_top.y, right_bottom.y do
local tile = surface.get_tile(x, y)
@@ -58,11 +58,10 @@ end
--- Gets the average tile strengths around position
--- @param surface LuaSurface
---- @param position MapPosition
+--- @param position MapPosition.struct
--- @return number?
local function get_tile_strength(surface, position)
- --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761
- local tile = surface.get_tile(position)
+ local tile = surface.get_tile(position.x, position.y)
local tile_name = tile.name
local strength = config.strengths[tile_name]
if not strength then return end
diff --git a/exp_scenario/module/control/discord_alerts.lua b/exp_scenario/module/control/discord_alerts.lua
index 38978e1c..c4675140 100644
--- a/exp_scenario/module/control/discord_alerts.lua
+++ b/exp_scenario/module/control/discord_alerts.lua
@@ -31,15 +31,15 @@ local function append_playtime(player_name)
end
--- Get the player name from an event
---- @param event { player_index: number, by_player_name: string? }
---- @return string, string
+--- @param event { player_index: uint, by_player_name: string? }
+--- @return string, string?
local function get_player_name(event)
local player = game.players[event.player_index]
return player.name, event.by_player_name
end
--- Convert a colour value into hex
---- @param color Color.0
+--- @param color Color.struct
--- @return string
local function to_hex(color)
local hex_digits = "0123456789ABCDEF"
@@ -53,7 +53,7 @@ local function to_hex(color)
end
--- Emit the requires json to file for the given event arguments
---- @param opts { title: string?, color: (Color.0 | string)?, description: string?, tick: number?, fields: { name: string, value: string, inline: boolean? }[] }
+--- @param opts { title: string?, color: (Color.struct | string)?, description: string?, tick: number?, fields: { name: string, value: string, inline: boolean? }[] }
local function emit_event(opts)
local admins_online = 0
local players_online = 0
diff --git a/exp_scenario/module/control/extra_logging.lua b/exp_scenario/module/control/extra_logging.lua
index d469c390..07055245 100644
--- a/exp_scenario/module/control/extra_logging.lua
+++ b/exp_scenario/module/control/extra_logging.lua
@@ -23,7 +23,7 @@ end
--- @param event EventData.on_cargo_pod_finished_ascending
local function on_cargo_pod_finished_ascending(event)
if event.launched_by_rocket then
- local force = event.cargo_pod.force
+ local force = event.cargo_pod.force --[[@as LuaForce]]
if force.rockets_launched >= config.rocket_launch_display_rate and force.rockets_launched % config.rocket_launch_display_rate == 0 then
add_log_line("[ROCKET]", force.rockets_launched, "rockets launched")
elseif config.rocket_launch_display[force.rockets_launched] then
@@ -38,7 +38,7 @@ local function on_pre_player_died(event)
local cause = event.cause
if cause then
if cause.type == "character" then
- add_log_line("[DEATH]", player.name, "died because of", cause.player.name)
+ add_log_line("[DEATH]", player.name, "died because of", assert(cause.player).name)
else
add_log_line("[DEATH]", player.name, "died because of", cause.name)
end
diff --git a/exp_scenario/module/control/fast_deconstruction.lua b/exp_scenario/module/control/fast_deconstruction.lua
index 4481f9b4..acd83069 100644
--- a/exp_scenario/module/control/fast_deconstruction.lua
+++ b/exp_scenario/module/control/fast_deconstruction.lua
@@ -22,7 +22,7 @@ local min = math.min
--- @field trees LuaEntity[]
--- @field tree_count number
--- @field permission "fast" | "allow" | "disallow"
---- @field task Async.AsyncReturn
+--- @field task Async.AsyncReturn
local cache --- @type TreeDeconCache?
@@ -77,14 +77,15 @@ local function get_player_cache(player_index)
-- Create a new cache if the previous on is in use
if not cache or cache.task and not cache.task.completed then
- cache = {} --[[@as any]]
+ --- @diagnostic disable-next-line: missing-fields
+ cache = {} --[[@as TreeDeconCache]]
end
local player = assert(game.get_player(player_index))
cache.tick = game.tick
cache.player_index = player_index
cache.player = player
- cache.force = player.force --[[ @as LuaForce ]]
+ cache.force = player.force --[[@as LuaForce]]
cache.tree_count = 0
cache.trees = {}
cache.permission = get_permission(player)
diff --git a/exp_scenario/module/control/help_bubbles.lua b/exp_scenario/module/control/help_bubbles.lua
index 6740b93a..b37c143f 100644
--- a/exp_scenario/module/control/help_bubbles.lua
+++ b/exp_scenario/module/control/help_bubbles.lua
@@ -6,7 +6,7 @@ local Async = require("modules/exp_util/async")
local Storage = require("modules/exp_util/storage")
local config = require("modules.exp_legacy.config.compilatron")
---- @type table
+--- @type table>
local persistent_locations = {}
Storage.register(persistent_locations, function(tbl)
persistent_locations = tbl
@@ -55,7 +55,7 @@ local speech_bubble_task =
--- @param entity LuaEntity the entity which will have messages spawn from it
--- @param messages LocalisedString[] the messages which should be shown
--- @param starting_index number? the message index to start at, default 1
---- @return Async.AsyncReturn
+--- @return Async.AsyncReturn
local function register_entity(entity, messages, starting_index)
return speech_bubble_task{
entity = entity,
diff --git a/exp_scenario/module/control/mine_depletion.lua b/exp_scenario/module/control/mine_depletion.lua
index 894c3dfb..f8a6cb55 100644
--- a/exp_scenario/module/control/mine_depletion.lua
+++ b/exp_scenario/module/control/mine_depletion.lua
@@ -68,12 +68,13 @@ local function try_deconstruct_output_chest(entity)
end
-- Get all adjacent mining drills and inserters
+ local target_position = target.position
local entities = target.surface.find_entities_filtered{
type = { "mining-drill", "inserter" },
to_be_deconstructed = false,
area = {
- { target.position.x - 1, target.position.y - 1 },
- { target.position.x + 1, target.position.y + 1 }
+ left_top = { x = target_position.x - 1, y = target_position.y - 1 },
+ right_bottom = { x = target_position.x + 1, y = target_position.y + 1 },
},
}
@@ -250,16 +251,17 @@ local function on_resource_depleted(event)
local drills = resource.surface.find_entities_filtered{
type = "mining-drill",
area = {
- { position.x - max_mining_radius, position.y - max_mining_radius },
- { position.x + max_mining_radius, position.y + max_mining_radius },
+ left_top = { x = position.x - max_mining_radius, y = position.y - max_mining_radius },
+ right_bottom = { x = position.x + max_mining_radius, y = position.y + max_mining_radius },
},
}
-- Check which could have reached this resource
for _, drill in pairs(drills) do
local radius = drill.prototype.mining_drill_radius
- local dx = math.abs(drill.position.x - position.x)
- local dy = math.abs(drill.position.y - position.y)
+ local drill_position = drill.position
+ local dx = math.abs(drill_position.x - position.x)
+ local dy = math.abs(drill_position.y - position.y)
if dx <= radius and dy <= radius then
try_deconstruct_miner(drill)
end
diff --git a/exp_scenario/module/control/spawn_area.lua b/exp_scenario/module/control/spawn_area.lua
index e4c7213e..aab08d17 100644
--- a/exp_scenario/module/control/spawn_area.lua
+++ b/exp_scenario/module/control/spawn_area.lua
@@ -7,11 +7,11 @@ local config = require("modules.exp_legacy.config.spawn_area")
--- Apply an offset to a LuaPosition
--- @param position MapPosition
--- @param offset MapPosition
---- @return MapPosition.0
+--- @return MapPosition.struct
local function apply_offset(position, offset)
return {
- x = (position.x or position[1]) + (offset.x or offset[1]),
- y = (position.y or position[2]) + (offset.y or offset[2])
+ x = position.x + offset.x,
+ y = position.y + offset.y,
}
end
@@ -21,8 +21,8 @@ end
--- @param x_index number
--- @param y_index number
local function apply_offset_to_array(positions, offset, x_index, y_index)
- local x = (offset.x or offset[1])
- local y = (offset.y or offset[2])
+ local x = offset.x
+ local y = offset.y
for _, position in ipairs(positions) do
position[x_index] = position[x_index] + x
position[y_index] = position[y_index] + y
@@ -149,11 +149,13 @@ local function create_entities(surface, offset)
local pos = apply_offset({ entity_details[2], entity_details[3] }, offset)
local entity = surface.create_entity{ name = entity_details[1], position = pos, force = "neutral" }
- if entity and config.entities.protected then
- protect_entity(entity)
- end
+ if entity then
+ if config.entities.protected then
+ protect_entity(entity)
+ end
- entity.operable = config.entities.operable
+ entity.operable = config.entities.operable
+ end
end
end
@@ -164,8 +166,7 @@ local function clear_spawn_area(surface, offset)
local get_tile = surface.get_tile
-- Make sure a non water tile is used for filling
- --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761
- local starting_tile = get_tile(offset)
+ local starting_tile = get_tile(offset.x, offset.y)
local fill_tile = starting_tile.collides_with("player") and "landfill" or starting_tile.name
local fill_radius = config.spawn_area.landfill_radius
local fill_radius_sqr = fill_radius ^ 2
@@ -185,8 +186,7 @@ local function clear_spawn_area(surface, offset)
if dst < tile_radius_sqr then
-- If it is inside the decon radius always set the tile
tiles_to_make[#tiles_to_make + 1] = { name = decon_tile, position = pos }
- --- @diagnostic disable-next-line Incorrect Api Type: https://forums.factorio.com/viewtopic.php?f=233&t=109145&p=593761&hilit=get_tile#p593761
- elseif dst < fill_radius_sqr and get_tile(pos).collides_with("player") then
+ elseif dst < fill_radius_sqr and get_tile(pos.x, pos.y).collides_with("player") then
-- If it is inside the fill radius only set the tile if it is water
tiles_to_make[#tiles_to_make + 1] = { name = fill_tile, position = pos }
end
@@ -278,7 +278,8 @@ local function on_player_created(event)
if config.resource_patches.enabled then create_resource_patches(surface, offset) end
if config.turrets.enabled then update_turrets() end
- player.force.set_spawn_position(offset, surface)
+ local force = player.force --[[@as LuaForce]]
+ force.set_spawn_position(offset, surface)
player.teleport(offset, surface)
end
diff --git a/exp_scenario/module/control/station_auto_name.lua b/exp_scenario/module/control/station_auto_name.lua
index fb9b8905..96b8fc09 100644
--- a/exp_scenario/module/control/station_auto_name.lua
+++ b/exp_scenario/module/control/station_auto_name.lua
@@ -66,8 +66,9 @@ local function rename_station(event)
-- Check which recourse is closest
for _, resource in ipairs(resources) do
- local dx = px - resource.bounding_box.left_top.x
- local dy = py - resource.bounding_box.left_top.y
+ local resource_box = resource.bounding_box
+ local dx = px - resource_box.left_top.x
+ local dy = py - resource_box.left_top.y
local distance = (dx * dx) + (dy * dy)
if distance < closest_distance then
closest_distance = distance
@@ -78,7 +79,8 @@ local function rename_station(event)
-- Set the item name and icon
if closest_recourse then
item_name = closest_recourse.name:gsub("^%l", string.upper):gsub("-", " ") -- remove dashes and making first letter capital
- local product = closest_recourse.prototype.mineable_properties.products[1]
+ local products = assert(closest_recourse.prototype.mineable_properties.products)
+ local product = assert(products[1])
icon = string.format("[img=%s.%s]", product.type, product.name)
end
end
diff --git a/exp_scenario/module/gui/autofill.lua b/exp_scenario/module/gui/autofill.lua
index c973a256..3dc16175 100644
--- a/exp_scenario/module/gui/autofill.lua
+++ b/exp_scenario/module/gui/autofill.lua
@@ -49,7 +49,7 @@ Elements.toggle_section_button = Gui.define("autofill/toggle_section_button")
element.sprite = "utility/expand"
element.tooltip = { "exp-gui_autofill.tooltip-toggle-section-expand" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Toggle if an entity will be autofilled when played
--- @class ExpGui_Autofill.elements.toggle_entity_button: ExpElement
@@ -88,7 +88,7 @@ Elements.toggle_entity_button = Gui.define("autofill/toggle_entity_button")
style.padding = 0
style.height = 22
style.width = 22
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Toggle if an item will be inserted into an entity
--- @class ExpGui_Autofill.elements.toggle_item_button: ExpElement
@@ -127,7 +127,7 @@ Elements.toggle_item_button = Gui.define("autofill/toggle_item_button")
style.padding = -2
style.height = 32
style.width = 32
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- The amount of an item to insert
--- @class ExpGui_Autofill.elements.amount_textfield: ExpElement
@@ -165,7 +165,7 @@ Elements.amount_textfield = Gui.define("autofill/amount_textfield")
element.text = tostring(clamped)
player.print{ "exp-gui_autofill.invalid", clamped, rich_img("item", item_settings.name), rich_img("entity", item_settings.entity) }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A disabled version of the autofill settings used as a filler
Elements.disabled_autofill_setting = Gui.define("autofill/empty_autofill_setting")
@@ -221,9 +221,9 @@ Elements.section = Gui.define("autofill/section")
end)
:on_click(function(def, player, element, event)
--- @cast def ExpGui_Autofill.elements.section
- event.element = def.data[element] --[[ @as LuaGuiElement ]]
+ event.element = def.data[element] --[[@as LuaGuiElement]]
Elements.toggle_section_button:raise_event(event)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Add an item category to a section, at most three can exist
--- @param section LuaGuiElement
@@ -238,7 +238,7 @@ function Elements.section.add_category(section, category_name)
category.style.vertical_spacing = 1
local ctn = 0
- local entity_settings = Elements.section.data[section] --[[ @as ExpGui_Autofill.entity_settings ]]
+ local entity_settings = Elements.section.data[section] --[[@as ExpGui_Autofill.entity_settings]]
for _, item_data in pairs(entity_settings.items) do
if item_data.category == category_name then
Elements.toggle_item_button(category, item_data)
@@ -265,7 +265,7 @@ end
--- Container added to the left gui flow
--- @class ExpGui_Autofill.elements.container: ExpElement
---- @field data table
+--- @field data table>
Elements.container = Gui.define("autofill/container")
:draw(function(def, parent)
--- @cast def ExpGui_Autofill.elements.container
@@ -312,7 +312,7 @@ Elements.container = Gui.define("autofill/container")
end
return container.parent
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Get the autofill settings for a player
--- @param player LuaPlayer
diff --git a/exp_scenario/module/gui/debug/expcore_gui_view.lua b/exp_scenario/module/gui/debug/expcore_gui_view.lua
index 4fd18849..399656de 100644
--- a/exp_scenario/module/gui/debug/expcore_gui_view.lua
+++ b/exp_scenario/module/gui/debug/expcore_gui_view.lua
@@ -27,7 +27,7 @@ function Public.show(container)
local left_panel_style = left_panel.style
left_panel_style.width = 300
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
for element_name in pairs(ExpElement._elements) do
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = element_name }
Gui.set_data(header, element_name)
@@ -92,18 +92,18 @@ Gui.on_click(
input_text_box.text = concat{ "ExpElement._elements[\"", element_name, "\"]" }
input_text_box.style.font_color = Color.black
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
local define = ExpElement._elements[element_name]
local content = dump({
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
debug = define._debug,
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
has_handlers = define._has_handlers,
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
track_elements = define._track_elements,
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
elements = ExpIter._scopes[element_name],
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
data = ExpData._scopes[element_name]._raw,
}) or "nil"
right_panel.text = content
diff --git a/exp_scenario/module/gui/debug/model.lua b/exp_scenario/module/gui/debug/model.lua
index 52ab850f..387aed88 100644
--- a/exp_scenario/module/gui/debug/model.lua
+++ b/exp_scenario/module/gui/debug/model.lua
@@ -4,7 +4,7 @@ local ExpUtil = require("modules/exp_util")
local concat = table.concat
local inspect = table.inspect
local pcall = pcall
-local loadstring = loadstring --- @diagnostic disable-line
+local loadstring = load
local rawset = rawset
local Public = {}
diff --git a/exp_scenario/module/gui/debug/redmew_global_view.lua b/exp_scenario/module/gui/debug/redmew_global_view.lua
index 8e387479..de43f1ac 100644
--- a/exp_scenario/module/gui/debug/redmew_global_view.lua
+++ b/exp_scenario/module/gui/debug/redmew_global_view.lua
@@ -24,7 +24,7 @@ function Public.show(container)
local left_panel_style = left_panel.style
left_panel_style.width = 300
- --- @diagnostic disable-next-line invisible
+ --- @diagnostic disable-next-line: access-invisible
for token_id in pairs(Storage._registered) do
local header = left_panel.add{ type = "flow" }.add{ type = "label", name = header_name, caption = token_id }
Gui.set_data(header, token_id)
diff --git a/exp_scenario/module/gui/elements.lua b/exp_scenario/module/gui/elements.lua
index 66cfc99d..f399c82d 100644
--- a/exp_scenario/module/gui/elements.lua
+++ b/exp_scenario/module/gui/elements.lua
@@ -22,11 +22,10 @@ Elements.online_player_dropdown = Gui.define("player_dropdown")
end)
:style{
height = 24,
- } --[[ @as any ]]
+ } --[[@as any]]
--- To help with caching and avoid context changes the player list from the previous update is remembered
---- @type (string?)[]
-do local _player_names = {}
+do local _player_names = {} --- @type (string?)[]
--- Updates the player name list after a join or leave
--- @return (string?)[]
function Elements.online_player_dropdown._update_player_names()
diff --git a/exp_scenario/module/gui/module_inserter.lua b/exp_scenario/module/gui/module_inserter.lua
index a39bd391..33011cec 100644
--- a/exp_scenario/module/gui/module_inserter.lua
+++ b/exp_scenario/module/gui/module_inserter.lua
@@ -78,7 +78,7 @@ Elements.create_selection_planner = Gui.define("module_inserter/create_selection
:on_click(function(def, player, element)
--- @cast def ExpGui_ModuleInserter.elements.create_selection_planner
SelectArea:start(player, def.data[element])
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Used to select the machine to apply modules to
--- @class ExpGui_ModuleInserter.elements.machine_selector: ExpElement
@@ -98,7 +98,7 @@ Elements.machine_selector = Gui.define("module_inserter/machine_selector")
:on_elem_changed(function(def, player, element, event)
--- @cast def ExpGui_ModuleInserter.elements.machine_selector
local element_data = def.data[element]
- local machine_name = element.elem_value --[[ @as string? ]]
+ local machine_name = element.elem_value --[[@as string?]]
if not machine_name then
if element_data.on_last_row then
Elements.module_table.reset_row(element_data.module_table, element)
@@ -112,7 +112,7 @@ Elements.machine_selector = Gui.define("module_inserter/machine_selector")
Elements.module_table.add_row(element_data.module_table)
end
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Used to select the modules to be applied
Elements.module_selector = Gui.define("module_inserter/module_selector")
@@ -140,7 +140,7 @@ Elements.module_table = Gui.define("module_inserter/module_table")
local slots_per_row = config.module_slots_per_row + 1
return Gui.elements.scroll_table(parent, 280, slots_per_row)
end)
- :element_data{} --[[ @as any ]]
+ :element_data{} --[[@as any]]
--- Get all the rows in a module table
--- @param module_table LuaGuiElement
@@ -177,7 +177,7 @@ end
--- @param machine_selector LuaGuiElement
function Elements.module_table.remove_row(module_table, machine_selector)
local rows = Elements.module_table.data[module_table]
- local row = rows[machine_selector.index]
+ local row = assert(rows[machine_selector.index])
rows[machine_selector.index] = nil
Gui.destroy_if_valid(machine_selector)
for _, separator in pairs(row.row_separators) do
@@ -193,7 +193,7 @@ end
--- @param machine_selector LuaGuiElement
function Elements.module_table.reset_row(module_table, machine_selector)
local rows = Elements.module_table.data[module_table]
- local row = rows[machine_selector.index]
+ local row = assert(rows[machine_selector.index])
for _, separator in pairs(row.row_separators) do
separator.visible = false
@@ -211,9 +211,9 @@ end
--- @param machine_name string
function Elements.module_table.refresh_row(module_table, machine_selector, machine_name)
local rows = Elements.module_table.data[module_table]
- local row = rows[machine_selector.index]
+ local row = assert(rows[machine_selector.index])
- local active_module_count = prototypes.entity[machine_name].module_inventory_size
+ local active_module_count = assert(prototypes.entity[machine_name].module_inventory_size)
local visible_row_count = math.ceil(active_module_count / config.module_slots_per_row)
local visible_module_count = visible_row_count * config.module_slots_per_row
local module_elem_value = { name = config.machines[machine_name].module }
@@ -277,8 +277,8 @@ local function apply_planners_in_area(player, area, machine_name, planner_with_p
-- Bounding box table to be reused in the loop below
--- @type BoundingBox
local param_area = {
- left_top = {},
- right_bottom = {}
+ left_top = { x = 0, y = 0 },
+ right_bottom = { x = 0, y = 0 },
}
-- Update area param table to be reused in the loop below
@@ -334,7 +334,7 @@ SelectArea:on_selection(function(event, module_table)
}
for _, row in pairs(Elements.module_table.get_rows(module_table)) do
- local machine_name = row.machine_selector.elem_value --[[ @as string? ]]
+ local machine_name = row.machine_selector.elem_value --[[@as string?]]
if not machine_name then
goto continue
end
@@ -348,8 +348,8 @@ SelectArea:on_selection(function(event, module_table)
-- Get all the modules selected
for i = 1, entity_prototype.module_inventory_size do
- local module_selector = module_selectors[i]
- local module = module_selector.elem_value --[[ @as { name: string, quality: string }? ]]
+ local module_selector = assert(module_selectors[i])
+ local module = module_selector.elem_value --[[@as { name: string, quality: string }?]]
if module then
-- Module selected, add it the module arrays
local no_prod_name = module.name:gsub("productivity", "efficiency")
diff --git a/exp_scenario/module/gui/player_bonus.lua b/exp_scenario/module/gui/player_bonus.lua
index 7c5fd84b..054c3088 100644
--- a/exp_scenario/module/gui/player_bonus.lua
+++ b/exp_scenario/module/gui/player_bonus.lua
@@ -22,13 +22,16 @@ local Elements = {}
--- @field _cost_scale number
--- For perf calculate the division of scale against cost ahead of time
-for _, bonus_data in pairs(config.player_bonus) do
+--- @type table
+local player_bonus = config.player_bonus
+
+for _, bonus_data in pairs(player_bonus) do
bonus_data._cost_scale = bonus_data.cost / bonus_data.scale
end
--- Progress bar which displays how much of a bonus has been used
--- @class ExpGui_PlayerBonus.elements.bonus_used: ExpElement
---- @field data number
+--- @field data table
--- @overload fun(parent: LuaGuiElement): LuaGuiElement
Elements.bonus_used = Gui.define("player_bonus/bonus_used")
:track_all_elements()
@@ -44,11 +47,10 @@ Elements.bonus_used = Gui.define("player_bonus/bonus_used")
font = "heading-2",
color = { 1, 0, 0 },
}
- :element_data(0) --[[ @as any ]]
+ :element_data(0) --[[@as any]]
--- Value is cached to save perf
---- @type table
-do local _points_limit = {}
+do local _points_limit = {} --- @type table
--- Clear the cache for points limit
--- @param player LuaPlayer
function Elements.bonus_used._clear_points_limit_cache(player)
@@ -145,7 +147,7 @@ Elements.reset_button = Gui.define("player_bonus/reset_button")
Elements.bonus_table.reset_sliders(element_data.bonus_table)
local bonus_cost = Elements.bonus_table.calculate_cost(element_data.bonus_table)
Elements.bonus_used.refresh(element_data.bonus_used, bonus_cost)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Link an apply button to this reset button so that it will be disabled after being pressed
--- @param reset_button LuaGuiElement
@@ -186,7 +188,7 @@ Elements.apply_button = Gui.define("player_bonus/apply_button")
Elements.bonus_table.save_sliders(element_data.bonus_table)
Elements.container.apply_player_bonus(player)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Link an apply button to this reset button so that it will be disabled after being pressed
--- @param apply_button LuaGuiElement
@@ -207,7 +209,7 @@ Elements.bonus_table_label = Gui.define("player_bonus/table_label")
}
:style{
width = Gui.from_argument(3, 70),
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class ExpGui_PlayerBonus.elements.bonus_slider.elements
--- @field bonus_used LuaGuiElement
@@ -265,7 +267,7 @@ Elements.bonus_slider = Gui.define("player_bonus/bonus_slider")
element_data.label.caption = Elements.bonus_slider.calculate_slider_caption(bonus_data, value)
element_data.apply_button.enabled = Elements.bonus_used.update(element_data.bonus_used, value_change * bonus_data._cost_scale)
element_data.reset_button.enabled = true
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Get the caption of the slider label
--- @param bonus_data ExpGui_PlayerBonus.bonus_data
@@ -311,7 +313,7 @@ Elements.bonus_table = Gui.define("player_bonus/bonus_table")
:draw(function(_, parent)
return Gui.elements.scroll_table(parent, 300, 3)
end)
- :element_data{} --[[ @as any ]]
+ :element_data{} --[[@as any]]
--- Adds a row to the milestone table
--- @param bonus_table LuaGuiElement
@@ -378,7 +380,7 @@ Elements.container = Gui.define("player_bonus/container")
Elements.bonus_used.refresh(elements.bonus_used, bonus_cost)
return Gui.elements.container.get_root_element(container)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Set the bonus value for a player
--- @param player LuaPlayer
@@ -442,7 +444,7 @@ end
function Elements.container.calculate_cost(player)
local cost = 0
local player_data = Elements.container.data[player]
- for _, bonus_data in pairs(config.player_bonus) do
+ for _, bonus_data in pairs(player_bonus) do
cost = cost + (player_data[bonus_data.name] or 0) * bonus_data._cost_scale
end
return cost
diff --git a/exp_scenario/module/gui/player_list.lua b/exp_scenario/module/gui/player_list.lua
index 3b5379b3..905b5be2 100644
--- a/exp_scenario/module/gui/player_list.lua
+++ b/exp_scenario/module/gui/player_list.lua
@@ -48,14 +48,14 @@ Elements.open_action_bar = Gui.define("player_list/open_action_bar")
--- @cast def ExpGui_PlayerList.elements.open_action_bar
Elements.container.toggle_selected_player(player, def.data[element])
Elements.player_table.refresh_player(player)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Set whether an open action bar button shows as highlighted
--- @param open_button LuaGuiElement
--- @param highlighted boolean
function Elements.open_action_bar.set_highlight(open_button, highlighted)
open_button.style = highlighted and "tool_button" or "frame_button"
- local style = open_button.style
+ local style = open_button.style --[[@as LuaStyle]]
style.padding = -2
style.width = 8
style.height = 14
@@ -80,7 +80,7 @@ Elements.close_action_bar = Gui.define("player_list/close_action_bar")
:on_click(function(_, player)
Elements.container.set_selected_player(player, nil)
Elements.player_table.refresh_player(player)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Button used to confirm a reason
--- @class ExpGui_PlayerList.elements.reason_confirm: ExpElement
@@ -102,14 +102,14 @@ Elements.reason_confirm = Gui.define("player_list/reason_confirm")
local action_name = Elements.container.get_selected_action(player)
local button_data = action_name and config.buttons[action_name]
if button_data and button_data.reason_callback then
- local reason = element.parent.entry.text
+ local reason = assert(element.parent).entry.text --[[@as string?]]
if reason == nil or not reason:find("%S") then reason = "no reason given" end
button_data.reason_callback(player, reason)
end
- element.parent.entry.text = ""
+ assert(element.parent).entry.text = ""
Elements.container.set_selected_player(player, nil)
Elements.player_table.refresh_player(player)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Clickable player name label, left click opens the map and right click toggles the action bar
--- @class ExpGui_PlayerList.elements.player_name_label: ExpElement
@@ -142,7 +142,7 @@ Elements.player_name_label = Gui.define("player_list/player_name_label")
Elements.container.toggle_selected_player(player, selected_player)
Elements.player_table.refresh_player(player)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_PlayerList.elements.player_table.row
--- @field open_button LuaGuiElement
@@ -165,7 +165,7 @@ Elements.player_table = Gui.define("player_list/player_table")
end)
:style{
padding = { 1, 0, 1, 2 },
- } --[[ @as any ]]
+ } --[[@as any]]
--- Store the action and reason bars associated with a player table
--- @param player_table LuaGuiElement
@@ -342,7 +342,7 @@ Elements.action_bar = Gui.define("player_list/action_bar")
:style{
height = 35,
padding = { 1, 3 },
- } --[[ @as any ]]
+ } --[[@as any]]
--- Update the action bar buttons to match the selection for a player, hidden when nothing is selected
--- @param action_bar LuaGuiElement
@@ -390,7 +390,7 @@ Elements.reason_bar = Gui.define("player_list/reason_bar")
:style{
height = 35,
padding = { -1, 3 },
- } --[[ @as any ]]
+ } --[[@as any]]
--- Update the reason bar visibility to match the selection, shown only while an action awaits a reason
--- @param reason_bar LuaGuiElement
@@ -420,7 +420,7 @@ Elements.container = Gui.define("player_list/container")
Elements.player_table.rebuild(player_table, row_data)
return Gui.elements.container.get_root_element(container)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Get or create the selection state for a player
--- @param player LuaPlayer
diff --git a/exp_scenario/module/gui/player_stats.lua b/exp_scenario/module/gui/player_stats.lua
index c615506d..b0a57df3 100644
--- a/exp_scenario/module/gui/player_stats.lua
+++ b/exp_scenario/module/gui/player_stats.lua
@@ -93,7 +93,7 @@ Elements.table_label = Gui.define("player_stats/table_label")
}
:style{
width = Gui.from_argument("width"),
- } --[[ @as any ]]
+ } --[[@as any]]
--- Data table that shows all data for a player
--- @class ExpGui_PlayerStats.elements.player_stats_table: ExpElement
@@ -139,7 +139,7 @@ Elements.player_stats_table = Gui.define("player_stats/data_table")
def.data[data_table] = labels
return data_table
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh a data table with the most recent stats for a player
--- @param data_table LuaGuiElement
@@ -185,7 +185,7 @@ Elements.player_dropdown = Gui.define("player_stats/player_dropdown")
local data_table = def.data[element]
local target_player = ElementsExtra.online_player_dropdown.get_selected(element)
Elements.player_stats_table.refresh(data_table, target_player)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh all stats tables associated with a player dropdown
function Elements.player_dropdown.refresh_online()
diff --git a/exp_scenario/module/gui/production_stats.lua b/exp_scenario/module/gui/production_stats.lua
index deea2314..94b49562 100644
--- a/exp_scenario/module/gui/production_stats.lua
+++ b/exp_scenario/module/gui/production_stats.lua
@@ -9,6 +9,7 @@ local Roles = require("modules/exp_legacy/expcore/roles")
local Elements = {}
--- The flow precision values in the same order as production_precision_dropdown.items
+--- @type defines.flow_precision_index[]
local precision_indexes = {
defines.flow_precision_index.five_seconds,
defines.flow_precision_index.one_minute,
@@ -94,7 +95,7 @@ Elements.item_selector = Gui.define("production_stats/item_selector")
element_data.on_last_row = false
Elements.production_table.add_row(element_data.production_table)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Label used for every element in the production table
Elements.table_label = Gui.define("production_stats/table_label")
@@ -129,7 +130,7 @@ Elements.production_table = Gui.define("production_stats/production_table")
:track_all_elements()
:draw(function(def, parent)
local scroll_table = Gui.elements.scroll_table(parent, 304, 4)
- local display_alignments = scroll_table.style.column_alignments
+ local display_alignments = assert(scroll_table.style.column_alignments)
for i = 2, 4 do
display_alignments[i] = "right"
end
@@ -144,7 +145,7 @@ Elements.production_table = Gui.define("production_stats/production_table")
Elements.table_label(scroll_table, { "exp-gui_production-stats.caption-net" }, { "exp-gui_production-stats.tooltip-per-second" }, "heading_2_label")
return scroll_table
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Calculate the row data for a production table
--- @param force LuaForce
@@ -183,7 +184,7 @@ end
--- @param item_selector LuaGuiElement
function Elements.production_table.remove_row(production_table, item_selector)
local rows = Elements.production_table.data[production_table].rows
- local row = rows[item_selector.index]
+ local row = assert(rows[item_selector.index])
rows[item_selector.index] = nil
Gui.destroy_if_valid(item_selector)
for _, element in pairs(row) do
@@ -196,7 +197,7 @@ end
--- @param item_selector LuaGuiElement
function Elements.production_table.reset_row(production_table, item_selector)
local rows = Elements.production_table.data[production_table].rows
- local row = rows[item_selector.index]
+ local row = assert(rows[item_selector.index])
row.production.caption = "0.00"
row.consumption.caption = "0.00"
row.net.caption = "0.00"
@@ -209,7 +210,7 @@ end
--- @param row_data ExpGui_ProductionStats.elements.production_table.row_data
function Elements.production_table.refresh_row(production_table, item_selector, row_data)
local rows = Elements.production_table.data[production_table].rows
- local row = rows[item_selector.index]
+ local row = assert(rows[item_selector.index])
row.production.caption = row_data.production
row.consumption.caption = row_data.consumption
row.net.caption = row_data.net
@@ -223,9 +224,9 @@ function Elements.production_table.refresh_online()
local precision_index = precision_indexes[element_data.precision_dropdown.selected_index]
for _, row in pairs(element_data.rows) do
local item_selector = row.item_selector
- local item_name = item_selector.elem_value --[[ @as string? ]]
+ local item_name = item_selector.elem_value --[[@as string?]]
if item_name then
- local row_data = Elements.production_table.calculate_row_data(player.force --[[ @as LuaForce ]], player.surface, item_name, precision_index)
+ local row_data = Elements.production_table.calculate_row_data(player.force --[[@as LuaForce]], player.surface, item_name, precision_index)
Elements.production_table.refresh_row(production_table, item_selector, row_data)
end
end
diff --git a/exp_scenario/module/gui/quick_actions.lua b/exp_scenario/module/gui/quick_actions.lua
index 0eacba2c..92d358aa 100644
--- a/exp_scenario/module/gui/quick_actions.lua
+++ b/exp_scenario/module/gui/quick_actions.lua
@@ -43,13 +43,13 @@ local function new_quick_action(command, on_click)
:style{
width = 160,
}
- :on_click(on_click or function(def, player, element, event)
+ :on_click(on_click or function(_def, player, _element, _event)
command(player)
end)
Elements[command_name] = element
Actions[command_name] = {
- command = command --[[ @as ExpCommand ]],
+ command = command --[[@as ExpCommand]],
element = element,
}
end
diff --git a/exp_scenario/module/gui/readme.lua b/exp_scenario/module/gui/readme.lua
index ed0cf6ea..5a7749b6 100644
--- a/exp_scenario/module/gui/readme.lua
+++ b/exp_scenario/module/gui/readme.lua
@@ -47,7 +47,7 @@ Elements.title_table = Gui.define("readme/title_table")
cell_padding = 0,
vertical_align = "center",
horizontally_stretchable = true,
- } --[[ @as any ]]
+ } --[[@as any]]
--- Scroll pane used for title tables
--- @class ExpGui_Readme.elements.title_table_scroll: ExpElement
@@ -64,7 +64,7 @@ Elements.title_table_scroll = Gui.define("readme/title_table_scroll")
padding = { 1, 3 },
maximal_height = scroll_height,
horizontally_stretchable = true,
- } --[[ @as any ]]
+ } --[[@as any]]
--- Sub content frame
--- @class ExpGui_Readme.elements.sub_content: ExpElement
@@ -80,7 +80,7 @@ Elements.sub_content = Gui.define("readme/sub_content")
horizontal_align = "center",
padding = { 2, 2 },
top_margin = 2,
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class ExpGui_Readme.elements.join_server.elements
--- @field server_id string
@@ -119,7 +119,7 @@ Elements.join_server = Gui.define("readme/join_server")
--- @cast def ExpGui_Readme.elements.join_server
local server_id = def.data[button].server_id
External.request_connection(player, server_id, true)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh join server button
--- @param button LuaGuiElement
@@ -244,7 +244,7 @@ define_tab(
)
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- Rules tab
@@ -261,14 +261,15 @@ define_tab(
local rules = Gui.elements.scroll_table(container, scroll_height, 1)
rules.style = "bordered_table"
- rules.style.cell_padding = 4
+ local rules_style = rules.style --[[@as LuaStyle]]
+ rules_style.cell_padding = 4
for i = 1, 15 do
Gui.elements.centered_label(rules, frame_width - 30, { "exp-gui_readme.rules-" .. i })
end
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- Commands tab
@@ -287,7 +288,8 @@ define_tab(
local commands = Gui.elements.scroll_table(container, scroll_height, 2)
commands.style = "bordered_table"
- commands.style.cell_padding = 0
+ local commands_style = commands.style --[[@as LuaStyle]]
+ commands_style.cell_padding = 0
for name, command in pairs(Commands.list_for_player(player)) do
Gui.elements.centered_label(commands, 120, name)
@@ -295,7 +297,7 @@ define_tab(
end
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- Servers tab
@@ -338,7 +340,7 @@ define_tab(
end
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- Backers tab
@@ -359,32 +361,32 @@ define_tab(
roles = { "Senior Administrator", "Administrator" },
title = { "exp-gui_readme.backers-management" },
width = 230,
- players = {},
+ players = {}, --- @type string[]
},
{
roles = { "Board Member", "Senior Backer" },
title = { "exp-gui_readme.backers-board" },
width = 145,
- players = {},
+ players = {}, --- @type string[]
},
{
roles = { "Sponsor", "Supporter" },
title = { "exp-gui_readme.backers-backers" },
width = 196,
- players = {},
+ players = {}, --- @type string[]
},
{
roles = { "Moderator", "Trainee" },
title = { "exp-gui_readme.backers-staff" },
width = 235,
- players = {},
+ players = {}, --- @type string[]
},
{
roles = {},
time = 3 * 3600 * 60,
title = { "exp-gui_readme.backers-active" },
width = 235,
- players = {},
+ players = {}, --- @type string[]
},
}
@@ -433,7 +435,7 @@ define_tab(
end
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- @class (exact) ExpGui_Readme.elements.readme_data.param table
@@ -599,7 +601,7 @@ define_tab(
end
return container
- end) --[[ @as any ]]
+ end) --[[@as any]]
)
--- @class ExpGui_Readme.elements.container.elements
@@ -608,6 +610,7 @@ define_tab(
--- Main readme container
--- @class ExpGui_Readme.elements.container: ExpElement
--- @field data table
+--- @overload fun(parent: LuaGuiElement): LuaGuiElement
Elements.container = Gui.define("readme/container")
:track_all_elements()
:draw(function(def, parent)
diff --git a/exp_scenario/module/gui/research_milestones.lua b/exp_scenario/module/gui/research_milestones.lua
index d1c1a5d9..4652edcd 100644
--- a/exp_scenario/module/gui/research_milestones.lua
+++ b/exp_scenario/module/gui/research_milestones.lua
@@ -72,7 +72,7 @@ Elements.clock_label = Gui.define("research_milestones/clock_label")
type = "label",
caption = research_time_format_nil,
style = "heading_2_label",
- } --[[ @as any ]]
+ } --[[@as any]]
--- Update the clock label for all online players
function Elements.clock_label.refresh_online()
@@ -95,7 +95,7 @@ Elements.milestone_table_label = Gui.define("research_milestones/table_label")
minimal_width = Gui.from_argument(2, 70),
horizontal_align = Gui.from_argument(3, "right"),
font_color = font_color.neutral,
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class ExpGui_ResearchMilestones.elements.milestone_table.row_elements
--- @field name LuaGuiElement
@@ -124,10 +124,11 @@ Elements.milestone_table = Gui.define("research_milestones/milestone_table")
Elements.milestone_table_label(milestone_table, { "exp-gui_research-milestones.caption-difference" })
return milestone_table
end)
- :element_data{} --[[ @as any ]]
+ :element_data{} --[[@as any]]
do local _row_data = {}
--- @type ExpGui_ResearchMilestones.elements.milestone_table.row_data
+ --- @diagnostic disable-next-line: missing-fields
local empty_row_data = { color = font_color.positive }
--- Get the row data for a force and research
@@ -203,7 +204,7 @@ end
--- @param row_index number
--- @param row_data ExpGui_ResearchMilestones.elements.milestone_table.row_data
function Elements.milestone_table.refresh_row(milestone_table, row_index, row_data)
- local row = Elements.milestone_table.data[milestone_table][row_index]
+ local row = assert(Elements.milestone_table.data[milestone_table][row_index])
row.name.caption = row_data.name
row.target.caption = row_data.target
row.achieved.caption = row_data.achieved
@@ -224,7 +225,7 @@ end
--- Refresh all the labels on the table
--- @param milestone_table LuaGuiElement
function Elements.milestone_table.refresh(milestone_table)
- local force = Gui.get_player(milestone_table).force --[[ @as LuaForce ]]
+ local force = Gui.get_player(milestone_table).force --[[@as LuaForce]]
local start_index = Elements.container.calculate_starting_research_index(force)
for row_index = 1, display_size do
local row_data = Elements.milestone_table.calculate_row_data(force, start_index + row_index - 1)
@@ -234,7 +235,7 @@ end
--- Refresh all tables for a player
function Elements.milestone_table.refresh_player(player)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local start_index = Elements.container.calculate_starting_research_index(force)
for _, milestone_table in Elements.milestone_table:online_elements(player) do
for row_index = 1, display_size do
@@ -269,10 +270,9 @@ Elements.container = Gui.define("research_milestones/container")
local milestone_table = Elements.milestone_table(container)
Elements.clock_label(header)
- local force = Gui.get_player(parent).force
+ local force = Gui.get_player(parent).force --[[@as LuaForce]]
def.data[force] = def.data[force] or {} -- used by start index and row data
- local force = Gui.get_player(parent).force --[[ @as LuaForce ]]
local start_index = Elements.container.calculate_starting_research_index(force)
for research_index = start_index, start_index + display_size - 1 do
local row_data = Elements.milestone_table.calculate_row_data(force, research_index)
@@ -296,7 +296,7 @@ end
--- @param research_index number
--- @return number
function Elements.container.get_achieved_time(force, research_index)
- return Elements.container.data[force][research_index]
+ return assert(Elements.container.data[force][research_index])
end
--- Calculate the starting research index for a force
diff --git a/exp_scenario/module/gui/rocket_info.lua b/exp_scenario/module/gui/rocket_info.lua
index c377155a..d7999db3 100644
--- a/exp_scenario/module/gui/rocket_info.lua
+++ b/exp_scenario/module/gui/rocket_info.lua
@@ -90,7 +90,7 @@ Elements.toggle_section_button = Gui.define("rocket_info/toggle_section_button")
element.sprite = "utility/expand"
element.tooltip = { "exp-gui_rocket-info.tooltip-toggle-section-expand" }
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- A clickable coordinate label which opens the silo location on the map when pressed
--- @class ExpGui_RocketInfo.elements.position_label: ExpElement
@@ -114,7 +114,7 @@ Elements.position_label = Gui.define("rocket_info/position_label")
local entity = def.data[element]
if not entity or not entity.valid then return end
player.set_controller{ type = defines.controllers.remote, position = entity.position, surface = entity.surface }
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Data table showing the launch statistics for a force
--- @class ExpGui_RocketInfo.elements.stats_table: ExpElement
@@ -125,7 +125,7 @@ Elements.stats_table = Gui.define("rocket_info/stats_table")
:element_data{}
:draw(function(def, parent)
return Gui.elements.scroll_table(parent, 215, 2)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_RocketInfo.elements.stats_table.row_data
--- @field key string Unique key used to look up the value label
@@ -218,7 +218,7 @@ end
--- Refresh the stats table for a player, adding any rows that do not yet exist
--- @param player LuaPlayer
function Elements.stats_table.refresh_player(player)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local row_data = Elements.stats_table.calculate_row_data(force)
for _, stats_table in Elements.stats_table:online_elements(player) do
Elements.stats_table.refresh(stats_table, row_data)
@@ -243,7 +243,7 @@ Elements.milestones_table = Gui.define("rocket_info/milestones_table")
:element_data{}
:draw(function(def, parent)
return Gui.elements.scroll_table(parent, 215, 2)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_RocketInfo.elements.milestones_table.row_data
--- @field milestone number The milestone this row represents
@@ -315,7 +315,7 @@ end
--- Refresh the milestones table for a player, adding rows as new milestones become visible
--- @param player LuaPlayer
function Elements.milestones_table.refresh_player(player)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local row_data = Elements.stats_table.calculate_row_data(force)
for _, stats_table in Elements.stats_table:online_elements(player) do
Elements.stats_table.refresh(stats_table, row_data)
@@ -359,7 +359,7 @@ Elements.progress_table = Gui.define("rocket_info/progress_table")
def.data[progress_table] = { rows = {}, no_silos = no_silos }
return progress_table
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_RocketInfo.elements.progress_table.row_data
--- @field entity LuaEntity
@@ -404,9 +404,9 @@ end
--- @return ExpGui_RocketInfo.elements.progress_table.row_data[]
function Elements.progress_table.calculate_row_data_all(silo_data)
local row_data = {}
- for unit_number, silo_data in pairs(silo_data) do
- if silo_data.entity.valid then
- row_data[unit_number] = Elements.progress_table.calculate_row_data(silo_data)
+ for unit_number, silo in pairs(silo_data) do
+ if silo.entity.valid then
+ row_data[unit_number] = Elements.progress_table.calculate_row_data(silo)
else
-- Prune silos that are no longer valid
silo_data[unit_number] = nil
@@ -433,7 +433,8 @@ function Elements.progress_table.add_row(progress_table, row_data)
progress.style.padding = { 0, 2 }
progress.style.font_color = row_data.color
- rows[row_data.entity.unit_number] = { x = x, y = y, progress = progress }
+ local unit_number = row_data.entity.unit_number --[[@as uint]]
+ rows[unit_number] = { x = x, y = y, progress = progress }
end
--- Remove a silo row from the progress table
@@ -455,7 +456,8 @@ end
--- @param row_data ExpGui_RocketInfo.elements.progress_table.row_data
function Elements.progress_table.refresh_row(progress_table, row_data)
local element_data = Elements.progress_table.data[progress_table]
- local row = element_data.rows[row_data.entity.unit_number]
+ local unit_number = row_data.entity.unit_number --[[@as uint]]
+ local row = element_data.rows[unit_number]
row.x.caption = row_data.x
row.y.caption = row_data.y
row.progress.caption = row_data.caption
@@ -496,7 +498,7 @@ end
--- Refresh the progress table for a player, reconciling rows with the current set of silos
--- @param player LuaPlayer
function Elements.progress_table.refresh_player(player)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local silos = Elements.container.get_silos(force)
local row_data = Elements.progress_table.calculate_row_data_all(silos)
for _, progress_table in Elements.progress_table:online_elements(player) do
@@ -539,7 +541,7 @@ Elements.container = Gui.define("rocket_info/container")
container.style.padding = 0
local player = Gui.get_player(parent)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local force_data = def._get_force_data(force)
if config.stats.show_stats then
@@ -618,9 +620,10 @@ end
--- Add a silo to the list of current silos for a force
--- @param entity LuaEntity
function Elements.container.add_silo(entity)
- local force = entity.force --[[ @as LuaForce ]]
+ local force = entity.force --[[@as LuaForce]]
local silos = Elements.container._get_force_data(force).silos
- silos[entity.unit_number] = {
+ local unit_number = entity.unit_number --[[@as uint]]
+ silos[unit_number] = {
entity = entity,
launched = 0,
awaiting_reset = false,
@@ -630,9 +633,11 @@ end
--- Increment the launch count for a silo
--- @param entity LuaEntity
function Elements.container.increment_silo(entity)
- local force = entity.force --[[ @as LuaForce ]]
+ local force = entity.force --[[@as LuaForce]]
local silos = Elements.container._get_force_data(force).silos
- local silo_data = silos[entity.unit_number]
+ local unit_number = entity.unit_number
+ --- @cast unit_number uint
+ local silo_data = silos[unit_number]
if not silo_data then return end
silo_data.launched = silo_data.launched + 1
silo_data.awaiting_reset = true
@@ -653,8 +658,8 @@ Gui.toolbar.create_button{
--- Record the launch and update the stats when a cargo pod finishes ascending
--- @param event EventData.on_cargo_pod_finished_ascending
local function on_cargo_pod_finished_ascending(event)
- local force = event.cargo_pod.force --[[ @as LuaForce ]]
- local rockets_launched = force.rockets_launched
+ local force = event.cargo_pod.force --[[@as LuaForce]]
+ local rockets_launched = force.rockets_launched --[[@as number]]
-- Update the launch stats for the force
local stats = Elements.container.get_stats(force)
@@ -686,7 +691,7 @@ end
--- @param event EventData.on_rocket_launch_ordered
local function on_rocket_launch_ordered(event)
Elements.container.increment_silo(event.rocket_silo)
- Elements.progress_table.refresh_force(event.rocket_silo.force --[[ @as LuaForce ]])
+ Elements.progress_table.refresh_force(event.rocket_silo.force --[[@as LuaForce]])
end
--- Refresh the gui when a player joins the game as it may be outdated
@@ -704,7 +709,7 @@ local function on_built(event)
local entity = event.entity
if not entity.valid or entity.name ~= "rocket-silo" then return end
Elements.container.add_silo(entity)
- Elements.progress_table.refresh_force(entity.force --[[ @as LuaForce ]])
+ Elements.progress_table.refresh_force(entity.force --[[@as LuaForce]])
end
--- Refresh the progress for all forces that own at least one silo
diff --git a/exp_scenario/module/gui/science_production.lua b/exp_scenario/module/gui/science_production.lua
index 0224a253..ad7772af 100644
--- a/exp_scenario/module/gui/science_production.lua
+++ b/exp_scenario/module/gui/science_production.lua
@@ -79,7 +79,7 @@ Elements.production_label = Gui.define("science_production/production_label")
def.data[label] = suffix
return label
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class Elements.production_label.display_data
--- @field caption LocalisedString
@@ -109,7 +109,7 @@ function Elements.production_label.calculate_display_data(tooltip, value, cutoff
end
local suffix, caption = format_number(value)
- display_data = display_data or {}
+ display_data = display_data or {} --[[@as Elements.production_label.display_data]]
display_data.caption = caption
display_data.suffix = suffix
display_data.tooltip = tooltip
@@ -144,12 +144,12 @@ Elements.no_production_label = Gui.define("science_production/no_production_labe
padding = { 2, 4 },
single_line = false,
width = 200,
- } --[[ @as any ]]
+ } --[[@as any]]
--- Refresh a no production label
--- @param no_production_label LuaGuiElement
function Elements.no_production_label.refresh(no_production_label)
- local force = Gui.get_player(no_production_label).force --[[ @as LuaForce ]]
+ local force = Gui.get_player(no_production_label).force --[[@as LuaForce]]
no_production_label.visible = not Elements.container.has_production(force)
end
@@ -157,7 +157,7 @@ end
function Elements.no_production_label.refresh_online()
local force_data = {}
for player, no_production_label in Elements.no_production_label:online_elements() do
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local visible = force_data[force.name]
if visible == nil then
visible = not Elements.container.has_production(force)
@@ -193,10 +193,11 @@ Elements.science_table = Gui.define("science_production/science_table")
local science_table = Gui.elements.scroll_table(parent, 190, 4)
local no_production_label = Elements.no_production_label(science_table)
Elements.no_production_label.refresh(no_production_label)
- science_table.style.column_alignments[3] = "right"
+ local science_table_style = science_table.style --[[@as LuaStyle]]
+ science_table_style.column_alignments[3] = "right"
return science_table
end)
- :element_data{} --[[ @as any ]]
+ :element_data{} --[[@as any]]
--- Calculate the data needed to add or refresh a row
--- @param force LuaForce
@@ -220,7 +221,7 @@ function Elements.science_table.calculate_row_data(force, science_pack, row_data
end
-- Return the pack data
- row_data = row_data or {}
+ row_data = row_data or {} --[[@as ExpGui_ScienceProduction.elements.science_table.row_data]]
row_data.visible = production.total.made > 0
row_data.science_pack = science_pack
row_data.icon_style = icon_style
@@ -280,7 +281,8 @@ function Elements.science_table.add_row(science_table, row_data)
column_count = 2,
}
delta_table.style.padding = 0
- delta_table.style.column_alignments[1] = "right"
+ local delta_table_style = delta_table.style --[[@as LuaStyle]]
+ delta_table_style.column_alignments[1] = "right"
-- Draw the net production label
local net = Elements.production_label(science_table, row_data.net)
@@ -312,7 +314,8 @@ function Elements.science_table.refresh_row(science_table, row_data)
-- Update the icon
local icon = row.icon
icon.style = row_data.icon_style
- icon.style.height = 55
+ local icon_style = icon.style --[[@as LuaStyle]]
+ icon_style.height = 55
-- Update the element visibility
row.net_suffix.visible = true
@@ -326,8 +329,7 @@ function Elements.science_table.refresh_row(science_table, row_data)
Elements.production_label.refresh(row.used, row_data.used)
end
---- @type table
-do local _row_data = {}
+do local _row_data = {} --- @type table>
--- Refresh the production tables for all online players
function Elements.science_table.refresh_online()
-- Refresh the row data for online forces
@@ -361,7 +363,7 @@ Elements.eta_label = Gui.define("science_production/eta_label")
caption = clock_time_format_nil,
tooltip = long_time_format_nil,
style = "frame_title",
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class Elements.eta_label.display_data
--- @field caption LocalisedString
@@ -410,14 +412,13 @@ end
--- Refresh an eta label
--- @param eta_label LuaGuiElement
function Elements.eta_label.refresh(eta_label)
- local force = Gui.get_player(eta_label).force --[[ @as LuaForce ]]
+ local force = Gui.get_player(eta_label).force --[[@as LuaForce]]
local display_data = Elements.eta_label.calculate_display_data(force)
eta_label.caption = display_data.caption
eta_label.tooltip = display_data.tooltip
end
---- @type Elements.eta_label.display_data
-do local _display_data = {}
+do local _display_data = {} --- @type table
--- Refresh the eta label for all online players
function Elements.eta_label.refresh_online()
-- Refresh the row data for online forces
@@ -430,8 +431,10 @@ do local _display_data = {}
-- Update the eta labels
for player, eta_label in Elements.eta_label:online_elements() do
local display_data = _display_data[player.force.name]
- eta_label.caption = display_data.caption
- eta_label.tooltip = display_data.tooltip
+ if display_data then
+ eta_label.caption = display_data.caption
+ eta_label.tooltip = display_data.tooltip
+ end
end
end
end
@@ -443,7 +446,7 @@ Elements.container = Gui.define("science_production/container")
local container = Gui.elements.container(parent)
Gui.elements.header(container, { caption = { "exp-gui_science-production.caption-main" } })
- local force = Gui.get_player(parent).force --[[ @as LuaForce ]]
+ local force = Gui.get_player(parent).force --[[@as LuaForce]]
local science_table = Elements.science_table(container)
for _, science_pack in ipairs(config) do
--- @cast science_pack any
@@ -462,7 +465,7 @@ Elements.container = Gui.define("science_production/container")
end
return Gui.elements.container.get_root_element(container)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Cached mostly because they are long names
local _fp_one_minute = defines.flow_precision_index.one_minute
@@ -477,8 +480,7 @@ local _fp_one_hour = defines.flow_precision_index.one_hour
--- @field ten_minutes ExpGui_ScienceProduction._item_data
--- @field one_hour ExpGui_ScienceProduction._item_data
---- @type table
-do local _production_data = {}
+do local _production_data = {} --- @type table
--- Get the production stats for a force
--- @param flow_stats any
diff --git a/exp_scenario/module/gui/surveillance.lua b/exp_scenario/module/gui/surveillance.lua
index 0c1e79e2..0fd65924 100644
--- a/exp_scenario/module/gui/surveillance.lua
+++ b/exp_scenario/module/gui/surveillance.lua
@@ -25,7 +25,7 @@ Elements.player_dropdown = Gui.define("surveillance/player_dropdown")
local camera = def.data[element]
local target_player = assert(ElementsExtra.online_player_dropdown.get_selected(element))
Elements.camera.set_target_player(camera, target_player)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Button which sets the target of a camera to the current location
--- @class ExpGui_Surveillance.elements.set_location_button: ExpElement
@@ -48,7 +48,7 @@ Elements.set_location_button = Gui.define("surveillance/set_location_button")
--- @cast def ExpGui_Surveillance.elements.set_location_button
local camera = def.data[element]
Elements.camera.set_target_position(camera, player.physical_surface_index, player.physical_position)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_Surveillance.elements.type_dropdown.data
--- @field player_dropdown LuaGuiElement
@@ -87,7 +87,7 @@ Elements.type_dropdown = Gui.define("surveillance/type_dropdown")
local target_player = ElementsExtra.online_player_dropdown.get_selected(element_data.player_dropdown)
Elements.camera.set_target_player(element_data.camera, target_player)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh all online type dropdowns by cycling the associated player dropdown
function Elements.type_dropdown.refresh_online()
@@ -131,7 +131,7 @@ Elements.zoom_out_button = Gui.define("surveillance/zoom_out_button")
if camera.zoom > 0.2 then
camera.zoom = camera.zoom - 0.05
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Buttons which increases zoom by 5%
--- @class ExpGui_Surveillance.elements.zoom_in_button: ExpElement
@@ -156,7 +156,7 @@ Elements.zoom_in_button = Gui.define("surveillance/zoom_in_button")
if camera.zoom < 2.0 then
camera.zoom = camera.zoom + 0.05
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Camera which tracks a target with a physical_position and surface_index
--- @class ExpGui_Surveillance.elements.camera: ExpElement
@@ -176,7 +176,7 @@ Elements.camera = Gui.define("surveillance/camera")
}
:element_data(
Gui.from_argument(1)
- ) --[[ @as any ]]
+ ) --[[@as any]]
--- Set the target player for the camera
--- @param camera LuaGuiElement
diff --git a/exp_scenario/module/gui/task_list.lua b/exp_scenario/module/gui/task_list.lua
index e777aa3d..75858bad 100644
--- a/exp_scenario/module/gui/task_list.lua
+++ b/exp_scenario/module/gui/task_list.lua
@@ -105,7 +105,7 @@ Elements.new_task_button = Gui.define("task_list/new_task_button")
body = "",
new = true,
})
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the visibility based on player permissions
--- @param new_task_button LuaGuiElement
@@ -154,7 +154,7 @@ Elements.view_task_button = Gui.define("task_list/view_task_button")
--- @cast def ExpGui_TaskList.element.view_task_button
local elements = def.data[view_task_button]
Elements.container.open_view_task(elements.container, elements.task)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the title and tooltip of the view task button
--- @param view_task_button LuaGuiElement
@@ -187,19 +187,19 @@ Elements.no_tasks_header = Gui.define("task_list/no_tasks_header")
:style{
padding = { 2, 0 },
bottom_margin = 0,
- } --[[ @as any ]]
+ } --[[@as any]]
--- Refresh the visibility of the no tasks label
--- @param no_tasks_header LuaGuiElement
function Elements.no_tasks_header.refresh(no_tasks_header)
- local force = Gui.get_player(no_tasks_header).force --[[ @as LuaForce ]]
+ local force = Gui.get_player(no_tasks_header).force --[[@as LuaForce]]
no_tasks_header.visible = not Elements.container.has_tasks(force)
end
--- Refresh the visibility of the no tasks label
--- @param player LuaPlayer
function Elements.no_tasks_header.refresh_player(player)
- local visible = not Elements.container.has_tasks(player.force --[[ @as LuaForce ]])
+ local visible = not Elements.container.has_tasks(player.force --[[@as LuaForce]])
for _, no_tasks_header in Elements.no_tasks_header:tracked_elements(player) do
no_tasks_header.visible = visible
end
@@ -246,13 +246,13 @@ Elements.task_list = Gui.define("task_list/task_list")
return task_list
end)
- :element_data{} --[[ @as any ]]
+ :element_data{} --[[@as any]]
--- Adds a task to the task list
--- @param task_list LuaGuiElement
--- @param task ExpGui_TaskList.Task
function Elements.task_list.add_task(task_list, task)
- local container = assert(task_list.parent.parent.parent)
+ local container = assert(assert(assert(task_list.parent).parent).parent)
local view_task_buttons = Elements.task_list.data[task_list]
view_task_buttons[task.id] = Elements.view_task_button(task_list, task, container)
end
@@ -330,7 +330,7 @@ Elements.task_footer = Gui.define("task_list/task_footer")
height = 0,
padding = 5,
use_header_filler = false,
- } --[[ @as any ]]
+ } --[[@as any]]
--- @class ExpGui_TaskList.elements.close_task_button.elements
--- @field container LuaGuiElement
@@ -354,7 +354,7 @@ Elements.close_task_button = Gui.define("task_list/close_task_button")
--- @cast def ExpGui_TaskList.element.close_task_button
local elements = def.data[close_task_button]
Elements.container.close_footers(elements.container)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- @class ExpGui_TaskList.elements.task_button.elements
--- @field task ExpGui_TaskList.Task?
@@ -379,7 +379,7 @@ Elements.edit_task_button = Gui.define("task_list/edit_task_button")
--- @cast def ExpGui_TaskList.element.edit_task_button
local elements = def.data[edit_task_button]
Elements.container.open_edit_task(elements.container, assert(elements.task))
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the edit button
--- @param edit_task_button LuaGuiElement
@@ -415,9 +415,9 @@ Elements.delete_task_button = Gui.define("task_list/delete_task_button")
:on_click(function(def, player, delete_task_button)
--- @cast def ExpGui_TaskList.element.delete_task_button
local elements = def.data[delete_task_button]
- Elements.container.remove_task(player.force --[[ @as LuaForce ]], elements.task)
+ Elements.container.remove_task(player.force --[[@as LuaForce]], elements.task)
Elements.container.close_footers(elements.container)
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the delete button
--- @param delete_task_button LuaGuiElement
@@ -477,7 +477,7 @@ Elements.view_task_footer = Gui.define("task_list/view_task_footer")
}
return view_task_footer
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the view task with new task details
--- @param view_task_footer LuaGuiElement
@@ -532,9 +532,9 @@ Elements.task_message_textfield = Gui.define("task_list/task_message_textfield")
}
:on_text_changed(function(def, player, task_message_textfield)
--- @cast def ExpGui_TaskList.elements.task_message_textfield
- local confirm_task_button = def.data[task_message_textfield].confirm_task_button
+ local confirm_task_button = assert(def.data[task_message_textfield].confirm_task_button)
confirm_task_button.enabled = string.len(task_message_textfield.text) > 5
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Set the confirm task button to update on text changed
--- @param task_message_textfield LuaGuiElement
@@ -549,7 +549,7 @@ end
function Elements.task_message_textfield.refresh(task_message_textfield, task)
local elements = Elements.task_message_textfield.data[task_message_textfield]
local message = task.new and "" or task.title .. "\n" .. task.body
- elements.confirm_task_button.enabled = string.len(message) > 5
+ assert(elements.confirm_task_button).enabled = string.len(message) > 5
task_message_textfield.text = message
task_message_textfield.focus()
end
@@ -590,13 +590,13 @@ Elements.confirm_task_button = Gui.define("task_list/confirm_task_button")
Elements.container.close_footers(elements.container)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
if task.new then
Elements.container.add_task(force, task)
else
Elements.container.refresh_force_online(force, task)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the confirm task button
--- @param confirm_task_button LuaGuiElement
@@ -612,7 +612,7 @@ function Elements.confirm_task_button.parse(message)
-- Trim the spaces of the string
local trimmed = string.gsub(message, "^%s*(.-)%s*$", "%1")
local title, body = string.match(trimmed, "(.-)\n(.*)")
- local parsed = { title = title, body = body }
+ local parsed = { title = title, body = body } --[[@as { title: string, body: string }]]
if not title then
-- If it doesn't match the pattern return the str as a title
parsed.title = trimmed
@@ -649,7 +649,7 @@ Elements.discard_task_button = Gui.define("task_list/discard_task_button")
else
Elements.container.open_view_task(elements.container, task)
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the discard task button
--- @param discard_task_button LuaGuiElement
@@ -696,7 +696,7 @@ Elements.edit_task_footer = Gui.define("task_list/edit_task_footer")
}
return edit_task_footer
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the view task with new task details
--- @param edit_task_footer LuaGuiElement
@@ -755,9 +755,14 @@ end
--- @field view_task_footer LuaGuiElement
--- @field edit_task_footer LuaGuiElement
+--- @class ExpGui_TaskList.elements.container.data
+--- @field global_data { next_task_id: number }
+--- @field [LuaGuiElement] ExpGui_TaskList.elements.container.elements
+--- @field [LuaForce] ExpGui_TaskList.Task[]
+
--- Container added to the left gui flow
--- @class ExpGui_TaskList.elements.container: ExpElement
---- @field data table | table | table<"global_data", { next_task_id: number }>
+--- @field data ExpGui_TaskList.elements.container.data
Elements.container = Gui.define("task_list/container")
:track_all_elements()
:draw(function(def, parent)
@@ -781,7 +786,7 @@ Elements.container = Gui.define("task_list/container")
-- Add tasks to the list if there are any
local player = Gui.get_player(parent)
- local force = player.force --[[ @as LuaForce ]]
+ local force = player.force --[[@as LuaForce]]
local tasks = def.data[force]
if tasks then
for _, task in ipairs(tasks) do
@@ -796,11 +801,11 @@ Elements.container = Gui.define("task_list/container")
elements.edit_task_footer.visible = false
-- Set the data and return
- def.data[root] = elements --[[ @as any ]]
+ def.data[root] = elements --[[@as any]]
return root
end)
:global_data{ next_task_id = 1 }
- :force_data{} --[[ @as any ]]
+ :force_data{} --[[@as any]]
--- Check if a force has tasks
--- @param force LuaForce
@@ -885,7 +890,7 @@ end
--- Refresh all tasks for a player
--- @param player LuaPlayer
function Elements.container.refresh_player(player)
- local tasks = Elements.container.data[ player.force --[[ @as LuaForce ]] ]
+ local tasks = Elements.container.data[ player.force --[[@as LuaForce]] ]
for _, container in Elements.container:tracked_elements(player) do
local elements = Elements.container.data[container]
Elements.task_list.refresh_tasks(elements.task_list, tasks)
@@ -908,7 +913,7 @@ end
--- Add the element to the left flow with a toolbar button
Gui.add_left_element(Elements.container, function(player)
- return Elements.container.has_tasks(player.force --[[ @as LuaForce ]])
+ return Elements.container.has_tasks(player.force --[[@as LuaForce]])
end)
Gui.toolbar.create_button{
diff --git a/exp_server_ups/module/control.lua b/exp_server_ups/module/control.lua
index b39eab29..6d51c9d3 100644
--- a/exp_server_ups/module/control.lua
+++ b/exp_server_ups/module/control.lua
@@ -42,7 +42,7 @@ Elements.server_ups = Gui.define("server_ups")
if not existing or not existing.valid then
def.data[player] = element -- Only set if previous is invalid
end
- end) --[[ @as any ]]
+ end) --[[@as any]]
--- Refresh the caption for all online players
--- @param ups number The UPS to be displayed
diff --git a/exp_util/module/aabb.lua b/exp_util/module/aabb.lua
index 64c5719d..7b985702 100644
--- a/exp_util/module/aabb.lua
+++ b/exp_util/module/aabb.lua
@@ -11,22 +11,22 @@ local max = math.max
local AABB = {}
--- Check if an area is valid
---- @param aabb BoundingBox
+--- @param aabb BoundingBox.struct
--- @return boolean # True if the area is valid
function AABB.valid(aabb)
return aabb.left_top.x < aabb.right_bottom.x and aabb.left_top.y < aabb.right_bottom.y
end
--- Returns the size of the area contained within an AABB
---- @param aabb BoundingBox
+--- @param aabb BoundingBox.struct
--- @return number
function AABB.size(aabb)
return (aabb.right_bottom.x - aabb.left_top.x) * (aabb.right_bottom.y - aabb.left_top.y)
end
--- Clone an area, allows for safe mutation of an input value
---- @param aabb BoundingBox
---- @return BoundingBox
+--- @param aabb BoundingBox.struct
+--- @return BoundingBox.struct
function AABB.clone(aabb)
return {
left_top = { x = aabb.left_top.x, y = aabb.left_top.y },
@@ -35,8 +35,8 @@ function AABB.clone(aabb)
end
--- Expand an area to be integer aligned, expanding away from 0
---- @param aabb BoundingBox
---- @return BoundingBox
+--- @param aabb BoundingBox.struct
+--- @return BoundingBox.struct
function AABB.expand(aabb)
return {
left_top = { x = floor(aabb.left_top.x), y = floor(aabb.left_top.y) },
@@ -45,8 +45,8 @@ function AABB.expand(aabb)
end
--- Contract an area to be integer aligned, contracting towards 0
---- @param aabb BoundingBox
---- @return BoundingBox
+--- @param aabb BoundingBox.struct
+--- @return BoundingBox.struct
function AABB.contract(aabb)
return {
left_top = { x = ceil(aabb.left_top.x), y = ceil(aabb.left_top.y) },
@@ -55,9 +55,9 @@ function AABB.contract(aabb)
end
--- Expand an area to include all other areas
---- @param aabb BoundingBox
---- @param ... BoundingBox
---- @return BoundingBox
+--- @param aabb BoundingBox.struct
+--- @param ... BoundingBox.struct
+--- @return BoundingBox.struct
function AABB.union(aabb, ...)
local rtn = AABB.clone(aabb)
for _, next_aabb in ipairs{ ... } do
@@ -70,9 +70,9 @@ function AABB.union(aabb, ...)
end
--- Contract an area to include to the overlap of all areas
---- @param aabb BoundingBox
---- @param ... BoundingBox
---- @return BoundingBox? # Nil if there is no intersection
+--- @param aabb BoundingBox.struct
+--- @param ... BoundingBox.struct
+--- @return BoundingBox.struct? # Nil if there is no intersection
function AABB.intersect(aabb, ...)
local rtn = AABB.clone(aabb)
for _, next_aabb in ipairs{ ... } do
@@ -88,8 +88,8 @@ function AABB.intersect(aabb, ...)
end
--- Check if a point is contained within an area
---- @param aabb BoundingBox
---- @param point MapPosition
+--- @param aabb BoundingBox.struct
+--- @param point MapPosition.struct
--- @return boolean # True if the point is within or on the edge of the bounding box
function AABB.contains_point(aabb, point)
return point.x >= aabb.left_top.x and point.y >= aabb.left_top.y
@@ -97,8 +97,8 @@ function AABB.contains_point(aabb, point)
end
--- Check if an area is fulling contained within another area
---- @param aabb BoundingBox
---- @param other BoundingBox
+--- @param aabb BoundingBox.struct
+--- @param other BoundingBox.struct
--- @return boolean # True if the point is within or on the edge of the bounding box
function AABB.contains_area(aabb, other)
return AABB.contains_point(aabb, other.left_top) and AABB.contains_point(aabb, other.right_bottom)
diff --git a/exp_util/module/async.lua b/exp_util/module/async.lua
index 9afaa377..e3847436 100644
--- a/exp_util/module/async.lua
+++ b/exp_util/module/async.lua
@@ -93,8 +93,8 @@ local Async = {
Async.status = {}
--- @class Async.AsyncFunction
---- @field id number The id of this async function
---- @operator call: Async.AsyncReturn
+--- @field id string The id of this async function
+--- @overload fun(...: any): Async.AsyncReturn
Async._function_prototype = {}
Async._function_metatable = {
@@ -104,10 +104,10 @@ Async._function_metatable = {
}
--- @class Async.AsyncReturn
---- @field func_id number The id of the async function to be called
+--- @field func_id string The id of the async function to be called
--- @field args any[] The arguments to call the function with
--- @field tick number? If present, the function will be called on this game tick
---- @field next_id number? The id of the async function to be called with the return value
+--- @field next_id string? The id of the async function to be called with the return value
--- @field canceled boolean? True if the call has been canceled
--- @field completed boolean? True if the call has completed
--- @field return_values any? The return values of the function call
@@ -123,20 +123,20 @@ script.register_metatable("AsyncReturn", Async._return_metatable)
--- Storage Variables
-local resolve_next --- @type Async.AsyncReturn[] Stores a queue of async functions to be executed on the next tick
-local resolve_queue --- @type Async.AsyncReturn[] Stores a queue of async functions to be executed on a later tick
+local resolve_next --- @type Async.AsyncReturn[] Stores a queue of async functions to be executed on the next tick
+local resolve_queue --- @type Async.AsyncReturn[] Stores a queue of async functions to be executed on a later tick
--- Insert an item into the priority queue
---- @param pending Async.AsyncReturn
---- @return Async.AsyncReturn
+--- @param pending Async.AsyncReturn
+--- @return Async.AsyncReturn
local function add_to_next_tick(pending)
resolve_next[#resolve_next + 1] = pending
return pending
end
--- Insert an item into the priority queue
---- @param pending Async.AsyncReturn
---- @return Async.AsyncReturn
+--- @param pending Async.AsyncReturn
+--- @return Async.AsyncReturn
local function add_to_resolve_queue(pending)
local tick = pending.tick
for index = #resolve_queue, 1, -1 do
@@ -191,7 +191,7 @@ end
--- Run an async function on the next tick, this is the default and can be used to bypass permission groups
--- @param ... any The arguments to call the function with
---- @return Async.AsyncReturn
+--- @return Async.AsyncReturn
function Async._function_prototype:start_soon(...)
assert(Async._registered[self.id], "Async function is not registered")
Async._queue_pressure[self.id] = Async._queue_pressure[self.id] + 1
@@ -204,7 +204,7 @@ end
--- Run an async function after the given number of ticks
--- @param ticks number The number of ticks to call the function after
--- @param ... any The arguments to call the function with
---- @return Async.AsyncReturn
+--- @return Async.AsyncReturn
function Async._function_prototype:start_after(ticks, ...)
ExpUtil.assert_argument_type(ticks, "number", 1, "ticks")
assert(ticks > 0, "Ticks must be a positive number")
@@ -219,7 +219,7 @@ end
--- Run an async function on the next tick if the function is not already queued, allows singleton task/thread behaviour
--- @param ... any The arguments to call the function with
---- @return Async.AsyncReturn | nil
+--- @return Async.AsyncReturn | nil
function Async._function_prototype:start_task(...)
assert(Async._registered[self.id], "Async function is not registered")
if Async._queue_pressure[self.id] > 0 then return end
@@ -228,7 +228,7 @@ end
--- Run an async function on this tick, then queue it based on its return value
--- @param ... any The arguments to call the function with
---- @return Async.AsyncReturn
+--- @return Async.AsyncReturn
function Async._function_prototype:start_now(...)
assert(Async._registered[self.id], "Async function is not registered")
local status, rtn1, rtn2 = Async._registered[self.id](...)
@@ -261,7 +261,6 @@ local empty_table = setmetatable({}, {
--- Default status, will raise on_function_complete
--- @param ... any The return value of the async call
--- @return Async.Status, any[]
---- @type Async.Status
function Async.status.complete(...)
if ... == nil then
return Async.status.complete, empty_table
@@ -272,7 +271,6 @@ end
--- Will queue the function to be called again on the next tick using the new arguments
--- @param ... any The arguments to call the function with
--- @return Async.Status, any[]
---- @type Async.Status
function Async.status.continue(...)
if ... == nil then
return Async.status.continue, empty_table
@@ -284,7 +282,6 @@ end
--- @param ticks number The number of ticks to delay for
--- @param ... any The arguments to call the function with
--- @return Async.Status, number, any[]
---- @type Async.Status
function Async.status.delay(ticks, ...)
ExpUtil.assert_argument_type(ticks, "number", 1, "ticks")
assert(ticks > 0, "Ticks must be a positive number")
@@ -296,11 +293,11 @@ end
--- Status Returns.
---- @type Async.AsyncReturn[], Async.AsyncReturn[]
+--- @type Async.AsyncReturn[], Async.AsyncReturn[]
local new_next, new_queue = {}, {} -- File scope to allow for reuse
--- Executes an async function and processes the return value
---- @param pending Async.AsyncReturn
+--- @param pending Async.AsyncReturn
--- @param tick number
local function exec(pending, tick)
local async_func = Async._registered[pending.func_id]
@@ -400,9 +397,9 @@ end
--- @package
function Async.on_init()
if storage.exp_async_next == nil then
- --- @type Async.AsyncReturn[]
+ --- @type Async.AsyncReturn[]
storage.exp_async_next = {}
- --- @type Async.AsyncReturn[]
+ --- @type Async.AsyncReturn[]
storage.exp_async_queue = {}
end
Async.on_load()
diff --git a/exp_util/module/flying_text.lua b/exp_util/module/flying_text.lua
index f7ecaec3..180cd77e 100644
--- a/exp_util/module/flying_text.lua
+++ b/exp_util/module/flying_text.lua
@@ -42,12 +42,14 @@ end
--- @param options FlyingText.create_above_entity_param
function FlyingText.create_above_entity(options)
local entity = assert(options.target_entity, "A target entity is required")
- local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y
+ local bounding_box = entity.bounding_box
+ local size_y = bounding_box.left_top.y - bounding_box.right_bottom.y
+ local position = entity.position
local offset = options.offset or { x = 0, y = 0 }
options.position = {
- x = offset.x + entity.position.x,
- y = offset.y + entity.position.y + size_y * 0.25,
+ x = offset.x + position.x,
+ y = offset.y + position.y + size_y * 0.25,
}
FlyingText.create(options)
@@ -62,12 +64,14 @@ end
function FlyingText.create_above_player(options)
local player = assert(options.target_player, "A target player is required")
local entity = player.character; if not entity then return end
- local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y
+ local bounding_box = entity.bounding_box
+ local size_y = bounding_box.left_top.y - bounding_box.right_bottom.y
+ local position = entity.position
local offset = options.offset or { x = 0, y = 0 }
options.position = {
- x = offset.x + entity.position.x,
- y = offset.y + entity.position.y + size_y * 0.25,
+ x = offset.x + position.x,
+ y = offset.y + position.y + size_y * 0.25,
}
FlyingText.create(options)
@@ -82,13 +86,15 @@ end
function FlyingText.create_as_player(options)
local player = assert(options.target_player, "A target player is required")
local entity = player.character; if not entity then return end
- local size_y = entity.bounding_box.left_top.y - entity.bounding_box.right_bottom.y
+ local bounding_box = entity.bounding_box
+ local size_y = bounding_box.left_top.y - bounding_box.right_bottom.y
+ local position = entity.position
local offset = options.offset or { x = 0, y = 0 }
options.color = player.chat_color
options.position = {
- x = offset.x + entity.position.x,
- y = offset.y + entity.position.y + size_y * 0.25,
+ x = offset.x + position.x,
+ y = offset.y + position.y + size_y * 0.25,
}
FlyingText.create(options)
diff --git a/exp_util/module/module_exports.lua b/exp_util/module/module_exports.lua
index e6394bae..358c1706 100644
--- a/exp_util/module/module_exports.lua
+++ b/exp_util/module/module_exports.lua
@@ -92,7 +92,7 @@ local assert_argument_fmt = "Bad argument #%d to %s; %s expected to be of type %
function ExpUtil.assert_argument_type(arg_value, type_name, arg_index, arg_name)
local failed, actual_type = check_type(arg_value, type_name)
if failed then
- local func_name = getinfo(2, "n").name or ""
+ local func_name = assert(getinfo(2, "n")).name or ""
error(assert_argument_fmt:format(arg_index, func_name, arg_name or "Argument", type_name, actual_type), 2)
end
end
@@ -136,7 +136,7 @@ end
--- @param level number? The level of the stack to get the file of, a value of 1 is the caller of this function
--- @return string # The relative filepath of the given stack frame
function ExpUtil.safe_file_path(level)
- local debug_info = getinfo((level or 1) + 1, "Sn")
+ local debug_info = assert(getinfo((level or 1) + 1, "Sn"))
local safe_source = debug_info.source:find("@__level__")
return safe_source == 1 and debug_info.short_src:sub(10, -5) or debug_info.source
end
@@ -145,7 +145,7 @@ end
--- @param level number? The level of the stack to get the module of, a value of 1 is the caller of this function
--- @return string # The name of the module at the given stack frame
function ExpUtil.get_module_name(level)
- local file_within_module = getinfo((level or 1) + 1, "S").short_src:sub(19, -5)
+ local file_within_module = assert(getinfo((level or 1) + 1, "S")).short_src:sub(19, -5)
local next_slash = file_within_module:find("/")
if next_slash then
return file_within_module:sub(1, next_slash - 1)
@@ -159,7 +159,7 @@ end
--- @param raw boolean? When true there will not be any < > around the name
--- @return string # The name of the function at the given stack frame or provided as an argument
function ExpUtil.get_function_name(func, raw)
- local debug_info = getinfo(func, "Sn")
+ local debug_info = assert(getinfo(func, "Sn"))
local safe_source = debug_info.source:find("@__level__")
local file_name = safe_source == 1 and debug_info.source:sub(12, -5) or debug_info.source
local func_name = debug_info.name or debug_info.linedefined
@@ -172,7 +172,7 @@ end
--- @param raw boolean? When true there will not be any < > around the name
--- @return string # The relative filepath of the given stack frame
function ExpUtil.get_current_line(level, raw)
- local debug_info = getinfo((level or 1) + 1, "Snl")
+ local debug_info = assert(getinfo((level or 1) + 1, "Snl"))
local safe_source = debug_info.source:find("@__level__")
local file_path = safe_source == 1 and debug_info.short_src:sub(10, -5) or debug_info.source
if raw then return file_path .. ":" .. debug_info.currentline end
@@ -207,7 +207,7 @@ end
function ExpUtil.auto_complete(options, input, use_key, rtn_key, use_pattern)
input = input:lower()
local plain = use_pattern ~= true
- local found = {} --- @type { length: number, index: number, start: boolean, value: any }
+ local found = {} --- @type { length: number?, index: number?, start: boolean?, value: any }
for k, v in pairs(options) do
local str = use_key and k or v
local index = str:lower():find(input, nil, plain)
@@ -284,7 +284,7 @@ function ExpUtil.format_any(value, options)
end
return inspect(value, { depth = options.depth or 5, indent = "", newline = "", process = ExpUtil.safe_value })
end
- return formatted
+ return formatted --[[@as LocalisedString]]
end
--- @alias Common.format_time_param_format "short" | "long" | "clock"
@@ -319,15 +319,15 @@ function ExpUtil.extract_time_units(ticks, units)
-- Remove units that are not requested
if not units.days then
- rtn.hours = rtn.hours + rtn.days * 24
+ rtn.hours = assert(rtn.hours) + assert(rtn.days) * 24
rtn.days = nil
end
if not units.hours then
- rtn.minutes = rtn.minutes + rtn.hours * 60
+ rtn.minutes = assert(rtn.minutes) + assert(rtn.hours) * 60
rtn.hours = nil
end
if not units.minutes then
- rtn.seconds = rtn.seconds + rtn.minutes * 60
+ rtn.seconds = assert(rtn.seconds) + assert(rtn.minutes) * 60
rtn.minutes = nil
end
if not units.seconds then
@@ -487,7 +487,7 @@ function ExpUtil.get_storage_for_stack(options)
-- Find a valid entity from the search results
local current, count, entities = cache.current, cache.count, cache.entities
for i = 1, cache.count do
- local entity = entities[((current + i - 1) % count) + 1]
+ local entity = assert(entities[((current + i - 1) % count) + 1])
if entity.can_insert(item) then
cache.current = current + 1
return entity
@@ -522,7 +522,7 @@ end
--- Insert a copy of the given items into the found entities. If no entities are found then they will be created if possible.
--- @param options Common.copy_items_to_surface_param
---- @return LuaEntity # The last entity inserted into
+--- @return LuaEntity? # The last entity inserted into, nil if there were no items
function ExpUtil.copy_items_to_surface(options)
local entity
for item_index = 1, #options.items do
@@ -542,7 +542,7 @@ end
--- Insert a copy of the given items into the found entities. If no entities are found then they will be created if possible.
--- @param options Common.move_items_to_surface_param
---- @return LuaEntity # The last entity inserted into
+--- @return LuaEntity? # The last entity inserted into, nil if there were no items
function ExpUtil.move_items_to_surface(options)
local entity
for item_index = 1, #options.items do
@@ -551,7 +551,8 @@ function ExpUtil.move_items_to_surface(options)
options.item = item
entity = ExpUtil.get_storage_for_stack(options)
entity.insert(options.item)
- options.item.clear()
+ local item_stack = options.item --[[@as LuaItemStack]]
+ item_stack.clear()
end
end
return entity
@@ -563,7 +564,7 @@ end
--- Move the given inventory into the found entities. If no entities are found then they will be created if possible.
--- @param options Common.transfer_inventory_to_surface_param
---- @return LuaEntity # The last entity inserted into
+--- @return LuaEntity? # The last entity inserted into, nil if there were no items
function ExpUtil.transfer_inventory_to_surface(options)
options.items = options.inventory
local entity = ExpUtil.copy_items_to_surface(options)
@@ -604,6 +605,7 @@ end
--- @return string
function ExpUtil.comma_value(n) -- credit http://richard.warburton.it
local left, num, right = string.match(n, "^([^%d]*%d)(%d*)(.-)$")
+ assert(left and num and right)
return left .. (num:reverse():gsub("(%d%d%d)", "%1, "):reverse()) .. right
end
diff --git a/exp_util/module/selection.lua b/exp_util/module/selection.lua
index a50a7940..461963f6 100644
--- a/exp_util/module/selection.lua
+++ b/exp_util/module/selection.lua
@@ -23,7 +23,7 @@ local Selection = {
--- @field player_index number
--- @field selection Selection.Active
- --- @type table
+ --- @type table[] }>
_registered = {},
--- @package
@@ -54,7 +54,7 @@ local selection_tool = { name = "selection-tool" }
--- @param player LuaPlayer
--- @return boolean?
local function has_selection_tool_in_hand(player)
- return player.cursor_stack and player.cursor_stack.valid_for_read and player.cursor_stack.name == "selection-tool"
+ return assert(player.cursor_stack) and assert(player.cursor_stack).valid_for_read and assert(player.cursor_stack).name == "selection-tool"
end
--- Give a selection tool to a player if they don't have one
@@ -62,7 +62,7 @@ end
local function give_selection_tool(player)
if has_selection_tool_in_hand(player) then return end
player.clear_cursor()
- player.cursor_stack.set_stack(selection_tool)
+ assert(player.cursor_stack).set_stack(selection_tool)
-- This does not work for selection planners, will make a feature request for it
--player.cursor_stack_temporary = true
@@ -84,7 +84,7 @@ end
local function remove_selection_tool(player, old_character)
-- Remove the selection tool
if has_selection_tool_in_hand(player) then
- player.cursor_stack.clear()
+ assert(player.cursor_stack).clear()
else
player.remove_item(selection_tool)
end
diff --git a/type.patch.lua b/type.patch.lua
index 38c854d7..191d59d8 100644
--- a/type.patch.lua
+++ b/type.patch.lua
@@ -1,39 +1,8 @@
----@meta
-
----@class script
-script = {
- ---Raise an event. Only events generated with [LuaBootstrap::generate\_event\_name](https://lua-api.factorio.com/latest/classes/LuaBootstrap.html#generate_event_name) and the following can be raised:
- ---
- ---Events that can be raised manually:
- ---
- ---* [on\_console\_chat](https://lua-api.factorio.com/latest/events.html#on_console_chat)
- ---* [on\_player\_crafted\_item](https://lua-api.factorio.com/latest/events.html#on_player_crafted_item)
- ---* [on\_player\_fast\_transferred](https://lua-api.factorio.com/latest/events.html#on_player_fast_transferred)
- ---* [on\_biter\_base\_built](https://lua-api.factorio.com/latest/events.html#on_biter_base_built)
- ---* [on\_market\_item\_purchased](https://lua-api.factorio.com/latest/events.html#on_market_item_purchased)
- ---* [script\_raised\_built](https://lua-api.factorio.com/latest/events.html#script_raised_built)
- ---* [script\_raised\_destroy](https://lua-api.factorio.com/latest/events.html#script_raised_destroy)
- ---* [script\_raised\_revive](https://lua-api.factorio.com/latest/events.html#script_raised_revive)
- ---* [script\_raised\_teleported](https://lua-api.factorio.com/latest/events.html#script_raised_teleported)
- ---* [script\_raised\_set\_tiles](https://lua-api.factorio.com/latest/events.html#script_raised_set_tiles)
- ---
- ---### Example
- ---
- ---```
- ----- Raise the on_console_chat event with the desired message 'from' the first player
- ---local data = {player_index = 1, message = "Hello friends!"}
- ---script.raise_event(defines.events.on_console_chat, data)
- ---```
- ---
- ---[View Documentation](https://lua-api.factorio.com/latest/classes/LuaBootstrap.html#raise_event)
- ---
- --- Type patched in 2.0.28: [Bug Report](https://forums.factorio.com/viewtopic.php?f=233&t=125062)
- --- Changed "event" from "string | integer" to "LuaEventType"
- --- Resolved in 2.0.29, this patch will be removed was version is stable
- ---@param event LuaEventType ID or name of the event to raise.
- ---@param data table Table with extra data that will be passed to the event handler. Any invalid LuaObjects will silently stop the event from being raised.
- raise_event = function(event, data) end;
-}
-
----@class LuaObject:userdata
---https://github.com/justarandomgeek/vscode-factoriomod-debug/issues/165
+---@meta
+
+--- The api documents MapPosition and BoundingBox as a union of the named form
+--- and a positional array, because both are accepted as input. Everything read
+--- back from the game uses the named form, and we always write it that way too,
+--- so the positional variant is removed here.
+---@alias MapPosition MapPosition.struct
+---@alias BoundingBox BoundingBox.struct