mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2026-07-26 18:36:23 +09:00
Migrate rocket info gui to scenario and fix for Space Age
Port modules/gui/rocket-info into exp_scenario/gui/rocket_info using the new exp_gui element API, matching the other scenario guis. The per-force stats, launch times and silo tracking from the legacy control module are folded into the gui module. - Drop the removed auto/remote launch controls and count launches via on_cargo_pod_finished_ascending instead of the old launch event - Add the exp-gui_rocket-info locale section - Disable the legacy module in the file loader and re-enable the gui/rocket-info role permission Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
2c7b88bb81
commit
1fcf351566
@@ -22,7 +22,7 @@ return {
|
|||||||
--"modules.data.toolbar",
|
--"modules.data.toolbar",
|
||||||
|
|
||||||
--- GUI
|
--- GUI
|
||||||
"modules.gui.rocket-info",
|
-- "modules.gui.rocket-info", -- migrated to exp_scenario/gui/rocket_info
|
||||||
"modules.gui.warp-list",
|
"modules.gui.warp-list",
|
||||||
"modules.gui.player-list",
|
"modules.gui.player-list",
|
||||||
"modules.gui.vlayer",
|
"modules.gui.vlayer",
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ local default = Roles.new_role("Guest", "")
|
|||||||
"command/data-preference",
|
"command/data-preference",
|
||||||
"command/connect",
|
"command/connect",
|
||||||
"gui/player-list",
|
"gui/player-list",
|
||||||
--"gui/rocket-info",
|
"gui/rocket-info",
|
||||||
"gui/science-info",
|
"gui/science-info",
|
||||||
"gui/task-list",
|
"gui/task-list",
|
||||||
"gui/warp-list",
|
"gui/warp-list",
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ add(require("modules/exp_scenario/gui/production_stats"))
|
|||||||
add(require("modules/exp_scenario/gui/quick_actions"))
|
add(require("modules/exp_scenario/gui/quick_actions"))
|
||||||
add(require("modules/exp_scenario/gui/readme"))
|
add(require("modules/exp_scenario/gui/readme"))
|
||||||
add(require("modules/exp_scenario/gui/research_milestones"))
|
add(require("modules/exp_scenario/gui/research_milestones"))
|
||||||
|
add(require("modules/exp_scenario/gui/rocket_info"))
|
||||||
add(require("modules/exp_scenario/gui/science_production"))
|
add(require("modules/exp_scenario/gui/science_production"))
|
||||||
add(require("modules/exp_scenario/gui/surveillance"))
|
add(require("modules/exp_scenario/gui/surveillance"))
|
||||||
add(require("modules/exp_scenario/gui/task_list"))
|
add(require("modules/exp_scenario/gui/task_list"))
|
||||||
|
|||||||
@@ -0,0 +1,510 @@
|
|||||||
|
--[[-- Gui - Rocket Info
|
||||||
|
Adds a rocket information gui which shows general stats, milestones and build progress of rockets.
|
||||||
|
The auto launch and remote launch controls were removed because the api no longer exposes auto launch in space age.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local ExpUtil = require("modules/exp_util")
|
||||||
|
local Storage = require("modules/exp_util/storage")
|
||||||
|
local Gui = require("modules/exp_gui")
|
||||||
|
local Roles = require("modules/exp_legacy/expcore/roles")
|
||||||
|
local config = require("modules/exp_legacy/config/gui/rockets")
|
||||||
|
|
||||||
|
--- @class ExpGui_RocketInfo.elements
|
||||||
|
local Elements = {}
|
||||||
|
|
||||||
|
local time_formats = {
|
||||||
|
caption = ExpUtil.format_time_factory_locale{ format = "short", minutes = true, seconds = true },
|
||||||
|
caption_hours = ExpUtil.format_time_factory_locale{ format = "short", hours = true, minutes = true },
|
||||||
|
tooltip = ExpUtil.format_time_factory_locale{ format = "long", minutes = true, seconds = true },
|
||||||
|
tooltip_hours = ExpUtil.format_time_factory_locale{ format = "long", hours = true, minutes = true, seconds = true },
|
||||||
|
}
|
||||||
|
|
||||||
|
--- The font colours used for the build progress label
|
||||||
|
local font_color = {
|
||||||
|
neutral = { r = 1, g = 1, b = 1 },
|
||||||
|
waiting = { r = 0.3, g = 1, b = 1 },
|
||||||
|
launched = { r = 0.3, g = 1, b = 0.3 },
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Below here is the rocket data tracking, it stores per force stats and the times each rocket was launched.
|
||||||
|
This used to live in modules/control/rockets but it is only used by this gui so it has been folded in.
|
||||||
|
]]
|
||||||
|
|
||||||
|
--- @class ExpGui_RocketInfo.silo_data
|
||||||
|
--- @field entity LuaEntity The rocket silo entity
|
||||||
|
--- @field force string The name of the force that owns the silo
|
||||||
|
--- @field launched number The number of rockets launched from this silo
|
||||||
|
--- @field awaiting_reset boolean True when a launch is ordered but the silo has not reset yet
|
||||||
|
|
||||||
|
--- @type table<string, table<number, number>> Force name to an array of launch ticks indexed by rocket number
|
||||||
|
local rocket_times = {}
|
||||||
|
--- @type table<string, { first_launch: number?, last_launch: number?, fastest_launch: number? }> Force name to launch stats
|
||||||
|
local rocket_stats = {}
|
||||||
|
--- @type table<number, ExpGui_RocketInfo.silo_data> Silo unit number to its data
|
||||||
|
local rocket_silos = {}
|
||||||
|
|
||||||
|
Storage.register({
|
||||||
|
rocket_times = rocket_times,
|
||||||
|
rocket_stats = rocket_stats,
|
||||||
|
rocket_silos = rocket_silos,
|
||||||
|
}, function(tbl)
|
||||||
|
rocket_times = tbl.rocket_times
|
||||||
|
rocket_stats = tbl.rocket_stats
|
||||||
|
rocket_silos = tbl.rocket_silos
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- The largest rolling average is used to know when an old launch time can be discarded
|
||||||
|
local largest_rolling_avg = 0
|
||||||
|
for _, avg_over in pairs(config.stats.rolling_avg) do
|
||||||
|
if avg_over > largest_rolling_avg then
|
||||||
|
largest_rolling_avg = avg_over
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get all the valid rocket silos that belong to a force, pruning any that are no longer valid
|
||||||
|
--- @param force_name string Name of the force to get the silos for
|
||||||
|
--- @return ExpGui_RocketInfo.silo_data[]
|
||||||
|
local function get_silos(force_name)
|
||||||
|
local rtn = {}
|
||||||
|
for unit_number, silo_data in pairs(rocket_silos) do
|
||||||
|
if not silo_data.entity.valid then
|
||||||
|
rocket_silos[unit_number] = nil
|
||||||
|
elseif silo_data.force == force_name then
|
||||||
|
rtn[#rtn + 1] = silo_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return rtn
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the number of rockets that a force has launched
|
||||||
|
--- @param force_name string Name of the force to get the count for
|
||||||
|
--- @return number
|
||||||
|
local function get_rocket_count(force_name)
|
||||||
|
return game.forces[force_name].rockets_launched
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the total number of rockets launched by all forces
|
||||||
|
--- @return number
|
||||||
|
local function get_game_rocket_count()
|
||||||
|
local rtn = 0
|
||||||
|
for _, force in pairs(game.forces) do
|
||||||
|
rtn = rtn + force.rockets_launched
|
||||||
|
end
|
||||||
|
|
||||||
|
return rtn
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the rolling average time to launch a rocket based on the last count rockets
|
||||||
|
--- @param force_name string Name of the force to get the average for
|
||||||
|
--- @param count number Number of rockets to average over
|
||||||
|
--- @return number # Number of ticks required to launch one rocket
|
||||||
|
local function get_rolling_average(force_name, count)
|
||||||
|
local times = rocket_times[force_name]
|
||||||
|
local rocket_count = game.forces[force_name].rockets_launched
|
||||||
|
if rocket_count == 0 or not times then return 0 end
|
||||||
|
|
||||||
|
local last_launch_time = times[rocket_count] or 0
|
||||||
|
local start_rocket_time = 0
|
||||||
|
if count < rocket_count then
|
||||||
|
start_rocket_time = times[rocket_count - count + 1] or 0
|
||||||
|
rocket_count = count
|
||||||
|
end
|
||||||
|
|
||||||
|
return math.floor((last_launch_time - start_rocket_time) / rocket_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Below here is the gui, it is split into three collapsible sections; stats, milestones, and build progress.
|
||||||
|
]]
|
||||||
|
|
||||||
|
--- Toggle the visible state of a section, the section is stored in the element data
|
||||||
|
--- @class ExpGui_RocketInfo.elements.toggle_section_button: ExpElement
|
||||||
|
--- @field data table<LuaGuiElement, LuaGuiElement>
|
||||||
|
--- @overload fun(parent: LuaGuiElement, section: LuaGuiElement): LuaGuiElement
|
||||||
|
Elements.toggle_section_button = Gui.define("rocket_info/toggle_section_button")
|
||||||
|
:draw{
|
||||||
|
type = "sprite-button",
|
||||||
|
sprite = "utility/expand",
|
||||||
|
tooltip = { "exp-gui_rocket-info.tooltip-toggle-section-expand" },
|
||||||
|
style = "frame_action_button",
|
||||||
|
}
|
||||||
|
:style{
|
||||||
|
size = 20,
|
||||||
|
padding = -2,
|
||||||
|
}
|
||||||
|
:element_data(
|
||||||
|
Gui.from_argument(1)
|
||||||
|
)
|
||||||
|
:on_click(function(def, player, element)
|
||||||
|
--- @cast def ExpGui_RocketInfo.elements.toggle_section_button
|
||||||
|
local section = def.data[element]
|
||||||
|
if Gui.toggle_visible_state(section) then
|
||||||
|
element.sprite = "utility/collapse"
|
||||||
|
element.tooltip = { "exp-gui_rocket-info.tooltip-toggle-section-collapse" }
|
||||||
|
else
|
||||||
|
element.sprite = "utility/expand"
|
||||||
|
element.tooltip = { "exp-gui_rocket-info.tooltip-toggle-section-expand" }
|
||||||
|
end
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- A clickable coordinate label which opens the silo location on the map when pressed
|
||||||
|
--- @class ExpGui_RocketInfo.elements.position_label: ExpElement
|
||||||
|
--- @field data table<LuaGuiElement, number>
|
||||||
|
--- @overload fun(parent: LuaGuiElement, opts: { caption: LocalisedString, tooltip: LocalisedString?, unit_number: number }): LuaGuiElement
|
||||||
|
Elements.position_label = Gui.define("rocket_info/position_label")
|
||||||
|
:draw{
|
||||||
|
type = "label",
|
||||||
|
caption = Gui.from_argument("caption"),
|
||||||
|
tooltip = Gui.from_argument("tooltip"),
|
||||||
|
}
|
||||||
|
:style{
|
||||||
|
padding = { 0, 2 },
|
||||||
|
}
|
||||||
|
:element_data(
|
||||||
|
Gui.from_argument("unit_number")
|
||||||
|
)
|
||||||
|
:on_click(function(def, player, element)
|
||||||
|
--- @cast def ExpGui_RocketInfo.elements.position_label
|
||||||
|
if not config.progress.allow_zoom_to_map then return end
|
||||||
|
local silo_data = rocket_silos[def.data[element]]
|
||||||
|
if not silo_data or not silo_data.entity.valid then return end
|
||||||
|
local entity = silo_data.entity
|
||||||
|
player.set_controller{ type = defines.controllers.remote, position = entity.position, surface = entity.surface }
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- Add a name and value label pair to a data table
|
||||||
|
--- @param data_table LuaGuiElement The two column table to add the pair to
|
||||||
|
--- @param name string The data name, used to select the locale key
|
||||||
|
--- @param subname number? Optional subname passed as a parameter to the locale string
|
||||||
|
--- @param value LocalisedString The value to display
|
||||||
|
--- @param value_tooltip LocalisedString? Optional tooltip for the value label
|
||||||
|
local function add_data_label(data_table, name, subname, value, value_tooltip)
|
||||||
|
local name_label = data_table.add{
|
||||||
|
type = "label",
|
||||||
|
caption = { "exp-gui_rocket-info.data-caption-" .. name, subname },
|
||||||
|
tooltip = { "exp-gui_rocket-info.data-tooltip-" .. name, subname },
|
||||||
|
}
|
||||||
|
name_label.style.padding = { 0, 2 }
|
||||||
|
|
||||||
|
local value_label = data_table.add{
|
||||||
|
type = "label",
|
||||||
|
caption = value,
|
||||||
|
tooltip = value_tooltip,
|
||||||
|
}
|
||||||
|
value_label.style.padding = { 0, 2 }
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Data table showing the launch statistics for a force
|
||||||
|
--- @class ExpGui_RocketInfo.elements.stats_table: ExpElement
|
||||||
|
--- @overload fun(parent: LuaGuiElement): LuaGuiElement
|
||||||
|
Elements.stats_table = Gui.define("rocket_info/stats_table")
|
||||||
|
:track_all_elements()
|
||||||
|
:draw(function(def, parent)
|
||||||
|
return Gui.elements.scroll_table(parent, 215, 2)
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- Refresh a stats table with the most recent data for a force
|
||||||
|
--- @param stats_table LuaGuiElement
|
||||||
|
--- @param force_name string
|
||||||
|
function Elements.stats_table.refresh(stats_table, force_name)
|
||||||
|
stats_table.clear()
|
||||||
|
local stats = rocket_stats[force_name] or {}
|
||||||
|
local force_rockets = get_rocket_count(force_name)
|
||||||
|
|
||||||
|
if config.stats.show_first_rocket then
|
||||||
|
local value = stats.first_launch or 0
|
||||||
|
add_data_label(stats_table, "first-launch", nil, time_formats.caption_hours(value), time_formats.tooltip_hours(value))
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.stats.show_last_rocket then
|
||||||
|
local value = stats.last_launch or 0
|
||||||
|
add_data_label(stats_table, "last-launch", nil, time_formats.caption_hours(value), time_formats.tooltip_hours(value))
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.stats.show_fastest_rocket then
|
||||||
|
local value = stats.fastest_launch or 0
|
||||||
|
add_data_label(stats_table, "fastest-launch", nil, time_formats.caption_hours(value), time_formats.tooltip_hours(value))
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.stats.show_total_rockets then
|
||||||
|
local total_rockets = get_game_rocket_count()
|
||||||
|
if total_rockets == 0 then total_rockets = 1 end
|
||||||
|
local percentage = math.floor(force_rockets / total_rockets * 1000) / 10
|
||||||
|
add_data_label(stats_table, "total-rockets", nil, tostring(force_rockets), { "exp-gui_rocket-info.value-tooltip-total-rockets", percentage })
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.stats.show_game_avg then
|
||||||
|
local avg = force_rockets > 0 and math.floor(game.tick / force_rockets) or 0
|
||||||
|
add_data_label(stats_table, "avg-launch", nil, time_formats.caption(avg), time_formats.tooltip(avg))
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, avg_over in pairs(config.stats.rolling_avg) do
|
||||||
|
local avg = get_rolling_average(force_name, avg_over)
|
||||||
|
add_data_label(stats_table, "avg-launch-n", avg_over, time_formats.caption(avg), time_formats.tooltip(avg))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Data table showing the milestones for a force
|
||||||
|
--- @class ExpGui_RocketInfo.elements.milestones_table: ExpElement
|
||||||
|
--- @overload fun(parent: LuaGuiElement): LuaGuiElement
|
||||||
|
Elements.milestones_table = Gui.define("rocket_info/milestones_table")
|
||||||
|
:track_all_elements()
|
||||||
|
:draw(function(def, parent)
|
||||||
|
return Gui.elements.scroll_table(parent, 215, 2)
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- Refresh a milestones table with the most recent data for a force
|
||||||
|
--- @param milestones_table LuaGuiElement
|
||||||
|
--- @param force_name string
|
||||||
|
function Elements.milestones_table.refresh(milestones_table, force_name)
|
||||||
|
milestones_table.clear()
|
||||||
|
local force_rockets = get_rocket_count(force_name)
|
||||||
|
local times = rocket_times[force_name] or {}
|
||||||
|
|
||||||
|
for _, milestone in ipairs(config.milestones) do
|
||||||
|
if milestone <= force_rockets then
|
||||||
|
local time = times[milestone] or 0
|
||||||
|
add_data_label(milestones_table, "milestone-n", milestone, time_formats.caption_hours(time), time_formats.tooltip_hours(time))
|
||||||
|
else
|
||||||
|
-- The first unachieved milestone is shown as the next milestone then we stop
|
||||||
|
add_data_label(milestones_table, "milestone-n", milestone, { "exp-gui_rocket-info.data-caption-milestone-next" }, { "exp-gui_rocket-info.data-tooltip-milestone-next" })
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Data table showing the build progress of each silo for a force
|
||||||
|
--- @class ExpGui_RocketInfo.elements.progress_table: ExpElement
|
||||||
|
--- @overload fun(parent: LuaGuiElement): LuaGuiElement
|
||||||
|
Elements.progress_table = Gui.define("rocket_info/progress_table")
|
||||||
|
:track_all_elements()
|
||||||
|
:draw(function(def, parent)
|
||||||
|
return Gui.elements.scroll_table(parent, 215, 3)
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- Refresh a progress table with the most recent data for a force
|
||||||
|
--- @param progress_table LuaGuiElement
|
||||||
|
--- @param force_name string
|
||||||
|
function Elements.progress_table.refresh(progress_table, force_name)
|
||||||
|
progress_table.clear()
|
||||||
|
local silos = get_silos(force_name)
|
||||||
|
|
||||||
|
if #silos == 0 then
|
||||||
|
progress_table.add{
|
||||||
|
type = "label",
|
||||||
|
caption = { "exp-gui_rocket-info.progress-no-silos" },
|
||||||
|
}.style.padding = { 1, 2 }
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local zoom_tooltip = config.progress.allow_zoom_to_map and { "exp-gui_rocket-info.progress-label-tooltip" } or nil
|
||||||
|
for _, silo_data in pairs(silos) do
|
||||||
|
local entity = silo_data.entity
|
||||||
|
local position = entity.position
|
||||||
|
|
||||||
|
-- Work out the progress caption, tooltip and colour
|
||||||
|
local waiting = entity.status == defines.entity_status.waiting_to_launch_rocket
|
||||||
|
local progress_caption = { "exp-gui_rocket-info.progress-caption", entity.rocket_parts }
|
||||||
|
local progress_tooltip = { "exp-gui_rocket-info.progress-tooltip", silo_data.launched }
|
||||||
|
local progress_color = font_color.neutral
|
||||||
|
if waiting and silo_data.awaiting_reset then
|
||||||
|
progress_caption = { "exp-gui_rocket-info.progress-launched" }
|
||||||
|
progress_color = font_color.launched
|
||||||
|
elseif waiting then
|
||||||
|
progress_caption = { "exp-gui_rocket-info.progress-caption", 100 }
|
||||||
|
progress_color = font_color.waiting
|
||||||
|
else
|
||||||
|
silo_data.awaiting_reset = false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add the clickable coordinates and the progress label
|
||||||
|
Elements.position_label(progress_table, { caption = { "exp-gui_rocket-info.progress-x-pos", position.x }, tooltip = zoom_tooltip, unit_number = entity.unit_number })
|
||||||
|
Elements.position_label(progress_table, { caption = { "exp-gui_rocket-info.progress-y-pos", position.y }, tooltip = zoom_tooltip, unit_number = entity.unit_number })
|
||||||
|
local progress_label = progress_table.add{
|
||||||
|
type = "label",
|
||||||
|
caption = progress_caption,
|
||||||
|
tooltip = progress_tooltip,
|
||||||
|
}
|
||||||
|
progress_label.style.padding = { 0, 2 }
|
||||||
|
progress_label.style.font_color = progress_color
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a collapsible section to a container, returns the populated data table
|
||||||
|
--- @param container LuaGuiElement The container frame to add the section to
|
||||||
|
--- @param section_name string Used to select the locale keys for the header
|
||||||
|
--- @param table_define ExpElement The data table element define to add
|
||||||
|
--- @param force_name string The force to populate the table with
|
||||||
|
--- @return LuaGuiElement
|
||||||
|
local function add_section(container, section_name, table_define, force_name)
|
||||||
|
local header = Gui.elements.header(container, {
|
||||||
|
caption = { "exp-gui_rocket-info.section-caption-" .. section_name },
|
||||||
|
tooltip = { "exp-gui_rocket-info.section-tooltip-" .. section_name },
|
||||||
|
})
|
||||||
|
|
||||||
|
local data_table = table_define(container)
|
||||||
|
table_define.refresh(data_table, force_name)
|
||||||
|
|
||||||
|
-- The scroll pane is the parent of the table, it is what gets collapsed
|
||||||
|
local scroll_pane = assert(data_table.parent)
|
||||||
|
scroll_pane.visible = false
|
||||||
|
Elements.toggle_section_button(header, scroll_pane)
|
||||||
|
|
||||||
|
return data_table
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Container added to the left gui flow
|
||||||
|
--- @class ExpGui_RocketInfo.elements.container: ExpElement
|
||||||
|
--- @overload fun(parent: LuaGuiElement): LuaGuiElement
|
||||||
|
Elements.container = Gui.define("rocket_info/container")
|
||||||
|
:draw(function(def, parent)
|
||||||
|
local container = Gui.elements.container(parent, 200)
|
||||||
|
container.style.padding = 0
|
||||||
|
|
||||||
|
local force_name = Gui.get_player(parent).force.name --[[ @as string ]]
|
||||||
|
|
||||||
|
if config.stats.show_stats then
|
||||||
|
add_section(container, "stats", Elements.stats_table, force_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.milestones.show_milestones then
|
||||||
|
add_section(container, "milestones", Elements.milestones_table, force_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
if config.progress.show_progress then
|
||||||
|
add_section(container, "progress", Elements.progress_table, force_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
return Gui.elements.container.get_root_element(container)
|
||||||
|
end) --[[ @as any ]]
|
||||||
|
|
||||||
|
--- Add the element to the left flow with a toolbar button
|
||||||
|
Gui.add_left_element(Elements.container, false)
|
||||||
|
Gui.toolbar.create_button{
|
||||||
|
name = "toggle_rocket_info",
|
||||||
|
left_element = Elements.container,
|
||||||
|
sprite = "item/rocket-silo",
|
||||||
|
tooltip = { "exp-gui_rocket-info.tooltip-main" },
|
||||||
|
visible = function(player, element)
|
||||||
|
return Roles.player_allowed(player, "gui/rocket-info")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Below here is the event handling, the data tracking and gui refreshing are wired up to the same events.
|
||||||
|
]]
|
||||||
|
|
||||||
|
--- Refresh the stats and milestones tables for all online players on a force
|
||||||
|
--- @param force_name string
|
||||||
|
local function refresh_force_stats(force_name)
|
||||||
|
local force = game.forces[force_name]
|
||||||
|
for _, stats_table in Elements.stats_table:online_elements(force) do
|
||||||
|
Elements.stats_table.refresh(stats_table, force_name)
|
||||||
|
end
|
||||||
|
for _, milestones_table in Elements.milestones_table:online_elements(force) do
|
||||||
|
Elements.milestones_table.refresh(milestones_table, force_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Refresh the progress table for all online players on a force
|
||||||
|
--- @param force_name string
|
||||||
|
local function refresh_force_progress(force_name)
|
||||||
|
local force = game.forces[force_name]
|
||||||
|
for _, progress_table in Elements.progress_table:online_elements(force) do
|
||||||
|
Elements.progress_table.refresh(progress_table, force_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- 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 force_name = force.name
|
||||||
|
local rockets_launched = force.rockets_launched
|
||||||
|
|
||||||
|
-- Update the launch stats for the force
|
||||||
|
local stats = rocket_stats[force_name]
|
||||||
|
if not stats then
|
||||||
|
stats = {}
|
||||||
|
rocket_stats[force_name] = stats
|
||||||
|
end
|
||||||
|
|
||||||
|
if rockets_launched == 1 then
|
||||||
|
stats.first_launch = event.tick
|
||||||
|
stats.fastest_launch = event.tick
|
||||||
|
elseif stats.last_launch and event.tick - stats.last_launch < (stats.fastest_launch or math.huge) then
|
||||||
|
stats.fastest_launch = event.tick - stats.last_launch
|
||||||
|
end
|
||||||
|
|
||||||
|
stats.last_launch = event.tick
|
||||||
|
|
||||||
|
-- Append the launch tick into the times array
|
||||||
|
local times = rocket_times[force_name]
|
||||||
|
if not times then
|
||||||
|
times = {}
|
||||||
|
rocket_times[force_name] = times
|
||||||
|
end
|
||||||
|
|
||||||
|
times[rockets_launched] = event.tick
|
||||||
|
|
||||||
|
-- Discard the launch time that is no longer needed by any rolling average unless it is a milestone
|
||||||
|
local remove_rocket = rockets_launched - largest_rolling_avg
|
||||||
|
if remove_rocket > 0 and not table.array_contains(config.milestones, remove_rocket) then
|
||||||
|
times[remove_rocket] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
refresh_force_stats(force_name)
|
||||||
|
refresh_force_progress(force_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Mark a silo as awaiting reset when a launch is ordered
|
||||||
|
--- @param event EventData.on_rocket_launch_ordered
|
||||||
|
local function on_rocket_launch_ordered(event)
|
||||||
|
local silo_data = rocket_silos[event.rocket_silo.unit_number]
|
||||||
|
if not silo_data then return end
|
||||||
|
silo_data.launched = silo_data.launched + 1
|
||||||
|
silo_data.awaiting_reset = true
|
||||||
|
refresh_force_progress(event.rocket_silo.force.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a silo to the list when it is built
|
||||||
|
--- @param event EventData.on_built_entity | EventData.on_robot_built_entity | EventData.script_raised_built | EventData.script_raised_revive
|
||||||
|
local function on_built(event)
|
||||||
|
local entity = event.entity
|
||||||
|
if not entity.valid or entity.name ~= "rocket-silo" then return end
|
||||||
|
rocket_silos[entity.unit_number] = {
|
||||||
|
entity = entity,
|
||||||
|
force = entity.force.name,
|
||||||
|
launched = 0,
|
||||||
|
awaiting_reset = false,
|
||||||
|
}
|
||||||
|
refresh_force_progress(entity.force.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Refresh the progress for all forces that own at least one silo
|
||||||
|
local function refresh_all_progress()
|
||||||
|
for _, force in pairs(game.forces) do
|
||||||
|
if #get_silos(force.name) > 0 then
|
||||||
|
refresh_force_progress(force.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local e = defines.events
|
||||||
|
|
||||||
|
return {
|
||||||
|
elements = Elements,
|
||||||
|
events = {
|
||||||
|
[e.on_cargo_pod_finished_ascending] = on_cargo_pod_finished_ascending,
|
||||||
|
[e.on_rocket_launch_ordered] = on_rocket_launch_ordered,
|
||||||
|
[e.on_built_entity] = on_built,
|
||||||
|
[e.on_robot_built_entity] = on_built,
|
||||||
|
[e.script_raised_built] = on_built,
|
||||||
|
[e.script_raised_revive] = on_built,
|
||||||
|
},
|
||||||
|
on_nth_tick = {
|
||||||
|
[150] = refresh_all_progress,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -431,6 +431,42 @@ caption-research-name=[technology=__1__] __2__
|
|||||||
notice-inf=[color=255, 255, 255] Research completed at __1__ - [technology=__2__] - __3__[/color]
|
notice-inf=[color=255, 255, 255] Research completed at __1__ - [technology=__2__] - __3__[/color]
|
||||||
notice=[color=255, 255, 255] Research completed at __1__ - [technology=__2__][/color]
|
notice=[color=255, 255, 255] Research completed at __1__ - [technology=__2__][/color]
|
||||||
|
|
||||||
|
[exp-gui_rocket-info]
|
||||||
|
tooltip-main=Rocket Info
|
||||||
|
caption-main=Rocket Info
|
||||||
|
tooltip-toggle-section-expand=Expand Section
|
||||||
|
tooltip-toggle-section-collapse=Collapse Section
|
||||||
|
section-caption-stats=Statistics
|
||||||
|
section-tooltip-stats=Statistics about how rockets are launched
|
||||||
|
section-caption-milestones=Milestones
|
||||||
|
section-tooltip-milestones=The times when milestones were met
|
||||||
|
section-caption-progress=Build Progress
|
||||||
|
section-tooltip-progress=The progress for your rocket silos
|
||||||
|
progress-no-silos=You have no rocket silos
|
||||||
|
data-caption-first-launch=First Launch
|
||||||
|
data-tooltip-first-launch=The time of the first launch
|
||||||
|
data-caption-last-launch=Last Launch
|
||||||
|
data-tooltip-last-launch=The time of the last launch
|
||||||
|
data-caption-fastest-launch=Fastest Launch
|
||||||
|
data-tooltip-fastest-launch=The time taken for the fastest launch
|
||||||
|
data-caption-total-rockets=Total Launched
|
||||||
|
data-tooltip-total-rockets=Total number of rockets launched by your force
|
||||||
|
value-tooltip-total-rockets=__1__% of all rockets on this map
|
||||||
|
data-caption-avg-launch=Average Time
|
||||||
|
data-tooltip-avg-launch=The average amount of time taken to launch a rocket
|
||||||
|
data-caption-avg-launch-n=Average Time __1__
|
||||||
|
data-tooltip-avg-launch-n=The average amount of time taken to launch the last __1__ rockets
|
||||||
|
data-caption-milestone-n=Milestone __1__
|
||||||
|
data-tooltip-milestone-n=Time taken to reach __1__ rockets
|
||||||
|
data-caption-milestone-next=N/A
|
||||||
|
data-tooltip-milestone-next=Not yet achieved
|
||||||
|
progress-x-pos=X __1__
|
||||||
|
progress-y-pos=Y __1__
|
||||||
|
progress-label-tooltip=View on map
|
||||||
|
progress-launched=Launched
|
||||||
|
progress-caption=__1__%
|
||||||
|
progress-tooltip=This silo has launched __1__ rockets
|
||||||
|
|
||||||
[exp-gui_science-production]
|
[exp-gui_science-production]
|
||||||
tooltip-main=Science Production
|
tooltip-main=Science Production
|
||||||
caption-main=Science
|
caption-main=Science
|
||||||
|
|||||||
Reference in New Issue
Block a user