Merge branch 'release/5.8.0'

This commit is contained in:
Cooldude2606
2019-06-14 20:40:31 +01:00
51 changed files with 1128 additions and 1024 deletions

View File

@@ -56,6 +56,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
| Scenario Version* | Version Name | Factorio Version** |
|---|---|---|
| [v5.7][s5.8] | Home and Chat Bot | [v0.17.47][f0.17.49] |
| [v5.7][s5.7] | Warp System | [v0.17.47][f0.17.47] |
| [v5.6][s5.6] | Information Guis | [v0.17.44][f0.17.44] |
| [v5.5][s5.5] | Gui System | [v0.17.43][f0.17.43] |
@@ -74,6 +75,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
\*\* Factorio versions show the version they were made for, often the minimum requirement.
[s5.8]: https://github.com/explosivegaming/scenario/releases/tag/5.8.0
[s5.7]: https://github.com/explosivegaming/scenario/releases/tag/5.7.0
[s5.6]: https://github.com/explosivegaming/scenario/releases/tag/5.6.0
[s5.5]: https://github.com/explosivegaming/scenario/releases/tag/5.5.0
@@ -88,6 +90,7 @@ All are welcome to make pull requests and issues for this scenario, if you are i
[s1.0]: https://github.com/explosivegaming/scenario/releases/tag/v1.0
[s0.1]: https://github.com/explosivegaming/scenario/releases/tag/v0.1
[f0.17.49]: https://wiki.factorio.com/Version_history/0.17.0#0.17.49
[f0.17.47]: https://wiki.factorio.com/Version_history/0.17.0#0.17.47
[f0.17.44]: https://wiki.factorio.com/Version_history/0.17.0#0.17.44
[f0.17.43]: https://wiki.factorio.com/Version_history/0.17.0#0.17.43

View File

@@ -24,6 +24,7 @@ return {
'modules.commands.warnings',
'modules.commands.find',
'modules.commands.bonus',
'modules.commands.home',
-- QoL Addons
'modules.addons.chat-popups',
'modules.addons.damage-popups',
@@ -35,6 +36,7 @@ return {
'modules.addons.pollution-grading',
'modules.addons.random-player-colours',
'modules.addons.discord-alerts',
'modules.addons.chat-reply',
-- GUI
'modules.gui.rocket-info',
'modules.gui.science-info',

66
config/chat_reply.lua Normal file
View File

@@ -0,0 +1,66 @@
--- This file defines the different triggers for the chat bot
local format_time = ext_require('expcore.common','format_time')
return {
allow_command_prefix_for_messages = true, -- when true any message trigger will print to all player when prefixed
messages = { -- will trigger when ever the word is said
['discord']={'info.discord'},
['expgaming']={'info.website'},
['website']={'info.website'},
['wiki']={'info.wiki'},
['status']={'info.status'},
['github']={'info.github'},
['command']={'info.custom-commands'},
['commands']={'info.custom-commands'},
['softmod']={'info.softmod'},
['script']={'info.softmod'},
['loop']={'chat-bot.loops'},
['loops']={'chat-bot.loops'},
['rhd']={'chat-bot.lhd'},
['lhd']={'chat-bot.lhd'},
['roundabout']={'chat-bot.loops'},
['roundabouts']={'chat-bot.loops'},
['redmew']={'chat-bot.redmew'},
['afk']=function(player)
local max=player
for _,next_player in pairs(game.connected_players) do
if max.afk_time < next_player.afk_time then
max=next_player
end
end
return {'chat-bot.afk',max.name,format_time(max.afk_time,{minutes=true,seconds=true,long=true})}
end,
['players']=function()
return {'chat-bot.players',#game.players}
end,
['online']=function()
return {'chat-bot.players-online',#game.connected_players}
end,
['time']=function()
return {'chat-bot.map-time',format_time(game.tick,{days=true,hours=true,minutes=true,seconds=true,long=true})}
end,
},
command_admin_only = false, -- when true will only allow chat commands for admins
command_permission = 'command/chat-bot', -- the permision used to allow command prefixs
command_prefix = '!', -- prefix used for commands below and to print to all players (if enabled above)
commands = { -- will trigger only when command prefix is given
['dev']={'chat-bot.not-real-dev'},
['blame']=function(player)
local names = {'Cooldude2606','arty714','badgamernl',player.name}
for _,next_player in pairs(game.connected_players) do
names[#names + 1] = next_player.name
end
return {'chat-bot.blame',table.get_random_dictionary_entry(names)}
end,
['magic']={'chat-bot.magic'},
['aids']={'chat-bot.aids'},
['riot']={'chat-bot.riot'},
['lenny']={'chat-bot.lenny'},
['hodor']=function()
local options = {'?','.','!','!!!'}
return {'chat-bot.hodor',table.get_random_dictionary_entry(options)}
end,
['evolution']=function()
return {'chat-bot.current-evolution',string.format('%.2f',game.forces['enemy'].evolution_factor)}
end,
}
}

View File

@@ -6,17 +6,17 @@ return {
},
messages={ -- the messages that each one will say, must be same name as its location
['Spawn']={
{'info.website-message'},
{'info.website'},
{'info.read-readme'},
{'info.discord-message'},
{'info.discord'},
{'info.softmod'},
{'info.wiki-message'},
{'info.wiki'},
{'info.redmew'},
{'info.feedback-message'},
{'info.feedback'},
{'info.custom-commands'},
{'info.status-message'},
{'info.status'},
{'info.lhd'},
{'info.github-message'},
{'info.github'},
}
}
}

View File

@@ -82,6 +82,10 @@ Roles.new_role('Moderator','Mod')
'command/clear-temp-ban',
'command/clear-inventory',
'command/bonus',
'command/home',
'command/home-set',
'command/home-get',
'command/return',
'gui/rocket-info/toggle-active',
'gui/rocket-info/remote_launch',
}
@@ -128,6 +132,10 @@ Roles.new_role('Pay to Win','P2W')
'gui/rocket-info/toggle-active',
'gui/rocket-info/remote_launch',
'command/bonus',
'command/home',
'command/home-set',
'command/home-get',
'command/return',
}
Roles.new_role('Donator','Don')
@@ -155,6 +163,7 @@ Roles.new_role('Veteran','Vet')
:set_custom_color{r=140,g=120,b=200}
:set_parent('Member')
:allow{
'command/chat-bot',
}
:set_auto_promote_condition(function(player)
if player.online_time > 10*216000 then

View File

@@ -11,7 +11,7 @@ return {
{'warnings.received',{'warnings.pre-pre-ban'}},
{'warnings.received',{'warnings.pre-ban'}},
function(player,by_player_name,number_of_warnings)
game.ban_player(player,{'warnings.received',by_player_name,number_of_warnings,{'warnings.ban',{'info.website-link'}}})
game.ban_player(player,{'warnings.received',by_player_name,number_of_warnings,{'warnings.ban',{'links.website'}}})
end
},
temp_warning_cool_down=30, -- time for a temp warning (given by script) to be removed (in minutes)

View File

@@ -41,7 +41,6 @@ for index,path in pairs(files) do
if not success then
-- Failed to load a file
log('[ERROR] Failed to load file: '..path)
log('[ERROR] '..file)
table.insert(errors,'[ERROR] '..path..' :: '..file)
elseif type(file) == 'string' and file:find('not found') then
-- Returned a file not found message

View File

@@ -3,43 +3,49 @@
local Gui = require 'expcore.gui.core'
--[[
Gui._prototype_factory(tbl) --- Used internally to create new prototypes for element defines
Gui._event_factory(name) --- Used internally to create event handler adders for element defines
Gui._store_factory(callback) --- Used internally to create store adders for element defines
Gui._sync_store_factory(callback) --- Used internally to create synced store adders for element defines
Gui._define_factory(prototype) --- Used internally to create new element defines from a class prototype
Core
Gui._prototype:uid() --- Gets the uid for the element define
Gui._prototype:debug_name(name) --- Sets a debug alias for the define
Gui._prototype:set_caption(caption) --- Sets the caption for the element define
Gui._prototype:set_tooltip(tooltip) --- Sets the tooltip for the element define
Gui._prototype:set_style(style,callback) --- Sets the style for the element define
Gui._prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Gui._prototype:on_element_update(callback) --- Add a hander to run on the general value update event, different classes will handle this event differently
Gui._prototype:set_pre_authenticator(callback) --- Sets an authenticator that blocks the draw function if check fails
Gui._prototype:set_post_authenticator(callback) --- Sets an authenticator that disables the element if check fails
Gui._prototype:draw_to(element) --- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype
Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to
Gui._prototype:add_store(categorize) --- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
Gui._prototype:add_sync_store(location,categorize) --- Adds a store location for the define that will sync between games, categorize is a function that returns a string
Gui._prototype:on_store_update(callback) --- Adds a event callback for when the store changes are other events are not gauenteted to be raised
Gui.player_store(element) --- A categorize function to be used with add_store, each player has their own value
Gui.force_store(element) --- A categorize function to be used with add_store, each force has its own value
Gui.surface_store(element) --- A categorize function to be used with add_store, each surface has its own value
Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value
Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value
Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value
Gui._prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Gui._prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Gui.get_store(name,category) --- Gets the value that is stored for a given element define, category needed if categorize function used
Gui.set_store(name,category,value) --- Sets the value stored for a given element define, category needed if categorize function used
Gui.toggle_enable(element) --- Will toggle the enabled state of an element
Gui.toggle_enabled(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.create_alignment(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
Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size
Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area
Prototype Constructor
Constructor.event(event_name) --- Creates a new function to add functions to an event handler
Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define
Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set
Base Prototype
Prototype:uid() --- Gets the uid for the element define
Prototype:debug_name(value) --- Sets a debug alias for the define
Prototype:set_caption(value) --- Sets the caption for the element define
Prototype:set_tooltip(value) --- Sets the tooltip for the element define
Prototype:set_style(style,callback) --- Sets the style for the element define
Prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails
Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails
Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element
Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used
]]
local Instances = require 'expcore.gui.instances'
@@ -48,8 +54,20 @@ Gui.get_instances = Instances.get_elements
Gui.add_instance = Instances.get_elements
Gui.update_instances = Instances.apply_to_elements
Gui.classes.instances = Instances
--[[
Instances.has_categories(name) --- Returns if a instnace group has a categorise function; must be registerd
Instances.is_registered(name) --- Returns if the given name is a registered instance group
Instances.register(name,categorise) --- Registers the name of an instance group to allow for storing element instances
local Button = require 'expcore.gui.buttons'
Instances.add_element(name,element) --- Adds an element to the instance group under the correct category; must be registered
Instances.get_elements_raw(name,category) --- Gets all element instances without first removing any invalid ones; used internally and must be registered
Instances.get_valid_elements(name,category,callback) --- Gets all valid element instances and has the option of running a callback on those that are valid
Instances.unregistered_add_element(name,category,element) --- A version of add_element that does not require the group to be registered
Instances.unregistered_get_elements(name,category,callback) --- A version of get_elements that does not require the group to be registered
]]
local Button = require 'expcore.gui.elements.buttons'
Gui.new_button = Button.new_button
Gui.classes.button = Button
--[[
@@ -64,7 +82,7 @@ Gui.classes.button = Button
Button._prototype:set_key_filter(filter,...) --- Adds a control key filter to the button
]]
local Checkbox = require 'expcore.gui.checkboxs'
local Checkbox = require 'expcore.gui.elements.checkboxs'
Gui.new_checkbox = Checkbox.new_checkbox
Gui.new_radiobutton = Checkbox.new_radiobutton
Gui.new_radiobutton_option_set = Checkbox.new_option_set
@@ -86,7 +104,7 @@ Gui.classes.checkbox = Checkbox
Checkbox.reset_radiobutton(element,exclude,recursive) --- Sets all radiobutotn in a element to false (unless excluded) and can act recursivly
]]
local Dropdown = require 'expcore.gui.dropdown'
local Dropdown = require 'expcore.gui.elements.dropdown'
Gui.new_dropdown = Dropdown.new_dropdown
Gui.new_list_box = Dropdown.new_list_box
Gui.classes.dropdown = Dropdown
@@ -105,7 +123,7 @@ Gui.classes.dropdown = Dropdown
Dropdown.get_selected_value(element) --- Returns the currently selected value rather than index
]]
local Slider = require 'expcore.gui.slider'
local Slider = require 'expcore.gui.elements.slider'
Gui.new_slider = Slider.new_slider
Gui.classes.slider = Slider
--[[
@@ -114,13 +132,12 @@ Gui.classes.slider = Slider
Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
Slider._prototype:use_notches(state) --- Adds notches to the slider
Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider
]]
local Text = require 'expcore.gui.text'
local Text = require 'expcore.gui.elements.text'
Gui.new_text_filed = Text.new_text_field
Gui.new_text_box = Text.new_text_box
Gui.classes.text = Text
@@ -137,7 +154,7 @@ Gui.classes.text = Text
Text._prototype_box:set_read_only(state) --- Sets the text box to be read only
]]
local ElemButton = require 'expcore.gui.elem-button'
local ElemButton = require 'expcore.gui.elements.elem-button'
Gui.new_elem_button = ElemButton.new_elem_button
Gui.classes.elem_button = ElemButton
--[[
@@ -150,7 +167,7 @@ Gui.classes.elem_button = ElemButton
ElemButton._prototype:set_default(value) --- Sets the default value for the elem button, this may be a function or a string
]]
local ProgressBar = require 'expcore.gui.progress-bar'
local ProgressBar = require 'expcore.gui.elements.progress-bar'
Gui.new_progressbar = ProgressBar.new_progressbar
Gui.set_progressbar_maximum = ProgressBar.set_maximum
Gui.increment_progressbar = ProgressBar.increment
@@ -177,7 +194,7 @@ Gui.classes.progressbar = ProgressBar
ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggeres, can filter which elements are decremented
]]
local Toolbar = require 'expcore.gui.toolbar'
local Toolbar = require 'expcore.gui.concepts.toolbar'
Gui.new_toolbar_button = Toolbar.new_button
Gui.add_button_to_toolbar = Toolbar.add_button
Gui.update_toolbar = Toolbar.update
@@ -188,7 +205,7 @@ Gui.classes.toolbar = Toolbar
Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return
]]
local LeftFrames = require 'expcore.gui.left'
local LeftFrames = require 'expcore.gui.concepts.left'
Gui.get_left_frame_flow = LeftFrames.get_flow
Gui.toggle_left_frame = LeftFrames.toggle_frame
Gui.new_left_frame = LeftFrames.new_frame
@@ -217,7 +234,7 @@ Gui.classes.left_frames = LeftFrames
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local CenterFrames = require 'expcore.gui.center'
local CenterFrames = require 'expcore.gui.concepts.center'
Gui.get_center_flow = CenterFrames.get_flow
Gui.toggle_center_frame = CenterFrames.toggle_frame
Gui.draw_center_frame = CenterFrames.draw_frame
@@ -240,7 +257,7 @@ Gui.classes.center_frames = CenterFrames
CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local PopupFrames = require 'expcore.gui.popups'
local PopupFrames = require 'expcore.gui.concepts.popups'
Gui.get_popup_flow = PopupFrames.get_flow
Gui.open_popup = PopupFrames.open
Gui.new_popup = PopupFrames.new_popup

