mirror of
https://github.com/PHIDIAS0303/ExpCluster.git
synced 2025-12-31 13:01:39 +09:00
Moved All Code Out Of Locale
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
|
||||
--[[
|
||||
How to use groups:
|
||||
name the name that you can use to refence it.
|
||||
disallow if present then all ranks in this group will have this added to their disallow.
|
||||
allow if present then all ranks in this group will have this added to their allow.
|
||||
highest is asigned by the script to show the highest rank in this group.
|
||||
lowest is asigned by the script to show the lowest rank in this group.
|
||||
How to add ranks:
|
||||
Name is what will be used in the scripts and is often the best choice for display in text.
|
||||
short_hand is what can be used when short on space but the rank still need to be displayed.
|
||||
tag is the tag the player will gain when moved to the rank, it can be nil.
|
||||
time is used for auto-rank feature where you are moved to the rank after a certain play time in minutes.
|
||||
colour is the RGB value that can be used to emphasise GUI elements based on rank.
|
||||
power is asigned by the script based on their index in ranks, you can insert new ranks between current ones.
|
||||
group is asigned by the script to show the group this rank is in
|
||||
disallow is a list containing input actions that the user can not perform.
|
||||
allow is a list of custom commands and effects that that rank can use, all defined in the sctips.
|
||||
|
||||
For allow, add the allow as the key and the value as true
|
||||
Example: test for 'server-interface' => allow['server-interface'] = true
|
||||
|
||||
For disallow, add to the list the end part of the input action
|
||||
Example: defines.input_action.drop_item -> 'drop_item'
|
||||
http://lua-api.factorio.com/latest/defines.html#defines.input_action
|
||||
--]]
|
||||
|
||||
-- see ExpCore/ranks.lua for examples - you add your own and edit pre-made ones here.
|
||||
|
||||
local groups = Ranking._groups(true)
|
||||
local ranks = Ranking._ranks(true)
|
||||
|
||||
groups['Root']:edit('allow',false,{
|
||||
['testing']=true
|
||||
})
|
||||
ranks['Root']:edit('test',true,'testing')
|
||||
|
||||
groups['User']:add_rank{
|
||||
name='Veteran',
|
||||
short_hand='Vet',
|
||||
tag='[Veteran]',
|
||||
time=600,
|
||||
colour={r=140,g=120,b=200},
|
||||
power=8
|
||||
}
|
||||
groups['User']:add_rank{
|
||||
name='Regular',
|
||||
short_hand='Reg',
|
||||
tag='[Regular]',
|
||||
time=180,
|
||||
colour={r=24,g=172,b=188},
|
||||
power=10
|
||||
}
|
||||
|
||||
Ranking._base_preset{
|
||||
['badgamernl']='Owner',
|
||||
['arty714']='Community Manager',
|
||||
['cooldude2606']='Developer',
|
||||
['mark9064']='Admin'
|
||||
}
|
||||
@@ -1,280 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
|
||||
local inputs = {}
|
||||
inputs._input = {}
|
||||
-- these are just so you can have short cuts to this
|
||||
inputs.events = {
|
||||
error='error',
|
||||
state=defines.events.on_gui_checked_state_changed,
|
||||
click=defines.events.on_gui_click,
|
||||
elem=defines.events.on_gui_elem_changed,
|
||||
selection=defines.events.on_gui_selection_state_changed,
|
||||
text=defines.events.on_gui_text_changed,
|
||||
slider=defines.events.on_gui_value_changed
|
||||
}
|
||||
|
||||
--- Sets the input to trigger on an certain event
|
||||
-- @usage button:on_event(defines.events.on_gui_click,player_return)
|
||||
-- @param event the event to raise callback on | can be number of the event | can be a key of inputs.events
|
||||
-- @tparam function callback the function you want to run on the event
|
||||
-- @treturn table returns self so you can chain together
|
||||
function inputs._input:on_event(event,callback)
|
||||
if not is_type(callback,'function') then return self end
|
||||
if inputs.events[event] then event = inputs.events[event] end
|
||||
if event == 'error' then self._error = callback return self end
|
||||
self.events[event] = callback
|
||||
return self
|
||||
end
|
||||
|
||||
--- Draw the input into the root element
|
||||
-- @usage button:draw(frame)
|
||||
-- @param root the element you want to add the input to
|
||||
-- @return returns the element that was added
|
||||
function inputs._input:draw(root)
|
||||
if is_type(self.draw_data.caption,'string') and game.player.gui.is_valid_sprite_path(self.draw_data.caption) then
|
||||
local data = table.deepcopy(self.draw_data)
|
||||
data.type = 'sprite-button'
|
||||
return root.add(data)
|
||||
elseif is_type(self.draw_data.sprite,'string') and game.player.gui.is_valid_sprite_path(self.draw_data.sprite) then
|
||||
local data = table.deepcopy(self.draw_data)
|
||||
data.type = 'sprite-button'
|
||||
return root.add(data)
|
||||
elseif is_type(self.data._state,'function') then
|
||||
local data = table.deepcopy(self.draw_data)
|
||||
local success, err = pcall(self.data._state,root)
|
||||
if success then data.state = err else error(err) end
|
||||
return root.add(data)
|
||||
else
|
||||
return root.add(self.draw_data)
|
||||
end
|
||||
end
|
||||
|
||||
--- Add a new input, this is the same as doing frame.add{} but returns a diffrent object
|
||||
-- @usage Gui.inputs.add{type='button',name='test',caption='Test'}
|
||||
-- @tparam table obj the new element to add if caption is a sprite path then sprite is used
|
||||
-- @treturn table the custom input object
|
||||
function inputs.add(obj)
|
||||
if not is_type(obj,'table') then return end
|
||||
if not is_type(obj.type,'string') then return end
|
||||
local type = obj.type
|
||||
if type == 'button' or
|
||||
type == 'sprite-button' or
|
||||
type == 'choose-elem-button' or
|
||||
type == 'checkbox' or
|
||||
type == 'radiobutton' or
|
||||
type == 'textfield' or
|
||||
type == 'text-box' or
|
||||
type == 'slider'
|
||||
then else return end
|
||||
if obj.type == 'button' or obj.type == 'sprite-button' then obj.style = mod_gui.button_style end
|
||||
obj.draw_data = table.deepcopy(obj)
|
||||
obj.data = {}
|
||||
obj.events = {}
|
||||
setmetatable(obj,{__index=inputs._input})
|
||||
Gui._add_data('inputs_'..type,obj.name,obj)
|
||||
return obj
|
||||
end
|
||||
|
||||
-- this just runs the events given to inputs
|
||||
function inputs._event_handler(event)
|
||||
local elements = Gui._get_data('inputs_'..event.element.type) or {}
|
||||
local element = elements[event.element.name]
|
||||
if not element and event.element.type == 'sprite-button' then
|
||||
elements = Gui._get_data('inputs_button') or {}
|
||||
element = elements[event.element.name]
|
||||
end
|
||||
if element then
|
||||
if not is_type(element.events[event.name],'function') then return end
|
||||
local success, err = pcall(element.events[event.name],event)
|
||||
if not success then
|
||||
if is_type(element._error,'function') then pcall(element._error)
|
||||
else error(err) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.register(inputs.events.state,inputs._event_handler)
|
||||
Event.register(inputs.events.click,inputs._event_handler)
|
||||
Event.register(inputs.events.elem,inputs._event_handler)
|
||||
Event.register(inputs.events.state,inputs._event_handler)
|
||||
Event.register(inputs.events.text,inputs._event_handler)
|
||||
|
||||
-- the folwing functions are just to make inputs easier but if what you want is not include use inputs.add(obj)
|
||||
--- Used to define a button, can have many function
|
||||
-- @usage Gui.inputs.add_button('test','Test','Just for testing',{{condition,callback},...})
|
||||
-- @tparam string name the name of this button
|
||||
-- @tparam string the display for this button, either text or sprite path
|
||||
-- @tparam string tooltip the tooltip to show on the button
|
||||
-- @param callbacks can either be a single function or a list of function pairs see exaplmes at bottom
|
||||
-- @treturn table the button object that was made, to allow a custom error event if wanted
|
||||
function inputs.add_button(name,display,tooltip,callbacks)
|
||||
local button = inputs.add{
|
||||
type='button',
|
||||
name=name,
|
||||
caption=display,
|
||||
tooltip=tooltip
|
||||
}
|
||||
button.data._callbacks = callbacks
|
||||
button:on_event('click',function(event)
|
||||
local player = Game.get_player(event)
|
||||
local mouse = event.button
|
||||
local keys = {alt=event.alt,ctrl=event.control,shift=event.shift}
|
||||
local element = event.element
|
||||
local callbacks = button.data._callbacks
|
||||
if is_type(callbacks,'function') then callbacks = {function(...) return true end,callbacks} end
|
||||
for _,data in pairs(callbacks) do
|
||||
if is_type(data[1],'function') and is_type(data[2],'function') then
|
||||
local success, err = pcall(data[1],player,mouse,keys,event)
|
||||
if success and err == true then
|
||||
local success, err = pcall(data[2],player,element,event)
|
||||
if not success then error(err) end
|
||||
elseif not success then error(err) end
|
||||
else error('Invalid Callback Condition Format') end
|
||||
end
|
||||
end)
|
||||
return button
|
||||
end
|
||||
|
||||
--- Used to define a choose-elem-button callback only on elem_changed
|
||||
-- @usage Gui.inputs.add_elem_button('test','Test','Just for testing',function)
|
||||
-- @tparam string name the name of this button
|
||||
-- @tparam string the display for this button, either text or sprite path
|
||||
-- @tparam string tooltip the tooltip to show on the button
|
||||
-- @tparam function the callback to call on change function(player,element,elem)
|
||||
-- @treturn table the button object that was made, to allow a custom error event if wanted
|
||||
function inputs.add_elem_button(name,elem_type,tooltip,callback)
|
||||
local button = inputs.add{
|
||||
type='choose-elem-button',
|
||||
name=name,
|
||||
elem_type=elem_type,
|
||||
tooltip=tooltip
|
||||
}
|
||||
button.data._callback = callback
|
||||
button:on_event('elem',function(event)
|
||||
local player = Game.get_player(event)
|
||||
local element = event.element or {elem_type=nil,elem_value=nil}
|
||||
local elem = {type=element.elem_type,value=element.elem_value}
|
||||
if is_type(button.data._callback,'function') then
|
||||
local success, err = pcall(button.data._callback,player,element,elem)
|
||||
if not success then error(err) end
|
||||
else error('Invalid Callback') end
|
||||
end)
|
||||
return button
|
||||
end
|
||||
|
||||
--- Used to define a checkbox callback only on state_changed
|
||||
-- @usage Gui.inputs.add_checkbox('test',false,'Just for testing',function,function,funvtion)
|
||||
-- @tparam string name the name of this button
|
||||
-- @tparam string the display for this button, either text or sprite path
|
||||
-- @tparam string tooltip the tooltip to show on the button
|
||||
-- @tparam function the callback to call on change function(player,element,elem)
|
||||
-- @treturn table the button object that was made, to allow a custom error event if wanted
|
||||
function inputs.add_checkbox(name,radio,display,default,callback_true,callback_false)
|
||||
local type = 'checkbox'; if radio then type='radiobutton' end
|
||||
local state = false; if is_type(default,'boolean') then state = default end
|
||||
local checkbox = inputs.add{
|
||||
type=type,
|
||||
name=name,
|
||||
caption=display,
|
||||
state=state
|
||||
}
|
||||
if is_type(default,'function') then checkbox.data._state = default end
|
||||
checkbox.data._true = callback_true
|
||||
checkbox.data._false = callback_false
|
||||
checkbox:on_event('state',function(event)
|
||||
local player = Game.get_player(event)
|
||||
local state = event.element.state
|
||||
if state then
|
||||
if is_type(checkbox.data._true,'function') then
|
||||
local success, err = pcall(checkbox.data._true,player,event.element)
|
||||
if not success then error(err) end
|
||||
else error('Invalid Callback') end
|
||||
else
|
||||
if is_type(checkbox.data._false,'function') then
|
||||
local success, err = pcall(checkbox.data._false,player,event.element)
|
||||
if not success then error(err) end
|
||||
else error('Invalid Callback') end
|
||||
end
|
||||
end)
|
||||
return checkbox
|
||||
end
|
||||
|
||||
--- Used to reset the state of radio buttons, recomened to be called on_state_change to reset any radio buttons it is ment to work with.
|
||||
-- @usage Gui.inputs.reset_radio{radio1,radio2,...}
|
||||
-- @param elements can be a list of elements or a single element
|
||||
function inputs.reset_radio(elements)
|
||||
if #elements > 0 then
|
||||
for _,element in pairs(elements) do
|
||||
if element.valid then
|
||||
local _elements = Gui._get_data('inputs_'..element.type) or {}
|
||||
local _element = _elements[element.name]
|
||||
local state = false
|
||||
local success, err = pcall(_element.data._state,element.parent)
|
||||
if success then state = err else error(err) end
|
||||
element.state = state
|
||||
end
|
||||
end
|
||||
else
|
||||
if elements.valid then
|
||||
local _elements = Gui._get_data('inputs_'..elements.type) or {}
|
||||
local _element = _elements[elements.name]
|
||||
local state = false
|
||||
local success, err = pcall(_element.data._state,elements.parent)
|
||||
if success then state = err else error(err) end
|
||||
element.state = state
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return inputs
|
||||
--[[
|
||||
|
||||
Input Example
|
||||
|
||||
-- Basic Button Using Gui.inputs.add
|
||||
local test = Gui.inputs.add{
|
||||
name='test-button',
|
||||
type='button',
|
||||
caption='Test'
|
||||
}
|
||||
test:on_event(Gui.inputs.events.click,function(event) game.print('test') end)
|
||||
|
||||
-- then later in code
|
||||
local frame = player.gui.top.add{name='test',type='frame'}
|
||||
test:draw(frame)
|
||||
|
||||
-- Mutly Function Button Using Gui.inputs.add_button
|
||||
Gui.inputs.add_button('test-inputs','Try RMB','alt,ctrl,shift and mouse buttons',{
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.left and keys.alt end,
|
||||
function(player,element) player_return('Left: Alt',nil,player) end
|
||||
},
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.left and keys.ctrl end,
|
||||
function(player,element) player_return('Left: Ctrl',nil,player) end
|
||||
},
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.left and keys.shift end,
|
||||
function(player,element) player_return('Left: Shift',nil,player) end
|
||||
},
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.right and keys.alt end,
|
||||
function(player,element) player_return('Right: Alt',nil,player) end
|
||||
},
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.right and keys.ctrl end,
|
||||
function(player,element) player_return('Right: Ctrl',nil,player) end
|
||||
},
|
||||
{
|
||||
function(player,mouse,keys) return mouse == defines.mouse_button_type.right and keys.shift end,
|
||||
function(player,element) player_return('Right: Shift',nil,player) end
|
||||
}
|
||||
}):on_event('error',function(err) game.print('this is error handliling') end)
|
||||
]]
|
||||
@@ -1,48 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
|
||||
local toolbar = {}
|
||||
|
||||
--- Add a button to the toolbar, ranks need to be allowed to use these buttons if ranks is preset
|
||||
-- @usage toolbar.add('foo','Foo','Test',function() game.print('test') end)
|
||||
-- @tparam string name the name of the button
|
||||
-- @tparam string caption can be a sprite path or text to show
|
||||
-- @tparma string tooltip the help to show for the button
|
||||
-- @tparam function callback the function which is called on_click
|
||||
-- @treturn table the button object that was made
|
||||
function toolbar.add(name,caption,tooltip,callback)
|
||||
local button = Gui.inputs.add{type='button',name=name,caption=caption,tooltip=tooltip}
|
||||
button:on_event(Gui.inputs.events.click,callback)
|
||||
Gui._add_data('toolbar',name,button)
|
||||
return button
|
||||
end
|
||||
|
||||
--- Draws the toolbar for a certain player
|
||||
-- @usage toolbar.draw(1)
|
||||
-- @param player the player to draw the tool bar of
|
||||
function toolbar.draw(player)
|
||||
local player = Game.get_player(player)
|
||||
if not player then return end
|
||||
local toolbar_frame = mod_gui.get_button_flow(player)
|
||||
toolbar_frame.clear()
|
||||
for name,button in pairs(Gui._get_data('toolbar')) do
|
||||
if is_type(Ranking,'table') and Ranking._presets and Ranking._presets().meta.rank_count > 0 then
|
||||
local rank = Ranking.get_rank(player)
|
||||
if rank:allowed(name) then
|
||||
button:draw(toolbar_frame)
|
||||
end
|
||||
else button:draw(toolbar_frame) end
|
||||
end
|
||||
end
|
||||
|
||||
if defines.events.rank_change then
|
||||
Event.register(defines.events.rank_change,toolbar.draw)
|
||||
end
|
||||
|
||||
return toolbar
|
||||
@@ -1,139 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
local command_calls = {}
|
||||
local command_data = {}
|
||||
|
||||
--- Uses a commands data to return the inputs as a string
|
||||
-- @usage command = command_data[command_name]
|
||||
-- command_inputs(command) -- returns "<input1> <input2> "
|
||||
-- @tparam table the data for the command being run
|
||||
-- @treturn string the inputs in string format
|
||||
local function command_inputs(command)
|
||||
if not is_type(command,'table') then return end
|
||||
local inputs = ''
|
||||
for _,input in pairs(command.inputs) do
|
||||
if input == true then break end
|
||||
inputs = inputs..'<'..input..'> '
|
||||
end
|
||||
return inputs
|
||||
end
|
||||
|
||||
--- Uses the command data and the event to return a table of the args
|
||||
-- @usage command = command_data[command_name]
|
||||
-- command_args(event,command) -- return {input1='one',input2='two'}
|
||||
-- @tparam defines.events.on_console_command event the event rasied by the command
|
||||
-- @tparam table command the data for the command being run
|
||||
-- @treturn table a table version of the event.parameter based on expected inputs
|
||||
local function command_args(event,command)
|
||||
if not event or not is_type(command,'table') then return end
|
||||
local args = {}
|
||||
-- haddles no parameters given
|
||||
if not event.parameter then
|
||||
if #command.inputs > 0 then return args, false
|
||||
else return args, true
|
||||
end
|
||||
end
|
||||
-- finds all the words and cheaks if the right number were given
|
||||
local words = string.split(event.parameter,' ')
|
||||
if table.last(command.inputs) == true then
|
||||
if #words < #command.inputs-1 then return args, false end
|
||||
else
|
||||
if #words < #command.inputs then return args, false end
|
||||
end
|
||||
-- if it is the right number then process and return the args
|
||||
for index,input in pairs(command.inputs) do
|
||||
if command.inputs[index+1] == true then
|
||||
args[input] = table.concat(words,' ',index)
|
||||
break
|
||||
else
|
||||
args[input] = words[index]
|
||||
end
|
||||
end
|
||||
return args, true
|
||||
end
|
||||
|
||||
--- Used to return all the commands a player can use
|
||||
-- @usage get_commands(1) -- return {{command data},{command data}}
|
||||
-- @param player the player refreced by string|number|LuaPlayer|event
|
||||
-- @treturn table a table containg all the commands the player can use
|
||||
function get_commands(player)
|
||||
local commands = {}
|
||||
local player = Game.get_player(player)
|
||||
if not player then return commands end
|
||||
local rank = Ranking.get_rank(player)
|
||||
for name,data in pairs(command_data) do
|
||||
if Ranking.rank_allowed(rank,name) then table.insert(commands,data) end
|
||||
end
|
||||
return commands
|
||||
end
|
||||
|
||||
--- Used to call the custom commands
|
||||
-- @usage You dont its an internal command
|
||||
-- @tparam defines.events.on_console_command event the event rasied by the command=
|
||||
local function run_custom_command(command)
|
||||
local command_data = command_data[command.name]
|
||||
local player_name = Game.get_player(command) and Game.get_player(command).name or 'server'
|
||||
-- is the player allowed to use this command
|
||||
if is_type(Ranking,'table') and Ranking._presets and Ranking._presets().meta.rank_count > 0 and not Ranking.get_rank(player_name):allowed(command.name) then
|
||||
player_return({'commands.unauthorized'},defines.text_color.crit)
|
||||
if game.player then game.player.play_sound{path='utility/cannot_build'} end
|
||||
game.write_file('commands.log','\n'..game.tick
|
||||
..' Player: '..player_name
|
||||
..' Failed to use command (Unauthorized): '..command.name
|
||||
..' With args of: '..table.to_string(command_args(command,command_data))
|
||||
, true, 0)
|
||||
return
|
||||
end
|
||||
-- gets the args for the command
|
||||
local args, valid = command_args(command,command_data)
|
||||
if not valid then
|
||||
player_return({'commands.invalid-inputs',command.name,command_inputs(command_data)},defines.text_color.high)
|
||||
if game.player then game.player.play_sound{path='utility/deconstruct_big'} end
|
||||
game.write_file('commands.log','\n'..game.tick
|
||||
..' Player: '..player_name
|
||||
..' Failed to use command (Invalid Args): '..command.name
|
||||
..' With args of: '..table.to_string(args)
|
||||
, true, 0)
|
||||
return
|
||||
end
|
||||
-- runs the command
|
||||
local success, err = pcall(command_calls[command.name],event,args)
|
||||
if err then error(err) end
|
||||
player_return({'commands.command-ran'},defines.text_color.info)
|
||||
game.write_file('commands.log','\n'..game.tick
|
||||
..' Player: '..player_name
|
||||
..' Used command: '..command.name
|
||||
..' With args of: '..table.to_string(args)
|
||||
, true, 0)
|
||||
end
|
||||
|
||||
commands._add_command = commands.add_command
|
||||
commands._expgaming = true
|
||||
--- Used to define commands
|
||||
-- @usage inputs = {'player','reason',true}
|
||||
-- commands.add_command('ban','bans a player',inputs,function() return end)
|
||||
-- @tparam string name the name of the command
|
||||
-- @tparam[opt='No Description'] string description the description of the command
|
||||
-- @tparam[opt={'parameter',true}] table inputs a table of the inputs to be used, last index being true makes the last parameter open ended (longer than one word)
|
||||
-- @tparam function event the function to call on the event
|
||||
commands.add_command = function(name, description, inputs, event)
|
||||
if command_calls[name] then return end
|
||||
if not is_type(name,'string') then return end
|
||||
if not is_type(event,'function') then return end
|
||||
local description = is_type(description,'string') and description or 'No Description'
|
||||
local inputs = is_type(inputs,'table') and inputs or {'parameter',true}
|
||||
command_data[name] = {
|
||||
name=name,
|
||||
description=description,
|
||||
inputs=inputs
|
||||
}
|
||||
command_calls[name] = event
|
||||
commands._add_command(name,command_inputs(command_data[name])..description,run_custom_command)
|
||||
end
|
||||
@@ -1,28 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
|
||||
local Gui = {}
|
||||
local Gui_data = {}
|
||||
|
||||
-- this is to enforce the read only propetry of the gui
|
||||
function Gui._add_data(key,value_key,value)
|
||||
if game then return end
|
||||
if not Gui_data[key] then Gui_data[key] = {} end
|
||||
Gui_data[key][value_key] = value
|
||||
end
|
||||
|
||||
function Gui._get_data(key) return Gui_data[key] end
|
||||
|
||||
function Gui:_load_parts(parts)
|
||||
for _,part in pairs(parts) do
|
||||
self[part] = require('/GuiParts/'..part)
|
||||
end
|
||||
end
|
||||
|
||||
return Gui
|
||||
@@ -1,40 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
|
||||
--[[
|
||||
ExpCore
|
||||
|
||||
This file allow you to only require this one file to return the diffent libarys.
|
||||
This file will return a function which can be used to access only the part you want.
|
||||
Pass a table with the names of the objects you want and it will be return in that order
|
||||
]]
|
||||
|
||||
local StdExpCoreLib = {}
|
||||
|
||||
require '/commands'
|
||||
StdExpCoreLib.Server = require '/server'
|
||||
StdExpCoreLib.Ranking = require '/ranking'
|
||||
StdExpCoreLib.Gui = require '/gui'
|
||||
StdExpCoreLib.Gui:_load_parts{
|
||||
'inputs',
|
||||
'toolbar',
|
||||
--'center',
|
||||
--'left',
|
||||
--'popup'
|
||||
}
|
||||
|
||||
return function(rtn)
|
||||
local _return = {}
|
||||
for _,name in pairs(rtn) do
|
||||
if StdExpCoreLib[name] then
|
||||
table.insert(_return,StdExpCoreLib[name])
|
||||
end
|
||||
end
|
||||
return unpack(_return)
|
||||
end
|
||||
@@ -1,312 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
local Ranking = {}
|
||||
defines.events.rank_change = script.generate_event_name()
|
||||
Ranking._rank = {}
|
||||
Ranking._group = {}
|
||||
-- this function is to avoid errors - see /ranks.lua
|
||||
function Ranking._ranks(names)
|
||||
return {}
|
||||
end
|
||||
|
||||
-- this function is to avoid errors - see /ranks.lua
|
||||
function Ranking._groups(names)
|
||||
return {}
|
||||
end
|
||||
|
||||
-- this function is to avoid errors - see /ranks.lua
|
||||
function Ranking._meta()
|
||||
return {}
|
||||
end
|
||||
|
||||
-- this function is to avoid errors - see addons/playerRanks.lua
|
||||
function Ranking._base_preset(table)
|
||||
Ranking._presets().current = table
|
||||
end
|
||||
|
||||
-- this returns a global list
|
||||
function Ranking._presets()
|
||||
if not global.exp_core then global.exp_core = {} end
|
||||
if not global.exp_core.ranking then global.exp_core.ranking = {meta=Ranking._meta(),old={},current={}} end
|
||||
return global.exp_core.ranking
|
||||
end
|
||||
|
||||
--- Returns a rank object given a player or rank name
|
||||
-- @usage Ranking.get_rank(game.player)
|
||||
-- Ranking.get_rank('admin')
|
||||
-- @param mixed player|player index|player name|rank name|rank|'server'|'root' what rank to get
|
||||
-- @treturn table the rank that is linked to mixed
|
||||
function Ranking.get_rank(mixed)
|
||||
if not mixed then return false end
|
||||
local ranks = Ranking._ranks(true)
|
||||
local _return = false
|
||||
if is_type(mixed,'table') then
|
||||
if mixed.index then
|
||||
_return = game.players[mixed.index] and ranks[mixed.permission_group.name] or false
|
||||
else
|
||||
_return = mixed.group and mixed or false
|
||||
end
|
||||
else
|
||||
_return = game.players[mixed] and ranks[game.players[mixed].permission_group.name]
|
||||
or table.autokey(ranks,mixed) and table.autokey(ranks,mixed)
|
||||
or string.contains(mixed,'server') and Ranking.get_rank(Ranking._presets().meta.root)
|
||||
or string.contains(mixed,'root') and Ranking.get_rank(Ranking._presets().meta.root)
|
||||
or false
|
||||
end
|
||||
return _return
|
||||
end
|
||||
|
||||
--- Returns the group object used to sort ranks given group name or see Ranking.get_rank
|
||||
-- @usage Ranking.get_group(game.player)
|
||||
-- Ranking.get_group('root')
|
||||
-- @param mixed player|player index|player name|rank name|rank|'server'|'root'|group name|group what group to get
|
||||
-- @treturn table the group that is linked to mixed
|
||||
function Ranking.get_group(mixed)
|
||||
if not mixed then return false end
|
||||
local groups = Ranking._groups(true)
|
||||
local rank = Ranking.get_rank(mixed)
|
||||
return rank and rank.group
|
||||
or is_type(mixed,'table') and mixed.ranks and mixed
|
||||
or is_type(mixed,'string') and table.autokey(groups,mixed) and table.autokey(groups,mixed)
|
||||
or false
|
||||
end
|
||||
|
||||
--- Prints to all rank of greater/lower power of the rank given
|
||||
-- @usage Ranking.print('admin','We got a grifer')
|
||||
-- @param rank_base the rank that acts as the cut off point (rank is always included)
|
||||
-- @param rtn what do you want to return to the players
|
||||
-- @tparam bolean below if true rank below base are printed to
|
||||
function Ranking.print(rank_base,rtn,colour,below)
|
||||
local colour = colour or defines.color.white
|
||||
local rank_base = Ranking.get_rank(rank_base)
|
||||
local ranks = Ranking._ranks()
|
||||
if below then
|
||||
for power,rank in pairs(ranks) do
|
||||
if rank_base.power >= power then rank:print(rtn,colour) end
|
||||
end
|
||||
else
|
||||
for power,rank in pairs(ranks) do
|
||||
if rank_base.power <= power then rank:print(rtn,colour) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Gives a user a rank
|
||||
-- @usage Ranking.give_rank(1,'admin')
|
||||
-- @param player the player to give the rank to
|
||||
-- @param rank the rank to give to the player
|
||||
-- @param[opt='server'] by_player the player who is giving the rank
|
||||
-- @param[opt=game.tick] tick the tick that the rank is being given on
|
||||
function Ranking.give_rank(player,rank,by_player,tick)
|
||||
local print_colour = defines.text_color.info
|
||||
local tick = tick or game.tick
|
||||
local by_player_name = Game.get_player(by_player) and Game.get_player(by_player).name or game.player and game.player.name or 'server'
|
||||
local rank = Ranking.get_rank(rank) or Ranking.get_rank(Ranking._presets().meta.default)
|
||||
local player = Game.get_player(player) or error('No Player To Give Rank')
|
||||
local old_rank = Ranking.get_rank(player) or Ranking.get_rank(Ranking._presets().meta.default)
|
||||
local message = 'ranking.rank-down'
|
||||
-- messaging
|
||||
if old_rank.name == rank.name then return end
|
||||
if rank.power < old_rank.power then message = 'ranking.rank-up' player.play_sound{path='utility/achievement_unlocked'}
|
||||
else player.play_sound{path='utility/game_lost'} end
|
||||
game.print({message,player.name,rank.name,by_player_name},print_colour)
|
||||
if rank.group.name ~= 'User' then player_return({'ranking.rank-given',rank.name},print_colour,player) end
|
||||
if player.tag ~= old_rank.tag then player_return({'ranking.tag-reset'},print_colour,player) end
|
||||
-- rank change
|
||||
player.permission_group = game.permissions.get_group(rank.name)
|
||||
player.tag = rank.tag
|
||||
if not old_rank.group.name == 'Jail' then Ranking._presets().old[player.index] = rank.name end
|
||||
if defines.events.rank_change then
|
||||
script.raise_event(defines.events.rank_change,{
|
||||
name=defines.events.rank_change,
|
||||
tick=tick,
|
||||
player_index=player.index,
|
||||
by_player_name=by_player_name,
|
||||
new_rank=rank,
|
||||
old_rank=old_rank
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
--- Revert the last change to a players rank
|
||||
-- @usage Ranking.revert(1)
|
||||
-- @param player the player to revert the rank of
|
||||
-- @param[opt=nil] by_player the player who is doing the revert
|
||||
function Ranking.revert(player,by_player)
|
||||
local player = Game.get_player(player)
|
||||
Ranking.give_rank(player,Ranking._presets().old[player.index],by_player)
|
||||
end
|
||||
|
||||
--- Given the player has a rank in the preset table it is given
|
||||
-- @usage Ranking.find_preset(1)
|
||||
-- @param player the player to test for an auto rank
|
||||
-- @tparam[opt=nil] tick the tick it happens on
|
||||
function Ranking.find_preset(player,tick)
|
||||
local presets = Ranking._presets().current
|
||||
local meta_data = Ranking._presets().meta
|
||||
local default = Ranking.get_rank(meta_data.default)
|
||||
local player = Game.get_player(player)
|
||||
local current_rank = Ranking.get_rank(player) or {power=-1,group={name='not jail'}}
|
||||
local ranks = {default}
|
||||
if current_rank.group.name == 'Jail' then return end
|
||||
if presets[string.lower(player.name)] then
|
||||
local rank = Ranking.get_rank(presets[string.lower(player.name)])
|
||||
if current_rank.power >= rank.power then return end
|
||||
table.insert(ranks,rank)
|
||||
end
|
||||
if current_rank.power < meta_data.time_highest and tick_to_min(player.online_time) > meta_data.time_lowest then
|
||||
for _,rank_name in pairs(meta_data.time_ranks) do
|
||||
local rank = Ranking.get_rank(rank_name)
|
||||
if tick_to_min(player.online_time) > rank.time then
|
||||
table.insert(ranks,rank)
|
||||
end
|
||||
end
|
||||
end
|
||||
local _rank = nil
|
||||
for _,rank in pairs(ranks) do
|
||||
if rank.power > current_rank.power then _rank = rank end
|
||||
end
|
||||
if _rank then
|
||||
if _rank.name == default.name then
|
||||
player.tag = _rank.tag
|
||||
player.permission_group = game.permissions.get_group(_rank.name)
|
||||
else
|
||||
Ranking.give_rank(player,_rank,nil,tick)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this is the base rank object, do not store in global
|
||||
|
||||
--- Is this rank allowed to open this gui or use this command etc.
|
||||
-- @usage rank:allowed('server-interface')
|
||||
-- @tparam teh action to test for
|
||||
-- @treturn bolean is it allowed
|
||||
function Ranking._rank:allowed(action)
|
||||
return self.allow[action] or self.is_root or false
|
||||
end
|
||||
|
||||
--- Get all the players in this rank
|
||||
-- @usage rank:get_players()
|
||||
-- @tparam bolean online get only online players
|
||||
-- @treturn table a table of all players in this rank
|
||||
function Ranking._rank:get_players(online)
|
||||
local players = game.permissions.get_group(rank.name).players
|
||||
local _return = {}
|
||||
if online then
|
||||
for _,player in pairs(players) do
|
||||
if player.connected then table.insert(_return,player) end
|
||||
end
|
||||
else
|
||||
_return = players
|
||||
end
|
||||
return _return
|
||||
end
|
||||
|
||||
--- Print a message to all players of this rank
|
||||
-- @usage rank:print('foo')
|
||||
-- @param rtn any value you want to return
|
||||
function Ranking._rank:print(rtn,colour)
|
||||
local colour = colour or defines.color.white
|
||||
if not Server or not Server._thread then
|
||||
for _,player in pairs(self:get_players()) do
|
||||
player_return(rtn,colour,player)
|
||||
end
|
||||
else
|
||||
-- using threads to make less lag
|
||||
Server.new_thread{
|
||||
data={rank=self,rtn=rtn}
|
||||
}:on_event('resolve',function(thread)
|
||||
return thread.data.rank:get_players(true)
|
||||
end):on_event('success',function(thread,players)
|
||||
for _,player in pairs(players) do
|
||||
player_return(thread.data.rtn,colour,player)
|
||||
end
|
||||
end):queue()
|
||||
end
|
||||
end
|
||||
|
||||
-- this is used to edit a group once made key is what is being edited and set_value makes it over ride the current value
|
||||
-- see Addons/playerRanks for examples
|
||||
function Ranking._rank:edit(key,set_value,value)
|
||||
if game then return end
|
||||
if set_value then self[key] = value return end
|
||||
if key == 'disallow' then
|
||||
self.disallow = table.merge(self.disallow,value,true)
|
||||
elseif key == 'allow' then
|
||||
self.allow = table.merge(self.allow,value)
|
||||
end
|
||||
Ranking._update_rank(self)
|
||||
end
|
||||
|
||||
-- this is the base group object, do not store in global, these cant be used in game
|
||||
|
||||
-- this makes a new group
|
||||
-- {name='root',allow={},disallow={}}
|
||||
function Ranking._group:create(obj)
|
||||
if game then return end
|
||||
if not is_type(obj.name,'string') then return end
|
||||
setmetatable(obj,{__index=Ranking._group})
|
||||
self.index = #Ranking._groups(names)+1
|
||||
obj.ranks = {}
|
||||
obj.allow = obj.allow or {}
|
||||
obj.disallow = obj.disallow or {}
|
||||
Ranking._add_group(obj)
|
||||
return obj
|
||||
end
|
||||
|
||||
-- this makes a new rank in side this group
|
||||
-- {name='Root',short_hand='Root',tag='[Root]',time=nil,colour=defines.colors.white,allow={},disallow={}}
|
||||
function Ranking._group:add_rank(obj)
|
||||
if game then return end
|
||||
if not is_type(obj.name,'string') or
|
||||
not is_type(obj.short_hand,'string') or
|
||||
not is_type(obj.tag,'string') or
|
||||
not is_type(obj.colour,'table') then return end
|
||||
setmetatable(obj,{__index=Ranking._rank})
|
||||
obj.group = self
|
||||
obj.allow = obj.allow or {}
|
||||
obj.disallow = obj.disallow or {}
|
||||
setmetatable(obj.allow,{__index=self.allow})
|
||||
setmetatable(obj.disallow,{__index=self.disallow})
|
||||
Ranking._add_rank(obj,obj.power)
|
||||
Ranking._set_rank_power()
|
||||
table.insert(self.ranks,obj)
|
||||
if not self.highest or obj.power > self.highest.power then self.highest = obj end
|
||||
if not self.lowest or obj.power < self.lowest.power then self.lowest = obj end
|
||||
end
|
||||
|
||||
-- this is used to edit a group once made key is what is being edited and set_value makes it over ride the current value
|
||||
-- see Addons/playerRanks for examples
|
||||
function Ranking._group:edit(key,set_value,value)
|
||||
if game then return end
|
||||
if set_value then self[key] = value return end
|
||||
if key == 'disallow' then
|
||||
self.disallow = table.merge(self.disallow,value,true)
|
||||
elseif key == 'allow' then
|
||||
self.allow = table.merge(self.allow,value)
|
||||
end
|
||||
Ranking._update_group(self)
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_player_joined_game,function(event)
|
||||
Ranking.find_preset(event.player_index)
|
||||
end)
|
||||
|
||||
Event.register(-1,function(event)
|
||||
for power,rank in pairs(Ranking._ranks()) do
|
||||
local perm = game.permissions.create_group(rank.name)
|
||||
for _,toRemove in pairs(rank.disallow) do
|
||||
perm.set_allows_action(defines.input_action[toRemove],false)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return Ranking
|
||||
@@ -1,237 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
local groups = {}
|
||||
local ranks = {}
|
||||
|
||||
function Ranking._add_group(group) if game then return end table.insert(groups,group) end
|
||||
function Ranking._add_rank(rank,pos) if game then return end if pos then table.insert(ranks,pos,rank) else table.insert(ranks,rank) end end
|
||||
function Ranking._set_rank_power() if game then return end for power,rank in pairs(ranks) do rank.power = power end end
|
||||
function Ranking._update_rank(rank) if game then return end ranks[rank.power] = rank end
|
||||
function Ranking._update_group(group) if game then return end groups[group.index] = group end
|
||||
|
||||
--[[
|
||||
How to use groups:
|
||||
name the name that you can use to refence it.
|
||||
disallow if present then all ranks in this group will have this added to their disallow.
|
||||
allow if present then all ranks in this group will have this added to their allow.
|
||||
highest is asigned by the script to show the highest rank in this group.
|
||||
lowest is asigned by the script to show the lowest rank in this group.
|
||||
How to add ranks:
|
||||
Name is what will be used in the scripts and is often the best choice for display in text.
|
||||
short_hand is what can be used when short on space but the rank still need to be displayed.
|
||||
tag is the tag the player will gain when moved to the rank, it can be nil.
|
||||
time is used for auto-rank feature where you are moved to the rank after a certain play time in minutes.
|
||||
colour is the RGB value that can be used to emphasise GUI elements based on rank.
|
||||
power is asigned by the script based on their index in ranks, you can insert new ranks between current ones, lower is better
|
||||
group is asigned by the script to show the group this rank is in
|
||||
disallow is a list containing input actions that the user can not perform.
|
||||
allow is a list of custom commands and effects that that rank can use, all defined in the sctips.
|
||||
|
||||
For allow, add the allow as the key and the value as true
|
||||
Example: test for 'server-interface' => allow['server-interface'] = true
|
||||
|
||||
For disallow, add to the list the end part of the input action
|
||||
Example: defines.input_action.drop_item -> 'drop_item'
|
||||
http://lua-api.factorio.com/latest/defines.html#defines.input_action
|
||||
--]]
|
||||
|
||||
-- If you wish to add more groups please use addons/playerRanks.lua
|
||||
-- If you wish to add to these rank groups use addons/playerRanks.lua
|
||||
-- Ranks will inherite from each other ie higher ranks can do everything lower ranks can
|
||||
-- But groups do not inherite from each other
|
||||
-- DO NOT REMOVE ANY OF THESE GROUPS
|
||||
|
||||
local root = Ranking._group:create{
|
||||
name='Root',
|
||||
allow={
|
||||
['interface'] = true
|
||||
},
|
||||
disallow={}
|
||||
}
|
||||
local admin = Ranking._group:create{
|
||||
name='Admin',
|
||||
allow={},
|
||||
disallow={
|
||||
'set_allow_commands',
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group'
|
||||
}
|
||||
}
|
||||
local user = Ranking._group:create{
|
||||
name='User',
|
||||
allow={},
|
||||
disallow={
|
||||
'set_allow_commands',
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group'
|
||||
}
|
||||
}
|
||||
local jail = Ranking._group:create{
|
||||
name='Jail',
|
||||
allow={},
|
||||
disallow={
|
||||
'set_allow_commands',
|
||||
'edit_permission_group',
|
||||
'delete_permission_group',
|
||||
'add_permission_group'
|
||||
}
|
||||
}
|
||||
|
||||
-- If you wish to add more ranks please use addons/playerRanks.lua
|
||||
-- If you wish to add to these rank use addons/playerRanks.lua
|
||||
root:add_rank{
|
||||
name='Root',
|
||||
short_hand='Root',
|
||||
tag='[Root]',
|
||||
colour=defines.color.white,
|
||||
is_root=true
|
||||
}
|
||||
root:add_rank{
|
||||
name='Owner',
|
||||
short_hand='Owner',
|
||||
tag='[Owner]',
|
||||
time=nil,
|
||||
colour={r=170,g=0,b=0}
|
||||
}
|
||||
root:add_rank{
|
||||
name='Community Manager',
|
||||
short_hand='Com Mngr',
|
||||
tag='[Com Mngr]',
|
||||
colour={r=150,g=68,b=161}
|
||||
}
|
||||
root:add_rank{
|
||||
name='Developer',
|
||||
short_hand='Dev',
|
||||
tag='[Dev]',
|
||||
colour={r=179,g=125,b=46}
|
||||
}
|
||||
|
||||
admin:add_rank{
|
||||
name='Admin',
|
||||
short_hand='Admin',
|
||||
tag='[Admin]',
|
||||
colour={r=233,g=63,b=233}
|
||||
}
|
||||
admin:add_rank{
|
||||
name='Mod',
|
||||
short_hand='Mod',
|
||||
tag='[Mod]',
|
||||
colour={r=0,g=170,b=0},
|
||||
disallow={
|
||||
'server_command'
|
||||
}
|
||||
}
|
||||
|
||||
user:add_rank{
|
||||
name='Donator',
|
||||
short_hand='P2W',
|
||||
tag='[P2W]',
|
||||
colour={r=233,g=63,b=233}
|
||||
}
|
||||
user:add_rank{
|
||||
name='Member',
|
||||
short_hand='Mem',
|
||||
tag='[Member]',
|
||||
colour={r=24,g=172,b=188},
|
||||
disallow={
|
||||
'set_auto_launch_rocket',
|
||||
'change_programmable_speaker_alert_parameters',
|
||||
'drop_item'
|
||||
}
|
||||
}
|
||||
user:add_rank{
|
||||
name='Guest',
|
||||
short_hand='',
|
||||
tag='',
|
||||
colour={r=255,g=159,b=27},
|
||||
is_default=true,
|
||||
disallow={
|
||||
'build_terrain',
|
||||
'remove_cables',
|
||||
'launch_rocket',
|
||||
'reset_assembling_machine',
|
||||
'cancel_research'
|
||||
}
|
||||
}
|
||||
|
||||
jail:add_rank{
|
||||
name='Jail',
|
||||
short_hand='Jail',
|
||||
tag='[Jail]',
|
||||
colour={r=50,g=50,b=50},
|
||||
disallow={
|
||||
'open_character_gui',
|
||||
'begin_mining',
|
||||
'start_walking',
|
||||
'player_leave_game'
|
||||
}
|
||||
}
|
||||
|
||||
function Ranking._auto_edit_ranks()
|
||||
for power,rank in pairs(ranks) do
|
||||
if ranks[power-1] then
|
||||
rank:edit('disallow',false,ranks[power-1].disallow)
|
||||
end
|
||||
end
|
||||
for power = #ranks, 1, -1 do
|
||||
rank = ranks[power]
|
||||
if ranks[power+1] then
|
||||
rank:edit('allow',false,ranks[power+1].allow)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- used to force rank to be read-only
|
||||
function Ranking._groups(name)
|
||||
if name then
|
||||
if name then
|
||||
local _return = {}
|
||||
for power,group in pairs(groups) do
|
||||
_return[group.name] = group
|
||||
end
|
||||
return _return
|
||||
end
|
||||
end
|
||||
return groups
|
||||
end
|
||||
|
||||
function Ranking._ranks(name)
|
||||
if name then
|
||||
local _return = {}
|
||||
for power,rank in pairs(ranks) do
|
||||
_return[rank.name] = rank
|
||||
end
|
||||
return _return
|
||||
end
|
||||
return ranks
|
||||
end
|
||||
|
||||
-- used to save lag by doing some calculation at the start
|
||||
function Ranking._meta()
|
||||
local meta = {time_ranks={}}
|
||||
for power,rank in pairs(ranks) do
|
||||
meta.rank_count = power
|
||||
if rank.is_default then
|
||||
meta.default = rank.name
|
||||
end
|
||||
if rank.is_root then
|
||||
meta.root = rank.name
|
||||
end
|
||||
if rank.time then
|
||||
table.insert(meta.time_ranks,rank.name)
|
||||
if not meta.time_highest or power < meta.time_highest then meta.time_highest = power end
|
||||
if not meta.time_lowest or rank.time < meta.time_lowest then meta.time_lowest = power.time end
|
||||
end
|
||||
meta.time_highest = meta.time_highest or 0
|
||||
meta.time_lowest = meta.time_lowest or 0
|
||||
end
|
||||
return meta
|
||||
end
|
||||
@@ -1,421 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
--Please Only Edit Below This Line-----------------------------------------------------------
|
||||
-- server allows control over threads and other features the devs missed out
|
||||
local Server = {}
|
||||
Server._thread = {}
|
||||
|
||||
--- Returns a un-used uuid (better system needed)
|
||||
-- @usage obj.uuid = Server.new_uuid()
|
||||
-- @treturn string the new uuid
|
||||
function Server.new_uuid()
|
||||
local uuid = tostring(Server._uuid()())
|
||||
uuid = string.to_hex('uuid'..uuid)
|
||||
return uuid
|
||||
end
|
||||
|
||||
-- use this to change the location of the server uuids
|
||||
function Server._uuid(reset)
|
||||
global.exp_core = not reset and global.exp_core or {}
|
||||
global.exp_core.uuids = not reset and global.exp_core.uuids or game.create_random_generator()
|
||||
return global.exp_core.uuids
|
||||
end
|
||||
|
||||
--- Returns either the number of threads or a able of threads
|
||||
-- @usage Server.threads() -- return {...}
|
||||
-- Server.threads(true) -- return int
|
||||
-- @tparam[opt=nil] bolean count true to return the number of threads
|
||||
-- @return either a list of threads or a number
|
||||
function Server.threads(count)
|
||||
return count and Server._threads().all._n or Server._threads().all
|
||||
end
|
||||
|
||||
-- use this to change the location of the server threads
|
||||
-- all stores the threads indexed uuid, the other three only store the uuid's to index in the all table
|
||||
function Server._threads(reset)
|
||||
global.exp_core = not reset and global.exp_core or {}
|
||||
global.exp_core.threads = not reset and global.exp_core.threads or {print_to={},queue={},tick={},timeout={},events={},all={_n=0},paused={},named={}}
|
||||
return global.exp_core.threads
|
||||
end
|
||||
|
||||
-- see thread:create (this was done so thread can remain local)
|
||||
function Server.new_thread(obj)
|
||||
return Server._thread:create(obj)
|
||||
end
|
||||
|
||||
--- Used to get a thread via it's uuid or by name if one is given
|
||||
-- @usage Server.get_thread('decon') -- return thread
|
||||
-- @param mixed either a uuid or the name given to a thread
|
||||
-- @treturn table the thread by that name or uuid
|
||||
function Server.get_thread(mixed)
|
||||
local threads = Server._threads()
|
||||
if threads.named[mixed] then return threads.all[threads.named[mixed]]
|
||||
elseif threads.paused[mixed] then return threads.all[threads.paused[mixed]]
|
||||
elseif threads.all[mixed] then return threads.all[mixed]
|
||||
else return false end
|
||||
end
|
||||
|
||||
--- Adds a thread into the resolve queue, can be used to lower lag
|
||||
-- @usage Server.queue_thread(thread) -- return true/false
|
||||
-- @tparam table the thread to add to the queue must have a resolve function (must be open)
|
||||
-- @treturn bolean was the thread added
|
||||
function Server.queue_thread(thread_to_queue)
|
||||
if not thread_to_queue and not thread_to_queue.valid and not thread_to_queue:valid() then return false end
|
||||
if not thread_to_queue._resolve then return false end
|
||||
table.insert(Server._threads().queue,thread_to_queue.uuid)
|
||||
return true
|
||||
end
|
||||
|
||||
--- Closes all active threads, can use force if it causes errors
|
||||
-- @usage Server.close_all_threads()
|
||||
-- Server.close_all_threads(true) -- use if no force makes errors
|
||||
-- @tparam bolean with_force use force when closing
|
||||
function Server.close_all_threads(with_force)
|
||||
if not with_force then
|
||||
for uuid,next_thread in pairs(Server.threads()) do
|
||||
if uuid ~= '_n' then next_thread:close() end
|
||||
end
|
||||
else
|
||||
Server._threads(true)
|
||||
end
|
||||
end
|
||||
|
||||
--- Runs all the theads which have opened with an on_tick event
|
||||
-- @ussage Server.run_tick_threads()
|
||||
function Server.run_tick_threads()
|
||||
table.each(Server._threads().tick,function(uuid)
|
||||
local next_thread = Server.get_thread(uuid)
|
||||
if next_thread and next_thread:valid() and next_thread._tick then
|
||||
local success, err = pcall(next_thread._tick,next_thread)
|
||||
if not success then next_thread:error(err) end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Checks the timeout on all active timeout threads
|
||||
-- @ussage Server.check_timeouts()
|
||||
function Server.check_timeouts()
|
||||
table.each(Server._threads().timeout,function(uuid)
|
||||
local next_thread = Server.get_thread(uuid)
|
||||
if next_thread and next_thread:valid() then
|
||||
next_thread:check_timeout()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- for use in debuging
|
||||
function Server._thread_handler_debuger(player,event,state)
|
||||
local player = Game.get_player(player)
|
||||
local print_to = Server._threads().print_to
|
||||
print_to[player.index] = print_to[player.index] or {}
|
||||
print_to[player.index][event] = state
|
||||
end
|
||||
--- Calles all threads on a certain game event (used with script.on_event)
|
||||
-- @tparam table event the event that is called
|
||||
function Server._thread_handler(event)
|
||||
table.each(Server._threads().print_to,function(print_to,player_index,event)
|
||||
if event.name == defines.events.on_tick then return true end
|
||||
if print_to[event.name] then
|
||||
player_return(event,defines.text_color.bg,player_index)
|
||||
end
|
||||
end,event)
|
||||
local event_id = event.name
|
||||
local threads = Server._threads().events[event_id]
|
||||
if not threads then return end
|
||||
table.each(threads,function(uuid)
|
||||
local next_thread = Server.get_thread(uuid)
|
||||
if next_thread and next_thread:valid() then
|
||||
if is_type(next_thread._events[event_id],'function') then
|
||||
local success, err = pcall(next_thread._events[event_id],next_thread,event)
|
||||
if not success then next_thread:error(err) end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
for _,event in pairs(defines.events) do Event.register(event,Server._thread_handler) end
|
||||
|
||||
--[[ cant be used V
|
||||
--- Adds a event handler to tell threads about events
|
||||
-- @usage Server.add_thread_handler(defines.event)
|
||||
-- @tparam number event the event to run the thread handler on
|
||||
-- @treturn bolean if the handler was added
|
||||
function Server.add_thread_handler(event)
|
||||
if not is_type(event,'number') then return false end
|
||||
local threads = Server._threads()
|
||||
if not threads.events[event] then
|
||||
threads.events[event] = {}
|
||||
Event.register(event,Server._thread_handler)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
]]
|
||||
|
||||
--- Given a string or function it will run that function and return any values
|
||||
-- @usage Server.interface('local x = 1+1 print(x) return x') -- return 2
|
||||
-- Server.interface('local x = 1+1 print(x)',thread) -- no return
|
||||
-- @param callback either a function or string which will be ran via pcall
|
||||
-- @param[opt] use_thread give a thread for the interface to run on (does not need to be open, but cant use on_resolve)
|
||||
-- @param[opt] ... any args you want to pass to the function
|
||||
function Server.interface(callback,use_thread,...)
|
||||
if use_thread then
|
||||
if use_thread == true then use_thread = Server.new_thread{data={callback,...}} end
|
||||
use_thread:on_event('resolve',function(thread)
|
||||
if is_type(thread.data[1],'function') then
|
||||
local success, err = pcall(unpack(thread.data))
|
||||
if not success then error(err) end
|
||||
return err
|
||||
else
|
||||
local callback = table.remove(thread.data,1)
|
||||
local success, err = pcall(loadstring(callback),unpack(thread.data))
|
||||
if not success then error(err) end
|
||||
return err
|
||||
end
|
||||
end)
|
||||
use_thread:open()
|
||||
Server.queue_thread(use_thread)
|
||||
else
|
||||
if is_type(callback,'function') then
|
||||
local success, err = pcall(callback,...)
|
||||
return success, err
|
||||
else
|
||||
local success, err = pcall(loadstring(callback),...)
|
||||
return success, err
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if commands._expgaming then
|
||||
commands.add_command('interface', 'Runs the given input from the script', {'code',true}, function(event,args)
|
||||
local callback = args.code
|
||||
if not string.find(callback,'%s') and not string.find(callback,'return') then callback = 'return '..callback end
|
||||
if game.player then callback = 'local player, surface, force = game.player, game.player.surface, game.player.force '..callback end
|
||||
if Ranking and Ranking.get_rank and game.player then callback = 'local rank = Ranking.get_rank(game.player) '..callback end
|
||||
local success, err = Server.interface(callback)
|
||||
player_return(err)
|
||||
end)
|
||||
end
|
||||
|
||||
-- thread allows you to run fuinction async to the main game
|
||||
--- Returns a new thread object
|
||||
-- @usage new_thread = thread:create()
|
||||
-- @tparam[opt={}] table obj all are opt {timeout=int,name=str,data=any} advanced users can prefix with _function to avoid the on_function functions
|
||||
-- @treturn table the new thread object
|
||||
function Server._thread:create(obj)
|
||||
local obj = obj or {}
|
||||
setmetatable(obj,{__index=Server._thread})
|
||||
obj.uuid = Server.new_uuid()
|
||||
return obj
|
||||
end
|
||||
|
||||
-- see Server.queue_thread - this just opens it first
|
||||
function Server._thread:queue()
|
||||
self:open()
|
||||
return Server.queue_thread(self)
|
||||
end
|
||||
|
||||
--- Test if the thread has all requied parts
|
||||
-- @usage if thread:valid() then end
|
||||
-- @tparam bolean skip_location_check true to skip the location check
|
||||
-- @treturn bolean is the thread valid
|
||||
function Server._thread:valid(skip_location_check)
|
||||
local skip_location_check = skip_location_check or false
|
||||
if is_type(self.uuid,'string') and
|
||||
skip_location_check or is_type(self.opened,'number') and
|
||||
skip_location_check or is_type(Server._threads().all[self.uuid],'table') and
|
||||
is_type(self.timeout) or is_type(self.timeout,'number') and
|
||||
is_type(self.name) or is_type(self.name,'string') and
|
||||
is_type(self._close) or is_type(self._close,'function') and
|
||||
is_type(self._timeout) or is_type(self._timeout,'function') and
|
||||
is_type(self._tick) or is_type(self._tick,'function') and
|
||||
is_type(self._resolve) or is_type(self._resolve,'function') and
|
||||
is_type(self._success) or is_type(self._success,'function') and
|
||||
is_type(self._error) or is_type(self._error,'function') then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Opens the thread by storing it in a place the server object can find it
|
||||
-- @usage thread:open() -- return true
|
||||
-- @treturn bolean if the thread was opened
|
||||
function Server._thread:open()
|
||||
if not self:valid(true) or self.opened then return false end
|
||||
local threads = Server._threads()
|
||||
local uuid = self.uuid
|
||||
self.opened = game.tick
|
||||
threads.all[uuid] = threads.all[uuid] or self
|
||||
threads.all._n = threads.all._n+1
|
||||
if is_type(self.timeout,'number') then table.insert(threads.timeout,uuid) end
|
||||
if is_type(self._tick,'function') then table.insert(threads.tick,uuid) end
|
||||
if is_type(self.name,'string') then threads.named[self.name] = threads.named[self.name] or self.uuid end
|
||||
if is_type(self._events,'table') then
|
||||
table.each(self._events,function(callback,event,threads,uuid)
|
||||
-- cant be used V
|
||||
--Server.add_thread_handler(event)
|
||||
if not threads.events[event] then threads.events[event] = {} end
|
||||
table.insert(threads.events[event],uuid)
|
||||
end,threads,self.uuid)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
--- Inverse of thread:open() - it removes the thread and calles on_close
|
||||
-- @usage thread:close() -- return true
|
||||
-- @treturn bolean if the thread had a on_close function
|
||||
function Server._thread:close()
|
||||
local threads = Server._threads()
|
||||
local uuid = self.uuid
|
||||
local _return = false
|
||||
if is_type(self._close,'function') then pcall(self._close,self) _return = true end
|
||||
local value,key = table.find(threads.queue,function(v,k,uuid) return v == uuid end,uuid)
|
||||
if key then table.remove(threads.queue,key) end
|
||||
local value,key = table.find(threads.timeout,function(v,k,uuid) return v == uuid end,uuid)
|
||||
if key then table.remove(threads.timeout,key) end
|
||||
local value,key = table.find(threads.tick,function(v,k,uuid) return v == uuid end,uuid)
|
||||
if key then table.remove(threads.tick,key) end
|
||||
if is_type(self._events,'table') then
|
||||
table.each(self._events,function(callback,event)
|
||||
if threads.events[event] then
|
||||
local value,key = table.find(threads.events[event],function(v,k,uuid) return v == uuid end,uuid)
|
||||
if key then table.remove(threads.events[event],key) end
|
||||
-- cant be used V
|
||||
--if #threads.events[event] == 0 then Event.remove(event,Server.game_event) threads.events[event] = nil end
|
||||
end
|
||||
end)
|
||||
end
|
||||
if is_type(self.name,'string') then threads.paused[self.name] = self.uuid self.opened = nil
|
||||
else threads.all[uuid] = nil threads.all._n = threads.all._n-1 end
|
||||
return _return
|
||||
end
|
||||
|
||||
--- Trigger the on_resolve function and closes the thread - error and success called based on result of pcall (useful for async)
|
||||
-- @usage thread:resolve(x,y,z) -- return true
|
||||
-- @param[opt] ... any arguments you want to pass to the resolve function
|
||||
-- @treturn bolean true if the thread called on_success or on_error
|
||||
function Server._thread:resolve(...)
|
||||
local _return = false
|
||||
if is_type(self._resolve,'function') then
|
||||
local success, err = pcall(self._resolve,self,...)
|
||||
if success then
|
||||
if is_type(self._success,'function') then
|
||||
Server.interface(function(thread,err)
|
||||
local success,err = pcall(thread._success,thread,err)
|
||||
if not success then thread:error(err) end
|
||||
end,true,self,err)
|
||||
_return = true
|
||||
end
|
||||
else
|
||||
_return = self:error(err)
|
||||
end
|
||||
end
|
||||
self:close()
|
||||
return _return
|
||||
end
|
||||
|
||||
--- Checks the timeout on a thread - if timedout then it calles on_timeout and closes
|
||||
-- @usage thread:check_timeout() -- return true
|
||||
-- @treturn bolean if the thread timedout
|
||||
function Server._thread:check_timeout()
|
||||
local _return = false
|
||||
if not self:valid() then return false end
|
||||
if is_type(self.timeout,'number') and game.tick >= (self.opened+self.timeout) then
|
||||
if is_type(self._timeout,'function') then
|
||||
pcall(self._timeout,self)
|
||||
end
|
||||
_return = true
|
||||
self:close()
|
||||
end
|
||||
return _return
|
||||
end
|
||||
|
||||
--- Rasies an error on this thread
|
||||
-- @usage thread:error(err) -- return true
|
||||
-- @param err the err to be rasied
|
||||
-- @treturn bolean did the thread handdle the error
|
||||
function Server._thread:error(err)
|
||||
local _return = false
|
||||
if is_type(self._error,'function') then
|
||||
pcall(self._error,self,err)
|
||||
_return = true
|
||||
else
|
||||
error(err)
|
||||
end
|
||||
return _return
|
||||
end
|
||||
--- Set function to run then an event is called on a thread, none of them are 'needed' but you are advised to have atleast one
|
||||
-- @usage thread:on_event('close',function) -- return true
|
||||
-- events = ['close','timeout','tick','resolve','success','error']
|
||||
-- if event is a number then it is asumed to be a game event
|
||||
-- @tparam string event the name of the event that it is called on
|
||||
-- @tparam function callback the function which is called on the event
|
||||
-- @treturn table returns self so that there can be chained
|
||||
function Server._thread:on_event(event,callback)
|
||||
local events = {'close','timeout','tick','resolve','success','error'}
|
||||
local value = table.find(events,function(v,k,find) return v == string.lower(find) end,event)
|
||||
if value and is_type(callback,'function') then
|
||||
self['_'..value] = callback
|
||||
elseif is_type(event,'number') and is_type(callback,'function') then
|
||||
if not self._events then self._events = {} end
|
||||
self._events[event] = callback
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
Event.register(defines.events.on_tick,function(event)
|
||||
local threads = Server._threads()
|
||||
if #threads.tick > 0 then Server.run_tick_threads() end
|
||||
if #threads.timeout > 0 then Server.check_timeouts() end
|
||||
if #threads.queue > 0 then
|
||||
local current_thread = threads.all[threads.queue[1]]
|
||||
if current_thread and current_thread:valid() then current_thread:resolve() end
|
||||
end
|
||||
end)
|
||||
|
||||
Event.register(-2,function(event)
|
||||
local threads = Server.threads()
|
||||
for uuid,thread in pairs(threads) do
|
||||
if uuid ~= '_n' then setmetatable(thread,{__index=Server._thread}) end
|
||||
end
|
||||
end)
|
||||
|
||||
return Server
|
||||
--[[
|
||||
Thread Example:
|
||||
|
||||
local thread = Server.new_thread{name='tree-decon',data={}}
|
||||
-- user thread:on_event('tick') rather than thread:on_event(defines.events.on_tick) as it makes less lag
|
||||
thread:on_event('tick',function(self)
|
||||
local trees = self.data
|
||||
if #trees == 0 then return end
|
||||
local tree = table.remove(trees,1)
|
||||
if tree.valid then tree.destroy() end
|
||||
end)
|
||||
thread:on_event('error',function(self,err)
|
||||
-- cant see how this can cause an error
|
||||
-- but this is where error handling goes
|
||||
-- any event including on_resolve and on_tick can raise this
|
||||
end)
|
||||
thread:on_event(defines.events.on_marked_for_deconstruction,function(self,event)
|
||||
if event.entity.type == 'tree' then
|
||||
table.insert(self.data,event.entity)
|
||||
end
|
||||
end)
|
||||
thread:open()
|
||||
|
||||
local thread = Server.new_thread{name='print-place',data={}}
|
||||
thread:on_event(defines.events.on_built_entity,function(self,event)
|
||||
game.print('Events')
|
||||
end)
|
||||
thread:open()
|
||||
|
||||
all on_event functions can be chained from the thread creation rather than use varibles
|
||||
]]
|
||||
@@ -1,314 +0,0 @@
|
||||
--- A defines module for retrieving colors by name.
|
||||
-- Extends the Factorio defines table.
|
||||
-- @usage require('stdlib/defines/color')
|
||||
-- @module defines.color
|
||||
-- @see Concepts.Color
|
||||
|
||||
-- defines table is automatically required in all mod loading stages.
|
||||
-- luacheck: ignore 122/defines
|
||||
-- Ignore assigning to read only defines table. defines table is not ready only, however
|
||||
-- marking it this way allows warnings to be generated when trying to assign values
|
||||
|
||||
defines = defines or {} --luacheck: ignore defines (This is used for testing locally)
|
||||
|
||||
--- A table of colors allowing retrieval by color name.
|
||||
-- @usage color = defines.color.red
|
||||
-- @tfield Concepts.Color white
|
||||
-- @tfield Concepts.Color black
|
||||
-- @tfield Concepts.Color darkgrey
|
||||
-- @tfield Concepts.Color grey
|
||||
-- @tfield Concepts.Color lightgrey
|
||||
-- @tfield Concepts.Color red
|
||||
-- @tfield Concepts.Color darkred
|
||||
-- @tfield Concepts.Color lightred
|
||||
-- @tfield Concepts.Color green
|
||||
-- @tfield Concepts.Color darkgreen
|
||||
-- @tfield Concepts.Color lightgreen
|
||||
-- @tfield Concepts.Color blue
|
||||
-- @tfield Concepts.Color darkblue
|
||||
-- @tfield Concepts.Color lightblue
|
||||
-- @tfield Concepts.Color orange
|
||||
-- @tfield Concepts.Color yellow
|
||||
-- @tfield Concepts.Color pink
|
||||
-- @tfield Concepts.Color purple
|
||||
-- @tfield Concepts.Color brown
|
||||
defines.color = {}
|
||||
|
||||
local colors = {
|
||||
white = {r = 1.00, g = 1.00, b = 1.00},
|
||||
black = {r = 0.00, g = 0.00, b = 0.00},
|
||||
darkgrey = {r = 0.25, g = 0.25, b = 0.25},
|
||||
grey = {r = 0.50, g = 0.50, b = 0.50},
|
||||
lightgrey = {r = 0.75, g = 0.75, b = 0.75},
|
||||
red = {r = 1.00, g = 0.00, b = 0.00},
|
||||
darkred = {r = 0.50, g = 0.00, b = 0.00},
|
||||
lightred = {r = 1.00, g = 0.50, b = 0.50},
|
||||
green = {r = 0.00, g = 1.00, b = 0.00},
|
||||
darkgreen = {r = 0.00, g = 0.50, b = 0.00},
|
||||
lightgreen = {r = 0.50, g = 1.00, b = 0.50},
|
||||
blue = {r = 0.00, g = 0.00, b = 1.00},
|
||||
darkblue = {r = 0.00, g = 0.00, b = 0.50},
|
||||
lightblue = {r = 0.50, g = 0.50, b = 1.00},
|
||||
orange = {r = 1.00, g = 0.55, b = 0.10},
|
||||
yellow = {r = 1.00, g = 1.00, b = 0.00},
|
||||
pink = {r = 1.00, g = 0.00, b = 1.00},
|
||||
purple = {r = 0.60, g = 0.10, b = 0.60},
|
||||
brown = {r = 0.60, g = 0.40, b = 0.10}
|
||||
}
|
||||
|
||||
--- Returns white for dark colors or black for lighter colors.
|
||||
-- @tfield Concepts.Color green defines.color.black
|
||||
-- @tfield Concepts.Color grey defines.color.black
|
||||
-- @tfield Concepts.Color lightblue defines.color.black
|
||||
-- @tfield Concepts.Color lightgreen defines.color.black
|
||||
-- @tfield Concepts.Color lightgrey defines.color.black
|
||||
-- @tfield Concepts.Color lightred defines.color.black
|
||||
-- @tfield Concepts.Color orange defines.color.black
|
||||
-- @tfield Concepts.Color white defines.color.black
|
||||
-- @tfield Concepts.Color yellow defines.color.black
|
||||
-- @tfield Concepts.Color black defines.color.white
|
||||
-- @tfield Concepts.Color blue defines.color.white
|
||||
-- @tfield Concepts.Color brown defines.color.white
|
||||
-- @tfield Concepts.Color darkblue defines.color.white
|
||||
-- @tfield Concepts.Color darkgreen defines.color.white
|
||||
-- @tfield Concepts.Color darkgrey defines.color.white
|
||||
-- @tfield Concepts.Color darkred defines.color.white
|
||||
-- @tfield Concepts.Color pink defines.color.white
|
||||
-- @tfield Concepts.Color purple defines.color.white
|
||||
-- @tfield Concepts.Color red defines.color.white
|
||||
defines.anticolor = {}
|
||||
|
||||
local anticolors = {
|
||||
green = colors.black,
|
||||
grey = colors.black,
|
||||
lightblue = colors.black,
|
||||
lightgreen = colors.black,
|
||||
lightgrey = colors.black,
|
||||
lightred = colors.black,
|
||||
orange = colors.black,
|
||||
white = colors.black,
|
||||
yellow = colors.black,
|
||||
black = colors.white,
|
||||
blue = colors.white,
|
||||
brown = colors.white,
|
||||
darkblue = colors.white,
|
||||
darkgreen = colors.white,
|
||||
darkgrey = colors.white,
|
||||
darkred = colors.white,
|
||||
pink = colors.white,
|
||||
purple = colors.white,
|
||||
red = colors.white
|
||||
}
|
||||
|
||||
--- Returns a lighter color of a named color.
|
||||
-- @tfield Concepts.Color white defines.color.lightgrey
|
||||
-- @tfield Concepts.Color grey defines.color.darkgrey
|
||||
-- @tfield Concepts.Color lightgrey defines.color.grey
|
||||
-- @tfield Concepts.Color red defines.color.lightred
|
||||
-- @tfield Concepts.Color green defines.color.lightgreen
|
||||
-- @tfield Concepts.Color blue defines.color.lightblue
|
||||
-- @tfield Concepts.Color yellow defines.color.orange
|
||||
-- @tfield Concepts.Color pink defines.color.purple
|
||||
defines.lightcolor = {}
|
||||
local lightcolors = {
|
||||
white = colors.lightgrey,
|
||||
grey = colors.darkgrey,
|
||||
lightgrey = colors.grey,
|
||||
red = colors.lightred,
|
||||
green = colors.lightgreen,
|
||||
blue = colors.lightblue,
|
||||
yellow = colors.orange,
|
||||
pink = colors.purple
|
||||
}
|
||||
|
||||
-- added by cooldude2606
|
||||
--- Returns a lighter color of a named color.
|
||||
-- @tfield Concepts.Color info
|
||||
-- @tfield Concepts.Color bg
|
||||
-- @tfield Concepts.Color low
|
||||
-- @tfield Concepts.Color med
|
||||
-- @tfield Concepts.Color high
|
||||
-- @tfield Concepts.Color crit
|
||||
defines.text_color = {}
|
||||
local text_color = {
|
||||
info = {r = 0.21, g = 0.95, b = 1.00},
|
||||
bg = {r = 0.00, g = 0.00, b = 0.00},
|
||||
low = {r = 0.18, g = 0.77, b = 0.18},
|
||||
med = {r = 1.00, g = 0.89, b = 0.26},
|
||||
high = {r = 1.00, g = 0.33, b = 0.00},
|
||||
crit = {r = 1.00, g = 0.00, b = 0.00}
|
||||
}
|
||||
|
||||
local _mt = {
|
||||
color = {
|
||||
__index = function(_, c)
|
||||
return colors[c]
|
||||
and { r = colors[c]['r'], g=colors[c]['g'], b=colors[c]['b'], a = colors[c]['a'] }
|
||||
or { r = 1, g = 1, b = 1, a = 1 }
|
||||
end,
|
||||
__pairs = function()
|
||||
local k = nil
|
||||
local c = colors
|
||||
return function()
|
||||
local v
|
||||
k, v = next(c, k)
|
||||
return k, (v and {r = v['r'], g = v['g'], b = v['b'], a = v['a']}) or nil
|
||||
end
|
||||
end
|
||||
},
|
||||
anticolor = {
|
||||
__index = function(_, c)
|
||||
return anticolors[c]
|
||||
and { r = anticolors[c]['r'], g=anticolors[c]['g'], b=anticolors[c]['b'], a = anticolors[c]['a'] }
|
||||
or { r = 1, g = 1, b = 1, a = 1 }
|
||||
end,
|
||||
__pairs = function()
|
||||
local k = nil
|
||||
local c = anticolors
|
||||
return function()
|
||||
local v
|
||||
k, v = next(c, k)
|
||||
return k, (v and {r = v['r'], g = v['g'], b = v['b'], a = v['a']}) or nil
|
||||
end
|
||||
end
|
||||
},
|
||||
lightcolor = {
|
||||
__index = function(_, c)
|
||||
return lightcolors[c]
|
||||
and { r = lightcolors[c]['r'], g=lightcolors[c]['g'], b=lightcolors[c]['b'], a = lightcolors[c]['a'] }
|
||||
or { r = 1, g = 1, b = 1, a = 1 }
|
||||
end,
|
||||
__pairs = function()
|
||||
local k = nil
|
||||
local c = lightcolors
|
||||
return function()
|
||||
local v
|
||||
k, v = next(c, k)
|
||||
return k, (v and {r = v['r'], g = v['g'], b = v['b'], a = v['a']}) or nil
|
||||
end
|
||||
end
|
||||
},
|
||||
text_color = { -- added by cooldude2606
|
||||
__index = function(_, c)
|
||||
return text_color[c]
|
||||
and { r = text_color[c]['r'], g=text_color[c]['g'], b=text_color[c]['b'], a = text_color[c]['a'] }
|
||||
or { r = 1, g = 1, b = 1, a = 1 }
|
||||
end,
|
||||
__pairs = function()
|
||||
local k = nil
|
||||
local c = text_color
|
||||
return function()
|
||||
local v
|
||||
k, v = next(c, k)
|
||||
return k, (v and {r = v['r'], g = v['g'], b = v['b'], a = v['a']}) or nil
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
setmetatable(defines.color, _mt.color)
|
||||
setmetatable(defines.anticolor, _mt.anticolor)
|
||||
setmetatable(defines.text_color, _mt.text_color)
|
||||
setmetatable(defines.lightcolor, _mt.lightcolor)
|
||||
|
||||
--- For playing with colors.
|
||||
-- @module Color
|
||||
-- @usage local Color = require('stdlib/color/color')
|
||||
|
||||
--require 'stdlib/defines/color'
|
||||
local fail_if_missing = require 'game'['fail_if_missing']
|
||||
|
||||
local Color = {} --luacheck: allow defined top
|
||||
|
||||
--- Set a value for the alpha channel in the given color table.
|
||||
-- `color.a` represents the alpha channel in the given color table.
|
||||
-- <ul>
|
||||
-- <li>If ***alpha*** is given, set `color.a` to it.
|
||||
-- <li>If ***alpha*** is not given, and if the given color table does not have a value for `color.a`, set `color.a` to 1.
|
||||
-- <li>If ***alpha*** is not given, and if the given color table already has a value for `color.a`, then leave `color.a` alone.
|
||||
-- </ul>
|
||||
-- @tparam[opt=white] defines.color|Concepts.Color color the color to configure
|
||||
-- @tparam[opt=1] float alpha the alpha value (*[0 - 1]*) to set for the given color
|
||||
-- @treturn Concepts.Color a color table that has the specified value for the alpha channel
|
||||
function Color.set(color, alpha)
|
||||
color = color or defines.color.white
|
||||
Color.to_table(color)
|
||||
color.a = alpha or color.a or 1
|
||||
return color
|
||||
end
|
||||
|
||||
--- Converts a color in the array format to a color in the table format.
|
||||
-- @tparam array c_arr the color to convert — { [1] = @{float}, [2] = @{float}, [3] = @{float}, [4] = @{float} }
|
||||
-- @treturn Concepts.Color a converted color — { r = c\_arr[1], g = c\_arr[2], b = c\_arr[3], a = c\_arr[4] }
|
||||
function Color.to_table(c_arr)
|
||||
if #c_arr > 0 then
|
||||
return {r = c_arr[1], g = c_arr[2], b = c_arr[3], a = c_arr[4]}
|
||||
end
|
||||
return c_arr
|
||||
end
|
||||
|
||||
--- Converts a color in the rgb format to a color table
|
||||
-- @tparam[opt=0] int r 0-255 red
|
||||
-- @tparam[opt=0] int g 0-255 green
|
||||
-- @tparam[opt=0] int b 0-255 blue
|
||||
-- @tparam[opt=255] int a 0-255 alpha
|
||||
-- @treturn Concepts.Color
|
||||
function Color.from_rgb(r, g, b, a)
|
||||
r = r or 0
|
||||
g = g or 0
|
||||
b = b or 0
|
||||
a = a or 255
|
||||
return {r = r/255, g = g/255, b = b/255, a = a/255}
|
||||
end
|
||||
|
||||
--- Get a color table with a hexadecimal string.
|
||||
-- Optionally provide the value for the alpha channel.
|
||||
-- @tparam string hex hexadecimal color string (#ffffff, not #fff)
|
||||
-- @tparam[opt=1] float alpha the alpha value to set; such that ***[ 0 ⋜ value ⋜ 1 ]***
|
||||
-- @treturn Concepts.Color a color table with RGB converted from Hex and with alpha
|
||||
function Color.from_hex(hex, alpha)
|
||||
fail_if_missing(hex, "missing color hex value")
|
||||
if hex:find("#") then hex = hex:sub(2) end
|
||||
if not(#hex == 6) then error("invalid color hex value: "..hex) end
|
||||
local number = tonumber(hex, 16)
|
||||
return {
|
||||
r = bit32.extract(number, 16, 8) / 255,
|
||||
g = bit32.extract(number, 8, 8) / 255,
|
||||
b = bit32.extract(number, 0, 8) / 255,
|
||||
a = alpha or 1
|
||||
}
|
||||
end
|
||||
|
||||
--added by cooldude2606
|
||||
--- Converts a color in the color table format to rgb
|
||||
-- @tparam table color the color to convert
|
||||
-- @treturn table the color as rgb
|
||||
function Color.to_rgb(color)
|
||||
local r = color.r or 0
|
||||
local g = color.g or 0
|
||||
local b = color.b or 0
|
||||
local a = color.a or 0.5
|
||||
return {r = r*255, g = g*255, b = b*255, a = a*255}
|
||||
end
|
||||
|
||||
--added by cooldude2606
|
||||
--- Converts a color in the color table format to hex
|
||||
-- @tparam table color the color to convert
|
||||
-- @treturn string the color as hex
|
||||
function Color.to_hex(color)
|
||||
local hexadecimal = '0x'
|
||||
for key, value in pairs{math.floor(color.r*255),math.floor(color.g*255),math.floor(color.b*255)} do
|
||||
local hex = ''
|
||||
while(value > 0)do
|
||||
local index = math.fmod(value, 16) + 1
|
||||
value = math.floor(value / 16)
|
||||
hex = string.sub('0123456789ABCDEF', index, index) .. hex
|
||||
end
|
||||
if string.len(hex) == 0 then hex = '00'
|
||||
elseif string.len(hex) == 1 then hex = '0' .. hex
|
||||
end
|
||||
hexadecimal = hexadecimal .. hex
|
||||
end
|
||||
return hexadecimal
|
||||
end
|
||||
|
||||
return Color
|
||||
@@ -1,173 +0,0 @@
|
||||
--- Makes working with events in factorio a lot more simple.
|
||||
-- <p>Factorio can only have one handler registered per event. This module
|
||||
-- allows you to easily register multiple handlers for each event.
|
||||
-- Using this module is as simple as replacing script.on_event(...) with Event.register(...)</p>
|
||||
-- @module Event
|
||||
-- @usage require('stdlib/event/event')
|
||||
|
||||
local fail_if_missing = require 'game'['fail_if_missing']
|
||||
local Game = require 'game'
|
||||
|
||||
local Event = { --luacheck: allow defined top
|
||||
_registry = {},
|
||||
core_events = {
|
||||
init = -1,
|
||||
load = -2,
|
||||
configuration_changed = -3,
|
||||
_register = function(id)
|
||||
if id == Event.core_events.init then
|
||||
script.on_init(
|
||||
function()
|
||||
Event.dispatch({name = Event.core_events.init, tick = game.tick})
|
||||
end
|
||||
)
|
||||
elseif id == Event.core_events.load then
|
||||
script.on_load(
|
||||
function()
|
||||
Event.dispatch({name = Event.core_events.load, tick = -1})
|
||||
end
|
||||
)
|
||||
elseif id == Event.core_events.configuration_changed then
|
||||
script.on_configuration_changed(
|
||||
function(event)
|
||||
event.name = Event.core_events.configuration_changed
|
||||
event.data = event -- for backwards compatibilty
|
||||
Event.dispatch(event)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
--[[ edit by cooldude2606 to allow change during run-time without desyncs -- still going to use this but FACTORIO NO LIKE
|
||||
Event.__registry = Event._registry
|
||||
Event._registry = function()
|
||||
if game and global then
|
||||
if not global.event_registry then global.event_registry = Event.__registry end
|
||||
return global.event_registry
|
||||
end
|
||||
return Event.__registry
|
||||
end]]
|
||||
|
||||
--- Registers a function for a given event. If a nil handler is passed remove all events and stop listening for that event.
|
||||
-- Events are dispatched in the order they are registered.
|
||||
-- @usage Event.register(defines.events.on_tick, function(event) print event.tick end)
|
||||
-- -- creates an event that prints the current tick every tick.
|
||||
-- @tparam defines.events|{defines.events,...} event events to register
|
||||
-- @tparam function handler Function to call when event is triggered
|
||||
-- @treturn Event
|
||||
function Event.register(event, handler)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
|
||||
event = (type(event) == "table" and event) or {event}
|
||||
|
||||
for _, event_id in pairs(event) do
|
||||
if not (type(event_id) == "number" or type(event_id) == "string") then
|
||||
error("Invalid Event Id, Must be string or int, or array of strings and/or ints", 2)
|
||||
end
|
||||
if handler == nil then
|
||||
Event._registry[event_id] = nil
|
||||
script.on_event(event_id, nil)
|
||||
else
|
||||
if not Event._registry[event_id] then
|
||||
Event._registry[event_id] = {}
|
||||
|
||||
if type(event_id) == "string" or event_id >= 0 then
|
||||
script.on_event(event_id, Event.dispatch)
|
||||
elseif event_id < 0 then
|
||||
Event.core_events._register(event_id)
|
||||
end
|
||||
end
|
||||
table.insert(Event._registry[event_id], handler)
|
||||
end
|
||||
end
|
||||
return Event
|
||||
end
|
||||
|
||||
--- Calls the registerd handlers
|
||||
-- Will stop dispatching remaning handlers if any handler passes invalid event userdata.
|
||||
-- Handlers are dispatched in the order they were created
|
||||
-- @tparam table event LuaEvent as created by script.raise_event
|
||||
-- @see https://forums.factorio.com/viewtopic.php?t=32039#p202158 Invalid Event Objects
|
||||
function Event.dispatch(event)
|
||||
if event then
|
||||
local _registry = event.name and Event._registry[event.name] or event.input_name and Event._registry[event.input_name]
|
||||
if _registry then
|
||||
local force_crc = Event.force_crc
|
||||
for idx, handler in ipairs(_registry) do
|
||||
|
||||
-- Check for userdata and stop processing further handlers if not valid
|
||||
for _, val in pairs(event) do
|
||||
if type(val) == "table" and val.__self == "userdata" and not val.valid then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
setmetatable(event, { __index = { _handler = handler } })
|
||||
|
||||
-- Call the handler
|
||||
local success, err = pcall(handler, event)
|
||||
|
||||
-- If the handler errors lets make sure someone notices
|
||||
if not success then
|
||||
if _G.game then -- may be nil in on_load
|
||||
-- edit by cooldude2606 custom error haddle
|
||||
--if Game.print_all(err) == 0 then
|
||||
--error(err) -- no players received the message, force a real error so someone notices
|
||||
--end
|
||||
error(err)
|
||||
else
|
||||
error(err) -- no way to handle errors cleanly when the game is not up
|
||||
end
|
||||
-- continue processing the remaning handlers. In most cases they won't be related to the failed code.
|
||||
end
|
||||
|
||||
-- force a crc check if option is enabled. This is a debug option and will hamper perfomance if enabled
|
||||
if (force_crc or event.force_crc) and _G.game then
|
||||
local msg = 'CRC check called for event '..event.name..' handler #'..idx
|
||||
log(msg) -- log the message to factorio-current.log
|
||||
game.force_crc()
|
||||
end
|
||||
|
||||
-- if present stop further handlers for this event
|
||||
if event.stop_processing then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
error('missing event argument')
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the handler from the event. If it removes the last handler for an event stop listening for that event.
|
||||
-- @tparam defines.events|{defines.events,...} event events to remove the handler for
|
||||
-- @tparam function handler to remove
|
||||
-- @return Event
|
||||
function Event.remove(event, handler)
|
||||
fail_if_missing(event, "missing event argument")
|
||||
fail_if_missing(handler, "missing handler argument")
|
||||
|
||||
event = (type(event) == "table" and event) or {event}
|
||||
|
||||
for _, event_id in pairs(event) do
|
||||
if not (type(event_id) == "number" or type(event_id) == "string") then
|
||||
error("Invalid Event Id, Must be string or int, or array of strings and/or ints", 2)
|
||||
end
|
||||
if Event._registry[event_id] then
|
||||
for i=#Event._registry[event_id], 1, -1 do
|
||||
if Event._registry[event_id][i] == handler then
|
||||
table.remove(Event._registry[event_id], i)
|
||||
end
|
||||
end
|
||||
if #Event._registry[event_id] == 0 then
|
||||
Event._registry[event_id] = nil
|
||||
script.on_event(event_id, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
return Event
|
||||
end
|
||||
|
||||
return Event
|
||||
@@ -1,103 +0,0 @@
|
||||
--- The game module.
|
||||
-- @module Game
|
||||
-- @usage local Game = require('stdlib/game')
|
||||
|
||||
local Game = { --luacheck: allow defined top
|
||||
VALID_FILTER = function(v)
|
||||
return v and v.valid
|
||||
end,
|
||||
_protect = function(module_name)
|
||||
return {
|
||||
__newindex = function() error("Attempt to mutatate read-only "..module_name.." Module") end,
|
||||
__metatable = true
|
||||
}
|
||||
end,
|
||||
_concat = function(lhs, rhs)
|
||||
--Sanatize to remove address
|
||||
return tostring(lhs):gsub("(%w+)%: %x+", "%1: (ADDR)") .. tostring(rhs):gsub("(%w+)%: %x+", "%1: (ADDR)")
|
||||
end,
|
||||
_rawstring = function (t)
|
||||
local m = getmetatable(t)
|
||||
local f = m.__tostring
|
||||
m.__tostring = nil
|
||||
local s = tostring(t)
|
||||
m.__tostring = f
|
||||
return s
|
||||
end
|
||||
}
|
||||
|
||||
-- No Doc
|
||||
-- This is a helper global and functions until .16
|
||||
-- to set the name of your mod in control.lua set _stdlib_mod_name = 'name of your mod'
|
||||
-- luacheck: ignore _stdlib_mod_name
|
||||
function Game.get_mod_name()
|
||||
local ok, mod_name = pcall(function() return script.mod_name end)
|
||||
return ok and mod_name or _stdlib_mod_name or "stdlib"
|
||||
end
|
||||
|
||||
--- Print msg if specified var evaluates to false.
|
||||
-- @tparam Mixed var variable to evaluate
|
||||
-- @tparam[opt="missing value"] string msg message
|
||||
function Game.fail_if_missing(var, msg)
|
||||
if not var then
|
||||
error(msg or "Missing value", 3)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
--- Return a valid player object from event, index, string, or userdata
|
||||
-- @tparam string|number|LuaPlayer|event mixed
|
||||
-- @treturn LuaPlayer a valid player or nil
|
||||
function Game.get_player(mixed)
|
||||
if type(mixed) == "table" then
|
||||
if mixed.__self then
|
||||
return mixed and mixed.valid and mixed
|
||||
elseif mixed.player_index then
|
||||
local player = game.players[mixed.player_index]
|
||||
return player and player.valid and player
|
||||
end
|
||||
elseif mixed then
|
||||
local player = game.players[mixed]
|
||||
return player and player.valid and player
|
||||
end
|
||||
end
|
||||
|
||||
--- Return a valid force object from event, string, or userdata
|
||||
-- @tparam string|LuaForce|event mixed
|
||||
-- @treturn LuaForce a valid force or nil
|
||||
function Game.get_force(mixed)
|
||||
if type(mixed) == "table" then
|
||||
if mixed.__self then
|
||||
return mixed and mixed.valid and mixed
|
||||
elseif mixed.force then
|
||||
return Game.get_force(mixed.force)
|
||||
end
|
||||
elseif type(mixed) == "string" then
|
||||
local force = game.forces[mixed]
|
||||
return (force and force.valid) and force
|
||||
end
|
||||
end
|
||||
|
||||
--- Messages all players currently connected to the game.
|
||||
--> Offline players are not counted as having received the message.
|
||||
-- If no players exist msg is stored in the `global._print_queue` table.
|
||||
-- @tparam string msg the message to send to players
|
||||
-- @tparam[opt] ?|nil|boolean condition the condition to be true for a player to be messaged
|
||||
-- @treturn uint the number of players who received the message.
|
||||
function Game.print_all(msg, condition)
|
||||
local num = 0
|
||||
if #game.players > 0 then
|
||||
for _, player in pairs(game.players) do
|
||||
if condition == nil or select(2, pcall(condition, player)) then
|
||||
player.print(msg)
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
return num
|
||||
else
|
||||
global._print_queue = global._print_queue or {}
|
||||
global._print_queue[#global._print_queue + 1] = msg
|
||||
end
|
||||
end
|
||||
|
||||
return Game
|
||||
@@ -1,35 +0,0 @@
|
||||
--[[
|
||||
Explosive Gaming
|
||||
|
||||
This file can be used with permission but this and the credit below must remain in the file.
|
||||
Contact a member of management on our discord to seek permission to use our code.
|
||||
Any changes that you may make to the code are yours but that does not make the script yours.
|
||||
Discord: https://discord.gg/r6dC2uK
|
||||
]]
|
||||
|
||||
--[[
|
||||
StdLib
|
||||
|
||||
This file allow you to only require this one file to return the diffent libarys.
|
||||
This file will return a function which can be used to access only the part you want.
|
||||
Pass a table with the names of the objects you want and it will be return in that order
|
||||
]]
|
||||
|
||||
local StdLib = {}
|
||||
|
||||
require '/table'
|
||||
require '/string'
|
||||
require '/time'
|
||||
StdLib.Color = require '/color'
|
||||
StdLib.Game = require '/game'
|
||||
StdLib.Event = require '/event'
|
||||
|
||||
return function(rtn)
|
||||
local _return = {}
|
||||
for _,name in pairs(rtn) do
|
||||
if StdLib[name] then
|
||||
table.insert(_return,StdLib[name])
|
||||
end
|
||||
end
|
||||
return unpack(_return)
|
||||
end
|
||||
@@ -1,86 +0,0 @@
|
||||
--- Extends Lua 5.2 string.
|
||||
-- @module string
|
||||
-- @see string
|
||||
|
||||
-- luacheck: globals string (Allow mutating string)
|
||||
|
||||
--- Returns a copy of the string with any leading or trailing whitespace from the string removed.
|
||||
-- @tparam string s the string to remove leading or trailing whitespace from
|
||||
-- @treturn string a copy of the string without leading or trailing whitespace
|
||||
function string.trim(s)
|
||||
return (s:gsub("^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
--- Tests if a string starts with a given substring.
|
||||
-- @tparam string s the string to check for the start substring
|
||||
-- @tparam string start the substring to test for
|
||||
-- @treturn boolean true if the start substring was found in the string
|
||||
function string.starts_with(s, start)
|
||||
return string.find(s, start, 1, true) == 1
|
||||
end
|
||||
|
||||
--- Tests if a string ends with a given substring.
|
||||
-- @tparam string s the string to check for the end substring
|
||||
-- @tparam string ends the substring to test for
|
||||
-- @treturn boolean true if the end substring was found in the string
|
||||
function string.ends_with(s, ends)
|
||||
return #s >= #ends and string.find(s, ends, #s - #ends + 1, true) and true or false
|
||||
end
|
||||
|
||||
--- Tests if a string contains a given substring.
|
||||
-- @tparam string s the string to check for the substring
|
||||
-- @tparam string contains the substring to test for
|
||||
-- @treturn boolean true if the substring was found in the string
|
||||
function string.contains(s, contains)
|
||||
return s and string.find(s, contains) ~= nil
|
||||
end
|
||||
|
||||
--- Tests whether a string is empty.
|
||||
-- @tparam string s the string to test
|
||||
-- @treturn boolean true if the string is empty
|
||||
function string.is_empty(s)
|
||||
return s == nil or s == ''
|
||||
end
|
||||
|
||||
--- Splits a string into an array.
|
||||
-- *Note:* Empty split substrings are not included in the resulting table.
|
||||
-- <p>For example, `string.split("foo.bar...", ".", false)` results in the table `{"foo", "bar"}`.
|
||||
-- @tparam string s the string to split
|
||||
-- @tparam[opt="."] string sep the separator to use.
|
||||
-- @tparam[opt=false] boolean pattern whether to interpret the separator as a lua pattern or plaintext for the string split
|
||||
-- @treturn {string,...} an array of strings
|
||||
function string.split(s, sep, pattern)
|
||||
sep = sep or "."
|
||||
sep = sep ~= "" and sep or "."
|
||||
sep = not pattern and string.gsub(sep, "([^%w])", "%%%1") or sep
|
||||
|
||||
local fields = {}
|
||||
local start_idx, end_idx = string.find(s, sep)
|
||||
local last_find = 1
|
||||
while start_idx do
|
||||
local substr = string.sub(s, last_find, start_idx - 1)
|
||||
if string.len(substr) > 0 then
|
||||
table.insert(fields, string.sub(s, last_find, start_idx - 1))
|
||||
end
|
||||
last_find = end_idx + 1
|
||||
start_idx, end_idx = string.find(s, sep, end_idx + 1)
|
||||
end
|
||||
local substr = string.sub(s, last_find)
|
||||
if string.len(substr) > 0 then
|
||||
table.insert(fields, string.sub(s, last_find))
|
||||
end
|
||||
return fields
|
||||
end
|
||||
|
||||
-- added by cooldude2606
|
||||
--- Returns a string as a hex format (also a string)
|
||||
-- @usage a = 'foo'
|
||||
-- string.to_hex(a) -- return '666f6f'
|
||||
-- @tparam string str the string to encode
|
||||
-- @treturn string the hex format of the string
|
||||
function string.to_hex(str)
|
||||
if not is_type(str,'string') then return '' end
|
||||
return str:gsub('.',function (c)
|
||||
return string.format('%02X',string.byte(c))
|
||||
end)
|
||||
end
|
||||
@@ -1,497 +0,0 @@
|
||||
--- Extends Lua 5.2 table.
|
||||
-- @module table
|
||||
-- @see table
|
||||
|
||||
-- luacheck: globals table (Allow mutating global table)
|
||||
|
||||
--- Given a mapping function, creates a transformed copy of the table
|
||||
--- by calling the function for each element in the table, and using
|
||||
--- the result as the new value for the key. Passes the index as second argument to the function.
|
||||
--- @usage a= { 1, 2, 3, 4, 5}
|
||||
---table.map(a, function(v) return v * 10 end) --produces: { 10, 20, 30, 40, 50 }
|
||||
--- @usage a = {1, 2, 3, 4, 5}
|
||||
---table.map(a, function(v, k, x) return v * k + x end, 100) --produces { 101, 104, 109, 116, 125}
|
||||
-- @tparam table tbl the table to be mapped to the transform
|
||||
-- @tparam function func the function to transform values
|
||||
-- @param[opt] ... additional arguments passed to the function
|
||||
-- @treturn table a new table containing the keys and mapped values
|
||||
function table.map(tbl, func, ...)
|
||||
local newtbl = {}
|
||||
for i, v in pairs(tbl) do
|
||||
newtbl[i] = func(v, i, ...)
|
||||
end
|
||||
return newtbl
|
||||
end
|
||||
|
||||
--- Given a filter function, creates a filtered copy of the table
|
||||
--- by calling the function for each element in the table, and
|
||||
--- filtering out any key-value pairs for non-true results. Passes the index as second argument to the function.
|
||||
--- @usage a= { 1, 2, 3, 4, 5}
|
||||
---table.filter(a, function(v) return v % 2 == 0 end) --produces: { 2, 4 }
|
||||
--- @usage a = {1, 2, 3, 4, 5}
|
||||
---table.filter(a, function(v, k, x) return k % 2 == 1 end) --produces: { 1, 3, 5 }
|
||||
-- @tparam table tbl the table to be filtered
|
||||
-- @tparam function func the function to filter values
|
||||
-- @param[opt] ... additional arguments passed to the function
|
||||
-- @treturn table a new table containing the filtered key-value pairs
|
||||
function table.filter(tbl, func, ...)
|
||||
local newtbl = {}
|
||||
local insert = #tbl > 0
|
||||
for k, v in pairs(tbl) do
|
||||
if func(v, k, ...) then
|
||||
if insert then table.insert(newtbl, v)
|
||||
else newtbl[k] = v end
|
||||
end
|
||||
end
|
||||
return newtbl
|
||||
end
|
||||
|
||||
--- Given a candidate search function, iterates over the table, calling the function
|
||||
--- for each element in the table, and returns the first element the search function returned true.
|
||||
--- Passes the index as second argument to the function.
|
||||
--- @usage a= { 1, 2, 3, 4, 5}
|
||||
---table.find(a, function(v) return v % 2 == 0 end) --produces: 2
|
||||
--- @usage a = {1, 2, 3, 4, 5}
|
||||
---table.find(a, function(v, k, x) return k % 2 == 1 end) --produces: 1
|
||||
-- @tparam table tbl the table to be searched
|
||||
-- @tparam function func the function to use to search for any matching element
|
||||
-- @param[opt] ... additional arguments passed to the function
|
||||
-- @treturn ?|nil|Mixed the first found value, or nil if none was found
|
||||
function table.find(tbl, func, ...)
|
||||
for k, v in pairs(tbl) do
|
||||
if func(v, k, ...) then
|
||||
return v, k
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Given a candidate search function, iterates over the table, calling the function
|
||||
-- for each element in the table, and returns true if search function returned true.
|
||||
-- Passes the index as second argument to the function.
|
||||
-- @see table.find
|
||||
--- @usage a= { 1, 2, 3, 4, 5}
|
||||
---table.any(a, function(v) return v % 2 == 0 end) --produces: true
|
||||
--- @usage a = {1, 2, 3, 4, 5}
|
||||
---table.any(a, function(v, k, x) return k % 2 == 1 end) --produces: true
|
||||
-- @tparam table tbl the table to be searched
|
||||
-- @tparam function func the function to use to search for any matching element
|
||||
-- @param[opt] ... additional arguments passed to the function
|
||||
-- @treturn boolean true if an element was found, false if none was found
|
||||
function table.any(tbl, func, ...)
|
||||
return table.find(tbl, func, ...) ~= nil
|
||||
end
|
||||
|
||||
--- Given a function, apply it to each element in the table.
|
||||
-- Passes the index as the second argument to the function.
|
||||
-- <p>Iteration is aborted if the applied function returns true for any element during iteration.
|
||||
-- @usage
|
||||
-- a = {10, 20, 30, 40}
|
||||
-- table.each(a, function(v) game.print(v) end) --prints 10, 20, 30, 40, 50
|
||||
-- @tparam table tbl the table to be iterated
|
||||
-- @tparam function func the function to apply to elements
|
||||
-- @param[opt] ... additional arguments passed to the function
|
||||
-- @treturn table the table where the given function has been applied to its elements
|
||||
function table.each(tbl, func, ...)
|
||||
for k, v in pairs(tbl) do
|
||||
if func(v, k, ...) then
|
||||
break
|
||||
end
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
--- Returns a new array that is a one-dimensional recursive flattening of the given array.
|
||||
-- For every element that is an array, extract its elements into the new array.
|
||||
-- <p>The optional level argument determines the level of recursion to flatten.
|
||||
--> This function flattens an integer-indexed array, but not an associative array.
|
||||
-- @tparam array tbl the array to be flattened
|
||||
-- @tparam[opt] uint level recursive levels, or no limit to recursion if not supplied
|
||||
-- @treturn array a new array that represents the flattened contents of the given array
|
||||
function table.flatten(tbl, level)
|
||||
local flattened = {}
|
||||
table.each(tbl,
|
||||
function(value)
|
||||
if type(value) == "table" and #value > 0 then
|
||||
if level then
|
||||
if level > 0 then
|
||||
table.merge(flattened, table.flatten(value, level - 1), true)
|
||||
else
|
||||
table.insert(flattened, value)
|
||||
end
|
||||
else
|
||||
table.merge(flattened, table.flatten(value), true)
|
||||
end
|
||||
else
|
||||
table.insert(flattened, value)
|
||||
end
|
||||
end
|
||||
)
|
||||
return flattened
|
||||
end
|
||||
|
||||
--- Given an array, returns the first element or nil if no element exists.
|
||||
-- @tparam array tbl the array
|
||||
-- @treturn ?|nil|Mixed the first element
|
||||
function table.first(tbl)
|
||||
return tbl[1]
|
||||
end
|
||||
|
||||
--- Given an array, returns the last element or nil if no elements exist.
|
||||
-- @tparam array tbl the array
|
||||
-- @treturn ?|nil|Mixed the last element or nil
|
||||
function table.last(tbl)
|
||||
local size = #tbl
|
||||
if size == 0 then return nil end
|
||||
return tbl[size]
|
||||
end
|
||||
|
||||
--- Given an array of only numeric values, returns the minimum or nil if no element exists.
|
||||
-- @tparam {number,...} tbl the array with only numeric values
|
||||
-- @treturn ?|nil|number the minimum value
|
||||
function table.min(tbl)
|
||||
if #tbl == 0 then return nil end
|
||||
|
||||
local min = tbl[1]
|
||||
for _, num in pairs(tbl) do
|
||||
min = num < min and num or min
|
||||
end
|
||||
return min
|
||||
end
|
||||
|
||||
---Given an array of only numeric values, returns the maximum or nil if no element exists.
|
||||
-- @tparam {number,...} tbl the array with only numeric values
|
||||
-- @treturn ?|nil|number the maximum value
|
||||
function table.max(tbl)
|
||||
if #tbl == 0 then return nil end
|
||||
|
||||
local max = tbl[1]
|
||||
for _, num in pairs(tbl) do
|
||||
max = num > max and num or max
|
||||
end
|
||||
return max
|
||||
end
|
||||
|
||||
--- Given an array of only numeric values, return the sum of all values, or 0 for empty arrays.
|
||||
-- @tparam {number,...} tbl the array with only numeric values
|
||||
-- @treturn number the sum of the numbers or zero if the given array was empty
|
||||
function table.sum(tbl)
|
||||
local sum = 0
|
||||
for _, num in pairs(tbl) do
|
||||
sum = sum + num
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
--- Given an array of only numeric values, returns the average or nil if no element exists.
|
||||
-- @tparam {number,...} tbl the array with only numeric values
|
||||
-- @treturn ?|nil|number the average value
|
||||
function table.avg(tbl)
|
||||
local cnt = #tbl
|
||||
return cnt ~= 0 and table.sum(tbl) / cnt or nil
|
||||
end
|
||||
|
||||
--- Merges two tables — values from first get overwritten by the second.
|
||||
--- @usage
|
||||
-- function some_func(x, y, args)
|
||||
-- args = table.merge({option1=false}, args)
|
||||
-- if opts.option1 == true then return x else return y end
|
||||
-- end
|
||||
-- some_func(1,2) -- returns 2
|
||||
-- some_func(1,2,{option1=true}) -- returns 1
|
||||
-- @tparam table tblA first table
|
||||
-- @tparam table tblB second table
|
||||
-- @tparam[opt=false] boolean array_merge set to true to merge the tables as an array or false for an associative array
|
||||
-- @treturn array|table an array or an associated array where tblA and tblB have been merged
|
||||
function table.merge(tblA, tblB, array_merge)
|
||||
if not tblB then
|
||||
return tblA
|
||||
end
|
||||
if array_merge then
|
||||
for _, v in pairs(tblB) do
|
||||
table.insert(tblA, v)
|
||||
end
|
||||
|
||||
else
|
||||
for k, v in pairs(tblB) do
|
||||
tblA[k] = v
|
||||
end
|
||||
end
|
||||
return tblA
|
||||
end
|
||||
|
||||
-- copied from factorio/data/core/luablib/util.lua
|
||||
|
||||
--- Creates a deep copy of table without copying Factorio objects.
|
||||
-- @usage local copy = table.deepcopy[data.raw.["stone-furnace"]["stone-furnace"]] -- returns a copy of the stone furnace entity
|
||||
-- @tparam table object the table to copy
|
||||
-- @treturn table a copy of the table
|
||||
function table.deepcopy(object)
|
||||
local lookup_table = {}
|
||||
local function _copy(this_object)
|
||||
if type(this_object) ~= "table" then
|
||||
return this_object
|
||||
elseif this_object.__self then
|
||||
return this_object
|
||||
elseif lookup_table[this_object] then
|
||||
return lookup_table[this_object]
|
||||
end
|
||||
local new_table = {}
|
||||
lookup_table[this_object] = new_table
|
||||
for index, value in pairs(this_object) do
|
||||
new_table[_copy(index)] = _copy(value)
|
||||
end
|
||||
return setmetatable(new_table, getmetatable(this_object))
|
||||
end
|
||||
return _copy(object)
|
||||
end
|
||||
|
||||
--- Returns a copy of all of the values in the table.
|
||||
-- @tparam table tbl the table to copy the keys from, or an empty table if tbl is nil
|
||||
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
|
||||
-- @tparam[opt] boolean as_string whether to try and parse the values as strings, or leave them as their existing type
|
||||
-- @treturn array an array with a copy of all the values in the table
|
||||
function table.values(tbl, sorted, as_string)
|
||||
if not tbl then return {} end
|
||||
local valueset = {}
|
||||
local n = 0
|
||||
if as_string then --checking as_string /before/ looping is faster
|
||||
for _, v in pairs(tbl) do
|
||||
n = n + 1
|
||||
valueset[n] = tostring(v)
|
||||
end
|
||||
else
|
||||
for _, v in pairs(tbl) do
|
||||
n = n + 1
|
||||
valueset[n] = v
|
||||
end
|
||||
end
|
||||
if sorted then
|
||||
table.sort(valueset,
|
||||
function(x, y) --sorts tables with mixed index types.
|
||||
local tx = type(x) == 'number'
|
||||
local ty = type(y) == 'number'
|
||||
if tx == ty then
|
||||
return x < y and true or false --similar type can be compared
|
||||
elseif tx == true then
|
||||
return true --only x is a number and goes first
|
||||
else
|
||||
return false --only y is a number and goes first
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
return valueset
|
||||
end
|
||||
|
||||
--- Returns a copy of all of the keys in the table.
|
||||
-- @tparam table tbl the table to copy the keys from, or an empty table if tbl is nil
|
||||
-- @tparam[opt] boolean sorted whether to sort the keys (slower) or keep the random order from pairs()
|
||||
-- @tparam[opt] boolean as_string whether to try and parse the keys as strings, or leave them as their existing type
|
||||
-- @treturn array an array with a copy of all the keys in the table
|
||||
function table.keys(tbl, sorted, as_string)
|
||||
if not tbl then return {} end
|
||||
local keyset = {}
|
||||
local n = 0
|
||||
if as_string then --checking as_string /before/ looping is faster
|
||||
for k, _ in pairs(tbl) do
|
||||
n = n + 1
|
||||
keyset[n] = tostring(k)
|
||||
end
|
||||
else
|
||||
for k, _ in pairs(tbl) do
|
||||
n = n + 1
|
||||
keyset[n] = k
|
||||
end
|
||||
end
|
||||
if sorted then
|
||||
table.sort(keyset,
|
||||
function(x, y) --sorts tables with mixed index types.
|
||||
local tx = type(x) == 'number'
|
||||
local ty = type(y) == 'number'
|
||||
if tx == ty then
|
||||
return x < y and true or false --similar type can be compared
|
||||
elseif tx == true then
|
||||
return true --only x is a number and goes first
|
||||
else
|
||||
return false --only y is a number and goes first
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
return keyset
|
||||
end
|
||||
|
||||
--- Removes keys from a table by setting the values associated with the keys to nil.
|
||||
-- @usage local a = {1, 2, 3, 4}
|
||||
--table.remove_keys(a, {1,3}) --returns {nil, 2, nil, 4}
|
||||
-- @usage local b = {k1 = 1, k2 = 'foo', old_key = 'bar'}
|
||||
--table.remove_keys(b, {'old_key'}) --returns {k1 = 1, k2 = 'foo'}
|
||||
-- @tparam table tbl the table to remove the keys from
|
||||
-- @tparam {Mixed,...} keys an array of keys that exist in the given table
|
||||
-- @treturn table tbl without the specified keys
|
||||
function table.remove_keys(tbl, keys)
|
||||
for i = 1, #keys do
|
||||
tbl[keys[i]] = nil
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
--- Returns the number of keys in a table, if func is passed only count keys when the function is true.
|
||||
-- @tparam table tbl to count keys
|
||||
-- @tparam[opt] function func to incremement counter
|
||||
-- @param[optchain] ... additional arguments passed to the function
|
||||
-- @treturn number The number of keys matching the function or the number of all keys if func isn't passed
|
||||
-- @treturn number The total number of keys
|
||||
-- @usage local a = { 1, 2, 3, 4, 5}
|
||||
-- table.count_keys(a) -- produces: 5, 5
|
||||
-- @usage local a = {1, 2, 3, 4, 5}
|
||||
-- table.count_keys(a, function(v, k) return k % 2 == 1 end) -- produces: 3, 5
|
||||
function table.count_keys(tbl, func, ...)
|
||||
if type(tbl) ~= 'table' then return 0, 0 end
|
||||
local count, total = 0, 0
|
||||
for k, v in pairs(tbl) do
|
||||
total = total + 1
|
||||
if func then
|
||||
if func(v, k, ...) then
|
||||
count = count + 1
|
||||
end
|
||||
else
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
return count, total
|
||||
end
|
||||
|
||||
--- Returns an inverted (***{[value] = key,...}***) copy of the given table. If the values are not unique, the assigned key depends on the order of pairs().
|
||||
-- @usage local a = {k1 = 'foo', k2 = 'bar'}
|
||||
--table.invert(a) --returns {'foo' = k1, 'bar' = k2}
|
||||
-- @usage local b = {k1 = 'foo', k2 = 'bar', k3 = 'bar'}
|
||||
--table.invert(b) --returns {'foo' = k1, 'bar' = ?}
|
||||
-- @tparam table tbl the table to invert
|
||||
-- @treturn table a new table with inverted mapping
|
||||
function table.invert(tbl)
|
||||
local inverted = {}
|
||||
for k, v in pairs(tbl) do
|
||||
inverted[v] = k
|
||||
end
|
||||
return inverted
|
||||
end
|
||||
|
||||
--- Return the size of a table using built in table_size function
|
||||
-- @function size
|
||||
-- @tparam table table to use
|
||||
-- @treturn int size of the table
|
||||
table.size = table_size
|
||||
|
||||
--- For all string or number values in an array map them to a key = true table
|
||||
-- @usage local a = {"v1", "v2"}
|
||||
-- table.array_to_dict_bool(a) -- return {["v1"] = true, ["v2"]= true}
|
||||
-- @tparam table tbl the table to convert
|
||||
-- @treturn table the converted table
|
||||
function table.arr_to_bool(tbl)
|
||||
local newtbl = {}
|
||||
for _, v in pairs(tbl) do
|
||||
if type(v) == "string" or type(v) == "number" then
|
||||
newtbl[v] = true
|
||||
end
|
||||
end
|
||||
return newtbl
|
||||
end
|
||||
|
||||
-- Any thing below here i (cooldude2606) have added and was not here by default
|
||||
--- Returns a value in a form able to be read as a value
|
||||
-- @usage local a = 'value'
|
||||
-- table.val_to_str(a) -- return '"value"'
|
||||
-- @param v value to convert
|
||||
-- @treturn string the converted value
|
||||
function table.val_to_str(v)
|
||||
if "string" == type( v ) then
|
||||
v = string.gsub(v,"\n","\\n")
|
||||
if string.match(string.gsub(v,"[^'\"]",""),'^"+$') then
|
||||
return "'"..v.."'"
|
||||
end
|
||||
return '"'..string.gsub(v,'"', '\\"' )..'"'
|
||||
else
|
||||
return "table" == type( v) and table.to_string(v) or
|
||||
"function" == type(v) and '"cant-display-function"' or
|
||||
"userdata" == type(v) and '"cant-display-userdata"' or
|
||||
tostring(v)
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a value in a form able to be read as a key
|
||||
-- @usage local a = 'key'
|
||||
-- table.key_to_str(a) -- return '["key"]'
|
||||
-- @param k key to convert
|
||||
-- @treturn string the converted key
|
||||
function table.key_to_str (k)
|
||||
if "string" == type(k) and string.match(k,"^[_%player][_%player%d]*$") then
|
||||
return k
|
||||
else
|
||||
return "["..table.val_to_str(k).."]"
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns a table in a form able to be read as a table
|
||||
-- @usage local a = {k1='foo',k2='bar'}
|
||||
-- table.tostring(a) -- return '{["k1"]="foo",["k2"]="bar"}'
|
||||
-- @tparam table tbl table to convert
|
||||
-- @treturn string the converted table
|
||||
function table.to_string(tbl)
|
||||
local result, done = {}, {}
|
||||
for k, v in ipairs(tbl) do
|
||||
table.insert(result,table.val_to_str(v))
|
||||
done[k] = true
|
||||
end
|
||||
for k, v in pairs(tbl) do
|
||||
if not done[k] then
|
||||
table.insert(result,
|
||||
table.key_to_str(k).."="..table.val_to_str(v))
|
||||
end
|
||||
end
|
||||
return "{"..table.concat(result,",") .."}"
|
||||
end
|
||||
|
||||
--- Simmilar to table.to_string but converts a lua table to a json one
|
||||
-- @usage local a = {k1='foo',k2='bar'}
|
||||
-- talbe.json(a) -- return '{"k1":"foo","k2":"bar"}'
|
||||
-- @tparam table lua_table the table to convert
|
||||
-- @treturn string the table in a json format
|
||||
function table.json(lua_table)
|
||||
local result, done, only_indexs = {}, {}, true
|
||||
for key,value in ipairs(lua_table) do
|
||||
done[key] = true
|
||||
if type(value) == 'table' then table.insert(result,table.json(value,true))
|
||||
elseif type(value) == 'string' then table.insert(result,'"'..value..'"')
|
||||
elseif type(value) == 'number' then table.insert(result,value)
|
||||
elseif type(value) == 'boolean' then table.insert(result,tostring(value))
|
||||
else table.insert(result,'null')
|
||||
end
|
||||
end
|
||||
for key,value in pairs(lua_table) do
|
||||
if not done[key] then
|
||||
only_indexs = false
|
||||
if type(value) == 'table' then table.insert(result,'"'..key..'":'..table.json(value,true))
|
||||
elseif type(value) == 'string' then table.insert(result,'"'..key..'":"'..value..'"')
|
||||
elseif type(value) == 'number' then table.insert(result,'"'..key..'":'..value)
|
||||
elseif type(value) == 'boolean' then table.insert(result,'"'..key..'":'..tostring(value))
|
||||
else table.insert(result,'"'..key..'":null')
|
||||
end
|
||||
end
|
||||
end
|
||||
if only_indexs then return "["..table.concat(result,",").."]"
|
||||
else return "{"..table.concat(result,",").."}"
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns the closest match to a key
|
||||
-- @usage tbl = {foo=1,bar=2}
|
||||
-- table.autokey(tbl,'f') -- return 1
|
||||
function table.autokey(tbl,str)
|
||||
local _return = {}
|
||||
for key,value in pairs(tbl) do
|
||||
if string.contains(string.lower(key),string.lower(str)) then table.insert(_return,value) end
|
||||
end
|
||||
return _return[1] or false
|
||||
end
|
||||
@@ -1,31 +0,0 @@
|
||||
--- A defines module for retrieving the number of ticks in 1 unit of time.
|
||||
-- Extends the Factorio defines table.
|
||||
-- @module defines.time
|
||||
-- @usage require('stdlib/defines/time')
|
||||
|
||||
-- defines table is automatically required in all mod loading stages.
|
||||
-- luacheck: ignore 122/defines
|
||||
-- Ignore assigning to read only defines table. defines table is not read only, however
|
||||
-- marking it this way allows warnings to be generated when trying to assign values.
|
||||
|
||||
defines = defines or {} --luacheck: ignore defines (This is used for testing locally)
|
||||
|
||||
local SECOND = 60
|
||||
local MINUTE = SECOND * 60
|
||||
local HOUR = MINUTE * 60
|
||||
local DAY = HOUR * 24
|
||||
local WEEK = DAY * 7
|
||||
local MONTH = DAY * 30
|
||||
local YEAR = DAY * 365
|
||||
|
||||
--- Returns the number of ticks in a second, minute, hour, day, week, month, or year.
|
||||
-- @usage local ten_seconds = defines.time.second * 10
|
||||
defines.time = {
|
||||
second = SECOND, -- the number of Factorio ticks in a second
|
||||
minute = MINUTE, -- the number of Factorio ticks in a second
|
||||
hour = HOUR, -- the number of Factorio ticks in an hour
|
||||
day = DAY, -- the number of Factorio ticks in an day
|
||||
week = WEEK, -- the number of Factorio ticks in a week
|
||||
month = MONTH, -- the number of Factorio ticks in a month (30 days)
|
||||
year = YEAR, -- the number of Factorio ticks in a year (365 days)
|
||||
}
|
||||
Reference in New Issue
Block a user