Files
factorio-scenario-ExpCluster/modules/gui/readme.lua
2020-03-25 23:30:34 +00:00

371 lines
11 KiB
Lua

--[[-- Gui Module - Readme
- Adds a main gui that contains lots of important information about our server
@gui Readme
@alias readme
]]
local Gui = require 'expcore.gui' --- @dep expcore.gui
local Roles = require 'expcore.roles' --- @dep expcore.roles
local Commands = require 'expcore.commands' --- @dep expcore.commands
local Event = require 'utils.event' --- @dep utils.event
local Game = require 'utils.game' --- @dep utils.game
local tabs = {}
local function Tab(caption,tooltip,element_define)
tabs[#tabs+1] = {caption,tooltip,element_define}
end
local frame_width = 595
local function description_label(parent,width,caption)
local label = parent.add{
type = 'label',
caption = caption,
style = 'description_label'
}
local style = label.style
style.horizontal_align = 'center'
style.single_line = false
style.width = width
end
--- Sub content area used within the content areas
-- @element sub_content
local sub_content =
Gui.element(function(_,parent)
return parent.add{
type = 'frame',
direction = 'vertical',
style = 'image_frame'
}
end)
:style{
horizontally_stretchable = true,
horizontal_align = 'center'
}
--- Title element with bars on each side
-- @element title
local title =
Gui.element(function(_,parent,bar_size,caption)
local title_flow = parent.add{ type='flow' }
title_flow.style.vertical_align = 'center'
Gui.bar(title_flow,bar_size)
local title_label = title_flow.add{
type = 'label',
caption = caption,
style = 'heading_1_label'
}
Gui.bar(title_flow)
return title_label
end)
--- Table which has a title above it
-- @element title_table
local title_table =
Gui.element(function(_,parent,bar_size,caption,column_count)
title(parent, bar_size, caption)
return parent.add{
type = 'table',
column_count = column_count,
style = 'bordered_table'
}
end)
:style{
padding = 0,
cell_padding = 0,
vertical_align = 'center',
horizontally_stretchable = true
}
--- Scroll to be used with title tables
-- @element title_table_scroll
local title_table_scroll =
Gui.element{
type = 'scroll-pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto',
style = 'scroll_pane_under_subheader'
}
:style{
padding = {1,3},
maximal_height = 275,
horizontally_stretchable = true,
}
--- Content area for the welcome tab
-- @element welcome_content
Tab({'readme.welcome-tab'},{'readme.welcome-tooltip'},
Gui.element(function(_,parent)
local server_details = global.server_details or { name='ExpGaming S0 - Local', description='Failed to load description: disconnected from sync api.', reset_time='Non Set', branch='Unknown'}
local container = parent.add{ type='flow', direction='vertical' }
local player = Gui.get_player_from_element(parent)
-- Set up the top flow with logos
local top_flow = container.add{ type='flow' }
top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'}
local top_vertical_flow = top_flow.add{ type='flow', direction='vertical' }
top_flow.add{ type='sprite', sprite='file/modules/gui/logo.png'}
top_vertical_flow.style.horizontal_align = 'center'
-- Add the title to the top flow
title(top_vertical_flow,62,'Welcome to '..server_details.name)
-- Add the description to the top flow
description_label(top_vertical_flow,380,server_details.description)
Gui.bar(container)
container.add{ type='flow' }.style.height = 4
-- Get the names of the roles the player has
local player_roles = Roles.get_player_roles(player)
local role_names = {}
for i,role in ipairs(player_roles) do
role_names[i] = role.name
end
-- Add the other information to the gui
description_label(sub_content(container),frame_width,{'readme.welcome-general',server_details.reset_time})
description_label(sub_content(container),frame_width,{'readme.welcome-roles',table.concat(role_names,', ')})
description_label(sub_content(container),frame_width,{'readme.welcome-chat'})
return container
end))
--- Content area for the rules tab
-- @element rules_content
Tab({'readme.rules-tab'},{'readme.rules-tooltip'},
Gui.element(function(_,parent)
local container = parent.add{ type='flow', direction='vertical' }
-- Add the title to the content
title(container,267,{'readme.rules-tab'})
-- Add the tab description
description_label(container,frame_width,{'readme.rules-general'})
Gui.bar(container)
-- Add a table for the rules
container.add{ type='flow' }
local rules = Gui.scroll_table(container,275,1)
rules.style = 'bordered_table'
-- Add the rules to the table
for i = 1,15 do
description_label(rules,560,{'readme.rules-'..i})
end
return container
end))
--- Content area for the commands tab
-- @element commands_content
Tab({'readme.commands-tab'},{'readme.commands-tooltip'},
Gui.element(function(_,parent)
local container = parent.add{ type='flow', direction='vertical' }
local player = Gui.get_player_from_element(parent)
-- Add the title to the content
title(container,250,{'readme.commands-tab'})
-- Add the tab description
description_label(container,frame_width,{'readme.commands-general'})
Gui.bar(container)
-- Add a table for the commands
container.add{ type='flow' }
local commands = Gui.scroll_table(container,275,2)
commands.style = 'bordered_table'
-- Add the rules to the table
for name,command in pairs(Commands.get(player)) do
description_label(commands,100,name)
description_label(commands,444,command.help)
end
return container
end))
--- Content area for the servers tab
-- @element servers_content
Tab({'readme.servers-tab'},{'readme.servers-tooltip'},
Gui.element(function(_,parent)
local container = parent.add{ type='flow', direction='vertical' }
-- Add the title to the content
title(container,260,{'readme.servers-tab'})
-- Add the tab description
description_label(container,frame_width,{'readme.servers-general'})
Gui.bar(container)
-- Draw the scroll
container.add{ type='flow' }
local scroll_pane = title_table_scroll(container)
scroll_pane.style.maximal_height = 295
-- Add the dactorio servers
local factoiro_servers = title_table(scroll_pane, 225, {'readme.servers-factorio'}, 2)
for i = 1,8 do
description_label(factoiro_servers,106,{'readme.servers-'..i})
description_label(factoiro_servers,462,{'readme.servers-d'..i})
end
-- Add the external links
local external_links = title_table(scroll_pane, 235, {'readme.servers-external'}, 2)
for _,key in ipairs{'discord','website','patreon','status','github'} do
description_label(external_links,106,key:gsub("^%l", string.upper))
description_label(external_links,462,{'links.'..key})
end
return container
end))
--- Content area for the servers tab
-- @element backers_content
Tab({'readme.backers-tab'},{'readme.backers-tooltip'},
Gui.element(function(_,parent)
local container = parent.add{ type='flow', direction='vertical' }
-- Add the title to the content
title(container,260,{'readme.backers-tab'})
-- Add the tab description
description_label(container,frame_width,{'readme.backers-general'})
Gui.bar(container)
-- Find which players will go where
local done = {}
local groups = {
Administrator = { _title={'readme.backers-management'}, _width=230 },
Sponsor = { _title={'readme.backers-board'}, _width=145 }, -- change role to board
Donator = { _title={'readme.backers-backers'}, _width=196 }, -- change to backer
Moderator = { _title={'readme.backers-staff'}, _width=235 },
Active = { _title={'readme.backers-active'}, _width=235 },
}
-- Fill by player roles
for player_name, player_roles in pairs(Roles.config.players) do
for role_name, players in pairs(groups) do
if table.contains(player_roles, role_name) then
done[player_name] = true
table.insert(players,player_name)
break
end
end
end
-- Fill by active times
local active_time = 3*3600*60
for _, player in pairs(game.players) do
if not done[player.name] then
if player.online_time > active_time then
table.insert(groups.Active,player.name)
end
end
end
-- Draw the scroll
container.add{ type='flow' }
local scroll_pane = title_table_scroll(container)
-- Add the different tables
for _, players in pairs(groups) do
local table = title_table(scroll_pane, players._width, players._title, 4)
for _,player_name in ipairs(players) do
description_label(table,140,player_name)
end
if #players < 4 then
for i = 1,4-#players do
description_label(table,140)
end
end
end
return container
end))
--- Main readme container for the center flow
-- @element readme
local readme_toggle
local readme =
Gui.element(function(event_trigger,parent)
local container = parent.add{
name = event_trigger,
type = 'frame',
style = 'invisible_frame'
}
-- Add the left hand side of the frame back, removed because of frame_tabbed_pane style
local left_lignment = Gui.alignment(container,nil,nil,'bottom')
left_lignment.style.padding = {32,0,0,0}
local left_side =
left_lignment.add{
type = 'frame',
style = 'frame_without_right_side'
}
left_side.style.vertically_stretchable = true
left_side.style.padding = 0
left_side.style.width = 5
-- Add the tab pane
local tab_pane = container.add{
name = 'pane',
type = 'tabbed-pane',
style = 'frame_tabbed_pane'
}
-- Add the different content areas
for _,tab_details in ipairs(tabs) do
local tab = tab_pane.add{ type = 'tab', style = 'frame_tab', caption = tab_details[1], tooltip = tab_details[2] }
tab_pane.add_tab(tab, tab_details[3](tab_pane))
end
return container
end)
:on_open(function(player)
local toggle_button = Gui.get_top_element(player, readme_toggle)
Gui.toolbar_button_style(toggle_button, true)
end)
:on_close(function(player,element)
local toggle_button = Gui.get_top_element(player, readme_toggle)
Gui.toolbar_button_style(toggle_button, false)
Gui.destroy_if_valid(element)
end)
--- Toggle button for the readme gui
-- @element readme_toggle
readme_toggle =
Gui.toolbar_button('virtual-signal/signal-info',{'readme.main-tooltip'},function(player)
return Roles.player_allowed(player,'gui/readme')
end)
:on_click(function(player,_)
local center = player.gui.center
if center[readme.name] then
player.opened = nil
else
player.opened = readme(center)
end
end)
--- When a player joins the game for the first time show this gui
Event.add(defines.events.on_player_created,function(event)
local player = Game.get_player_by_index(event.player_index)
local element = readme(player.gui.center)
element.pane.selected_tab_index = 1
player.opened = element
end)
--- When a player joins clear center unless the player has something open
Event.add(defines.events.on_player_joined_game,function(event)
local player = Game.get_player_by_index(event.player_index)
if not player.opened then
player.gui.center.clear()
end
end)