View File

@@ -16,12 +16,13 @@
CenterFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local Gui = require 'expcore.gui.core'
local Toolbar = require 'expcore.gui.toolbar'
local Prototype = require 'expcore.gui.prototype'
local Toolbar = require 'expcore.gui.concepts.toolbar'
local Game = require 'utils.game'
local CenterFrames = {
_prototype = Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw')
_prototype = Prototype.extend{
on_creation = Prototype.event
}
}
@@ -141,9 +142,7 @@ function CenterFrames._prototype:draw_frame(player)
player.opened = frame
end
if self.events.on_draw then
self.events.on_draw(player,frame)
end
self:raise_event('on_creation',player,frame)
return frame
end

View File

@@ -49,18 +49,19 @@
LeftFrames._prototype:event_handler(action) --- Creates an event handler that will trigger one of its functions, use with Event.add
]]
local Gui = require 'expcore.gui.core'
local Toolbar = require 'expcore.gui.toolbar'
local Buttons = require 'expcore.gui.buttons'
local Prototype = require 'expcore.gui.prototype'
local Toolbar = require 'expcore.gui.concepts.toolbar'
local Buttons = require 'expcore.gui.elements.buttons'
local mod_gui = require 'mod-gui'
local Game = require 'utils.game'
local Event = require 'utils.event'
local LeftFrames = {
frames={},
_prototype=Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw'),
on_update = Gui._event_factory('on_update'),
on_player_toggle = Gui._event_factory('on_player_toggle')
_prototype=Prototype.extend{
on_creation = Prototype.event,
on_update = Prototype.event,
on_player_toggle = Prototype.event
}
}
setmetatable(LeftFrames._prototype, {
@@ -132,7 +133,6 @@ end
-- @tparam string permision_name the name that can be used with the permision system
-- @treturn table the new left frame define
function LeftFrames.new_frame(permision_name)
local self = Toolbar.new_button(permision_name)
local mt = getmetatable(self)
@@ -141,11 +141,8 @@ function LeftFrames.new_frame(permision_name)
self:on_click(function(player,_element)
local visible = self:toggle(player)
if self.events.on_player_toggle then
local frame = self:get_frame(player)
self.events.on_player_toggle(player,frame,visible)
end
local frame = self:get_frame(player)
self:raise_event('on_player_toggle',player,frame,visible)
end)
LeftFrames.frames[self.name] = self
@@ -176,6 +173,34 @@ function LeftFrames._prototype:set_direction(direction)
return self
end
--- Creates the gui for the first time, used internally
-- @tparam LuaPlayer player the player to draw the frame to
-- @treturn LuaGuiElement the frame that was made
function LeftFrames._prototype:_internal_draw(player)
local flow = LeftFrames.get_flow(player)
local frame = flow.add{
type='frame',
name=self.name..'-frame',
direction=self.direction
}
self:raise_event('on_creation',player,frame)
if not self.open_by_default then
frame.visible = false
elseif type(self.open_by_default) == 'function' then
if not self.open_by_default(player,self.name) then
frame.visible = false
end
end
if not Toolbar.allowed(player,self.name) then
frame.visible = false
end
return frame
end
--- Gets the frame for this define from the left frame flow
-- @tparam LuaPlayer player the player to get the frame of
-- @treturn LuaGuiElement the frame in the left frame flow for this define
@@ -183,6 +208,8 @@ function LeftFrames._prototype:get_frame(player)
local flow = LeftFrames.get_flow(player)
if flow[self.name..'-frame'] and flow[self.name..'-frame'].valid then
return flow[self.name..'-frame']
else
return self:_internal_draw(player)
end
end
@@ -208,11 +235,9 @@ end
-- @tparam LuaPlayer player the player to update the frame of
function LeftFrames._prototype:update(player)
local frame = self:get_frame(player)
if self.events.on_update then
self.events.on_update(player,frame)
elseif self.events.on_draw then
if self:raise_event('on_update',player,frame) == 0 then
frame.clear()
self.events.on_draw(player,frame)
self:raise_event('on_creation',player,frame)
end
end
@@ -230,9 +255,7 @@ end
function LeftFrames._prototype:redraw(player)
local frame = self:get_frame(player)
frame.clear()
if self.events.on_draw then
self.events.on_draw(player,frame)
end
self:raise_event('on_creation',player,frame)
end
--- Redraws the frame for all players, see redraw
@@ -265,10 +288,7 @@ Buttons.new_button()
for _,define in pairs(LeftFrames.frames) do
local frame = LeftFrames.get_frame(define.name,player)
frame.visible = false
if define.events.on_player_toggle then
define.events.on_player_toggle(player,frame,false)
end
define:raise_event('on_player_toggle',player,frame,false)
end
element.visible = false
end)
@@ -285,28 +305,7 @@ Event.add(defines.events.on_player_created,function(event)
style.font = 'default-small-bold'
for _,define in pairs(LeftFrames.frames) do
local frame = flow.add{
type='frame',
name=define.name..'-frame',
direction=define.direction
}
if define.events.on_draw then
define.events.on_draw(player,frame)
end
if not define.open_by_default then
frame.visible = false
elseif type(define.open_by_default) == 'function' then
if not define.open_by_default(player,define.name) then
frame.visible = false
end
end
if not Toolbar.allowed(player,define.name) then
frame.visible = false
end
define:_internal_draw(player)
end
LeftFrames.get_open(player)

View File

@@ -12,10 +12,11 @@
PopupFrames._prototype:open(player,open_time,...) --- Opens this define for a player, can be given open time and any other params for the draw function
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
local Event = require 'utils.event'
local ProgressBar = require 'expcore.gui.progress-bar'
local Button = require 'expcore.gui.buttons'
local ProgressBar = require 'expcore.gui.elements.progress-bar'
local Button = require 'expcore.gui.elements.buttons'
local mod_gui = require 'mod-gui'
local Color = require 'resources.color_presets'
local Global = require 'utils.global'
@@ -25,8 +26,8 @@ local PopupFrames = {
popup_flow_name = Gui.uid_name(),
main_frame_name = Gui.uid_name(),
close_frame_name = Gui.uid_name(),
_prototype = Gui._prototype_factory{
on_draw = Gui._event_factory('on_draw')
_prototype = Prototype.extend{
on_creation = Prototype.event
}
}
Global.register(PopupFrames.paused_popups,function(tbl)
@@ -120,20 +121,16 @@ end)
-- @tparam[opt] string name the optional debug name that can be added
-- @treturn table the new popup frame define
function PopupFrames.new_popup(name)
local self = Gui._define_factory(PopupFrames._prototype)
local self = Gui.new_define(PopupFrames._prototype,name)
self.draw_data.type = 'flow'
self.draw_data.direction = 'vertical'
if name then
self:debug_name(name)
end
local mt = getmetatable(self)
mt.__call = function(tbl,player,open_time,...)
return tbl:open(player,open_time,...)
end
self.post_draw = function(element,maximum,...)
self:on_draw(function(player,element,maximum,...)
-- main content frame
local frame = element.add{
type='flow',
@@ -172,11 +169,8 @@ function PopupFrames.new_popup(name)
close_button_style.height = 20
-- event trigger to draw the gui content
if self.events.on_draw then
local player = Game.get_player_by_index(element.player_index)
self.events.on_draw(player,frame,...)
end
end
self:raise_event('on_creation',player,frame,...)
end)
return self
end

View File

@@ -14,8 +14,8 @@
Toolbar.add_button(button) --- Adds an existing buttton to the toolbar
Toolbar.update(player) --- Updates the player's toolbar with an new buttons or expected change in auth return
]]
local Buttons = require 'expcore.gui.buttons'
local Gui = require 'expcore.gui.core'
local Buttons = require 'expcore.gui.elements.buttons'
local Roles = require 'expcore.roles'
local Event = require 'utils.event'
local Game = require 'utils.game'
@@ -92,13 +92,13 @@ Event.add(defines.events.on_player_created,function(event)
end)
--- When a player gets a new role they will have the toolbar updated
Event.add(Roles.player_role_assigned,function(event)
Event.add(Roles.events.on_role_assigned,function(event)
local player = Game.get_player_by_index(event.player_index)
Toolbar.update(player)
end)
--- When a player loses a role they will have the toolbar updated
Event.add(Roles.player_role_unassigned,function(event)
Event.add(Roles.events.on_role_unassigned,function(event)
local player = Game.get_player_by_index(event.player_index)
Toolbar.update(player)
end)

View File

@@ -16,12 +16,7 @@
Note that all event handlers will include event.player as a valid player and that if the player or the
element is not valid then the callback will not be run.
>>>> Interal factory functions
There are a few factory function that are used by the class definations the use of these function are important to
know about but should only be used when making a new class deination rather than an element defination. See one of
the existing class definations for an example of when to use these.
>>>> Basic prototype functions
>>>> Basic prototype functions (see expcore.gui.prototype)
Using a class defination you can create a new element dinfation in our examples we will be using the checkbox.
local checkbox_example = Gui.new_checkbox()
@@ -74,14 +69,14 @@
return global.checkbox_example_allow_post_auth
end)
>>>> Using store
>>>> Using store (see expcore.gui.prototype and expcore.gui.instances)
A powerful assept of this gui system is allowing an automatic store for the state of a gui element, this means that when a gui is closed and re-opened
the elements which have a store will retain they value even if the element was previously destroied. The store is not limited to only per player and can
be catergorised by any method you want such as one that is shared between all players or by all players on a force. Using a method that is not limited to
one player means that when one player changes the state of the element it will be automaticlly updated for all other player (even if the element is already drawn)
and so this is a powerful and easy way to sync gui elements.
-- note the example below is the same as checkbox_example:add_store(Gui.player_store)
-- note the example below is the same as checkbox_example:add_store(Gui.categorize_by_player)
checkbox_example:add_store(function(element)
local player = Game.get_player_by_index(element.player_index)
return player.force.name
@@ -89,7 +84,7 @@
Of course this tool is not limited to only player interactions; the current satate of a define can be gotten using a number of methods and the value can
even be updated by the script and have all instances of the element define be updated. When you use a category then we must give a category to the get
and set functions; in our case we used Gui.player_store which uses the player's name as the category which is why 'Cooldude2606' is given as a argument,
and set functions; in our case we used Gui.categorize_by_player which uses the player's name as the category which is why 'Cooldude2606' is given as a argument,
if we did not set a function for add_store then all instances for all players have the same value and so a category is not required.
checkbox_example:get_store('Cooldude2606')
@@ -112,333 +107,57 @@
Gui.new_checkbox()
:set_caption('Example Checkbox')
:set_tooltip('Example checkbox')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Example checkbox is now: '..tostring(value))
end)
>>>> Functions
Gui._prototype_factory(tbl) --- Used internally to create new prototypes for element defines
Gui._event_factory(name) --- Used internally to create event handler adders for element defines
Gui._store_factory(callback) --- Used internally to create store adders for element defines
Gui._sync_store_factory(callback) --- Used internally to create synced store adders for element defines
Gui._define_factory(prototype) --- Used internally to create new element defines from a class prototype
Gui._prototype:uid() --- Gets the uid for the element define
Gui._prototype:debug_name(name) --- Sets a debug alias for the define
Gui._prototype:set_caption(caption) --- Sets the caption for the element define
Gui._prototype:set_tooltip(tooltip) --- Sets the tooltip for the element define
Gui._prototype:set_style(style,callback) --- Sets the style for the element define
Gui._prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Gui._prototype:on_element_update(callback) --- Add a hander to run on the general value update event, different classes will handle this event differently
Gui._prototype:set_pre_authenticator(callback) --- Sets an authenticator that blocks the draw function if check fails
Gui._prototype:set_post_authenticator(callback) --- Sets an authenticator that disables the element if check fails
Gui._prototype:draw_to(element) --- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
Gui.new_define(prototype) --- Used internally to create new element defines from a class prototype
Gui.draw(name,element) --- Draws a copy of the element define to the parent element, see draw_to
Gui._prototype:add_store(categorize) --- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
Gui._prototype:add_sync_store(location,categorize) --- Adds a store location for the define that will sync between games, categorize is a function that returns a string
Gui._prototype:on_store_update(callback) --- Adds a event callback for when the store changes are other events are not gauenteted to be raised
Gui.player_store(element) --- A categorize function to be used with add_store, each player has their own value
Gui.force_store(element) --- A categorize function to be used with add_store, each force has its own value
Gui.surface_store(element) --- A categorize function to be used with add_store, each surface has its own value
Gui.categorize_by_player(element) --- A categorize function to be used with add_store, each player has their own value
Gui.categorize_by_force(element) --- A categorize function to be used with add_store, each force has its own value
Gui.categorize_by_surface(element) --- A categorize function to be used with add_store, each surface has its own value
Gui._prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Gui._prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Gui.get_store(name,category) --- Gets the value that is stored for a given element define, category needed if categorize function used
Gui.set_store(name,category,value) --- Sets the value stored for a given element define, category needed if categorize function used
Gui.toggle_enable(element) --- Will toggle the enabled state of an element
Gui.toggle_enabled(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.create_alignment(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
Gui.create_scroll_table(element,table_size,maximal_height,name) --- Creates a scroll area with a table inside, table can be any size
Gui.create_header(element,caption,tooltip,right_align,name) --- Creates a header section with a label and button area
]]
local Gui = require 'utils.gui'
local Game = require 'utils.game'
local Store = require 'expcore.store'
local Instances = require 'expcore.gui.instances'
Gui._prototype = {} -- Stores the base prototype of all element defines
Gui.classes = {} -- Stores the class definations used to create element defines
Gui.defines = {} -- Stores the indivdual element definations
Gui.names = {} -- Stores debug names to link to gui uids
--- Used internally to create new prototypes for element defines
-- @tparam table tbl table a that will have functions added to it
-- @treturn table the new table with the keys added to it
function Gui._prototype_factory(tbl)
for k,v in pairs(Gui._prototype) do
if not tbl[k] then tbl[k] = v end
end
return tbl
end
--- Used internally to create event handler adders for element defines
-- @tparam string name the key that the event will be stored under, should be the same as the event name
-- @treturn function the function that can be used to add an event handler
function Gui._event_factory(name)
--- Gui._prototype:on_event(callback)
--- Add a hander to run on this event, replace event with the event, different classes have different events
-- @tparam function callback the function that will be called on the event
-- callback param - player LuaPlayer - the player who owns the gui element
-- callback param - element LuaGuiElement - the element that caused the event
-- callback param - value any - (not always present) the updated value for the element
-- callback param - ... any - other class defines may add more params
-- @treturn self the element define to allow chaining
return function(self,callback)
if type(callback) ~= 'function' then
return error('Event callback must be a function',2)
end
self.events[name] = callback
return self
end
end
--- Used internally to create store adders for element defines
-- @tparam callback a callback is called when there is an update to the stored value and stould set the state of the element
-- @treturn function the function that can be used to add a store the the define
function Gui._store_factory(callback)
--- Gui._prototype:add_store(categorize)
--- Adds a store location for the define that will save the state of the element, categorize is a function that returns a string
-- @tparam[opt] function categorize if present will be called to convert an element into a category string
-- categorize param - element LuaGuiElement - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,categorize)
if self.store then return end
self.store = Store.uid_location()
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,function(value,category)
if self.events.on_store_update then
self.events.on_store_update(value,category)
end
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self.name,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Used internally to create synced store adders for element defines
-- @tparam callback a callback is called when there is an update to the stored value and stould set the state of the element
-- @treturn function the function that can be used to add a sync store the the define
function Gui._sync_store_factory(callback)
--- Gui._prototype:add_sync_store(location,categorize)
--- Adds a store location for the define that will sync between games, categorize is a function that returns a string
-- @tparam string location string a unique location, unlike add_store a uid location should not be used to avoid migration problems
-- @tparam[opt] function categorize if present will be called to convert an element into a category string
-- categorize param - element LuaGuiElement - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,location,categorize)
if self.store then return end
if Store.is_registered(location) then
return error('Location for store is already registered: '..location,2)
end
self.store = location
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,true,function(value,category)
if self.events.on_store_update then
self.events.on_store_update(value,category)
end
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Used internally to create new element defines from a class prototype
--- Used to create new element defines from a class prototype, please use the own given by the class
-- @tparam table prototype the class prototype that will be used for the element define
-- @treturn table the new element define with all functions accessed via __index metamethod
function Gui._define_factory(prototype)
local uid = Gui.uid_name()
function Gui.new_define(prototype,debug_name)
local name = Gui.uid_name()
local define = setmetatable({
name=uid,
events={},
draw_data={
name=uid
debug_name = debug_name,
name = name,
events = {},
draw_data = {
name = name
}
},{
__index=prototype,
__call=function(self,element,...)
return self:draw_to(element,...)
__index = prototype,
__call = function(self,...)
return self:draw_to(...)
end
})
Gui.defines[define.name] = define
return define
end
--- Gets the uid for the element define
-- @treturn string the uid of this element define
function Gui._prototype:uid()
return self.name
end
--- Sets a debug alias for the define
-- @tparam string name the debug name for the element define that can be used to get this element define
-- @treturn self the element define to allow chaining
function Gui._prototype:debug_name(name)
self.debug_name = name
return self
end
--- Sets the caption for the element define
-- @tparam string caption the caption that will be drawn with the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_caption(caption)
self.draw_data.caption = caption
return self
end
--- Sets the tooltip for the element define
-- @tparam string tooltip the tooltip that will be displayed for this element when drawn
-- @treturn self the element define to allow chaining
function Gui._prototype:set_tooltip(tooltip)
self.draw_data.tooltip = tooltip
return self
end
--- Sets the style for the element define
-- @tparam string style the style that will be used for this element when drawn
-- @tparam[opt] callback function function is called when element is drawn to alter its style
-- @treturn self the element define to allow chaining
function Gui._prototype:set_style(style,callback)
self.draw_data.style = style
self.events.on_style = callback
return self
end
--- Sets the element to be drawn inside a nameless flow, can be given a name using a function
-- @tparam state ?boolean|function when true a padless flow is created to contain the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_embeded_flow(state)
if state == false or type(state) == 'function' then
self.embeded_flow = state
else
self.embeded_flow = true
end
return self
end
--- Sets an authenticator that blocks the draw function if check fails
-- @tparam function callback the function that will be ran to test if the element should be drawn or not
-- callback param - player LuaPlayer - the player that the element is being drawn to
-- callback param - define_name string - the name of the define that is being drawn
-- callback return - boolean - false will stop the element from being drawn
-- @treturn self the element define to allow chaining
function Gui._prototype:set_pre_authenticator(callback)
if type(callback) ~= 'function' then
return error('Pre authenticator callback must be a function')
end
self.pre_authenticator = callback
return self
end
--- Sets an authenticator that disables the element if check fails
-- @tparam function callback the function that will be ran to test if the element should be enabled or not
-- callback param - player LuaPlayer - the player that the element is being drawn to
-- callback param - define_name string - the name of the define that is being drawn
-- callback return - boolean - false will disable the element
-- @treturn self the element define to allow chaining
function Gui._prototype:set_post_authenticator(callback)
if type(callback) ~= 'function' then
return error('Authenicater callback must be a function')
end
self.post_authenticator = callback
return self
end
--- Draws the element using what is in the draw_data table, allows use of authenticator if present, registers new instances if store present
-- the data with in the draw_data is set up through the use of all the other functions
-- @tparam LuaGuiElement element the element that the define will draw a copy of its self onto
-- @treturn LuaGuiElement the new element that was drawn so styles can be applied
function Gui._prototype:draw_to(element,...)
if element[self.name] then return end
local player = Game.get_player_by_index(element.player_index)
if self.pre_authenticator then
if not self.pre_authenticator(player,self.name) then return end
end
if self.embeded_flow then
local embeded_name
if type(self.embeded_flow) == 'function' then
embeded_name = self.embeded_flow(element,...)
end
element = element.add{type='flow',name=embeded_name}
Gui.set_padding(element)
end
local new_element = element.add(self.draw_data)
if self.events.on_style then
self.events.on_style(new_element.style)
end
if self.post_authenticator then
new_element.enabled = self.post_authenticator(player,self.name)
end
if Instances.is_registered(self.name) then
Instances.add_element(self.name,new_element)
end
if self.post_draw then self.post_draw(new_element,...) end
return new_element
end
--- Gets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @treturn any the value that is stored for this define
function Gui._prototype:get_store(category)
if not self.store then return end
return Store.get(self.store,category)
end
--- Sets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc
-- @treturn boolean true if the value was set
function Gui._prototype:set_store(category,value)
if not self.store then return end
return Store.set(self.store,category,value)
end
--- Sets the value in this elements store to nil, category needed if categorize function used
-- @tparam[opt] string category the category to get such as player name or force name
-- @treturn boolean true if the value was set
function Gui._prototype:clear_store(category)
if not self.store then return end
return Store.clear(self.store,category)
end
--- Gets an element define give the uid, debug name or a copy of the element define
-- @tparam name ?string|table the uid, debug name or define for the element define to get
-- @tparam[opt] boolean internal when true the error trace is one level higher (used internally)
@@ -463,29 +182,10 @@ function Gui.get_define(name,internal)
return define
end
--- Gets the value that is stored for a given element define, category needed if categorize function used
-- @tparam name ?string|table the uid, debug name or define for the element define to get
-- @tparam[opt] string category the category to get the value for
-- @treturn any the value that is stored for this define
function Gui.get_store(name,category)
local define = Gui.get_define(name,true)
return define:get_store(category)
end
--- Sets the value stored for a given element define, category needed if categorize function used
-- @tparam name ?string|table the uid, debug name or define for the element define to set
-- @tparam[opt] string category the category to set the value for
-- @tparam boolean any value the value to set for the define, must be valid for its type ie for a checkbox
-- @treturn boolean true if the value was set
function Gui.set_store(name,category,value)
local define = Gui.get_define(name,true)
return define:get_store(category,value)
end
--- A categorize function to be used with add_store, each player has their own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's name who owns this element
function Gui.player_store(element)
function Gui.categorize_by_player(element)
local player = Game.get_player_by_index(element.player_index)
return player.name
end
@@ -493,7 +193,7 @@ end
--- A categorize function to be used with add_store, each force has its own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's force name who owns this element
function Gui.force_store(element)
function Gui.categorize_by_force(element)
local player = Game.get_player_by_index(element.player_index)
return player.force.name
end
@@ -501,7 +201,7 @@ end
--- A categorize function to be used with add_store, each surface has its own value
-- @tparam LuaGuiElement element the element that will be converted to a string
-- @treturn string the player's surface name who owns this element
function Gui.surface_store(element)
function Gui.categorize_by_surface(element)
local player = Game.get_player_by_index(element.player_index)
return player.surface.name
end
@@ -518,7 +218,7 @@ end
--- Will toggle the enabled state of an element
-- @tparam LuaGuiElement element the gui element to toggle
-- @treturn boolean the new state that the element has
function Gui.toggle_enable(element)
function Gui.toggle_enabled(element)
if not element or not element.valid then return end
if not element.enabled then
element.enabled = true
@@ -568,20 +268,21 @@ 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 LuaGuiElement element the element to add this flow to,
-- @tparam[opt] string flow_name 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
--- Allows the creation of an alignment flow to place elements into
-- @tparam LuaGuiElement element the element to add this alignment into
-- @tparam[opt] string name the name to use for the alignment
-- @tparam[opt='right'] string horizontal_align the horizontal alignment of the elements in this flow
-- @tparam[opt='center'] string vertical_align the vertical alignment of the elements in this flow
-- @treturn LuaGuiElement the new flow that was created
function Gui.create_alignment(element,name,horizontal_align,vertical_align)
local flow = element.add{name=name,type='flow'}
local style = flow.style
Gui.set_padding(flow,1,1,2,2)
style.horizontal_align = horizontal_align or 'right'
style.vertical_align = vertical_align or 'center'
style.horizontally_stretchable =style.horizontal_align ~= 'center'
style.vertically_stretchable = style.vertical_align ~= 'center'
return flow
end
--- Destroies an element but tests for it being present and valid first
@@ -594,4 +295,65 @@ function Gui.destory_if_valid(element)
end
end
--- Creates a scroll area with a table inside, table can be any size
-- @tparam LuaGuiElement element the element to add this scroll into
-- @tparam number table_size the number of columns in the table
-- @tparam number maximal_height the max hieght of the scroll
-- @tparam[opt='scroll'] string name the name of the scoll element
-- @treturn LuaGuiElement the table that was made
function Gui.create_scroll_table(element,table_size,maximal_height,name)
local list_scroll =
element.add{
name=name or 'scroll',
type='scroll-pane',
direction='vertical',
horizontal_scroll_policy='never',
vertical_scroll_policy='auto-and-reserve-space'
}
Gui.set_padding(list_scroll,1,1,2,2)
list_scroll.style.horizontally_stretchable = true
list_scroll.style.maximal_height = maximal_height
local list_table =
list_scroll.add{
name='table',
type='table',
column_count=table_size
}
Gui.set_padding(list_table)
list_table.style.horizontally_stretchable = true
list_table.style.vertical_align = 'center'
list_table.style.cell_padding = 0
return list_table
end
--- Creates a header section with a label and button area
-- @tparam LuaGuiElement element the element to add this header into
-- @tparam localeString caption the caption that is used as the title
-- @tparam[opt] localeString tooltip the tooltip that is shown on the caption
-- @tparam[opt] boolean right_align when true will include the right align area
-- @tparam[opt='header'] string name the name of the header area
-- @treturn LuaGuiElement the header that was made, or the align area if that was created
function Gui.create_header(element,caption,tooltip,right_align,name)
local header =
element.add{
name=name or 'header',
type='frame',
style='subheader_frame'
}
Gui.set_padding(header,2,2,4,4)
header.style.horizontally_stretchable = true
header.style.use_header_filler = false
header.add{
type='label',
style='heading_1_label',
caption=caption,
tooltip=tooltip
}
return right_align and Gui.create_alignment(header,'header-align') or header
end
return Gui

View File

@@ -15,12 +15,14 @@
]]
local mod_gui = require 'mod-gui'
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Button = {
_prototype=Gui._prototype_factory{
on_click = Gui._event_factory('on_click'),
on_left_click = Gui._event_factory('on_left_click'),
on_right_click = Gui._event_factory('on_right_click'),
_prototype=Prototype.extend{
on_raw_click = Prototype.event,
on_click = Prototype.event,
on_left_click = Prototype.event,
on_right_click = Prototype.event,
}
}
@@ -29,27 +31,26 @@ local Button = {
-- @treturn table the new button element define
function Button.new_button(name)
local self = Gui._define_factory(Button._prototype)
local self = Gui.new_define(Button._prototype,name)
self.draw_data.type = 'button'
self.draw_data.style = mod_gui.button_style
if name then
self:debug_name(name)
end
Gui.on_click(self.name,function(event)
local mouse_button = event.button
local keys = {alt=event.alt,control=event.control,shift=event.shift}
local player,element = event.player,event.element
event.keys = keys
self:raise_event('on_raw_click',event)
if self.post_authenticator then
if not self.post_authenticator(event.player,self.name) then return end
end
if mouse_button == defines.mouse_button_type.left and self.events.on_left_click then
self.events.on_left_click(event.player,event.element)
if mouse_button == defines.mouse_button_type.left then
self:raise_event('on_left_click',player,element)
elseif mouse_button == defines.mouse_button_type.right and self.events.on_right_click then
self.events.on_right_click(event.player,event.element)
self:raise_event('on_right_click',player,element)
end
if self.mouse_button_filter and not self.mouse_button_filter[mouse_button] then return end
@@ -59,9 +60,7 @@ function Button.new_button(name)
end
end
if self.events.on_click then
self.events.on_click(event.player,event.element,event)
end
self:raise_event('on_click',player,element)
end)
return self

View File

@@ -10,7 +10,7 @@
local example_option_set =
Gui.new_option_set('example-option-set',function(value,category)
game.print('Example options set '..category..' is now: '..tostring(value))
end,Gui.player_store)
end,Gui.categorize_by_player)
Then you must register some radiobutton defines and include them in the option set:
@@ -46,43 +46,34 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Store = require 'expcore.store'
local Game = require 'utils.game'
--- Event call for on_checked_state_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam boolean value the new state of the checkbox
local function event_call(define,element,value)
if define.events.on_element_update then
local player = Game.get_player_by_index(element.player_index)
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam boolean value the new state of the checkbox
local function store_call(define,element,value)
local function store_update(define,element,value)
element.state = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local Checkbox = {
option_sets={},
option_categorize={},
_prototype_checkbox=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_checkbox=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
},
_prototype_radiobutton=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_radiobutton=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -91,21 +82,17 @@ local Checkbox = {
-- @treturn table the new checkbox element define
function Checkbox.new_checkbox(name)
local self = Gui._define_factory(Checkbox._prototype_checkbox)
local self = Gui.new_define(Checkbox._prototype_checkbox,name)
self.draw_data.type = 'checkbox'
self.draw_data.state = false
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local state = self:get_store(category,true)
if state then element.state = true end
end
end
end)
Gui.on_checked_state_changed(self.name,function(event)
local element = event.element
@@ -121,8 +108,7 @@ function Checkbox.new_checkbox(name)
self:set_store(category,value)
else
local value = element.state
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,element.state)
end
end)

