From 0b9e8b8cd50d284e06c7b2f2b20844a3ff1815bb Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Mon, 27 May 2019 22:37:59 +0100 Subject: [PATCH 1/5] Looks Sorted --- config/_file_loader.lua | 1 + config/rockets.lua | 37 +++ config/roles.lua | 5 + expcore/gui/core.lua | 21 ++ locale/en/gui.cfg | 1 + modules/gui/player-list.lua | 12 +- modules/gui/rocket-info.lua | 506 ++++++++++++++++++++++++++++++++++++ 7 files changed, 574 insertions(+), 9 deletions(-) create mode 100644 config/rockets.lua create mode 100644 modules/gui/rocket-info.lua diff --git a/config/_file_loader.lua b/config/_file_loader.lua index ca4405fd..746bbcb7 100644 --- a/config/_file_loader.lua +++ b/config/_file_loader.lua @@ -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 diff --git a/config/rockets.lua b/config/rockets.lua new file mode 100644 index 00000000..f6e7cb3b --- /dev/null +++ b/config/rockets.lua @@ -0,0 +1,37 @@ +--- This file controls what will show in each section of the rocket info gui +-- each function will be given the player and must return the value to show and a tooltip, nil will not show the stat +local Global = require 'utils.global' +local Event = require 'utils.event' + +return { + stats = { + show_stats=true, + show_first_rocket = true, + show_last_rocket = true, + show_fastest_rocket = true, + show_total_rockets = true, + show_game_avg = true, + rolling_avg = { + 5,10,25 + } + }, + milestones = { + show_milestones=true, + 1,2,5, + 10,20,50, + 100,200,500, + 1000,1500,2000,2500, + 3000,3500,4000,4500, + 5000 + }, + progress = { + show_progress = true, + allow_zoom_to_map = true, + allow_remote_launch = true, + remote_launch_admins_only = false, + remote_launch_role_permision = 'gui/rocket-info/remote_launch', + allow_toggle_active = true, + toggle_active_admins_only = false, + toggle_active_role_permision = 'gui/rocket-info/toggle-active' + } +} \ No newline at end of file diff --git a/config/roles.lua b/config/roles.lua index 3604d31a..532b2db5 100644 --- a/config/roles.lua +++ b/config/roles.lua @@ -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 diff --git a/expcore/gui/core.lua b/expcore/gui/core.lua index 8eb407cf..0415e8a1 100644 --- a/expcore/gui/core.lua +++ b/expcore/gui/core.lua @@ -153,6 +153,7 @@ 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 ]] local Gui = require 'utils.gui' local Game = require 'utils.game' @@ -515,6 +516,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 +524,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 +537,7 @@ function Gui.toggle_visible(element) else element.visible = false end + return element.visible end --- Sets the padding for a gui element @@ -562,4 +567,20 @@ 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 + return Gui \ No newline at end of file diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index 80a9e80d..f0ff3cfc 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -1,4 +1,5 @@ [player-list] +main-tooltip=Player list open-action-bar=Options close-action-bar=Close Options reason-confirm=Confirm Reason diff --git a/modules/gui/player-list.lua b/modules/gui/player-list.lua index 79339dd4..d2545f5a 100644 --- a/modules/gui/player-list.lua +++ b/modules/gui/player-list.lua @@ -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) diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua new file mode 100644 index 00000000..9531e0ab --- /dev/null +++ b/modules/gui/rocket-info.lua @@ -0,0 +1,506 @@ +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) + +local function get_silo_name(entity) + local position = entity.position + return 'X '..math.floor(position.x)..' Y '..math.floor(position.y) +end + +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.caption + local rocket_silo = rocket_silos[force.name][rocket_silo_name] + local position = rocket_silo.entity.position + event.player.zoom_to_world(position,2) +end) + +local launch_rocket = +Gui.new_button() +:set_sprites('utility/center') +:set_tooltip('Click to launch rocket') +: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 = rocket_silos[force.name][rocket_silo_name] + rocket_silo.entity.launch_rocket() +end) + +local toggle_rocket = +Gui.new_button() +:set_sprites('utility/play') +:set_tooltip('Click to launch rocket') +: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 status = true + if status 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!') + else + element.sprite = 'utility/stop' + end +end) + +local header_expand = +Gui.new_button() +:set_sprites('utility/expand_dark','utility/expand') +:set_tooltip('Click to expand') +: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' + else + element.sprite = 'utility/expand_dark' + element.hovered_sprite = 'utility/expand' + end +end) + +local function create_header_flow_combo(player,element,name,table_size,caption,tooltip) + -- header for the combo + local header = + element.add{ + type='frame', + name=name..'-header', + style='subheader_frame', + } + Gui.set_padding(header,1,1,3,3) + header.style.horizontally_stretchable = true + + -- caption for header bar + header.add{ + type='label', + style='heading_1_label', + caption=caption, + tooltip=tooltip + } + + -- right aligned button to toggle the drop down area + local expand_flow = Gui.create_right_align(header,name) + header_expand(expand_flow) + + -- flow for the combo + local flow = + element.add{ + name=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 to allow for nice looking labels + 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 + +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 + +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_header_flow_combo(player,container,'stats',2,'Statistics','Stats about rockets') + end + + if config.milestones.show_milestones then + create_header_flow_combo(player,container,'milestones',2,'Milestones','Rocket milestones') + end + + if config.progress.show_progress then + local col_count = 2 + 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_header_flow_combo(player,container,'progress',col_count,'Build Progress','Build progress of rockets') + container.progress.add{ + type='label', + name='no_silos', + caption='Your force has no silos' + } + end + +end + +local function create_label_pair_time(element,name,raw_value,caption,tooltip,no_hours) + local value = no_hours and format_time(raw_value,{minutes=true,seconds=true}) or format_time(raw_value) + local value_tooltip = format_time(raw_value,{hours=not no_hours,minutes=true,seconds=true,long=true}) + if not element[name] then + -- main label to show the name of the value + element.add{ + type='label', + name=name..'-label', + caption=caption, + tooltip=tooltip + } + -- flow which allows right align for the value + local right_flow = Gui.create_right_align(element,name) + right_flow.add{ + type='label', + name='label', + caption=value, + tooltip=value_tooltip + } + else + element[name].label.caption = value + element[name].label.tooltip = value_tooltip + end +end + +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_pair_time(element,'first_launch',rocket_stats.first_launch or 0,'First Launch','The time of launch of the first rocket') + end + + if config.stats.show_last_rocket then + create_label_pair_time(element,'last_launch',rocket_stats.last_launch or 0,'Last Launch','The time that the last rocket was launched') + end + + if config.stats.show_fastest_rocket then + create_label_pair_time(element,'fastest_launch',rocket_stats.fastest_launch or 0,'Fastest Launch','The time taken for the fastest launch',true) + end + + if config.stats.show_total_rockets then + local total_rockets = 0 + + for _,force in pairs(game.forces) do + total_rockets = total_rockets + force.rockets_launched + end + total_rockets = total_rockets > 0 and total_rockets or 1 + local percentage = math.round(force_rockets/total_rockets,3)*100 + + if not element.total_rockets then + -- main label to show the name of the value + element.add{ + type='label', + name='total_rockets-label', + caption='Total Lauched', + tooltip='The total number of rockets launched' + } + -- flow which allows right align for the value + local right_flow = Gui.create_right_align(element,'total_rockets') + right_flow.add{ + type='label', + name='label', + caption=force_rockets, + tooltip=percentage + } + else + element.total_rockets.label.caption = force_rockets + element.total_rockets.label.tooltip = percentage + end + end + + if config.stats.show_game_avg then + local tick = game.tick > 0 and game.tick or 1 + local avg = math.floor(force_rockets/tick) + create_label_pair_time(element,'avg_launch',avg,'Avg Launch','The average time to launch a rocket',true) + end + + for _,over in pairs(config.stats.rolling_avg) do + local total = 0 + local rocket_count = 0 + for i = force_rockets,force_rockets-over,-1 do + if rocket_times[i] then + rocket_count = rocket_count + 1 + total = total + rocket_times[i] + end + end + total = total > 0 and total or 1 + local avg = math.floor(rocket_count/total) + create_label_pair_time(element,'avg_launch_'..over,avg,'Avg Launch '..over,'The rolling average time to launch a rocket for the past '..over..' rockets',true) + end + +end + +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 and not element['milstone-'..milestone] then + create_label_pair_time(element,'milstone-'..milestone,rocket_times[player.force.name][milestone],'Milestone '..milestone,'Time taken to launch '..milestone..' rockets') + end + end +end + +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.name + + if not rocket_silos[force] or table.size(rocket_silos[force]) == 0 then + element.parent.no_silos.visible = true + + else + element.parent.no_silos.visible = false + for rocket_silo_name,rocket_silo in pairs(rocket_silos[force]) do + if not rocket_silo.entity or not rocket_silo.entity.valid then + rocket_silos[force][rocket_silo_name] = nil + if element['label_'..rocket_silo_name] then element['label_'..rocket_silo_name].destroy() end + if element['launch_'..rocket_silo_name] then element['launch_'..rocket_silo_name].destroy() end + if element['toggle_'..rocket_silo_name] then element['toggle_'..rocket_silo_name].destroy() end + if element[rocket_silo_name] then element[rocket_silo_name].destroy() end + + elseif not element[rocket_silo_name] then + local progress = rocket_silo.entity.rocket_parts + local status = rocket_silo.entity.status == 21 + local active = false -- need way to check this + + if player_allowed(player,'toggle_active') then + local toggle_rocket_element = toggle_rocket(element,rocket_silo_name) + toggle_rocket_element.enabled = false -- remove when done + if active then + toggle_rocket_element.sprite = 'utility/stop' + else + toggle_rocket_element.sprite = 'utility/play' + end + end + + if player_allowed(player,'remote_launch') then + local launch_rocket_element = launch_rocket(element,rocket_silo_name) + launch_rocket_element.enabled = status + end + + -- main label to show the name of the value + local flow = element.add{type='flow',name='label_'..rocket_silo_name} + Gui.set_padding(flow,0,0,2,0) + flow.add{ + type='label', + name=zoom_to_map_name, + caption=rocket_silo_name, + tooltip='Click to view on map' + } + + -- flow which allows right align for the value + local right_flow = Gui.create_right_align(element,rocket_silo_name) + right_flow.add{ + type='label', + name='label', + caption=progress..'%', + tooltip=rocket_silo.launched or 0 + } + + else + local progress = rocket_silo.entity.rocket_parts + local status = rocket_silo.entity.status == 21 + local active = false -- need way to check this + + local label = element[rocket_silo_name].label + label.caption = progress..'%' + label.tooltip = rocket_silo.launched or 0 + + if status then + label.caption = '100%' + label.style.font_color = Colors.cyan + else + label.style.font_color = Colors.white + end + + if player_allowed(player,'toggle_active') then + local toggle_rocket_element = element['toggle_'..rocket_silo_name] + if active then + toggle_rocket_element[toggle_rocket.name].sprite = 'utility/stop' + else + toggle_rocket_element[toggle_rocket.name].sprite = 'utility/play' + end + end + + if player_allowed(player,'remote_launch') then + local launch_rocket_element = element['launch_'..rocket_silo_name] + launch_rocket_element[launch_rocket.name].enabled = status + end + + + + 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 true + --return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(player,define_name) +end) +:set_open_by_default(function(player,define_name) + return true + --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 force = event.rocket_silo.force + local force_name = force.name + local rockets_launched = force.rockets_launched + + if not rocket_stats[force_name] then + rocket_stats[force_name] = {} + end + + if rockets_launched == 1 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 + + if not rocket_times[force_name] then + rocket_times[force_name] = {} + end + + rocket_times[force_name][rockets_launched] = event.tick + + local silo_name = get_silo_name(event.rocket_silo) + + if not rocket_silos[force_name] then + rocket_silos[force_name] = {} + end + + if not rocket_silos[force_name][silo_name] then + rocket_silos[force_name][silo_name] = {entity=event.rocket_silo,launched=0} + end + + rocket_silos[force_name][silo_name].launched = rocket_silos[force_name][silo_name].launched+1 + + for _,player in pairs(force.players) do + rocket_info:update(player) + Gui.update_toolbar(player) + end +end) + +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] = {entity=entity,launched=0} + + for _,player in pairs(force.players) do + rocket_info:update(player) + end + end +end + +Event.add(defines.events.on_built_entity,on_built) +Event.add(defines.events.on_robot_built_entity,on_built) +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 \ No newline at end of file From 56b102d823c6bf2977bfa5d175966d9fc2e42899 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 28 May 2019 01:08:09 +0100 Subject: [PATCH 2/5] Finished Rocket Gui --- expcore/gui.lua | 3 + expcore/gui/core.lua | 11 + locale/en/gui.cfg | 39 ++- modules/gui/rocket-info.lua | 631 ++++++++++++++++++++---------------- 4 files changed, 411 insertions(+), 273 deletions(-) diff --git a/expcore/gui.lua b/expcore/gui.lua index 70f0ffc3..7f38e777 100644 --- a/expcore/gui.lua +++ b/expcore/gui.lua @@ -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' diff --git a/expcore/gui/core.lua b/expcore/gui/core.lua index 0415e8a1..c58de2e3 100644 --- a/expcore/gui/core.lua +++ b/expcore/gui/core.lua @@ -154,6 +154,7 @@ 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' @@ -583,4 +584,14 @@ function Gui.create_right_align(element,flow_name) 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 \ No newline at end of file diff --git a/locale/en/gui.cfg b/locale/en/gui.cfg index f0ff3cfc..e7e2aee4 100644 --- a/locale/en/gui.cfg +++ b/locale/en/gui.cfg @@ -14,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 \ No newline at end of file +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 \ No newline at end of file diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 9531e0ab..3171643d 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -20,135 +20,13 @@ Global.register({ 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 'X '..math.floor(position.x)..' Y '..math.floor(position.y) -end - -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.caption - local rocket_silo = rocket_silos[force.name][rocket_silo_name] - local position = rocket_silo.entity.position - event.player.zoom_to_world(position,2) -end) - -local launch_rocket = -Gui.new_button() -:set_sprites('utility/center') -:set_tooltip('Click to launch rocket') -: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 = rocket_silos[force.name][rocket_silo_name] - rocket_silo.entity.launch_rocket() -end) - -local toggle_rocket = -Gui.new_button() -:set_sprites('utility/play') -:set_tooltip('Click to launch rocket') -: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 status = true - if status 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!') - else - element.sprite = 'utility/stop' - end -end) - -local header_expand = -Gui.new_button() -:set_sprites('utility/expand_dark','utility/expand') -:set_tooltip('Click to expand') -: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' - else - element.sprite = 'utility/expand_dark' - element.hovered_sprite = 'utility/expand' - end -end) - -local function create_header_flow_combo(player,element,name,table_size,caption,tooltip) - -- header for the combo - local header = - element.add{ - type='frame', - name=name..'-header', - style='subheader_frame', - } - Gui.set_padding(header,1,1,3,3) - header.style.horizontally_stretchable = true - - -- caption for header bar - header.add{ - type='label', - style='heading_1_label', - caption=caption, - tooltip=tooltip - } - - -- right aligned button to toggle the drop down area - local expand_flow = Gui.create_right_align(header,name) - header_expand(expand_flow) - - -- flow for the combo - local flow = - element.add{ - name=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 to allow for nice looking labels - 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 + 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 @@ -165,6 +43,166 @@ local function player_allowed(player,action) 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,1,1,3,3) + 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 @@ -180,223 +218,257 @@ local function generate_container(player,element) Gui.set_padding(container) if config.stats.show_stats then - create_header_flow_combo(player,container,'stats',2,'Statistics','Stats about rockets') + create_section(container,'stats',2) end if config.milestones.show_milestones then - create_header_flow_combo(player,container,'milestones',2,'Milestones','Rocket milestones') + create_section(container,'milestones',2) end if config.progress.show_progress then - local col_count = 2 + 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_header_flow_combo(player,container,'progress',col_count,'Build Progress','Build progress of rockets') + create_section(container,'progress',col_count) + --- label used when no active silos container.progress.add{ type='label', name='no_silos', - caption='Your force has no silos' + caption={'rocket-info.progress-no-silos'} } end end -local function create_label_pair_time(element,name,raw_value,caption,tooltip,no_hours) - local value = no_hours and format_time(raw_value,{minutes=true,seconds=true}) or format_time(raw_value) - local value_tooltip = format_time(raw_value,{hours=not no_hours,minutes=true,seconds=true,long=true}) - if not element[name] then - -- main label to show the name of the value +--- 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=name..'-label', - caption=caption, - tooltip=tooltip + name=data_name_extra..'-label', + caption={'rocket-info.data-caption-'..data_name,extra}, + tooltip={'rocket-info.data-tooltip-'..data_name,extra} } - -- flow which allows right align for the value - local right_flow = Gui.create_right_align(element,name) + --- 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=value_tooltip + tooltip=tooltip } - else - element[name].label.caption = value - element[name].label.tooltip = value_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_pair_time(element,'first_launch',rocket_stats.first_launch or 0,'First Launch','The time of launch of the first rocket') + create_label_value_pair_time(element,'first-launch',rocket_stats.first_launch or 0) end if config.stats.show_last_rocket then - create_label_pair_time(element,'last_launch',rocket_stats.last_launch or 0,'Last Launch','The time that the last rocket was launched') + create_label_value_pair_time(element,'last-launch',rocket_stats.last_launch or 0) end if config.stats.show_fastest_rocket then - create_label_pair_time(element,'fastest_launch',rocket_stats.fastest_launch or 0,'Fastest Launch','The time taken for the fastest launch',true) + 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 = 0 - - for _,force in pairs(game.forces) do - total_rockets = total_rockets + force.rockets_launched + 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 - total_rockets = total_rockets > 0 and total_rockets or 1 local percentage = math.round(force_rockets/total_rockets,3)*100 - - if not element.total_rockets then - -- main label to show the name of the value - element.add{ - type='label', - name='total_rockets-label', - caption='Total Lauched', - tooltip='The total number of rockets launched' - } - -- flow which allows right align for the value - local right_flow = Gui.create_right_align(element,'total_rockets') - right_flow.add{ - type='label', - name='label', - caption=force_rockets, - tooltip=percentage - } - else - element.total_rockets.label.caption = force_rockets - element.total_rockets.label.tooltip = percentage - end + 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 tick = game.tick > 0 and game.tick or 1 - local avg = math.floor(force_rockets/tick) - create_label_pair_time(element,'avg_launch',avg,'Avg Launch','The average time to launch a rocket',true) + 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 _,over in pairs(config.stats.rolling_avg) do - local total = 0 - local rocket_count = 0 - for i = force_rockets,force_rockets-over,-1 do - if rocket_times[i] then - rocket_count = rocket_count + 1 - total = total + rocket_times[i] - 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 - total = total > 0 and total or 1 - local avg = math.floor(rocket_count/total) - create_label_pair_time(element,'avg_launch_'..over,avg,'Avg Launch '..over,'The rolling average time to launch a rocket for the past '..over..' rockets',true) + 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 and not element['milstone-'..milestone] then - create_label_pair_time(element,'milstone-'..milestone,rocket_times[player.force.name][milestone],'Milestone '..milestone,'Time taken to launch '..milestone..' rockets') + 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.name + local force = player.force + local force_name = force.name + local force_silo_data = rocket_silos[force_name] - if not rocket_silos[force] or table.size(rocket_silos[force]) == 0 then + 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 rocket_silo_name,rocket_silo in pairs(rocket_silos[force]) do - if not rocket_silo.entity or not rocket_silo.entity.valid then - rocket_silos[force][rocket_silo_name] = nil - if element['label_'..rocket_silo_name] then element['label_'..rocket_silo_name].destroy() end - if element['launch_'..rocket_silo_name] then element['launch_'..rocket_silo_name].destroy() end - if element['toggle_'..rocket_silo_name] then element['toggle_'..rocket_silo_name].destroy() end - if element[rocket_silo_name] then element[rocket_silo_name].destroy() end - elseif not element[rocket_silo_name] then - local progress = rocket_silo.entity.rocket_parts - local status = rocket_silo.entity.status == 21 - local active = false -- need way to check this + 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]) - if player_allowed(player,'toggle_active') then - local toggle_rocket_element = toggle_rocket(element,rocket_silo_name) - toggle_rocket_element.enabled = false -- remove when done - if active then - toggle_rocket_element.sprite = 'utility/stop' - else - toggle_rocket_element.sprite = 'utility/play' - end - end - - if player_allowed(player,'remote_launch') then - local launch_rocket_element = launch_rocket(element,rocket_silo_name) - launch_rocket_element.enabled = status - end - - -- main label to show the name of the value - local flow = element.add{type='flow',name='label_'..rocket_silo_name} - Gui.set_padding(flow,0,0,2,0) - flow.add{ - type='label', - name=zoom_to_map_name, - caption=rocket_silo_name, - tooltip='Click to view on map' + 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 } - -- flow which allows right align for the value - local right_flow = Gui.create_right_align(element,rocket_silo_name) + generate_progress_buttons(player,element,rocket_silo_data) + + --- Creats two flows and two labels for the X and Y position + 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=zoom_to_map_name, + caption={'rocket-info.progress-x-pos',pos.x}, + tooltip={'rocket-info.progress-label-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=zoom_to_map_name, + caption={'rocket-info.progress-y-pos',pos.y}, + tooltip={'rocket-info.progress-label-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=progress..'%', - tooltip=rocket_silo.launched or 0 + caption={'rocket-info.progress-caption',progress}, + tooltip={'rocket-info.progress-tooltip',rocket_silo_data.launched or 0} } else - local progress = rocket_silo.entity.rocket_parts - local status = rocket_silo.entity.status == 21 - local active = false -- need way to check this + local entity = rocket_silo_data.entity + local progress = entity.rocket_parts + local status = entity.status == 21 - local label = element[rocket_silo_name].label - label.caption = progress..'%' - label.tooltip = rocket_silo.launched or 0 + 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 then - label.caption = '100%' + 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 - if player_allowed(player,'toggle_active') then - local toggle_rocket_element = element['toggle_'..rocket_silo_name] - if active then - toggle_rocket_element[toggle_rocket.name].sprite = 'utility/stop' - else - toggle_rocket_element[toggle_rocket.name].sprite = 'utility/play' - end - end - - if player_allowed(player,'remote_launch') then - local launch_rocket_element = element['launch_'..rocket_silo_name] - launch_rocket_element[launch_rocket.name].enabled = status - end - - + generate_progress_buttons(player,element,rocket_silo_data) end end @@ -408,12 +480,10 @@ local rocket_info = Gui.new_left_frame('gui/rocket-info') :set_sprites('entity/rocket-silo') :set_post_authenticator(function(player,define_name) - return true - --return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(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 true - --return player.force.rockets_launched > 0 + return player.force.rockets_launched > 0 end) :set_direction('vertical') :on_draw(function(player,element) @@ -429,15 +499,20 @@ end) 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 rockets_launched == 1 then + 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 @@ -446,30 +521,34 @@ Event.add(defines.events.on_rocket_launched,function(event) 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 - local silo_name = get_silo_name(event.rocket_silo) - - if not rocket_silos[force_name] then - rocket_silos[force_name] = {} - end - - if not rocket_silos[force_name][silo_name] then - rocket_silos[force_name][silo_name] = {entity=event.rocket_silo,launched=0} - end - - rocket_silos[force_name][silo_name].launched = rocket_silos[force_name][silo_name].launched+1 + --- 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) - Gui.update_toolbar(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 @@ -481,16 +560,24 @@ local function on_built(event) rocket_silos[force_name] = {} end - rocket_silos[force_name][silo_name] = {entity=entity,launched=0} + rocket_silos[force_name][silo_name] = { + name=silo_name, + entity=entity, + launched=0, + awaiting_reset=false + } for _,player in pairs(force.players) do - rocket_info:update(player) + 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] From 0ddf4676fe3bc0e38c3b918f1b7ccbd4786aa890 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 28 May 2019 01:20:58 +0100 Subject: [PATCH 3/5] Added config for silo script --- config/advanced_start.lua | 3 +++ modules/addons/advanced-start.lua | 10 ++++++++ modules/factorio-control.lua | 39 ++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/config/advanced_start.lua b/config/advanced_start.lua index 0847ac6d..586530ad 100644 --- a/config/advanced_start.lua +++ b/config/advanced_start.lua @@ -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 diff --git a/modules/addons/advanced-start.lua b/modules/addons/advanced-start.lua index 07ed9ddc..5379705b 100644 --- a/modules/addons/advanced-start.lua +++ b/modules/addons/advanced-start.lua @@ -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) \ No newline at end of file diff --git a/modules/factorio-control.lua b/modules/factorio-control.lua index 13557506..20394547 100644 --- a/modules/factorio-control.lua +++ b/modules/factorio-control.lua @@ -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", { From 84a377f4e57e81dccc18728f4d207e8c5b2510d0 Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 28 May 2019 01:37:43 +0100 Subject: [PATCH 4/5] Updated config for rocket Gui --- config/rockets.lua | 42 +++++++++++++++++-------------------- modules/gui/rocket-info.lua | 15 +++++++------ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/config/rockets.lua b/config/rockets.lua index f6e7cb3b..7025ae16 100644 --- a/config/rockets.lua +++ b/config/rockets.lua @@ -1,22 +1,18 @@ --- This file controls what will show in each section of the rocket info gui --- each function will be given the player and must return the value to show and a tooltip, nil will not show the stat -local Global = require 'utils.global' -local Event = require 'utils.event' - return { - stats = { - show_stats=true, - show_first_rocket = true, - show_last_rocket = true, - show_fastest_rocket = true, - show_total_rockets = true, - show_game_avg = true, - rolling_avg = { + 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 = { - show_milestones=true, + 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, @@ -24,14 +20,14 @@ return { 3000,3500,4000,4500, 5000 }, - progress = { - show_progress = true, - allow_zoom_to_map = true, - allow_remote_launch = true, - remote_launch_admins_only = false, - remote_launch_role_permision = 'gui/rocket-info/remote_launch', - allow_toggle_active = true, - toggle_active_admins_only = false, - toggle_active_role_permision = 'gui/rocket-info/toggle-active' + 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 } } \ No newline at end of file diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 3171643d..53734299 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -139,7 +139,7 @@ local function create_section(container,section_name,table_size) name=section_name..'-header', style='subheader_frame', } - Gui.set_padding(header,1,1,3,3) + Gui.set_padding(header,4,1,4,4) header.style.horizontally_stretchable = true --- Caption for the header bar @@ -413,6 +413,8 @@ local function generate_progress(player,frame) 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, @@ -421,9 +423,9 @@ local function generate_progress(player,frame) Gui.set_padding(flow_x,0,0,1,2) flow_x.add{ type='label', - name=zoom_to_map_name, + name=name, caption={'rocket-info.progress-x-pos',pos.x}, - tooltip={'rocket-info.progress-label-tooltip'} + tooltip=tooltip } local flow_y = element.add{ @@ -434,9 +436,9 @@ local function generate_progress(player,frame) Gui.set_padding(flow_y,0,0,1,2) flow_y.add{ type='label', - name=zoom_to_map_name, + name=name, caption={'rocket-info.progress-y-pos',pos.y}, - tooltip={'rocket-info.progress-label-tooltip'} + tooltip=tooltip } --- Creates the progress value which is right aligned @@ -483,7 +485,8 @@ Gui.new_left_frame('gui/rocket-info') 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 + return true + --return player.force.rockets_launched > 0 end) :set_direction('vertical') :on_draw(function(player,element) From 361438400f5ef52a19469b1e79a8cc269e7cb19d Mon Sep 17 00:00:00 2001 From: Cooldude2606 Date: Tue, 28 May 2019 01:38:42 +0100 Subject: [PATCH 5/5] Removed debug open by deafult --- modules/gui/rocket-info.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/gui/rocket-info.lua b/modules/gui/rocket-info.lua index 53734299..6a62a6f4 100644 --- a/modules/gui/rocket-info.lua +++ b/modules/gui/rocket-info.lua @@ -485,8 +485,7 @@ Gui.new_left_frame('gui/rocket-info') return player.force.rockets_launched > 0 and Gui.classes.toolbar.allowed(player,define_name) end) :set_open_by_default(function(player,define_name) - return true - --return player.force.rockets_launched > 0 + return player.force.rockets_launched > 0 end) :set_direction('vertical') :on_draw(function(player,element)