mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-27 11:35:22 +09:00
Merge branch 'feature/rocket-info' into dev
This commit is contained in:
@@ -35,6 +35,7 @@ return {
|
||||
'modules.addons.random-player-colours',
|
||||
-- GUI
|
||||
'modules.gui.player-list',
|
||||
'modules.gui.rocket-info',
|
||||
'modules.commands.debug',
|
||||
-- Config Files
|
||||
'config.expcore-commands.auth_admin', -- commands tagged with admin_only are blocked for non admins
|
||||
|
||||
@@ -62,6 +62,9 @@ end
|
||||
|
||||
return {
|
||||
skip_intro=true, -- skips the intro given in the default factorio free play scenario
|
||||
skip_victory=true, -- will skip the victory screen when a rocket is launched
|
||||
disable_base_game_silo_script=true, -- will not load the silo script at all
|
||||
research_queue_from_start=true, -- when true the research queue is useible from the start
|
||||
friendly_fire=false, -- weather players will be able to attack each other on the same force
|
||||
enemy_expansion=false, -- a catch all for in case the map settings file fails to load
|
||||
chart_radius=10*32, -- the number of tiles that will be charted when the map starts
|
||||
|
||||
33
config/rockets.lua
Normal file
33
config/rockets.lua
Normal file
@@ -0,0 +1,33 @@
|
||||
--- This file controls what will show in each section of the rocket info gui
|
||||
return {
|
||||
stats = { --- The data that will show in the stats section
|
||||
show_stats=true, -- false will hide this section all together
|
||||
show_first_rocket = true, -- false will not show when the first rocket was launched
|
||||
show_last_rocket = true, -- false will not show when the last rocket was launched
|
||||
show_fastest_rocket = true, -- false will not show the time taken for the fastest rocket
|
||||
show_total_rockets = true, -- false will not show the total number of rockets launched
|
||||
show_game_avg = true, -- false will hide the avg across the entire map time
|
||||
rolling_avg = { -- each number will be one stat; 5 means the avg time taken for the last 5 rockets
|
||||
5,10,25
|
||||
}
|
||||
},
|
||||
milestones = { -- each number will be one stat; 5 means the time that the 5th rocket was launched
|
||||
show_milestones=true, -- false will hide this section all together
|
||||
1,2,5,
|
||||
10,20,50,
|
||||
100,200,500,
|
||||
1000,1500,2000,2500,
|
||||
3000,3500,4000,4500,
|
||||
5000
|
||||
},
|
||||
progress = { --- The data and buttons in the build progress section
|
||||
show_progress = true, -- false will hide this section altogether
|
||||
allow_zoom_to_map = true, -- false will disable the zoom to map feature
|
||||
allow_remote_launch = true, -- false removes the remote launch button for all players
|
||||
remote_launch_admins_only = false, -- true will remove the remote launch button for all non (game) admins
|
||||
remote_launch_role_permision = 'gui/rocket-info/remote_launch', -- value used by custom permission system to allow or disllow the button
|
||||
allow_toggle_active = true, -- false removes the remote toggle auto launch button for all players
|
||||
toggle_active_admins_only = false, -- true will remove the toggle auto launch button for all non (game) admins
|
||||
toggle_active_role_permision = 'gui/rocket-info/toggle-active' -- value used by custom permission system to allow or disllow the button
|
||||
}
|
||||
}
|
||||
@@ -76,6 +76,8 @@ Roles.new_role('Moderator','Mod')
|
||||
'command/clear-warnings',
|
||||
'command/clear-temp-ban',
|
||||
'command/clear-inventory',
|
||||
'gui/rocket-info/toggle-active',
|
||||
'gui/rocket-info/remote_launch',
|
||||
}
|
||||
|
||||
Roles.new_role('Trainee','TrMod')
|
||||
@@ -115,6 +117,8 @@ Roles.new_role('Pay to Win','P2W')
|
||||
:set_flag('report-immune')
|
||||
:set_parent('Donator')
|
||||
:allow{
|
||||
'gui/rocket-info/toggle-active',
|
||||
'gui/rocket-info/remote_launch',
|
||||
}
|
||||
|
||||
Roles.new_role('Donator','Don')
|
||||
@@ -185,6 +189,7 @@ local default = Roles.new_role('Guest','')
|
||||
'command/find-on-map',
|
||||
'command/report',
|
||||
'gui/player-list',
|
||||
'gui/rocket-info',
|
||||
}
|
||||
|
||||
--- Jail role
|
||||
|
||||
@@ -37,6 +37,9 @@ local Gui = require 'expcore.gui.core'
|
||||
Gui.toggle_enable(element) --- Will toggle the enabled state of an element
|
||||
Gui.toggle_visible(element) --- Will toggle the visiblity of an element
|
||||
Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element
|
||||
Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style
|
||||
Gui.create_right_align(element,flow_name) --- Allows the creation of a right align flow to place elements into
|
||||
Gui.destory_if_valid(element) --- Destroies an element but tests for it being present and valid first
|
||||
]]
|
||||
|
||||
local Instances = require 'expcore.gui.instances'
|
||||
|
||||
@@ -153,6 +153,8 @@
|
||||
Gui.toggle_visible(element) --- Will toggle the visiblity of an element
|
||||
Gui.set_padding(element,up,down,left,right) --- Sets the padding for a gui element
|
||||
Gui.set_padding_style(style,up,down,left,right) --- Sets the padding for a gui style
|
||||
Gui.create_right_align(element,flow_name) --- Allows the creation of a right align flow to place elements into
|
||||
Gui.destory_if_valid(element) --- Destroies an element but tests for it being present and valid first
|
||||
]]
|
||||
local Gui = require 'utils.gui'
|
||||
local Game = require 'utils.game'
|
||||
@@ -515,6 +517,7 @@ end
|
||||
|
||||
--- Will toggle the enabled state of an element
|
||||
-- @tparam element LuaGuiElement the gui element to toggle
|
||||
-- @treturn boolean the new state that the element has
|
||||
function Gui.toggle_enable(element)
|
||||
if not element or not element.valid then return end
|
||||
if not element.enabled then
|
||||
@@ -522,10 +525,12 @@ function Gui.toggle_enable(element)
|
||||
else
|
||||
element.enabled = false
|
||||
end
|
||||
return element.enabled
|
||||
end
|
||||
|
||||
--- Will toggle the visiblity of an element
|
||||
-- @tparam element LuaGuiElement the gui element to toggle
|
||||
-- @treturn boolean the new state that the element has
|
||||
function Gui.toggle_visible(element)
|
||||
if not element or not element.valid then return end
|
||||
if not element.visible then
|
||||
@@ -533,6 +538,7 @@ function Gui.toggle_visible(element)
|
||||
else
|
||||
element.visible = false
|
||||
end
|
||||
return element.visible
|
||||
end
|
||||
|
||||
--- Sets the padding for a gui element
|
||||
@@ -562,4 +568,30 @@ function Gui.set_padding_style(style,up,down,left,right)
|
||||
style.right_padding = right or 0
|
||||
end
|
||||
|
||||
--- Allows the creation of a right align flow to place elements into
|
||||
-- @tparam element LuaGuiElement the element to add this flow to,
|
||||
-- @tparam[opt] flow_name string the name of the flow can be nil
|
||||
-- @treturn LuaGuiElement the flow that was created
|
||||
function Gui.create_right_align(element,flow_name)
|
||||
local right_flow =
|
||||
element.add{
|
||||
name=flow_name,
|
||||
type='flow'
|
||||
}
|
||||
Gui.set_padding(right_flow,1,1,2,2)
|
||||
right_flow.style.horizontal_align = 'right'
|
||||
right_flow.style.horizontally_stretchable = true
|
||||
return right_flow
|
||||
end
|
||||
|
||||
--- Destroies an element but tests for it being present and valid first
|
||||
-- @tparam element LuaGuiElement the element to be destroied
|
||||
-- @treturn boolean true if it was destoried
|
||||
function Gui.destory_if_valid(element)
|
||||
if element and element.valid then
|
||||
element.destroy()
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return Gui
|
||||
@@ -1,4 +1,5 @@
|
||||
[player-list]
|
||||
main-tooltip=Player list
|
||||
open-action-bar=Options
|
||||
close-action-bar=Close Options
|
||||
reason-confirm=Confirm Reason
|
||||
@@ -13,4 +14,41 @@ temp-ban-player=Temp ban player
|
||||
kick-player=Kick player
|
||||
ban-player=Ban player
|
||||
afk-time=__1__% of total map time\nLast moved __2__ ago
|
||||
open-map=__1__ __2__\n__3__\nClick to open map
|
||||
open-map=__1__ __2__\n__3__\nClick to open map
|
||||
|
||||
[rocket-info]
|
||||
main-tooltip=Rocket info
|
||||
launch-tooltip=Launch rocket
|
||||
launch-tooltip-disabled=Launch rocket (not ready)
|
||||
toggle-rocket-tooltip=Disable auto launch
|
||||
toggle-rocket-tooltip-disabled=Enable auto launch
|
||||
toggle-section-tooltip=Expand Section
|
||||
toggle-section-collapse-tooltip=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=Avg Time
|
||||
data-tooltip-avg-launch=The average amount of time taken to launch a rocket
|
||||
data-caption-avg-launch-n=Avg Time __1__
|
||||
data-tooltip-avg-launch-n=The average amount of time taken to launch the last __1__ rockets
|
||||
data-caption-milstone-n=Milestone __1__
|
||||
data-tooltip-milstone-n=Time taken to each __1__ rockets
|
||||
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
|
||||
@@ -31,4 +31,14 @@ Event.on_init(function()
|
||||
remote.call('freeplay','set_created_items',{})
|
||||
remote.call('freeplay','set_chart_distance',0)
|
||||
remote.call('freeplay','set_skip_intro',config.skip_intro)
|
||||
if config.research_queue_from_start then
|
||||
for _,force in pairs(game.forces) do
|
||||
force.research_queue_enabled = true
|
||||
end
|
||||
end
|
||||
if not config.disable_base_game_silo_script then
|
||||
if config.skip_victory then
|
||||
remote.call('silo_script','set_no_victory',true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -1,8 +1,13 @@
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local config = require 'config.advanced_start'
|
||||
local use_silo_script = not config.disable_base_game_silo_script
|
||||
|
||||
local util = require("util")
|
||||
local silo_script = require("silo-script")
|
||||
local silo_script
|
||||
if use_silo_script then
|
||||
silo_script = require("silo-script")
|
||||
end
|
||||
|
||||
local global = {}
|
||||
Global.register(global,function(tbl)
|
||||
@@ -29,8 +34,10 @@ local respawn_items = function()
|
||||
}
|
||||
end
|
||||
|
||||
for k,v in pairs(silo_script.get_events()) do
|
||||
Event.add(k, v)
|
||||
if use_silo_script then
|
||||
for k,v in pairs(silo_script.get_events()) do
|
||||
Event.add(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_created, function(event)
|
||||
@@ -48,27 +55,37 @@ Event.add(defines.events.on_player_created, function(event)
|
||||
end
|
||||
end
|
||||
|
||||
silo_script.on_event(event)
|
||||
if use_silo_script then
|
||||
silo_script.on_event(event)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_respawned, function(event)
|
||||
local player = game.players[event.player_index]
|
||||
util.insert_safe(player, global.respawn_items)
|
||||
silo_script.on_event(event)
|
||||
if use_silo_script then
|
||||
silo_script.on_event(event)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.on_load(function()
|
||||
silo_script.on_load()
|
||||
end)
|
||||
if use_silo_script then
|
||||
Event.on_load(function()
|
||||
silo_script.on_load()
|
||||
end)
|
||||
end
|
||||
|
||||
Event.on_init(function()
|
||||
global.created_items = created_items()
|
||||
global.respawn_items = respawn_items()
|
||||
silo_script.on_init()
|
||||
if use_silo_script then
|
||||
silo_script.on_init()
|
||||
end
|
||||
end)
|
||||
|
||||
silo_script.add_remote_interface()
|
||||
silo_script.add_commands()
|
||||
if use_silo_script then
|
||||
silo_script.add_remote_interface()
|
||||
silo_script.add_commands()
|
||||
end
|
||||
|
||||
remote.add_interface("freeplay",
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ end)
|
||||
--- Button used to close the action bar
|
||||
local close_action_bar =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/close_black')
|
||||
:set_sprites('utility/close_black','utility/close_white')
|
||||
:set_tooltip{'player-list.close-action-bar'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-1,-1,-1,-1)
|
||||
@@ -232,14 +232,7 @@ local function add_player(list_table,player,role_name)
|
||||
player_name.style.font_color = player.chat_color
|
||||
|
||||
-- flow which allows right align for the play time
|
||||
local time_flow =
|
||||
list_table.add{
|
||||
name='player-time-'..player.index,
|
||||
type='flow'
|
||||
}
|
||||
Gui.set_padding(time_flow)
|
||||
time_flow.style.horizontal_align = 'right'
|
||||
time_flow.style.horizontally_stretchable = true
|
||||
local time_flow = Gui.create_right_align(list_table,'player-time-'..player.index)
|
||||
|
||||
-- time given in Xh Ym and is right aligned
|
||||
local tick = game.tick > 0 and game.tick or 1
|
||||
@@ -271,6 +264,7 @@ end
|
||||
local player_list =
|
||||
Gui.new_left_frame('gui/player-list')
|
||||
:set_sprites('entity/character')
|
||||
:set_tooltip{'player-list.main-tooltip'}
|
||||
:set_open_by_default()
|
||||
:set_direction('vertical')
|
||||
:on_draw(function(player,element)
|
||||
|
||||
595
modules/gui/rocket-info.lua
Normal file
595
modules/gui/rocket-info.lua
Normal file
@@ -0,0 +1,595 @@
|
||||
local Gui = require 'expcore.gui'
|
||||
local Roles = require 'expcore.roles'
|
||||
local Event = require 'utils.event'
|
||||
local config = require 'config.rockets'
|
||||
local Global = require 'utils.global'
|
||||
local format_time = ext_require('expcore.common','format_time')
|
||||
local Colors = require 'resources.color_presets'
|
||||
|
||||
local rocket_times = {}
|
||||
local rocket_stats = {}
|
||||
local rocket_silos = {}
|
||||
|
||||
Global.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)
|
||||
|
||||
--- Gets the name used to refrence the the rocket silo
|
||||
local function get_silo_name(entity)
|
||||
local position = entity.position
|
||||
return math.floor(position.x)..':'..math.floor(position.y)
|
||||
end
|
||||
|
||||
--- Gets if a player is allowed to use the action buttons
|
||||
local function player_allowed(player,action)
|
||||
if not config.progress['allow_'..action] then
|
||||
return false
|
||||
end
|
||||
|
||||
if config.progress[action..'_admins_only'] and not player.admin then
|
||||
return false
|
||||
end
|
||||
|
||||
if config.progress[action..'_role_permision'] and not Roles.player_allowed(player,config.progress[action..'_role_permision']) then
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Used on the name label to allow zoom to map
|
||||
local zoom_to_map_name = Gui.uid_name()
|
||||
Gui.on_click(zoom_to_map_name,function(event)
|
||||
local force = event.player.force
|
||||
local rocket_silo_name = event.element.parent.caption
|
||||
local rocket_silo_data = rocket_silos[force.name][rocket_silo_name]
|
||||
local position = rocket_silo_data.entity.position
|
||||
event.player.zoom_to_world(position,2)
|
||||
end)
|
||||
|
||||
--- Used to launch the rocket, when it is ready
|
||||
local launch_rocket =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/center')
|
||||
:set_tooltip{'rocket-info.launch-tooltip'}
|
||||
:set_embeded_flow(function(element,rocket_silo_name)
|
||||
return 'launch-'..rocket_silo_name
|
||||
end)
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.width = 16
|
||||
style.height = 16
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local force = player.force
|
||||
local rocket_silo_name = element.parent.name:sub(8)
|
||||
local rocket_silo_data = rocket_silos[force.name][rocket_silo_name]
|
||||
if rocket_silo_data.entity.launch_rocket() then
|
||||
rocket_silo_data.awaiting_reset = true
|
||||
element.enabled = false
|
||||
end
|
||||
end)
|
||||
|
||||
--- Used to toggle the auto launch on a rocket
|
||||
local toggle_rocket =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/play')
|
||||
:set_tooltip{'rocket-info.toggle-rocket-tooltip'}
|
||||
:set_embeded_flow(function(element,rocket_silo_name)
|
||||
return 'toggle-'..rocket_silo_name
|
||||
end)
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.width = 16
|
||||
style.height = 16
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local force = player.force
|
||||
local rocket_silo_name = element.parent.name:sub(7)
|
||||
local rocket_silo = rocket_silos[force.name][rocket_silo_name]
|
||||
local active = true -- need to test for auto launch
|
||||
if active then
|
||||
player.print('WIP; We currently have no way to test or set the auto launch of a rocket so this button does not work!')
|
||||
element.sprite = 'utility/play'
|
||||
element.tooltip = {'rocket-info.toggle-rocket-tooltip'}
|
||||
-- insert function to disable auto launch
|
||||
else
|
||||
element.sprite = 'utility/stop'
|
||||
element.tooltip = {'rocket-info.toggle-rocket-tooltip-disabled'}
|
||||
-- insert function to enable auto launch
|
||||
end
|
||||
end)
|
||||
|
||||
--- Used to toggle the visiblty of the different sections
|
||||
local toggle_section =
|
||||
Gui.new_button()
|
||||
:set_sprites('utility/expand_dark','utility/expand')
|
||||
:set_tooltip{'rocket-info.toggle-section-tooltip'}
|
||||
:set_style('tool_button',function(style)
|
||||
Gui.set_padding_style(style,-2,-2,-2,-2)
|
||||
style.height = 20
|
||||
style.width = 20
|
||||
end)
|
||||
:on_click(function(player,element)
|
||||
local flow_name = element.parent.name
|
||||
local flow = element.parent.parent.parent[flow_name]
|
||||
if Gui.toggle_visible(flow) then
|
||||
element.sprite = 'utility/collapse_dark'
|
||||
element.hovered_sprite = 'utility/collapse'
|
||||
element.tooltip = {'rocket-info.toggle-section-collapse-tooltip'}
|
||||
else
|
||||
element.sprite = 'utility/expand_dark'
|
||||
element.hovered_sprite = 'utility/expand'
|
||||
element.tooltip = {'rocket-info.toggle-section-tooltip'}
|
||||
end
|
||||
end)
|
||||
|
||||
--- Used to create the three different sections
|
||||
local function create_section(container,section_name,table_size)
|
||||
--- Header for the section
|
||||
local header =
|
||||
container.add{
|
||||
type='frame',
|
||||
name=section_name..'-header',
|
||||
style='subheader_frame',
|
||||
}
|
||||
Gui.set_padding(header,4,1,4,4)
|
||||
header.style.horizontally_stretchable = true
|
||||
|
||||
--- Caption for the header bar
|
||||
header.add{
|
||||
type='label',
|
||||
style='heading_1_label',
|
||||
caption={'rocket-info.section-caption-'..section_name},
|
||||
tooltip={'rocket-info.section-tooltip-'..section_name}
|
||||
}
|
||||
|
||||
--- Right aligned button to toggle the section
|
||||
local expand_flow = Gui.create_right_align(header,section_name)
|
||||
toggle_section(expand_flow)
|
||||
|
||||
--- The area which contains the section content
|
||||
local flow =
|
||||
container.add{
|
||||
name=section_name,
|
||||
type='scroll-pane',
|
||||
direction='vertical',
|
||||
horizontal_scroll_policy='never',
|
||||
vertical_scroll_policy='auto-and-reserve-space'
|
||||
}
|
||||
Gui.set_padding(flow,1,1,2,2)
|
||||
flow.style.horizontally_stretchable = true
|
||||
flow.style.maximal_height = 215
|
||||
flow.visible = false
|
||||
|
||||
--- Table used to store the data
|
||||
local flow_table =
|
||||
flow.add{
|
||||
name='table',
|
||||
type='table',
|
||||
column_count=table_size
|
||||
}
|
||||
Gui.set_padding(flow_table)
|
||||
flow_table.style.horizontally_stretchable = true
|
||||
flow_table.style.vertical_align = 'center'
|
||||
flow_table.style.cell_padding = 0
|
||||
end
|
||||
|
||||
--[[ Creates the main structure for the gui
|
||||
element
|
||||
> container
|
||||
|
||||
>> stats-header
|
||||
>>> stats
|
||||
>>>> toggle_section.name
|
||||
>> stats
|
||||
>>> table
|
||||
|
||||
>> milestones-header
|
||||
>>> milestones
|
||||
>>>> toggle_section.name
|
||||
>> milestones
|
||||
>>> table
|
||||
|
||||
>> progress-header
|
||||
>>> progress
|
||||
>>>> toggle_section.name
|
||||
>> progress
|
||||
>>> table
|
||||
]]
|
||||
local function generate_container(player,element)
|
||||
Gui.set_padding(element,1,2,2,2)
|
||||
element.style.minimal_width = 200
|
||||
|
||||
-- main container which contains the other elements
|
||||
local container =
|
||||
element.add{
|
||||
name='container',
|
||||
type='frame',
|
||||
direction='vertical',
|
||||
style='window_content_frame_packed'
|
||||
}
|
||||
Gui.set_padding(container)
|
||||
|
||||
if config.stats.show_stats then
|
||||
create_section(container,'stats',2)
|
||||
end
|
||||
|
||||
if config.milestones.show_milestones then
|
||||
create_section(container,'milestones',2)
|
||||
end
|
||||
|
||||
if config.progress.show_progress then
|
||||
local col_count = 3
|
||||
if player_allowed(player,'remote_launch') then col_count = col_count+1 end
|
||||
if player_allowed(player,'toggle_active') then col_count = col_count+1 end
|
||||
create_section(container,'progress',col_count)
|
||||
--- label used when no active silos
|
||||
container.progress.add{
|
||||
type='label',
|
||||
name='no_silos',
|
||||
caption={'rocket-info.progress-no-silos'}
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Creates a text label followed by a data label, or updates them if already present
|
||||
local function create_label_value_pair(element,data_name,value,tooltip,extra)
|
||||
local data_name_extra = extra and data_name..extra or data_name
|
||||
if element[data_name_extra] then
|
||||
element[data_name_extra].label.caption = value
|
||||
element[data_name_extra].label.tooltip = tooltip
|
||||
else
|
||||
--- Label used with the data
|
||||
element.add{
|
||||
type='label',
|
||||
name=data_name_extra..'-label',
|
||||
caption={'rocket-info.data-caption-'..data_name,extra},
|
||||
tooltip={'rocket-info.data-tooltip-'..data_name,extra}
|
||||
}
|
||||
--- Right aligned label to store the data
|
||||
local right_flow = Gui.create_right_align(element,data_name_extra)
|
||||
right_flow.add{
|
||||
type='label',
|
||||
name='label',
|
||||
caption=value,
|
||||
tooltip=tooltip
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
--- Creates a text and data label using times as the data
|
||||
local function create_label_value_pair_time(element,data_name,raw_value,no_hours,extra)
|
||||
local value = no_hours and format_time(raw_value,{minutes=true,seconds=true}) or format_time(raw_value)
|
||||
local tooltip = format_time(raw_value,{hours=not no_hours,minutes=true,seconds=true,long=true})
|
||||
create_label_value_pair(element,data_name,value,tooltip,extra)
|
||||
end
|
||||
|
||||
--- Adds the data to the stats section
|
||||
local function generate_stats(player,frame)
|
||||
if not config.stats.show_stats then return end
|
||||
local element = frame.container.stats.table
|
||||
local force_rockets = player.force.rockets_launched
|
||||
|
||||
if config.stats.show_first_rocket then
|
||||
create_label_value_pair_time(element,'first-launch',rocket_stats.first_launch or 0)
|
||||
end
|
||||
|
||||
if config.stats.show_last_rocket then
|
||||
create_label_value_pair_time(element,'last-launch',rocket_stats.last_launch or 0)
|
||||
end
|
||||
|
||||
if config.stats.show_fastest_rocket then
|
||||
create_label_value_pair_time(element,'fastest-launch',rocket_stats.fastest_launch or 0,true)
|
||||
end
|
||||
|
||||
if config.stats.show_total_rockets then
|
||||
local total_rockets = 1
|
||||
if force_rockets > 0 then
|
||||
total_rockets = 0
|
||||
for _,force in pairs(game.forces) do
|
||||
total_rockets = total_rockets + force.rockets_launched
|
||||
end
|
||||
end
|
||||
local percentage = math.round(force_rockets/total_rockets,3)*100
|
||||
create_label_value_pair(element,'total-rockets',force_rockets,{'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
|
||||
create_label_value_pair_time(element,'avg-launch',avg,true)
|
||||
end
|
||||
|
||||
for _,avg_over in pairs(config.stats.rolling_avg) do
|
||||
local rocket_count = avg_over
|
||||
local first_rocket = 0
|
||||
if avg_over < force_rockets then
|
||||
first_rocket = rocket_times[player.force.name][force_rockets-avg_over]
|
||||
else
|
||||
rocket_count = force_rockets
|
||||
end
|
||||
local avg = rocket_count > 0 and math.floor((game.tick-first_rocket)/rocket_count) or 0
|
||||
create_label_value_pair_time(element,'avg-launch-n',avg,true,avg_over)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Creates the list of milestones
|
||||
local function generate_milestones(player,frame)
|
||||
if not config.milestones.show_milestones then return end
|
||||
local element = frame.container.milestones.table
|
||||
local force_rockets = player.force.rockets_launched
|
||||
|
||||
for _,milestone in ipairs(config.milestones) do
|
||||
if milestone <= force_rockets then
|
||||
local time = rocket_times[player.force.name][milestone]
|
||||
create_label_value_pair_time(element,'milstone-n',time,true,milestone)
|
||||
else
|
||||
create_label_value_pair_time(element,'milstone-n',0,true,milestone)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Creats the different action buttons
|
||||
local function generate_progress_buttons(player,element,rocket_silo_data)
|
||||
local silo_name = rocket_silo_data.name
|
||||
local status = rocket_silo_data.entity.status == 21
|
||||
local active = false -- need way to check this
|
||||
|
||||
if player_allowed(player,'toggle_active') then
|
||||
local button_element = element['toggle-'..silo_name]
|
||||
|
||||
if button_element then
|
||||
button_element = button_element[toggle_rocket.name]
|
||||
else
|
||||
button_element = toggle_rocket(element,silo_name)
|
||||
end
|
||||
|
||||
button_element.enabled = false -- remove once check is added
|
||||
if active then
|
||||
button_element.sprite = 'utility/stop'
|
||||
else
|
||||
button_element.sprite = 'utility/play'
|
||||
end
|
||||
end
|
||||
|
||||
if player_allowed(player,'remote_launch') then
|
||||
local button_element = element['launch-'..silo_name]
|
||||
|
||||
if button_element then
|
||||
button_element = button_element[launch_rocket.name]
|
||||
else
|
||||
button_element = launch_rocket(element,silo_name)
|
||||
end
|
||||
|
||||
if rocket_silo_data.awaiting_reset then
|
||||
button_element.enabled = false
|
||||
else
|
||||
button_element.enabled = status
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Creates build progress section
|
||||
local function generate_progress(player,frame)
|
||||
if not config.progress.show_progress then return end
|
||||
local element = frame.container.progress.table
|
||||
local force = player.force
|
||||
local force_name = force.name
|
||||
local force_silo_data = rocket_silos[force_name]
|
||||
|
||||
if not force_silo_data or table.size(force_silo_data) == 0 then
|
||||
element.parent.no_silos.visible = true
|
||||
|
||||
else
|
||||
element.parent.no_silos.visible = false
|
||||
|
||||
for silo_name,rocket_silo_data in pairs(force_silo_data) do
|
||||
if not rocket_silo_data.entity or not rocket_silo_data.entity.valid then
|
||||
force_silo_data[silo_name] = nil
|
||||
Gui.destory_if_valid(element['toggle-'..silo_name])
|
||||
Gui.destory_if_valid(element['launch-'..silo_name])
|
||||
Gui.destory_if_valid(element['label-x-'..silo_name])
|
||||
Gui.destory_if_valid(element['label-y-'..silo_name])
|
||||
Gui.destory_if_valid(element[silo_name])
|
||||
|
||||
elseif not element[silo_name] then
|
||||
local entity = rocket_silo_data.entity
|
||||
local progress = entity.rocket_parts
|
||||
local pos = {
|
||||
x=entity.position.x,
|
||||
y=entity.position.y
|
||||
}
|
||||
|
||||
generate_progress_buttons(player,element,rocket_silo_data)
|
||||
|
||||
--- Creats two flows and two labels for the X and Y position
|
||||
local name = config.progress.allow_zoom_to_map and zoom_to_map_name or nil
|
||||
local tooltip = config.progress.allow_zoom_to_map and {'rocket-info.progress-label-tooltip'} or nil
|
||||
local flow_x = element.add{
|
||||
type='flow',
|
||||
name='label-x-'..silo_name,
|
||||
caption=silo_name
|
||||
}
|
||||
Gui.set_padding(flow_x,0,0,1,2)
|
||||
flow_x.add{
|
||||
type='label',
|
||||
name=name,
|
||||
caption={'rocket-info.progress-x-pos',pos.x},
|
||||
tooltip=tooltip
|
||||
}
|
||||
|
||||
local flow_y = element.add{
|
||||
type='flow',
|
||||
name='label-y-'..silo_name,
|
||||
caption=silo_name
|
||||
}
|
||||
Gui.set_padding(flow_y,0,0,1,2)
|
||||
flow_y.add{
|
||||
type='label',
|
||||
name=name,
|
||||
caption={'rocket-info.progress-y-pos',pos.y},
|
||||
tooltip=tooltip
|
||||
}
|
||||
|
||||
--- Creates the progress value which is right aligned
|
||||
local right_flow = Gui.create_right_align(element,silo_name)
|
||||
right_flow.add{
|
||||
type='label',
|
||||
name='label',
|
||||
caption={'rocket-info.progress-caption',progress},
|
||||
tooltip={'rocket-info.progress-tooltip',rocket_silo_data.launched or 0}
|
||||
}
|
||||
|
||||
else
|
||||
local entity = rocket_silo_data.entity
|
||||
local progress = entity.rocket_parts
|
||||
local status = entity.status == 21
|
||||
|
||||
local label = element[silo_name].label
|
||||
label.caption = {'rocket-info.progress-caption',progress}
|
||||
label.tooltip = {'rocket-info.progress-tooltip',rocket_silo_data.launched or 0}
|
||||
|
||||
if status and rocket_silo_data.awaiting_reset then
|
||||
label.caption = {'rocket-info.progress-launched'}
|
||||
label.style.font_color = Colors.green
|
||||
elseif status then
|
||||
label.caption = {'rocket-info.progress-caption',100}
|
||||
label.style.font_color = Colors.cyan
|
||||
else
|
||||
rocket_silo_data.awaiting_reset = false
|
||||
label.style.font_color = Colors.white
|
||||
end
|
||||
|
||||
generate_progress_buttons(player,element,rocket_silo_data)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
local rocket_info =
|
||||
Gui.new_left_frame('gui/rocket-info')
|
||||
:set_sprites('entity/rocket-silo')
|
||||
:set_post_authenticator(function(player,define_name)
|
||||
return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(player,define_name)
|
||||
end)
|
||||
:set_open_by_default(function(player,define_name)
|
||||
return player.force.rockets_launched > 0
|
||||
end)
|
||||
:set_direction('vertical')
|
||||
:on_draw(function(player,element)
|
||||
generate_container(player,element)
|
||||
generate_stats(player,element)
|
||||
generate_milestones(player,element)
|
||||
generate_progress(player,element)
|
||||
end)
|
||||
:on_update(function(player,element)
|
||||
generate_stats(player,element)
|
||||
generate_milestones(player,element)
|
||||
generate_progress(player,element)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_rocket_launched,function(event)
|
||||
local entity = event.rocket_silo
|
||||
local silo_name = get_silo_name(entity)
|
||||
local force = event.rocket_silo.force
|
||||
local force_name = force.name
|
||||
local force_silo_data = rocket_silos[force_name]
|
||||
local rockets_launched = force.rockets_launched
|
||||
local first_rocket = rockets_launched == 1
|
||||
|
||||
--- Handles updates to the rocket stats
|
||||
if not rocket_stats[force_name] then
|
||||
rocket_stats[force_name] = {}
|
||||
end
|
||||
|
||||
if first_rocket then
|
||||
rocket_stats.first_launch = event.tick
|
||||
rocket_stats.fastest_launch = event.tick
|
||||
elseif event.tick-rocket_stats.last_launch < rocket_stats.fastest_launch then
|
||||
rocket_stats.fastest_launch = event.tick-rocket_stats.last_launch
|
||||
end
|
||||
|
||||
rocket_stats.last_launch = event.tick
|
||||
|
||||
--- Appends the new rocket into the array
|
||||
if not rocket_times[force_name] then
|
||||
rocket_times[force_name] = {}
|
||||
end
|
||||
|
||||
rocket_times[force_name][rockets_launched] = event.tick
|
||||
|
||||
--- Adds this 1 to the launch count for this silo
|
||||
force_silo_data[silo_name].launched = force_silo_data[silo_name].launched+1
|
||||
|
||||
--- Updates all the guis (and toolbar since the button may now be visible)
|
||||
for _,player in pairs(force.players) do
|
||||
rocket_info:update(player)
|
||||
if first_rocket then Gui.update_toolbar(player) end
|
||||
end
|
||||
end)
|
||||
|
||||
--- When a launch is reiggered it will await reset
|
||||
Event.add(defines.events.on_rocket_launch_ordered,function(event)
|
||||
local entity = event.rocket_silo
|
||||
local silo_name = get_silo_name(entity)
|
||||
local force = event.rocket_silo.force
|
||||
local force_name = force.name
|
||||
local force_silo_data = rocket_silos[force_name]
|
||||
force_silo_data[silo_name].awaiting_reset = true
|
||||
end)
|
||||
|
||||
--- Adds a silo to the list when it is built
|
||||
local function on_built(event)
|
||||
local entity = event.created_entity
|
||||
if entity.valid and entity.name == 'rocket-silo' then
|
||||
local force = entity.force
|
||||
local force_name = force.name
|
||||
local silo_name = get_silo_name(entity)
|
||||
|
||||
if not rocket_silos[force_name] then
|
||||
rocket_silos[force_name] = {}
|
||||
end
|
||||
|
||||
rocket_silos[force_name][silo_name] = {
|
||||
name=silo_name,
|
||||
entity=entity,
|
||||
launched=0,
|
||||
awaiting_reset=false
|
||||
}
|
||||
|
||||
for _,player in pairs(force.players) do
|
||||
local frame = rocket_info:get_frame(player)
|
||||
generate_progress(player,frame)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_built_entity,on_built)
|
||||
Event.add(defines.events.on_robot_built_entity,on_built)
|
||||
|
||||
--- Optimised update for only the build progress
|
||||
Event.on_nth_tick(150,function()
|
||||
for _,force in pairs(game.forces) do
|
||||
local silos = rocket_silos[force.name]
|
||||
if silos then
|
||||
for _,player in pairs(force.connected_players) do
|
||||
local frame = rocket_info:get_frame(player)
|
||||
generate_progress(player,frame)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return rocket_info
|
||||
Reference in New Issue
Block a user