View File

@@ -17,40 +17,30 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_selection_state_changed and store update
local select_value
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new option for the dropdown
local function event_call(define,element,value)
local function store_update(define,element,value)
select_value(element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
define:raise_event('on_element_update',player,element,value)
if define.option_callbacks and define.option_callbacks[value] then
define.option_callbacks[value](player,element,value)
end
end
local _select_value
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new option for the dropdown
local function store_call(define,element,value)
_select_value(element,value)
event_call(define,element,value)
end
local Dropdown = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -59,16 +49,11 @@ local Dropdown = {
-- @treturn table the new dropdown element define
function Dropdown.new_dropdown(name)
local self = Gui._define_factory(Dropdown._prototype)
local self = Gui.new_define(Dropdown._prototype,name)
self.draw_data.type = 'drop-down'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.dynamic_options then
local player = Game.get_player_by_index(element.player_index)
local dynamic_options = self.dynamic_options(player,element)
local items = element.items
for _,v in pairs(dynamic_options) do
@@ -82,7 +67,7 @@ function Dropdown.new_dropdown(name)
local value = self:get_store(category)
if value then Dropdown.select_value(element,value) end
end
end
end)
Gui.on_selection_state_changed(self.name,function(event)
local element = event.element
@@ -93,7 +78,12 @@ function Dropdown.new_dropdown(name)
self:set_store(category,value)
else
event_call(self,element,value)
local player = event.player
local option_callbacks = self.option_callbacks
self:raise_event('on_element_update',player,element,value)
if option_callbacks and option_callbacks[value] then
option_callbacks[value](player,element,value)
end
end
@@ -176,7 +166,7 @@ function Dropdown.select_value(element,value)
end
end
end
_select_value = Dropdown.select_value
select_value = Dropdown.select_value
--- Returns the currently selected value rather than index
-- @tparam LuaGuiElement element the gui element that you want to get the value of

View File

@@ -12,36 +12,25 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_elem_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new value for the elem button
local function event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new value for the elem button
local function store_call(define,element,value)
local function store_update(define,element,value)
element.elem_value = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local ElemButton = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -50,16 +39,10 @@ local ElemButton = {
-- @treturn table the new elem button element define
function ElemButton.new_elem_button(name)
local self = Gui._define_factory(ElemButton._prototype)
local self = Gui.new_define(ElemButton._prototype,name)
self.draw_data.type = 'choose-elem-button'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
local player = Game.get_player_by_index(element.player_index)
self:on_draw(function(player,element)
if type(self.default) == 'function' then
element.elem_value = self.default(player,element)
end
@@ -69,7 +52,7 @@ function ElemButton.new_elem_button(name)
local value = self:get_store(category)
if value then element.elem_value = value end
end
end
end)
Gui.on_elem_changed(self.name,function(event)
local element = event.element
@@ -80,7 +63,7 @@ function ElemButton.new_elem_button(name)
self:set_store(category,value)
else
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,value)
end
@@ -92,10 +75,7 @@ end
--- Sets the type of the elem button, the type is required so this must be called at least once
-- @tparam string type the type that this elem button is see factorio api
-- @treturn the element define to allow for chaining
function ElemButton._prototype:set_type(type)
self.draw_data.elem_type = type
return self
end
ElemButton._prototype.set_type = Prototype.setter('string','draw_data','elem_type')
--- Sets the default value for the elem button, this may be a function or a string
-- @tparam ?string|function value string a will be a static default and a function will be called when drawn to get the default

View File

@@ -21,6 +21,7 @@
ProgressBar._prototype:event_countdown(filter) --- Event handler factory that counts down by 1 every time the event triggeres, can filter which elements are decremented
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Global = require 'utils.global'
local Game = require 'utils.game'
@@ -29,20 +30,17 @@ local Game = require 'utils.game'
-- @tparam LuaGuiElement element the element that triggered the event
local function event_call(define,element)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_complete then
define.events.on_complete(player,element,function()
define:add_element(element)
define:reset_element(element)
end)
end
define:raise_event('on_complete',player,element,function()
define:add_element(element)
define:reset_element(element)
end)
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam number value the new value for the progress bar
local function store_call(define,element,value)
local function store_update(define,element,value)
if value then
element.value = value
if define.count_down and value <= 0
@@ -55,14 +53,14 @@ end
local ProgressBar = {
unregistered={}, -- elements with no callbacks
independent={}, -- elements with a link to a deinfe
_prototype=Gui._prototype_factory{
-- note both events will recive a reset function that can be used to reset the progress of the element/store
on_complete = Gui._event_factory('on_complete'),
on_store_complete = Gui._event_factory('on_store_complete'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_complete = Prototype.event,
on_store_complete = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
Global.register({
unregistered = ProgressBar.unregistered,
independent = ProgressBar.independent
@@ -182,14 +180,11 @@ end
-- @tparam[opt] string name the optional debug name that can be added
-- @treturn table the new progressbar elemente define
function ProgressBar.new_progressbar(name)
local self = Gui._define_factory(ProgressBar._prototype)
local self = Gui.new_define(ProgressBar._prototype,name)
self.draw_data.type = 'progressbar'
if name then
self:debug_name(name)
end
self.post_draw = function(element,maximum)
self:on_draw(function(player,element,maximum)
if self.store then
local category = self.categorize and self.categorize(element) or nil
local value = self:get_store(category)
@@ -215,7 +210,7 @@ function ProgressBar.new_progressbar(name)
end
end
end)
return self
end
@@ -263,11 +258,7 @@ local function change_value_prototype(self,amount,category,filter)
if self.count_down and new_value <= 0
or not self.count_down and new_value >= 1 then
self:clear_store(category)
if self.events.on_store_complete then
self.events.on_store_complete(category,reset_store)
end
self:raise_event('on_store_complete',category,reset_store)
return
end

View File

@@ -6,7 +6,6 @@
Slider._prototype:on_element_update(callback) --- Registers a handler for when an element instance updates
Slider._prototype:on_store_update(callback) --- Registers a handler for when the stored value updates
Slider._prototype:use_notches(state) --- Adds notches to the slider
Slider._prototype:set_range(min,max) --- Sets the range of a slider, if not used will use default values for a slider
Slider._prototype:draw_label(element) --- Draws a new label and links its value to the value of this slider, if no store then it will only show one value per player
Slider._prototype:enable_auto_draw_label(state) --- Enables auto draw of the label, the label will share the same parent element as the slider
@@ -14,6 +13,7 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Instances = require 'expcore.gui.instances'
local Game = require 'utils.game'
@@ -28,9 +28,7 @@ local function event_call(define,element,value)
local delta = max-min
local percent = delta == 0 and 0 or (value-min)/delta
if define.events.on_element_update then
define.events.on_element_update(player,element,value,percent)
end
define:raise_event('on_element_update',player,element,value,percent)
local category = player.name
if define.categorize then
@@ -46,17 +44,17 @@ end
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam number value the new value for the slider
local function store_call(define,element,value)
local function store_update(define,element,value)
element.slider_value = value
event_call(define,element,value)
end
local Slider = {
_prototype=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -65,15 +63,10 @@ local Slider = {
-- @treturn table the new slider element define
function Slider.new_slider(name)
local self = Gui._define_factory(Slider._prototype)
local self = Gui.new_define(Slider._prototype,name)
self.draw_data.type = 'slider'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
local player = Game.get_player_by_index(element.player_index)
self:on_draw(function(player,element)
local min,max = element.get_slider_minimum(),element.get_slider_maximum()
if type(self.min) == 'function' then
@@ -95,7 +88,7 @@ function Slider.new_slider(name)
if self.auto_label then
self:draw_label(element.parent)
end
end
end)
Gui.on_value_changed(self.name,function(event)
local element = event.element
@@ -115,17 +108,6 @@ function Slider.new_slider(name)
return self
end
--- Adds notches to the slider
-- @tparam[opt] boolean state when true will draw notches onto the slider
function Slider._prototype:use_notches(state)
if state == false then
self.draw_data.style = nil
else
self.draw_data.style = 'notched_slider'
end
return self
end
--- Sets the range of a slider, if not used will use default values for a slider
-- @tparam[opt] number min the minimum value that the slider can take
-- @tparam[opt] number max the maximum value that the slider can take
@@ -164,7 +146,7 @@ function Slider._prototype:draw_label(element)
caption=tostring(math.round(value,2))
}
local categorise = self.categorise or Gui.player_store
local categorise = self.categorise or Gui.categorize_by_player
local category = categorise(new_element)
Instances.unregistered_add_element(name,category,new_element)

View File

@@ -15,42 +15,31 @@
Other functions present from expcore.gui.core
]]
local Gui = require 'expcore.gui.core'
local Prototype = require 'expcore.gui.prototype'
local Game = require 'utils.game'
--- Event call for on_text_changed and store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new text for the text field
local function event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
if define.events.on_element_update then
define.events.on_element_update(player,element,value)
end
end
--- Store call for store update
-- @tparam table define the define that this is acting on
-- @tparam LuaGuiElement element the element that triggered the event
-- @tparam string value the new text for the text field
local function store_call(define,element,value)
local function store_update(define,element,value)
element.text = value
event_call(define,element,value)
local player = Game.get_player_by_index(element.player_index)
define:raise_event('on_element_update',player,element,value)
end
local Text = {
_prototype_field=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_field=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
},
_prototype_box=Gui._prototype_factory{
on_element_update = Gui._event_factory('on_element_update'),
on_store_update = Gui._event_factory('on_store_update'),
add_store = Gui._store_factory(store_call),
add_sync_store = Gui._sync_store_factory(store_call)
_prototype_box=Prototype.extend{
on_element_update = Prototype.event,
on_store_update = Prototype.event,
add_store = Prototype.store(false,store_update),
add_sync_store = Prototype.store(true,store_update)
}
}
@@ -59,14 +48,10 @@ local Text = {
-- @treturn table the new text field element define
function Text.new_text_field(name)
local self = Gui._define_factory(Text._prototype_field)
local self = Gui.new_define(Text._prototype_field,name)
self.draw_data.type = 'textfield'
if name then
self:debug_name(name)
end
self.post_draw = function(element)
self:on_draw(function(player,element)
if self.selectable then
element.selectable = true
end
@@ -84,7 +69,7 @@ function Text.new_text_field(name)
local value = self:get_store(category)
if value then element.text = value end
end
end
end)
Gui.on_text_changed(self.name,function(event)
local element = event.element
@@ -95,7 +80,7 @@ function Text.new_text_field(name)
self:set_store(category,value)
else
event_call(self,element,value)
self:raise_event('on_element_update',event.player,element,value)
end

View File

@@ -12,7 +12,7 @@
-- categorise works in the same way as store categorise
-- so the function will worl here but no value is stored only gui elements
Instances.register('score',Gui.force_store)
Instances.register('score',Gui.categorize_by_force)
Then when you draw the new element to a gui you will want to add the element to the group:
@@ -38,7 +38,7 @@
instance group would work when registered vs unregistered:
-- Registered with category
Instances.register('score',Gui.force_store) -- force_store will return the force name of an element
Instances.register('score',Gui.categorize_by_force) -- force_store will return the force name of an element
Instances.add_element('score',new_element) -- the new element is added to the category based on in force
Instances.apply_to_elements('score','player',function(element)
element.caption = '0'

303
expcore/gui/prototype.lua Normal file
View File

@@ -0,0 +1,303 @@
--- Used to create new gui prototypes see elements and concepts
--[[
>>>> Functions
Constructor.event(event_name) --- Creates a new function to add functions to an event handler
Constructor.extend(new_prototype) --- Extents a prototype with the base functions of all gui prototypes, no metatables
Constructor.store(sync,callback) --- Creates a new function which adds a store to a gui define
Constructor.setter(value_type,key,second_key) --- Creates a setter function that checks the type when a value is set
Prototype:uid() --- Gets the uid for the element define
Prototype:debug_name(value) --- Sets a debug alias for the define
Prototype:set_caption(value) --- Sets the caption for the element define
Prototype:set_tooltip(value) --- Sets the tooltip for the element define
Prototype:set_style(style,callback) --- Sets the style for the element define
Prototype:set_embeded_flow(state) --- Sets the element to be drawn inside a nameless flow, can be given a name using a function
Prototype:set_pre_authenticator --- Sets an authenticator that blocks the draw function if check fails
Prototype:set_post_authenticator --- Sets an authenticator that disables the element if check fails
Prototype:raise_event(event_name,...) --- Raises a custom event for this define, any number of params can be given
Prototype:draw_to(element,...) --- The main function for defines, when called will draw an instance of this define to the given element
Prototype:get_store(category) --- Gets the value in this elements store, category needed if categorize function used
Prototype:set_store(category,value) --- Sets the value in this elements store, category needed if categorize function used
Prototype:clear_store(category) --- Sets the value in this elements store to nil, category needed if categorize function used
]]
local Game = require 'utils.game'
local Store = require 'expcore.store'
local Instances = require 'expcore.gui.instances'
local Constructor = {}
local Prototype = {}
--- Creates a new function to add functions to an event handler
-- @tparam string event_name the name of the event that callbacks will be added to
-- @treturn function the function used to register handlers
function Constructor.event(event_name)
--- Adds a callback as a handler for an event
-- @tparam table self the gui define being acted on
-- @tparam function callback the function that will be added as a handler for the event
-- @treturn table self returned to allowing chaining of functions
return function(self,callback)
if type(callback) ~= 'function' then
return error('Event callback for '..event_name..' must be a function',2)
end
local handlers = self.events[event_name]
if not handlers then
handlers = {}
self.events[event_name] = handlers
end
handlers[#handlers+1] = callback
return self
end
end
--- Extents a prototype with the base functions of all gui prototypes, no metatables
-- @tparam table new_prototype the prototype that you want to add the functions to
-- @treturn table the same prototype but with the new functions added
function Constructor.extend(new_prototype)
for key,value in pairs(Prototype) do
if type(value) == 'table' then
new_prototype[key] = table.deepcopy(value)
else
new_prototype[key] = value
end
end
for key,value in pairs(new_prototype) do
if value == Constructor.event then
new_prototype[key] = Constructor.event(key)
end
end
return new_prototype
end
--- Creates a new function which adds a store to a gui define
-- @tparam boolean sync if the function should create a synced store
-- @tparam function callback the function called when needing to update the value of an element
-- @treturn function the function that will add a store for this define
function Constructor.store(sync,callback)
--- Adds a store for the define that is shared between all instances of the define in the same category, categorize is a function that returns a string
-- @tparam self table the gui define being acted on
-- @tparam[opt] string location a unique location identifier, when omited a uid location will be used, use when sync is set to true
-- @tparam[opt] function categorize function used to determine the category of a LuaGuiElement, when omited all share one single category
-- categorize param - LuaGuiElement element - the element that needs to be converted
-- categorize return - string - a determistic string that referses to a category such as player name or force name
-- @treturn self the element define to allow chaining
return function(self,location,categorize)
if self.store then return end
if not sync then
categorize = location
location = Store.uid_location()
end
if Store.is_registered(location) then
return error('Location for store is already registered: '..location,2)
end
self.store = location
self.categorize = categorize
Instances.register(self.name,self.categorize)
Store.register(self.store,sync,function(value,category)
self:raise_event('on_store_update',value,category)
if Instances.is_registered(self.name) then
Instances.apply_to_elements(self.name,category,function(element)
callback(self,element,value)
end)
end
end)
return self
end
end
--- Creates a setter function that checks the type when a value is set
-- @tparam string value_type the type that the value should be when it is set
-- @tparam string key the key of the define that will be set
-- @tparam[opt] string second_key allows for setting of a key in a sub table
-- @treturn function the function that will check the type and set the value
function Constructor.setter(value_type,key,second_key)
local display_message = 'Gui define '..key..' must be of type '..value_type
if second_key then
display_message = 'Gui define '..second_key..' must be of type '..value_type
end
local locale = false
if value_type == 'locale-string' then
locale = true
value_type = 'table'
end
return function(self,value)
local vtype = type(value)
if vtype ~= value_type and (not locale or vtype ~= 'string') then
error(display_message,2)
end
if second_key then
self[key][second_key] = value
else
self[key] = value
end
return self
end
end
--- Gets the uid for the element define
-- @treturn string the uid of this element define
function Prototype:uid()
return self.name
end
--- Sets a debug alias for the define
-- @tparam string name the debug name for the element define that can be used to get this element define
-- @treturn self the element define to allow chaining
Prototype.debug_name = Constructor.setter('string','debug_name')
--- Sets the caption for the element define
-- @tparam string caption the caption that will be drawn with the element
-- @treturn self the element define to allow chaining
Prototype.set_caption = Constructor.setter('locale-string','draw_data','caption')
--- Sets the tooltip for the element define
-- @tparam string tooltip the tooltip that will be displayed for this element when drawn
-- @treturn self the element define to allow chaining
Prototype.set_tooltip = Constructor.setter('locale-string','draw_data','tooltip')
--- Sets an authenticator that blocks the draw function if check fails
-- @tparam function callback the function that will be ran to test if the element should be drawn or not
-- callback param - LuaPlayer player - the player that the element is being drawn to
-- callback param - string define_name - the name of the define that is being drawn
-- callback return - boolean - false will stop the element from being drawn
-- @treturn self the element define to allow chaining
Prototype.set_pre_authenticator = Constructor.setter('function','pre_authenticator')
--- Sets an authenticator that disables the element if check fails
-- @tparam function callback the function that will be ran to test if the element should be enabled or not
-- callback param - LuaPlayer player - the player that the element is being drawn to
-- callback param - string define_name - the name of the define that is being drawn
-- callback return - boolean - false will disable the element
-- @treturn self the element define to allow chaining
Prototype.set_post_authenticator = Constructor.setter('function','post_authenticator')
--- Registers a callback to the on_draw event
-- @tparam function callback
-- callback param - LuaPlayer player - the player that the element was drawn to
-- callback param - LuaGuiElement element - the element that was drawn
-- callback param - any ... - any other params passed by the draw_to function
Prototype.on_draw = Constructor.event('on_draw')
--- Registers a callback to the on_style_update event
-- @tparam function callback
-- callback param - LuaStyle style - the style that was changed and/or needs changing
Prototype.on_style_update = Constructor.event('on_style_update')
--- Sets the style for the element define
-- @tparam string style the style that will be used for this element when drawn
-- @tparam[opt] callback function function is called when element is drawn to alter its style
-- @treturn self the element define to allow chaining
function Prototype:set_style(style,callback)
self.draw_data.style = style
if callback then
self:on_style_update(callback)
end
return self
end
--- Sets the element to be drawn inside a nameless flow, can be given a name using a function
-- @tparam state ?boolean|function when true a padless flow is created to contain the element
-- @treturn self the element define to allow chaining
function Prototype:set_embeded_flow(state)
if state == false or type(state) == 'function' then
self.embeded_flow = state
else
self.embeded_flow = true
end
return self
end
--- Raises a custom event for this define, any number of params can be given
-- @tparam string event_name the name of the event that you want to raise
-- @tparam any ... any params that you want to pass to the event
-- @treturn number the number of handlers that were registered
function Prototype:raise_event(event_name,...)
local handlers = self.events[event_name]
if handlers then
for _,handler in pairs(handlers) do
handler(...)
end
end
return handlers and #handlers or 0
end
--- The main function for defines, when called will draw an instance of this define to the given element
-- what is drawn is based on the data in draw_data which is set using other functions
-- @tparam LuaGuiElement element the element that the define will draw a instance of its self onto
-- @treturn LuaGuiElement the new element that was drawn
function Prototype:draw_to(element,...)
local name = self.name
if element[name] then return end
local player = Game.get_player_by_index(element.player_index)
if self.pre_authenticator then
if not self.pre_authenticator(player,self.name) then return end
end
if self.embeded_flow then
local embeded_name
if type(self.embeded_flow) == 'function' then
embeded_name = self.embeded_flow(element,...)
end
element = element.add{type='flow',name=embeded_name}
element.style.padding = 0
end
local new_element = element.add(self.draw_data)
self:raise_event('on_style_update',new_element.style)
if self.post_authenticator then
new_element.enabled = self.post_authenticator(player,self.name)
end
if Instances.is_registered(self.name) then
Instances.add_element(self.name,new_element)
end
self:raise_event('on_draw',player,new_element)
return new_element
end
--- Gets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @treturn any the value that is stored for this define
function Prototype:get_store(category)
if not self.store then return end
return Store.get(self.store,category)
end
--- Sets the value in this elements store, category needed if categorize function used
-- @tparam string category[opt] the category to get such as player name or force name
-- @tparam any value the value to set for this define, must be valid for its type ie for checkbox etc
-- @treturn boolean true if the value was set
function Prototype:set_store(category,value)
if not self.store then return end
return Store.set(self.store,category,value)
end
--- Sets the value in this elements store to nil, category needed if categorize function used
-- @tparam[opt] string category the category to get such as player name or force name
-- @treturn boolean true if the value was set
function Prototype:clear_store(category)
if not self.store then return end
return Store.clear(self.store,category)
end
return Constructor

View File

@@ -55,7 +55,7 @@ Gui.new_center_frame('gui-test-open')
return global.show_test_gui
end)
:on_draw(function(player,frame)
:on_creation(function(player,frame)
for test_group_name,test_group in pairs(tests) do
player.print('Starting tests for: '..format_chat_colour(test_group_name,Colors.cyan))
@@ -106,7 +106,7 @@ Gui.new_left_frame('test-left-frame')
end)
:set_open_by_default()
:on_draw(function(_player,frame)
:on_creation(function(_player,frame)
for _,player in pairs(game.connected_players) do
frame.add{
type='label',
@@ -125,7 +125,7 @@ Event.add(defines.events.on_player_left_game,left_frame 'update_all')
local test_popup =
Gui.new_popup('test-popup')
:on_draw(function(player,frame)
:on_creation(function(player,frame)
frame.add{
type='label',
caption=player.name
@@ -225,7 +225,7 @@ local checkbox_force =
Gui.new_checkbox('test-checkbox-store-force')
:set_tooltip('Checkboc store force')
:set_caption('Checkbox Store Force')
:add_store(Gui.force_store)
:add_store(Gui.categorize_by_force)
:on_element_update(function(player,element,state)
player.print('Checkbox store force: '..tostring(state))
end)
@@ -234,7 +234,7 @@ local checkbox_player =
Gui.new_checkbox('test-checkbox-store-player')
:set_tooltip('Checkbox store player')
:set_caption('Checkbox Store Player')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,state)
player.print('Checkbox store player: '..tostring(state))
end)
@@ -265,7 +265,7 @@ local radiobutton_player =
Gui.new_radiobutton('test-radiobutton-store')
:set_tooltip('Radiobutton store')
:set_caption('Radiobutton Store')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,state)
player.print('Radiobutton store: '..tostring(state))
end)
@@ -273,7 +273,7 @@ end)
local radiobutton_option_set =
Gui.new_radiobutton_option_set('gui.test.share',function(value,category)
game.print('Radiobutton option set for: '..category..' is now: '..tostring(value))
end,Gui.player_store)
end,Gui.categorize_by_player)
local radiobutton_option_one =
Gui.new_radiobutton('test-radiobutton-option-one')
@@ -332,7 +332,7 @@ local dropdown_player_static_general =
Gui.new_dropdown('test-dropdown-store-static-general')
:set_tooltip('Dropdown store static general')
:add_options('One','Two','Three','Four')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store static general: '..tostring(value))
end)
@@ -360,7 +360,7 @@ end
local dropdown_player_static_case =
Gui.new_dropdown('test-dropdown-store-static-case')
:set_tooltip('Dropdown store static case')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:add_options('One','Two')
:add_option_callback('One',print_option_selected_2)
:add_option_callback('Two',print_option_selected_2)
@@ -388,7 +388,7 @@ Gui.new_dropdown('test-dropdown-store-dynamic')
:add_dynamic(function(player,element)
return table_keys(Colors)
end)
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store dynamic: '..tostring(value))
end)
@@ -420,7 +420,7 @@ local list_box_player =
Gui.new_list_box('test-list-box-store')
:set_tooltip('List box store')
:add_options('One','Two','Three','Four')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Dropdown store: '..tostring(value))
end)
@@ -433,7 +433,6 @@ tests["List Boxs"] = {
--[[
Slider Tests
> Local default -- Simple slider with default range
> Local notched -- Simple slider with notches
> Store default -- Slider with default range that stores value between re-draws
> Static range -- Simple slider with a static range
> Dynamic range -- Slider with a dynamic range
@@ -448,18 +447,11 @@ Gui.new_slider('test-slider-local-default')
player.print('Slider local default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
local slider_notched_default =
Gui.new_slider('test-slider-notched-default')
:set_tooltip('Silder notched default')
:use_notches()
:on_element_update(function(player,element,value,percent)
player.print('Slider notched default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
local slider_player_default =
Gui.new_slider('test-slider-store-default')
:set_tooltip('Silder store default')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value,percent)
player.print('Slider store default: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
@@ -496,14 +488,13 @@ local label_slider_player =
Gui.new_slider('test-slider-store-label')
:set_tooltip('Silder store label')
:enable_auto_draw_label()
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value,percent)
player.print('Slider store label: '..tostring(math.round(value))..' '..tostring(math.round(percent,1)))
end)
tests.Sliders = {
['Local default']=slider_local_default,
['Local notched']=slider_notched_default,
['Player default']=slider_player_default,
['Static range']=slider_static,
['Dynamic range']=slider_dynamic,
@@ -535,7 +526,7 @@ end)
local text_filed_store =
Gui.new_text_filed('test-text-field-store')
:set_tooltip('Text field store')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Text field store: '..value)
end)
@@ -603,7 +594,7 @@ local elem_store =
Gui.new_elem_button('test-elem-store')
:set_tooltip('Elem store')
:set_type('item')
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:on_element_update(function(player,element,value)
player.print('Elem store: '..value)
end)
@@ -632,7 +623,7 @@ end)
local progressbar_two =
Gui.new_progressbar('test-prog-one')
:set_default_maximum(300)
:add_store(Gui.force_store)
:add_store(Gui.categorize_by_force)
:on_complete(function(player,element,reset_element)
reset_element()
end)

View File

@@ -163,6 +163,7 @@ local Colours = require 'resources.color_presets'
local write_json = ext_require('expcore.common','write_json')
local Roles = {
_prototype={},
config={
order={}, -- Contains the order of the roles, lower index is better
roles={}, -- Contains the raw info for the roles, indexed by role name
@@ -170,9 +171,10 @@ local Roles = {
internal={}, -- Contains all internally accessed roles, such as root, default
players={}
},
player_role_assigned=script.generate_event_name(),
player_role_unassigned=script.generate_event_name(),
_prototype={}
events = {
on_role_assigned=script.generate_event_name(),
on_role_unassigned=script.generate_event_name(),
}
}
--- When global is loaded it will have the metatable re-assigned to the roles
@@ -195,9 +197,9 @@ local function emit_player_roles_updated(player,type,roles,by_player_name,skip_g
local by_player = Game.get_player_from_any(by_player_name)
local by_player_index = by_player and by_player.index or 0
-- get the event id from the type of emit
local event = Roles.player_role_assigned
local event = Roles.events.on_role_assigned
if type == 'unassign' then
event = Roles.player_role_unassigned
event = Roles.events.on_role_unassigned
end
-- convert the roles to objects and get the names of the roles
local role_names = {}
@@ -775,8 +777,8 @@ local function role_update(event)
end
--- When a player joined or has a role change then the update is triggered
Event.add(Roles.player_role_assigned,role_update)
Event.add(Roles.player_role_unassigned,role_update)
Event.add(Roles.events.on_role_assigned,role_update)
Event.add(Roles.events.on_role_unassigned,role_update)
Event.add(defines.events.on_player_joined_game,role_update)
-- Every 60 seconds the auto promote check is preformed
Event.on_nth_tick(3600,function()

View File

@@ -79,8 +79,11 @@ local Store = {
registered={},
synced={},
callbacks={},
on_value_update=script.generate_event_name()
events = {
on_value_update=script.generate_event_name()
}
}
Global.register(Store.data,function(tbl)
Store.data = tbl
end)
@@ -184,7 +187,7 @@ function Store.set(location,child,value,from_sync)
data[location] = value
end
script.raise_event(Store.on_value_update,{
script.raise_event(Store.events.on_value_update,{
tick=game.tick,
location=location,
child=child,
@@ -215,7 +218,7 @@ function Store.clear(location,child,from_sync)
data[location] = nil
end
script.raise_event(Store.on_value_update,{
script.raise_event(Store.events.on_value_update,{
tick=game.tick,
location=location,
child=child,
@@ -235,7 +238,7 @@ function Store.get_children(location)
end
-- Handels syncing
Event.add(Store.on_value_update,function(event)
Event.add(Store.events.on_value_update,function(event)
if Store.callbacks[event.location] then
Store.callbacks[event.location](event.value,event.child)
end

View File

@@ -6,21 +6,23 @@ ping=You have been mentioned in chat by __1__.
player-health=__1__
player-damage=__1__
[links]
discord=https://discord.explosivegaming.nl
website=https://www.explosivegaming.nl
wiki=https://wiki.explosivegaming.nl/
feedback=https://exp.fider.io/
status=https://status.explosivegaming.nl
github=https://github.com/explosivegaming/scenario
[info]
players-online=There are __1__ players online
total-map-time=This map has been on for __1__
discord-link=https://discord.explosivegaming.nl
discord-message=Join use on our discord at: https://discord.explosivegaming.nl
website-link=https://www.explosivegaming.nl
website-message=Please vist our website at: https://www.explosivegaming.nl
wiki-link=https://wiki.explosivegaming.nl/
wiki-message=You can get more information about us and the custom scenario from our wiki: https://wiki.explosivegaming.nl/
feedback-link=https://exp.fider.io/
feedback-message=Do you have feedback? leave it at https://exp.fider.io/
status-link=https://status.explosivegaming.nl
status-message=Want to check if out servers are down, vist: https://status.explosivegaming.nl
github-link=https://github.com/explosivegaming/scenario
github-message=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/scenario
discord=Join use on our discord at: https://discord.explosivegaming.nl
website=Please vist our website at: https://www.explosivegaming.nl
wiki=You can get more information about us and the custom scenario from our wiki: https://wiki.explosivegaming.nl/
feedback=Do you have feedback? leave it at https://exp.fider.io/
status=Want to check if out servers are down, vist: https://status.explosivegaming.nl
github=Want to help improve our server with some extra features? Help us at: https://github.com/explosivegaming/scenario
custom-commands=We use custom commands, such as /tag and /me, use /chelp for more info.
read-readme=Make sure you have read the Readme (It can be found through the question mark on the top left)
softmod=We run a softmod on our servers. A softmod is a custom scenario that runs on this server, example is the player list.
@@ -36,4 +38,22 @@ pre-ban=This your LAST warning before you are BANNED! successful ban appeals are
ban=You were banned for having too many warnings; Vist __1__ to request a ban appeal.
script-warning=You are reciving script warnings; if you recive too many you will recive a permiment warning (__1__/__2__)
script-wrning-removed=A script warning has expired (__1__/__2__)
script-warning-limit=__1__ has recived a permiment warning from the script.
script-warning-limit=__1__ has recived a permiment warning from the script.
[chat-bot]
reply=[Chat Bot] __1__
disallow=You cant use global chat commands
players-online=There are __1__ players online
players=There have been __1__ players on this map
map-time=This map has been on for __1__
not-real-dev=Cooldude2606 is a dev for this server and makes the softmod (look top left) and is not a factorio dev.
softmod=A softmod is a custom scenario that runs on this server, example is the player list.
blame=Blame __1__ for what just happend!
afk=Your afk? Look at __1__, that player has been afk for: __2__
current-evolution=Current evolution factor is __1__
magic=Fear the admin magic (ノ゚∀゚)ノ⌒・*:.。. .。.:*・゜゚・*☆
aids=≖ ‿ ≖ Fear the aids of a public server ≖ ‿ ≖
riot=(admins) ┬┴┬┴┤ᵒ_ᵒ)├┬┴┬┴ \(´ω` )/\ (  ´)/\ ( ´ω`)/ (rest of server)
loops=NO LOOPS; LOOPS ARE BAD; JUST NO LOOPS!!!!!; IF YOU MAKE A LOOP.... IT WILL NOT END WELL!!!!!!!
lenny=( ͡° ͜ʖ ͡°)
hodor=Hodor

View File

@@ -53,4 +53,15 @@ cleared=__1__ had all they warnings cleared by __2__.
unavailable=They was a problem getting you to spawn, please try again later.
[expcom-repair]
result=__1__ entites were revived and __2__ were healed to max health.
result=__1__ entites were revived and __2__ were healed to max health.
[expcom-bonus]
set=Your bonus has been set to __1__.
wip=This command is tempary and will be replaced at some point in the future.
[expcom-home]
no-home=You have no home set.
no-return=You cant return when home has not yet been used.
home-set=Your home point has been set to x: __1__ y: __2__
return-set=Your return point has been set to x: __1__ y: __2__
home-get=Your home point is at x: __1__ y: __2__

View File

@@ -0,0 +1,51 @@
local Event = require 'utils.event'
local Game = require 'utils.game'
local Roles = require 'expcore.roles'
local config = require 'config.chat_reply'
Event.add(defines.events.on_console_chat,function(event)
local player_index = event.player_index
if not player_index or player_index < 1 then return end
local player = Game.get_player_by_index(player_index)
local message = event.message:lower():gsub("%s+", "")
local allowed = true
if config.command_admin_only and not player.admin then allowed = false end
if config.command_permission and not Roles.player_allowed(player,config.command_permission) then allowed = false end
local prefix = config.command_prefix
for key_word,reply in pairs(config.messages) do
if message:find(key_word) then
if type(reply) == 'function' then
reply = reply(player)
end
if message:find(prefix..key_word) then
if allowed then
game.print{'chat-bot.reply',reply}
else
player.print{'chat-bot.disallow'}
end
else
player.print{'chat-bot.reply',reply}
end
end
end
if not allowed then return end
for key_word,reply in pairs(config.commands) do
if message:find(prefix..key_word) then
if type(reply) == 'function' then
reply = reply(player)
if reply then
game.print{'chat-bot.reply',reply}
end
else
game.print{'chat-bot.reply',reply}
end
end
end
end)

View File

@@ -13,7 +13,7 @@ local function to_hex(color)
local hex_digits = '0123456789ABCDEF'
local function hex(bit)
local major, minor = math.modf(bit/16)
minor = minor*16
major,minor = major+1,minor*16+1
return hex_digits:sub(major,major)..hex_digits:sub(minor,minor)
end
@@ -77,7 +77,7 @@ end
--- Reports added and removed
if config.player_reports then
local Reports = require 'modules.addons.reports-control'
Event.add(Reports.player_report_added,function(event)
Event.add(Reports.events.on_player_reported,function(event)
local player_name,by_player_name = get_player_name(event)
emit_event{
title='Report',
@@ -88,7 +88,7 @@ if config.player_reports then
['Reason:']=event.reason
}
end)
Event.add(Reports.player_report_removed,function(event)
Event.add(Reports.events.on_player_report_removed,function(event)
local player_name,by_player_name = get_player_name(event)
emit_event{
title='Report Removed',
@@ -103,7 +103,7 @@ end
--- Warnings added and removed
if config.player_warnings then
local Warnings = require 'modules.addons.warnings-control'
Event.add(Warnings.player_warning_added,function(event)
Event.add(Warnings.events.on_player_warned,function(event)
local player_name,by_player_name = get_player_name(event)
emit_event{
title='Warning',
@@ -113,7 +113,7 @@ if config.player_warnings then
['By:']='<inline>'..by_player_name
}
end)
Event.add(Warnings.player_warning_removed,function(event)
Event.add(Warnings.events.on_player_warning_removed,function(event)
local player_name,by_player_name = get_player_name(event)
emit_event{
title='Warning Removed',

View File

@@ -3,21 +3,23 @@ local Game = require 'utils.game'
local Global = require 'utils.global'
local move_items = ext_require('expcore.common','move_items')
local Public = {
local Jail = {
old_roles = {},
temp_bans = {},
player_jailed=script.generate_event_name(),
player_unjailed=script.generate_event_name(),
player_temp_banned=script.generate_event_name(),
player_clear_temp_ban=script.generate_event_name()
events = {
on_player_jailed=script.generate_event_name(),
on_player_unjailed=script.generate_event_name(),
on_player_temp_banned=script.generate_event_name(),
on_player_temp_ban_cleared=script.generate_event_name()
}
}
Global.register({
old_roles = Public.old_roles,
temp_bans = Public.temp_bans
old_roles = Jail.old_roles,
temp_bans = Jail.temp_bans
},function(tbl)
Public.old_roles = tbl.old_roles
Public.temp_bans = tbl.temp_bans
Jail.old_roles = tbl.old_roles
Jail.temp_bans = tbl.temp_bans
end)
local function event_emit(event,player,by_player_name,reason)
@@ -34,15 +36,15 @@ end
-- @tparam LuaPlayer player the player that will be jailed, must not be in jail
-- @tparam[opt='<server>'] string by_player_name the name of the player doing the action used in logs
-- @treturn the number of roles that were removed, nil if there was an error
function Public.jail_player(player,by_player_name)
function Jail.jail_player(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
if Roles.player_has_role(player,'Jail') then return end
local old_roles = Roles.get_player_roles(player)
Public.old_roles[player.name] = old_roles
Jail.old_roles[player.name] = old_roles
Roles.unassign_player(player,old_roles,by_player_name,true)
Roles.assign_player(player,'Jail',by_player_name,true)
event_emit(Public.player_jailed,player,by_player_name)
event_emit(Jail.events.on_player_jailed,player,by_player_name)
return #old_roles
end
@@ -50,14 +52,14 @@ end
-- @tparam LuaPlayer player the player that will be unjailed, must be in jail
-- @tparam[opt='<server>'] string string by_player_name the name of the player who is doing the action
-- @treturn the number of roles that were added, nil if there was an error
function Public.unjail_player(player,by_player_name)
function Jail.unjail_player(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
if not Roles.player_has_role(player,'Jail') then return end
local old_roles = Public.old_roles[player.name]
local old_roles = Jail.old_roles[player.name]
Roles.unassign_player(player,'Jail',by_player_name,true)
Roles.assign_player(player,old_roles,by_player_name,true)
event_emit(Public.player_unjailed,player,by_player_name)
event_emit(Jail.events.on_player_unjailed,player,by_player_name)
return #old_roles
end
@@ -66,17 +68,17 @@ end
-- @tparam[opt='<server>'] string by_player_name the name of the player that is doing the action
-- @tparam[opt='None string Given.'] reason the reason that will be stored for this temp ban
-- @treturn boolean true if successful else will return nil
function Public.temp_ban_player(player,by_player_name,reason)
function Jail.temp_ban_player(player,by_player_name,reason)
player = Game.get_player_from_any(player)
reason = reason or 'None Given.'
if not player then return end
if Public.temp_bans[player.name] then return end
Public.jail_player(player,by_player_name)
Public.temp_bans[player.name] = {reason,by_player_name}
if Jail.temp_bans[player.name] then return end
Jail.jail_player(player,by_player_name)
Jail.temp_bans[player.name] = {reason,by_player_name}
local inv = player.get_main_inventory()
move_items(inv.get_contents())
inv.clear()
event_emit(Public.player_temp_banned,player,by_player_name,reason)
event_emit(Jail.events.on_player_temp_banned,player,by_player_name,reason)
return true
end
@@ -84,14 +86,14 @@ end
-- @tparam LuaPlayer player the player that will be cleared from temp baned, must be temp banned
-- @tparam[opt='<server>'] string by_player_name the name of the player that is doing the action
-- @treturn boolean true if successful else will return nil
function Public.clear_temp_ban_player(player,by_player_name)
function Jail.clear_temp_ban_player(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
if not Public.temp_bans[player.name] then return end
Public.unjail_player(player,by_player_name)
Public.temp_bans[player.name] = nil
event_emit(Public.player_clear_temp_ban,player,by_player_name)
if not Jail.temp_bans[player.name] then return end
Jail.unjail_player(player,by_player_name)
Jail.temp_bans[player.name] = nil
event_emit(Jail.events.on_player_temp_ban_cleared,player,by_player_name)
return true
end
return Public
return Jail

View File

@@ -1,18 +1,20 @@
local Game = require 'utils.game'
local Global = require 'utils.global'
local Public = {
local Reports = {
user_reports={},
player_report_added = script.generate_event_name(),
player_report_removed = script.generate_event_name()
events = {
on_player_reported = script.generate_event_name(),
on_player_report_removed = script.generate_event_name()
}
}
Global.register(Public.user_reports,function(tbl)
Public.user_reports = tbl
Global.register(Reports.user_reports,function(tbl)
Reports.user_reports = tbl
end)
local function event_emit(event,player,by_player_name)
local reports = Public.user_reports[player.name]
local reports = Reports.user_reports[player.name]
local reason = reports and reports[by_player_name]
script.raise_event(event,{
name=event,
@@ -28,20 +30,20 @@ end
-- @tparam[opt='Non string Given.'] reason the reason that the player is being reported
-- @tparam[opt='<server>'] string by_player_name the name of the player doing the action
-- @treturn boolean true if the report was added, nil if there is an error
function Public.report_player(player,reason,by_player_name)
function Reports.report_player(player,reason,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
reason = reason or 'Non Given.'
by_player_name = by_player_name or '<server>'
local reports = Public.user_reports[player.name]
local reports = Reports.user_reports[player.name]
if not reports then
Public.user_reports[player.name] = {
Reports.user_reports[player.name] = {
[by_player_name] = reason
}
elseif not reports[by_player_name] then
reports[by_player_name] = reason
else return false end
event_emit(Public.player_report_added,player,by_player_name)
event_emit(Reports.events.on_player_reported,player,by_player_name)
return true
end
@@ -49,16 +51,16 @@ end
-- @tparam LuaPlayer player the player that will have the report removed
-- @tparam[opt='<server>'] string by_player_name the name of the player doing the action
-- @treturn boolean true if the report was removed, nil if there was an error
function Public.remove_player_report(player,by_player_name)
function Reports.remove_player_report(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
by_player_name = by_player_name or '<server>'
local reports = Public.user_reports[player.name]
local reports = Reports.user_reports[player.name]
if reports and reports[by_player_name] then
event_emit(Public.player_report_removed,player,by_player_name)
event_emit(Reports.events.on_player_report_removed,player,by_player_name)
reports[by_player_name] = nil
if Public.count_player_reports(player) == 0 then
Public.user_reports[player.name] = nil
if Reports.count_player_reports(player) == 0 then
Reports.user_reports[player.name] = nil
end
return true
end
@@ -68,15 +70,15 @@ end
--- Clears all reports from a player, will emit an event for each individual report as if remove_player_report was used
-- @tparam LuaPlayer player the player to clear the reports of
-- @treturn boolean true if the reports were cleared, nil if error
function Public.clear_player_reports(player)
function Reports.clear_player_reports(player)
player = Game.get_player_from_any(player)
if not player then return end
local reports = Public.user_reports[player.name]
local reports = Reports.user_reports[player.name]
if reports then
for by_player_name,reason in pairs(reports) do
event_emit(Public.player_report_removed,player,by_player_name)
event_emit(Reports.events.on_player_report_removed,player,by_player_name)
end
Public.user_reports[player.name] = nil
Reports.user_reports[player.name] = nil
return true
end
return false
@@ -87,10 +89,10 @@ end
-- @tparam string by_player_name the player that made if the report if present (note server is not default here)
-- @tparam[opt=false] boolean rtn_reason true will return the reason for the report rather than a boolean
-- @treturn boolean true if a report from the player is present unless rtn_reason is true when a string is returned (or false)
function Public.player_is_reported_by(player,by_player_name,rtn_reason)
function Reports.player_is_reported_by(player,by_player_name,rtn_reason)
player = Game.get_player_from_any(player)
if not player then return end
local reports = Public.user_reports[player.name]
local reports = Reports.user_reports[player.name]
if reports and reports[by_player_name] then
return rtn_reason and reports[by_player_name] or true
end
@@ -100,10 +102,10 @@ end
--- Gets all the reports that are on a player
-- @tparam LuaPlayer player the player to get the reports of
-- @treturn table a table of all the reports for this player, empty table if no reports
function Public.get_player_reports(player)
function Reports.get_player_reports(player)
player = Game.get_player_from_any(player)
if not player then return end
return Public.user_reports[player.name] or {}
return Reports.user_reports[player.name] or {}
end
--- Counts all reports on a player returning a number, a custom count function can be given which should return a number
@@ -113,10 +115,10 @@ end
-- count_callback param - reason string - the reason the reason was made
-- count_callback return - number or boolean - if number then this will be added to the count, if boolean then false = 0 and true = 1
-- @treturn number the number of reports on the player
function Public.count_player_reports(player,count_callback)
function Reports.count_player_reports(player,count_callback)
player = Game.get_player_from_any(player)
if not player then return end
local reports = Public.user_reports[player.name] or {}
local reports = Reports.user_reports[player.name] or {}
if not count_callback then
local ctn = 0
for _ in pairs(reports) do
@@ -136,4 +138,4 @@ function Public.count_player_reports(player,count_callback)
end
end
return Public
return Reports

View File

@@ -5,26 +5,28 @@ local config = require 'config.warnings'
local format_chat_player_name = ext_require('expcore.common','format_chat_player_name')
require 'utils.table'
local Public = {
local Warnings = {
user_warnings={},
user_temp_warnings={},
player_warning_added = script.generate_event_name(),
player_warning_removed = script.generate_event_name(),
player_temp_warning_added = script.generate_event_name(),
player_temp_warning_removed = script.generate_event_name()
events = {
on_player_warned = script.generate_event_name(),
on_player_warning_removed = script.generate_event_name(),
on_temp_warning_added = script.generate_event_name(),
on_temp_warning_removed = script.generate_event_name(),
}
}
Global.register({
user_warnings = Public.user_warnings,
user_temp_warnings = Public.user_temp_warnings
user_warnings = Warnings.user_warnings,
user_temp_warnings = Warnings.user_temp_warnings
},function(tbl)
Public.user_warnings = tbl.user_warnings
Public.user_temp_warnings = tbl.user_temp_warnings
Warnings.user_warnings = tbl.user_warnings
Warnings.user_temp_warnings = tbl.user_temp_warnings
end)
local function event_emit(event,player,by_player_name)
local warnings = Public.user_warnings[player.name] or {}
local temp_warnings = Public.user_temp_warnings[player.name] or {}
local warnings = Warnings.user_warnings[player.name] or {}
local temp_warnings = Warnings.user_temp_warnings[player.name] or {}
script.raise_event(event,{
name=event,
tick=game.tick,
@@ -40,19 +42,19 @@ end
-- @tparam[opt='<server>'] string by_player_name the name of the player doing the action
-- @tparam[opt=1] number count the number of warnings to add
-- @treturn number the new number of warnings
function Public.add_warnings(player,by_player_name,count)
function Warnings.add_warnings(player,by_player_name,count)
player = Game.get_player_from_any(player)
if not player then return end
count = count or 1
by_player_name = by_player_name or '<server>'
local warnings = Public.user_warnings[player.name]
local warnings = Warnings.user_warnings[player.name]
if not warnings then
Public.user_warnings[player.name] = {}
warnings = Public.user_warnings[player.name]
Warnings.user_warnings[player.name] = {}
warnings = Warnings.user_warnings[player.name]
end
for _=1,count do
table.insert(warnings,by_player_name)
event_emit(Public.player_warning_added,player,by_player_name)
event_emit(Warnings.events.on_player_warned,player,by_player_name)
end
return #warnings
end
@@ -62,20 +64,20 @@ end
-- @tparam[opt='<server>'] string by_playey_name the name of the player doing the action
-- @tparam[opt=1] number count the number of warnings to remove (if greater than current warning count then all are removed)
-- @treturn number the new number of warnings
function Public.remove_warnings(player,by_player_name,count)
function Warnings.remove_warnings(player,by_player_name,count)
player = Game.get_player_from_any(player)
if not player then return end
count = count or 1
by_player_name = by_player_name or '<server>'
local warnings = Public.user_warnings[player.name]
local warnings = Warnings.user_warnings[player.name]
if not warnings then return end
for _=1,count do
if #warnings == 0 then break end
table.remove(warnings,1)
event_emit(Public.player_warning_removed,player,by_player_name)
event_emit(Warnings.events.on_player_warning_removed,player,by_player_name)
end
if #warnings == 0 then
Public.user_warnings[player.name] = nil
Warnings.user_warnings[player.name] = nil
return 0
end
return #warnings
@@ -85,16 +87,16 @@ end
-- @tparam LuaPlayer player the player to clear the warnings of
-- @tparam[oot='<server>'] string by_player_name the name of the player who is doing the action
-- @treturn boolean true if the warnings were cleared, nil if error
function Public.clear_warnings(player,by_player_name)
function Warnings.clear_warnings(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
local warnings = Public.user_warnings[player.name]
local warnings = Warnings.user_warnings[player.name]
if not warnings then return end
by_player_name = by_player_name or '<server>'
for _=1,#warnings do
event_emit(Public.player_warning_removed,player,by_player_name)
event_emit(Warnings.events.on_player_warning_removed,player,by_player_name)
end
Public.user_warnings[player.name] = {}
Warnings.user_warnings[player.name] = {}
return true
end
@@ -102,10 +104,10 @@ end
-- @tparam LuaPlayer player the player to get the warnings of
-- @tparam[opt=false] table table raw_table when true will return a which contains who gave warnings (the stored in global)
-- @treturn number the number of warnings a player has, a table if raw_table is true
function Public.get_warnings(player,raw_table)
function Warnings.get_warnings(player,raw_table)
player = Game.get_player_from_any(player)
if not player then return end
local warnings = Public.user_warnings[player.name] or {}
local warnings = Warnings.user_warnings[player.name] or {}
if raw_table then
return warnings
else
@@ -117,18 +119,18 @@ end
-- @tparam LuaPlayer player the player to give the warnings to
-- @tparam[opt=1] number count the number of warnings to give to the player
-- @treturn number the new number of warnings
function Public.add_temp_warnings(player,count)
function Warnings.add_temp_warnings(player,count)
player = Game.get_player_from_any(player)
if not player then return end
count = count or 1
local warnings = Public.user_temp_warnings[player.name]
local warnings = Warnings.user_temp_warnings[player.name]
if not warnings then
Public.user_temp_warnings[player.name] = {}
warnings = Public.user_temp_warnings[player.name]
Warnings.user_temp_warnings[player.name] = {}
warnings = Warnings.user_temp_warnings[player.name]
end
for _=1,count do
table.insert(warnings,game.tick)
event_emit(Public.player_temp_warning_added,player,'<server>')
event_emit(Warnings.events.on_temp_warning_added,player,'<server>')
end
return #warnings
end
@@ -137,17 +139,17 @@ end
local temp_warning_cool_down = config.temp_warning_cool_down*3600
Event.on_nth_tick(temp_warning_cool_down/4,function()
local check_time = game.tick-temp_warning_cool_down
for player_name,temp_warnings in pairs(Public.user_temp_warnings) do
for player_name,temp_warnings in pairs(Warnings.user_temp_warnings) do
local player = Game.get_player_from_any(player)
for index,time in pairs(temp_warnings) do
if time <= check_time then
table.remove(temp_warnings,index)
player.print{'warnings.script-warning-removed',#temp_warnings,config.temp_warning_limit}
event_emit(Public.player_temp_warning_removed,player,'<server>')
event_emit(Warnings.events.on_temp_warning_removed,player,'<server>')
end
end
if #temp_warnings == 0 then
Public.user_temp_warnings[player_name] = nil
Warnings.user_temp_warnings[player_name] = nil
end
end
end)
@@ -156,16 +158,16 @@ end)
-- @tparam LuaPlayer player the player to clear the warnings of
-- @tparam[opt='<server>'] string by_player_name the name of the player doing the action
-- @treturn boolean true if the warnings were cleared, nil for error
function Public.clear_temp_warnings(player,by_player_name)
function Warnings.clear_temp_warnings(player,by_player_name)
player = Game.get_player_from_any(player)
if not player then return end
local warnings = Public.user_temp_warnings[player.name]
local warnings = Warnings.user_temp_warnings[player.name]
if not warnings then return end
by_player_name = by_player_name or '<server>'
for _=1,#warnings do
event_emit(Public.player_temp_warning_removed,player,by_player_name)
event_emit(Warnings.events.on_temp_warning_removed,player,by_player_name)
end
Public.user_temp_warnings[player.name] = {}
Warnings.user_temp_warnings[player.name] = {}
return true
end
@@ -173,10 +175,10 @@ end
-- @tparam LuaPlayer player the player to get the warnings of
-- @tparam[opt=false] table raw_table if true will return a of ticks when warnings were added (the global table)
-- @treturn number the number of warnings which the player has, a table if raw_table is true
function Public.get_temp_warnings(player,raw_table)
function Warnings.get_temp_warnings(player,raw_table)
player = Game.get_player_from_any(player)
if not player then return end
local warnings = Public.user_temp_warnings[player.name] or {}
local warnings = Warnings.user_temp_warnings[player.name] or {}
if raw_table then
return warnings
else
@@ -185,7 +187,7 @@ function Public.get_temp_warnings(player,raw_table)
end
-- when a player gets a warning the actions in config are ran
Event.add(Public.player_warning_added,function(event)
Event.add(Warnings.events.on_player_warned,function(event)
local action = config.actions[event.warning_count]
if not action then return end
local player = Game.get_player_by_index(event.player_index)
@@ -205,10 +207,10 @@ Event.add(Public.player_warning_added,function(event)
end)
-- when a player gets a tempo warnings it is checked that it is not above the max
Event.add(Public.player_temp_warning_added,function(event)
Event.add(Warnings.events.on_temp_warning_added,function(event)
local player = Game.get_player_by_index(event.player_index)
if event.temp_warning_count > config.temp_warning_limit then
Public.add_warnings(event.player_index,event.by_player_name)
Warnings.add_warnings(event.player_index,event.by_player_name)
local player_name_color = format_chat_player_name(player)
game.print{'warnings.script-warning-limit',player_name_color}
else
@@ -216,4 +218,4 @@ Event.add(Public.player_temp_warning_added,function(event)
end
end)
return Public
return Warnings

View File

@@ -20,6 +20,8 @@ Commands.new_command('bonus','Changes the amount of bonus you receive')
:register(function(player,amount)
local percent = amount/100
Store.set(bonus_store,player.name,percent)
Commands.print{'expcom-bonus.set',amount}
Commands.print({'expcom-bonus.wip'},'orange')
end)
Event.add(defines.events.on_player_respawned,function(event)
@@ -54,5 +56,5 @@ local function role_update(event)
end
end
Event.add(Roles.player_role_assigned,role_update)
Event.add(Roles.player_role_unassigned,role_update)
Event.add(Roles.events.on_role_assigned,role_update)
Event.add(Roles.events.on_role_unassigned,role_update)

70
modules/commands/home.lua Normal file
View File

@@ -0,0 +1,70 @@
local Commands = require 'expcore.commands'
local Global = require 'utils.global'
require 'config.expcore-commands.parse_general'
local homes = {}
Global.register(homes,function(tbl)
homes = tbl
end)
local function teleport(player,position)
local surface = player.surface
local pos = surface.find_non_colliding_position('character',position,32,1)
if not position then return false end
if player.driving then player.driving = false end -- kicks a player out a vehicle if in one
player.teleport(pos,surface)
return true
end
local function floor_pos(position)
return {
x=math.floor(position.x),
y=math.floor(position.y)
}
end
Commands.new_command('home','Teleports you to your home location')
:register(function(player,raw)
local home = homes[player.index]
if not home or not home[1] then
return Commands.error{'expcom-home.no-home'}
end
local rtn = floor_pos(player.position)
teleport(player,home[1])
home[2] = rtn
Commands.print{'expcom-home.return-set',rtn.x,rtn.y}
end)
Commands.new_command('home-set','Sets your home location to your current position')
:register(function(player,raw)
local home = homes[player.index]
if not home then
home = {}
homes[player.index] = home
end
local pos = floor_pos(player.position)
home[1] = pos
Commands.print{'expcom-home.home-set',pos.x,pos.y}
end)
Commands.new_command('home-get','Returns your current home location')
:register(function(player,raw)
local home = homes[player.index]
if not home or not home[1] then
return Commands.error{'expcom-home.no-home'}
end
local pos = home[1]
Commands.print{'expcom-home.home-get',pos.x,pos.y}
end)
Commands.new_command('return','Teleports you to previous location')
:register(function(player,raw)
local home = homes[player.index]
if not home or not home[2] then
return Commands.error{'expcom-home.no-return'}
end
local rtn = floor_pos(player.position)
teleport(player,home[2])
home[2] = rtn
Commands.print{'expcom-home.return-set',rtn.x,rtn.y}
end)

View File

@@ -111,30 +111,8 @@ local function generate_container(player,element)
}
Gui.set_padding(container)
-- a scroll bar which allows 8 players to be seen at once
local list_scroll =
container.add{
name='scroll',
type='scroll-pane',
direction='vertical',
horizontal_scroll_policy='never',
vertical_scroll_policy='auto-and-reserve-space'
}
Gui.set_padding(list_scroll,1,1,2,2)
list_scroll.style.horizontally_stretchable = true
list_scroll.style.maximal_height = 188
-- 3 wide table to contain: action button, player name, and play time
local list_table =
list_scroll.add{
name='table',
type='table',
column_count=3
}
Gui.set_padding(list_table)
list_table.style.horizontally_stretchable = true
list_table.style.vertical_align = 'center'
list_table.style.cell_padding = 0
local list_table = Gui.create_scroll_table(container,3,188)
-- action bar which contains the different action buttons
local action_bar =
@@ -258,7 +236,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 = Gui.create_right_align(list_table,'player-time-'..player.index)
local time_flow = Gui.create_alignment(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
@@ -295,7 +273,7 @@ Gui.new_left_frame('gui/player-list')
:set_tooltip{'player-list.main-tooltip'}
:set_open_by_default()
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
local list_table,action_bar = generate_container(player,element)
generate_action_bar(player,action_bar)
@@ -378,7 +356,7 @@ end)
Event.on_nth_tick(1800,player_list 'update_all')
Event.add(defines.events.on_player_joined_game,player_list 'redraw_all')
Event.add(defines.events.on_player_left_game,player_list 'redraw_all')
Event.add(Roles.player_role_assigned,player_list 'redraw_all')
Event.add(Roles.player_role_unassigned,player_list 'redraw_all')
Event.add(Roles.events.on_role_assigned,player_list 'redraw_all')
Event.add(Roles.events.on_role_unassigned,player_list 'redraw_all')
return player_list

View File

@@ -145,52 +145,21 @@ 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}
}
local header_area = Gui.create_header(
container,
{'rocket-info.section-caption-'..section_name},
{'rocket-info.section-tooltip-'..section_name},
true,
section_name..'-header'
)
--- 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
toggle_section(header_area)
--- 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
local flow_table = Gui.create_scroll_table(container,table_size,215,section_name)
flow_table.parent.visible = false
end
--[[ Creates the main structure for the gui
@@ -272,7 +241,7 @@ local function create_label_value_pair(element,data_name,value,tooltip,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)
local right_flow = Gui.create_alignment(element,data_name_extra)
right_flow.add{
type='label',
name='label',
@@ -328,7 +297,7 @@ local function generate_stats(player,frame)
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]
first_rocket = rocket_times[player.force.name][force_rockets-avg_over+1]
else
rocket_count = force_rockets
end
@@ -347,9 +316,9 @@ local function generate_milestones(player,frame)
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)
create_label_value_pair_time(element,'milstone-n',time,false,milestone)
else
create_label_value_pair_time(element,'milstone-n',0,true,milestone)
create_label_value_pair_time(element,'milstone-n',0,false,milestone)
break
end
end
@@ -470,7 +439,7 @@ local function generate_progress(player,frame)
}
--- Creates the progress value which is right aligned
local right_flow = Gui.create_right_align(element,silo_name)
local right_flow = Gui.create_alignment(element,silo_name)
right_flow.add{
type='label',
name='label',
@@ -517,7 +486,7 @@ end)
return player.force.rockets_launched > 0
end)
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
generate_container(player,element)
generate_stats(player,element)
generate_milestones(player,element)
@@ -631,7 +600,7 @@ Event.on_nth_tick(150,function()
end)
--- Makes sure the right buttons are present when role changes
Event.add(Roles.player_role_assigned,rocket_info 'redraw')
Event.add(Roles.player_role_unassigned,rocket_info 'redraw')
Event.add(Roles.events.on_role_assigned,rocket_info 'redraw')
Event.add(Roles.events.on_role_unassigned,rocket_info 'redraw')
return rocket_info

View File

@@ -75,33 +75,18 @@ local function generate_container(player,element)
Gui.set_padding(container)
-- main header for the gui
local header =
container.add{
name='header',
type='frame',
caption={'science-info.main-caption'},
style='subheader_frame'
}
Gui.set_padding(header,2,2,4,4)
header.style.horizontally_stretchable = true
header.style.use_header_filler = false
Gui.create_header(
container,
{'science-info.main-caption'},
{'science-info.main-tooltip'}
)
-- main flow for the data
local flow =
container.add{
name='scroll',
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 = 185
-- table that stores all the data
local flow_table = Gui.create_scroll_table(container,4,185)
-- message to say that you have not made any packs yet
local non_made =
flow.add{
flow_table.parent.add{
name='non_made',
type='label',
caption={'science-info.no-packs'}
@@ -109,17 +94,6 @@ local function generate_container(player,element)
non_made.style.width = 200
non_made.style.single_line = false
-- table that stores all the data
local flow_table =
flow.add{
name='table',
type='table',
column_count=4
}
Gui.set_padding(flow_table)
flow_table.style.horizontally_stretchable = true
flow_table.style.vertical_align = 'center'
local eta
if config.show_eta then
-- footer used to store the eta
@@ -142,7 +116,7 @@ local function generate_container(player,element)
}
-- data for the footer
local right_align = Gui.create_right_align(footer,'eta')
local right_align = Gui.create_alignment(footer,'eta')
eta =
right_align.add{
name='label',
@@ -191,7 +165,7 @@ local function add_data_label(element,name,value,secondary,tooltip)
else
-- right aligned number
local right_align = Gui.create_right_align(element,name)
local right_align = Gui.create_alignment(element,name)
local data =
right_align.add{
name='label',
@@ -341,7 +315,7 @@ Gui.new_left_frame('gui/science-info')
:set_sprites('entity/lab')
:set_direction('vertical')
:set_tooltip{'science-info.main-tooltip'}
:on_draw(function(player,element)
:on_creation(function(player,element)
local table, eta = generate_container(player,element)
for _,science_pack in ipairs(config) do

View File

@@ -211,7 +211,7 @@ function generate_task(player,element,task_id)
Gui.set_padding(task_area)
-- if the player can edit then it adds the edit and delete button
local flow = Gui.create_right_align(element,'edit-'..task_id)
local flow = Gui.create_alignment(element,'edit-'..task_id)
local sub_flow = flow.add{type='flow',name=task_id}
edit_task(sub_flow)
@@ -310,46 +310,28 @@ local function generate_container(player,element)
container.style.vertically_stretchable = false
-- main header for the gui
local header =
container.add{
name='header',
type='frame',
style='subheader_frame'
}
Gui.set_padding(header,2,2,4,4)
header.style.horizontally_stretchable = true
header.style.use_header_filler = false
--- Caption for the header bar
header.add{
type='label',
style='heading_1_label',
caption={'task-list.main-caption'},
tooltip={'task-list.sub-tooltip'}
}
local header_area = Gui.create_header(
container,
{'task-list.main-caption'},
{'task-list.sub-tooltip'},
true
)
--- Right aligned button to toggle the section
if player_allowed_edit(player) then
local right_align = Gui.create_right_align(header)
add_new_task(right_align)
add_new_task(header_area)
end
-- main flow for the data
local flow =
container.add{
name='scroll',
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 = 185
-- table that stores all the data
local flow_table = Gui.create_scroll_table(container,3,185)
flow_table.draw_horizontal_lines = true
flow_table.vertical_centering = false
flow_table.style.top_cell_padding = 3
flow_table.style.bottom_cell_padding = 3
-- message to say that you have no tasks
local non_made =
flow.add{
flow_table.parent.add{
name='no_tasks',
type='label',
caption={'task-list.no-tasks'}
@@ -357,20 +339,6 @@ local function generate_container(player,element)
non_made.style.width = 200
non_made.style.single_line = false
-- table that stores all the data
local flow_table =
flow.add{
name='table',
type='table',
column_count=3,
draw_horizontal_lines=true,
vertical_centering=false
}
Gui.set_padding(flow_table)
flow_table.style.horizontally_stretchable = true
flow_table.style.top_cell_padding = 3
flow_table.style.bottom_cell_padding = 3
return flow_table
end
@@ -381,7 +349,7 @@ Gui.new_left_frame('gui/task-list')
:set_direction('vertical')
:set_tooltip{'task-list.main-tooltip'}
:set_open_by_default()
:on_draw(function(player,element)
:on_creation(function(player,element)
local data_table = generate_container(player,element)
local force_name = player.force.name
@@ -415,7 +383,7 @@ Store.register(task_store,function(value,task_id)
end)
--- Makess sure the right buttons are present when roles change
Event.add(Roles.player_role_assigned,task_list 'redraw')
Event.add(Roles.player_role_unassigned,task_list 'redraw')
Event.add(Roles.events.on_role_assigned,task_list 'redraw')
Event.add(Roles.events.on_role_unassigned,task_list 'redraw')
return task_list

View File

@@ -254,7 +254,7 @@ local warp_timer =
Gui.new_progressbar()
:set_tooltip{'warp-list.timer-tooltip',config.recharge_time}
:set_default_maximum(math.floor(config.recharge_time*config.update_smothing))
:add_store(Gui.player_store)
:add_store(Gui.categorize_by_player)
:set_style(nil,function(style)
style.horizontally_stretchable = true
style.color = Colors.light_blue
@@ -449,7 +449,7 @@ function generate_warp(player,element,warp_id)
Gui.set_padding(warp_area)
-- if the player can edit then it adds the edit and delete button
local flow = Gui.create_right_align(element,'edit-'..warp_id)
local flow = Gui.create_alignment(element,'edit-'..warp_id)
local sub_flow = flow.add{type='flow',name=warp_id}
edit_warp(sub_flow)
@@ -493,6 +493,7 @@ function generate_warp(player,element,warp_id)
local timer = warp_timer:get_store(player.name)
local enabled = not timer and Store.get(warp_player_in_range_store,player.name)
or Roles.player_allowed(player,config.bypass_warp_limits_permision)
if not enabled then
btn.enabled = false
btn.tooltip = {'warp-list.goto-disabled'}
@@ -577,52 +578,20 @@ local function generate_container(player,element)
container.style.vertically_stretchable = false
-- main header for the gui
local header =
container.add{
name='header',
type='frame',
style='subheader_frame'
}
Gui.set_padding(header,2,2,4,4)
header.style.horizontally_stretchable = true
header.style.use_header_filler = false
--- Caption for the header bar
header.add{
type='label',
style='heading_1_label',
caption={'warp-list.main-caption'},
tooltip={'warp-list.sub-tooltip',config.recharge_time,config.activation_range}
}
local header_area = Gui.create_header(
container,
{'warp-list.main-caption'},
{'warp-list.sub-tooltip',config.recharge_time,config.activation_range},
true
)
--- Right aligned button to toggle the section
if player_allowed_edit(player) then
local right_align = Gui.create_right_align(header)
add_new_warp(right_align)
add_new_warp(header_area)
end
-- main flow for the data
local flow =
container.add{
name='scroll',
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 = 258
-- table that stores all the data
local flow_table =
flow.add{
name='table',
type='table',
column_count=3
}
Gui.set_padding(flow_table)
flow_table.style.horizontally_stretchable = true
local flow_table = Gui.create_scroll_table(container,3,258)
flow_table.style.top_cell_padding = 3
flow_table.style.bottom_cell_padding = 3
@@ -637,7 +606,7 @@ Gui.new_left_frame('gui/warp-list')
:set_sprites('item/'..config.default_icon)
:set_tooltip{'warp-list.main-tooltip',config.activation_range}
:set_direction('vertical')
:on_draw(function(player,element)
:on_creation(function(player,element)
local data_table = generate_container(player,element)
local force_name = player.force.name
@@ -716,6 +685,10 @@ Store.register(warp_player_in_range_store,function(value,player_name)
Gui.toggle_left_frame(warp_list.name,player,value)
end
if Roles.player_allowed(player,config.bypass_warp_limits_permision) then
return
end
if force_warps[force.name] then
for _,warp_id in pairs(force_warps[force.name]) do
local element = table_area['icon-'..warp_id][goto_warp.name]
@@ -789,4 +762,24 @@ Event.add(defines.events.on_player_created,function(event)
end
end)
local function maintain_tag(event)
local tag = event.tag
local force = event.force
local warps = force_warps[force.name]
if warps then
for _,warp_id in pairs(warps) do
local warp = warp_details[warp_id]
if not warp.tag or not warp.tag.valid or warp.tag == tag then
if event.name == defines.events.on_chart_tag_removed then
warp.tag = nil
end
make_warp_tag(warp_id)
end
end
end
end
Event.add(defines.events.on_chart_tag_modified,maintain_tag)
Event.add(defines.events.on_chart_tag_removed,maintain_tag)
return warp_list